From 01d517cc277bc5eca5ff129280a9670e3385a09e Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:29:37 +0700 Subject: [PATCH] feat: add new employee while add worker after accepted --- src/controllers/05-quotation-controller.ts | 114 ++++++++++++++++++--- 1 file changed, 102 insertions(+), 12 deletions(-) diff --git a/src/controllers/05-quotation-controller.ts b/src/controllers/05-quotation-controller.ts index 447e12a..e653883 100644 --- a/src/controllers/05-quotation-controller.ts +++ b/src/controllers/05-quotation-controller.ts @@ -923,14 +923,63 @@ export class QuotationActionController extends Controller { @Request() req: RequestWithUser, @Path() quotationId: string, @Body() - body: { - workerId: string; - productServiceId: string[]; - }[], + body: ( + | { + workerId: string; + productServiceId: string[]; + } + | { + workerData: { + dateOfBirth: Date; + gender: string; + nationality: string; + namePrefix?: string; + firstName: string; + firstNameEN: string; + middleName?: string; + middleNameEN?: string; + lastName: string; + lastNameEN: string; + }; + productServiceId: string[]; + } + )[], ) { + const { existsEmployee, newEmployee } = body.reduce<{ + existsEmployee: { + workerId: string; + productServiceId: string[]; + }[]; + newEmployee: { + workerData: { + dateOfBirth: Date; + gender: string; + nationality: string; + namePrefix?: string; + firstName: string; + firstNameEN: string; + middleName?: string; + middleNameEN?: string; + lastName: string; + lastNameEN: string; + }; + productServiceId: string[]; + }[]; + }>( + (acc, current) => { + if ("workerId" in current) { + acc.existsEmployee.push(current); + } else { + acc.newEmployee.push(current); + } + return acc; + }, + { existsEmployee: [], newEmployee: [] }, + ); + const ids = { - employee: body.map((v) => v.workerId), - productService: body + employee: existsEmployee.map((v) => v.workerId), + productService: existsEmployee .flatMap((v) => v.productServiceId) .filter((lhs, i, a) => a.findIndex((rhs) => lhs === rhs) === i), }; @@ -940,6 +989,7 @@ export class QuotationActionController extends Controller { await Promise.all([ tx.quotation.findFirst({ include: { + customerBranch: true, worker: true, _count: { select: { @@ -965,11 +1015,13 @@ export class QuotationActionController extends Controller { if (ids.productService.length !== productService.length) throw relationError("Product"); if ( quotation._count.worker + - body.filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId)) - .length > + existsEmployee.filter( + (lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId), + ).length + + newEmployee.length > (quotation.workerMax || 0) ) { - if (body.length === 0) return; + if (existsEmployee.length === 0) return; throw new HttpError( HttpStatus.PRECONDITION_FAILED, "Worker exceed current quotation max worker.", @@ -978,8 +1030,46 @@ export class QuotationActionController extends Controller { } await prisma.$transaction(async (tx) => { + const customerBranch = quotation.customerBranch; + const lastEmployee = await tx.runningNo.upsert({ + where: { + key: `EMPLOYEE_${customerBranch.id}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}`, + }, + create: { + key: `EMPLOYEE_${customerBranch.id}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}`, + value: newEmployee.length, + }, + update: { value: { increment: newEmployee.length } }, + }); + + const newEmployeeWithId = await Promise.all( + newEmployee.map(async (v, i) => { + const data = await tx.employee.create({ + data: { + ...v.workerData, + code: `${customerBranch.code}-${`${new Date().getFullYear()}`.slice(-2).padStart(2, "0")}${`${lastEmployee.value - nonExistEmployee.length + i + 1}`.padStart(7, "0")}`, + customerBranchId: customerBranch.id, + }, + }); + + return { workerId: data.id, productServiceId: v.productServiceId }; + }), + ); + + const rearrange: typeof existsEmployee = []; + + while (body.length > 0) { + const item = body.shift(); + if (item && "workerId" in item) { + rearrange.push(item); + } else { + const popNew = newEmployeeWithId.shift(); + popNew && rearrange.push(popNew); + } + } + await tx.quotationProductServiceWorker.createMany({ - data: body + data: existsEmployee .filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId)) .flatMap((lhs) => lhs.productServiceId.map((rhs) => ({ @@ -1010,7 +1100,7 @@ export class QuotationActionController extends Controller { quotationStatus: QuotationStatus.PaymentSuccess, // NOTE: change back if already complete or canceled worker: { createMany: { - data: body + data: rearrange .filter((lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId)) .map((v, i) => ({ no: quotation._count.worker + i + 1, @@ -1022,7 +1112,7 @@ export class QuotationActionController extends Controller { quotation.quotationStatus === "PaymentInProcess" || quotation.quotationStatus === "PaymentSuccess" ? { - create: body + create: rearrange .filter( (lhs) => !quotation.worker.find((rhs) => rhs.employeeId === lhs.workerId) &&