diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index 7306749..1aebe39 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -40,7 +40,7 @@ jobs: port: ${{ vars.SSH_DEVELOPMENT_PORT }} username: ${{ secrets.SSH_DEVELOPMENT_USER }} password: ${{ secrets.SSH_DEVELOPMENT_PASSWORD }} - script: eval "${{ secrets.SSH_DEVELOPMENT_DEPLOY_CMD }}" & wait + script: eval "${{ secrets.SSH_DEVELOPMENT_DEPLOY_CMD }}" - name: Remote Deploy Test uses: appleboy/ssh-action@v1.2.1 with: @@ -48,7 +48,7 @@ jobs: port: ${{ vars.SSH_TEST_PORT }} username: ${{ secrets.SSH_TEST_USER }} password: ${{ secrets.SSH_TEST_PASSWORD }} - script: eval "${{ secrets.SSH_TEST_DEPLOY_CMD }}" & wait + script: eval "${{ secrets.SSH_TEST_DEPLOY_CMD }}" - name: Notify Discord Success if: success() run: | diff --git a/.forgejo/workflows/spellcheck.yaml b/.forgejo/workflows/spellcheck.yaml index 6b36c63..468d970 100644 --- a/.forgejo/workflows/spellcheck.yaml +++ b/.forgejo/workflows/spellcheck.yaml @@ -5,8 +5,6 @@ permissions: on: push: - branches: - - develop env: CLICOLOR: 1 diff --git a/src/controllers/06-request-list-controller.ts b/src/controllers/06-request-list-controller.ts index ec0da9c..bbb2e39 100644 --- a/src/controllers/06-request-list-controller.ts +++ b/src/controllers/06-request-list-controller.ts @@ -287,6 +287,217 @@ export class RequestDataActionController extends Controller { ]); }); } + + @Put("request-work/step-status/{step}") + @Security("keycloak") + async updateRequestWorkDataStepStatus( + @Path() requestDataId: string, + @Path() step: number, + @Body() + payload: { + workStatus?: RequestWorkStatus; + requestWorkId: string; + attributes?: Record; + customerDuty?: boolean | null; + customerDutyCost?: number | null; + companyDuty?: boolean | null; + companyDutyCost?: number | null; + individualDuty?: boolean | null; + individualDutyCost?: number | null; + responsibleUserLocal?: boolean | null; + responsibleUserId?: string | null; + }[], + ) { + payload.forEach((item) => { + if (!item.responsibleUserId) item.responsibleUserId = undefined; + }); + return await prisma.$transaction(async (tx) => { + const workStepCondition = await tx.requestData.findFirst({ + where: { + id: requestDataId, + }, + select: { id: true }, + }); + + if (!workStepCondition) { + throw new Error("RequestWork not found requestDataId"); + } + + const data = await Promise.all( + payload.map(async (item) => { + return await tx.requestWorkStepStatus.upsert({ + include: { + requestWork: { + include: { + request: true, + }, + }, + }, + where: { + step_requestWorkId: { + step: step, + requestWorkId: item.requestWorkId, + }, + requestWork: { + request: { id: requestDataId }, + }, + }, + create: { + ...item, + step: step, + requestWorkId: item.requestWorkId, + }, + update: item, + }); + }), + ); + + if ( + data.some((item) => { + return ( + item.workStatus === "Ready" && item.requestWork.request.requestDataStatus === "Pending" + ); + }) + ) { + await tx.requestData.updateMany({ + where: { + id: requestDataId, + requestDataStatus: "Pending", + }, + data: { requestDataStatus: "Ready" }, + }); + } + + if ( + data.some((item) => { + return ( + item.workStatus === "InProgress" || + item.workStatus === "Waiting" || + item.workStatus === "Validate" || + item.workStatus === "Completed" || + item.workStatus === "Ended" + ); + }) + ) { + await tx.requestData.update({ + where: { + id: requestDataId, + }, + data: { requestDataStatus: "InProgress" }, + }); + } + + if ( + data.some((item) => { + return item.workStatus === "Canceled"; + }) + ) { + const dataId = data.map((itemId) => itemId.requestWork.id); + await tx.task.updateMany({ + where: { + taskStatus: { notIn: [TaskStatus.Complete, TaskStatus.Redo] }, + requestWorkStep: { + step: step, + requestWorkId: { in: dataId }, + workStatus: { notIn: [RequestWorkStatus.Completed, RequestWorkStatus.Ended] }, + }, + }, + data: { taskStatus: TaskStatus.Canceled }, + }); + await Promise.all([ + tx.quotation.updateMany({ + where: { + requestData: { + every: { requestDataStatus: RequestDataStatus.Canceled }, + }, + }, + data: { quotationStatus: QuotationStatus.Canceled, urgent: false }, + }), + tx.taskOrder.updateMany({ + where: { + taskList: { + every: { taskStatus: TaskStatus.Canceled }, + }, + }, + data: { taskOrderStatus: TaskStatus.Canceled }, + }), + ]); + } + + const requestList = await tx.requestData.findMany({ + include: { + requestWork: { + include: { + productService: { + include: { + product: true, + service: true, + work: { + include: { productOnWork: true }, + }, + }, + }, + stepStatus: true, + }, + }, + }, + where: { + requestWork: { + some: { + requestDataId: requestDataId, + }, + }, + }, + }); + + const completed: string[] = []; + + requestList.forEach((item) => { + const completeCheck = item.requestWork.every((work) => { + const stepCount = + work.productService.work?.productOnWork.find( + (v) => v.productId === work.productService.productId, + )?.stepCount || 0; + + const completeCount = work.stepStatus.filter( + (v) => + v.workStatus === RequestWorkStatus.Completed || + v.workStatus === RequestWorkStatus.Ended || + v.workStatus === RequestWorkStatus.Canceled, + ).length; + + // NOTE: step found then check if complete count equals step count + if (stepCount === completeCount && completeCount > 0) return true; + // NOTE: likely no step found and completed at least one + if (stepCount === 0 && completeCount > 0) return true; + }); + + if (completeCheck) completed.push(item.id); + }); + + await tx.requestData.updateMany({ + where: { id: { in: completed } }, + data: { requestDataStatus: RequestDataStatus.Completed }, + }); + await tx.quotation.updateMany({ + where: { + quotationStatus: { + notIn: [QuotationStatus.Canceled, QuotationStatus.ProcessComplete], + }, + requestData: { + every: { + requestDataStatus: { + in: [RequestDataStatus.Canceled, RequestDataStatus.Completed], + }, + }, + }, + }, + data: { quotationStatus: QuotationStatus.ProcessComplete, urgent: false }, + }); + // dataRecord.push(record); + return data; + }); + } } @Route("/api/v1/request-work")