diff --git a/src/controllers/customer-branch-controller.ts b/src/controllers/customer-branch-controller.ts index c2220cc..0cf41ad 100644 --- a/src/controllers/customer-branch-controller.ts +++ b/src/controllers/customer-branch-controller.ts @@ -29,7 +29,7 @@ function imageLocation(id: string) { return `employee/profile-img-${id}`; } -type CustomerBranchCreate = { +export type CustomerBranchCreate = { customerId: string; status?: Status; @@ -56,7 +56,7 @@ type CustomerBranchCreate = { provinceId?: string | null; }; -type CustomerBranchUpdate = { +export type CustomerBranchUpdate = { customerId?: string; status?: "ACTIVE" | "INACTIVE"; diff --git a/src/controllers/customer-controller.ts b/src/controllers/customer-controller.ts index 4be81cf..086a8d2 100644 --- a/src/controllers/customer-controller.ts +++ b/src/controllers/customer-controller.ts @@ -18,6 +18,7 @@ import prisma from "../db"; import minio from "../services/minio"; import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; +import { CustomerBranchCreate, CustomerBranchUpdate } from "./customer-branch-controller"; if (!process.env.MINIO_BUCKET) { throw Error("Require MinIO bucket."); @@ -30,6 +31,7 @@ export type CustomerCreate = { customerType: CustomerType; customerName: string; customerNameEN: string; + customerBranch?: Omit[]; }; export type CustomerUpdate = { @@ -37,6 +39,7 @@ export type CustomerUpdate = { customerType?: CustomerType; customerName?: string; customerNameEN?: string; + customerBranch?: (Omit & { id: string })[]; }; function imageLocation(id: string) { @@ -103,10 +106,74 @@ export class CustomerController extends Controller { const code = `${body.customerType}${(+(last?.code.slice(-6) || 0) + 1).toString().padStart(6, "0")}`; + const { customerBranch, ...payload } = body; + + const provinceId = body.customerBranch?.reduce((acc, cur) => { + if (cur.provinceId && !acc.includes(cur.provinceId)) return acc.concat(cur.provinceId); + return acc; + }, []); + const districtId = body.customerBranch?.reduce((acc, cur) => { + if (cur.districtId && !acc.includes(cur.districtId)) return acc.concat(cur.districtId); + return acc; + }, []); + const subDistrictId = body.customerBranch?.reduce((acc, cur) => { + if (cur.subDistrictId && !acc.includes(cur.subDistrictId)) + return acc.concat(cur.subDistrictId); + return acc; + }, []); + + const [province, district, subDistrict] = await prisma.$transaction([ + prisma.province.findMany({ where: { id: { in: provinceId } } }), + prisma.district.findMany({ where: { id: { in: districtId } } }), + prisma.subDistrict.findMany({ where: { id: { in: subDistrictId } } }), + ]); + + if (provinceId && province.length !== provinceId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some province cannot be found.", + "missing_or_invalid_parameter", + ); + } + if (districtId && district.length !== districtId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some district cannot be found.", + "missing_or_invalid_parameter", + ); + } + if (subDistrictId && subDistrict.length !== subDistrictId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some sub district cannot be found.", + "missing_or_invalid_parameter", + ); + } + const record = await prisma.customer.create({ + include: { + branch: { + include: { + province: true, + district: true, + subDistrict: true, + }, + }, + }, data: { - ...body, + ...payload, code, + branch: { + createMany: { + data: + customerBranch?.map((v, i) => ({ + ...v, + branchNo: `${i + 1}`, + createdBy: req.user.name, + updateBy: req.user.name, + })) || [], + }, + }, createdBy: req.user.name, updateBy: req.user.name, }, @@ -138,11 +205,61 @@ export class CustomerController extends Controller { throw new HttpError(HttpStatus.NOT_FOUND, "Customer cannot be found.", "data_not_found"); } + const provinceId = body.customerBranch?.reduce((acc, cur) => { + if (cur.provinceId && !acc.includes(cur.provinceId)) return acc.concat(cur.provinceId); + return acc; + }, []); + const districtId = body.customerBranch?.reduce((acc, cur) => { + if (cur.districtId && !acc.includes(cur.districtId)) return acc.concat(cur.districtId); + return acc; + }, []); + const subDistrictId = body.customerBranch?.reduce((acc, cur) => { + if (cur.subDistrictId && !acc.includes(cur.subDistrictId)) + return acc.concat(cur.subDistrictId); + return acc; + }, []); + + const [province, district, subDistrict] = await prisma.$transaction([ + prisma.province.findMany({ where: { id: { in: provinceId } } }), + prisma.district.findMany({ where: { id: { in: districtId } } }), + prisma.subDistrict.findMany({ where: { id: { in: subDistrictId } } }), + ]); + + if (provinceId && province.length !== provinceId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some province cannot be found.", + "missing_or_invalid_parameter", + ); + } + if (districtId && district.length !== districtId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some district cannot be found.", + "missing_or_invalid_parameter", + ); + } + if (subDistrictId && subDistrict.length !== subDistrictId?.length) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Some sub district cannot be found.", + "missing_or_invalid_parameter", + ); + } + + const { customerBranch, ...payload } = body; + const record = await prisma.customer.update({ where: { id: customerId }, data: { - ...body, - createdBy: req.user.name, + ...payload, + branch: { + updateMany: + customerBranch?.map((v) => ({ + where: { id: v.id }, + data: { ...v, updateBy: req.user.name }, + })) || [], + }, updateBy: req.user.name, }, });