diff --git a/prisma/migrations/20240913062608_update_fields/migration.sql b/prisma/migrations/20240913062608_update_fields/migration.sql new file mode 100644 index 0000000..fe39123 --- /dev/null +++ b/prisma/migrations/20240913062608_update_fields/migration.sql @@ -0,0 +1,37 @@ +/* + Warnings: + + - You are about to drop the column `birthDate` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `firstName` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `firstNameEN` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `gender` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `lastName` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `lastNameEN` on the `Customer` table. All the data in the column will be lost. + - You are about to drop the column `namePrefix` on the `Customer` table. All the data in the column will be lost. + - Made the column `registeredBranchId` on table `Customer` required. This step will fail if there are existing NULL values in that column. + +*/ +-- DropForeignKey +ALTER TABLE "Customer" DROP CONSTRAINT "Customer_registeredBranchId_fkey"; + +-- AlterTable +ALTER TABLE "Customer" DROP COLUMN "birthDate", +DROP COLUMN "firstName", +DROP COLUMN "firstNameEN", +DROP COLUMN "gender", +DROP COLUMN "lastName", +DROP COLUMN "lastNameEN", +DROP COLUMN "namePrefix", +ALTER COLUMN "registeredBranchId" SET NOT NULL; + +-- AlterTable +ALTER TABLE "CustomerBranch" ADD COLUMN "birthDate" DATE, +ADD COLUMN "firstName" TEXT, +ADD COLUMN "firstNameEN" TEXT, +ADD COLUMN "gender" TEXT, +ADD COLUMN "lastName" TEXT, +ADD COLUMN "lastNameEN" TEXT, +ADD COLUMN "namePrefix" TEXT; + +-- AddForeignKey +ALTER TABLE "Customer" ADD CONSTRAINT "Customer_registeredBranchId_fkey" FOREIGN KEY ("registeredBranchId") REFERENCES "Branch"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d36d78e..87147f2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -420,22 +420,6 @@ model Customer { id String @id @default(cuid()) customerType CustomerType - telephoneNo String - - namePrefix String? - firstName String? - firstNameEN String? - lastName String? - lastNameEN String? - gender String? - birthDate DateTime? @db.Date - citizenId String? - - legalPersonNo String? - registerName String? - registerNameEN String? - businessType String? - jobPosition String? status Status @default(CREATED) statusOrder Int @default(0) @@ -464,8 +448,18 @@ model CustomerBranch { code String codeCustomer String + telephoneNo String + // NOTE: About (Natural Person) - citizenId String? + namePrefix String? + firstName String? + firstNameEN String? + lastName String? + lastNameEN String? + gender String? + birthDate DateTime? @db.Date + citizenId String? + // NOTE: About (Legal Entity) legalPersonNo String? registerName String? @@ -496,7 +490,6 @@ model CustomerBranch { email String contactName String - telephoneNo String employmentOffice String businessType String diff --git a/src/controllers/03-customer-branch-controller.ts b/src/controllers/03-customer-branch-controller.ts index 5769911..f9487d0 100644 --- a/src/controllers/03-customer-branch-controller.ts +++ b/src/controllers/03-customer-branch-controller.ts @@ -177,17 +177,11 @@ export class CustomerBranchController extends Controller { { registerNameEN: { contains: query } }, { email: { contains: query } }, { code: { contains: query } }, + { firstName: { contains: query } }, + { firstNameEN: { contains: query } }, + { lastName: { contains: query } }, + { lastNameEN: { contains: query } }, ...whereAddressQuery(query), - { - customer: { - OR: [ - { firstName: { contains: query } }, - { firstNameEN: { contains: query } }, - { lastName: { contains: query } }, - { lastNameEN: { contains: query } }, - ], - }, - }, ] : undefined, AND: { @@ -263,7 +257,6 @@ export class CustomerBranchController extends Controller { { firstNameEN: { contains: query } }, { lastName: { contains: query } }, { lastNameEN: { contains: query } }, - { passportNumber: { contains: query } }, ...whereAddressQuery(query), ], AND: { diff --git a/src/controllers/03-customer-controller.ts b/src/controllers/03-customer-controller.ts index 500104e..996fe1e 100644 --- a/src/controllers/03-customer-controller.ts +++ b/src/controllers/03-customer-controller.ts @@ -45,52 +45,60 @@ function globalAllow(user: RequestWithUser["user"]) { const permissionCond = createPermCondition(globalAllow); const permissionCheck = createPermCheck(globalAllow); -export type CustomerCreate = ( - | { - namePrefix: string; - firstName: string; - firstNameEN?: string; - lastName: string; - lastNameEN?: string; - gender: string; - birthDate: Date; - telephoneNo: string; - } - | { - legalPersonNo: string; - registerName: string; - registerNameEN?: string; - businessType: string; - jobPosition: string; - telephoneNo: string; - } -) & { +export type CustomerCreate = { registeredBranchId: string; - status?: Status; customerType: CustomerType; + status?: Status; selectedImage?: string; + + branch: (( + | { + // NOTE: About (Natural Person) + citizenId: string; + } + | { + // NOTE: About (Legal Entity) + legalPersonNo: string; + registerName: string; + registerNameEN: string; + registerDate: Date; + authorizedCapital: string; + } + ) & { + status?: Status; + + workplace: string; + workplaceEN: string; + address: string; + addressEN: string; + soi?: string | null; + soiEN?: string | null; + moo?: string | null; + mooEN?: string | null; + street?: string | null; + streetEN?: string | null; + + email: string; + contactName: string; + telephoneNo: string; + + employmentOffice: string; + businessType: string; + businessTypeEN: string; + jobPosition: string; + jobPositionEN: string; + jobDescription: string; + saleEmployee: string; + payDate: Date; + wageRate: number; + + subDistrictId?: string | null; + districtId?: string | null; + provinceId?: string | null; + })[]; }; -export type CustomerUpdate = ( - | { - namePrefix: string; - firstName: string; - firstNameEN?: string; - lastName: string; - lastNameEN?: string; - gender: string; - birthDate: Date; - telephoneNo: string; - } - | { - legalPersonNo: string; - registerName: string; - registerNameEN: string; - businessType: string; - jobPosition: string; - telephoneNo: string; - } -) & { +export type CustomerUpdate = { registeredBranchId?: string; status?: "ACTIVE" | "INACTIVE"; customerType?: CustomerType; @@ -135,11 +143,15 @@ export class CustomerController extends Controller { @Query() includeBranch: boolean = false, ) { const where = { - OR: [ - { namePrefix: { contains: query } }, - { firstName: { contains: query } }, - { firstNameEN: { contains: query } }, - ], + OR: query + ? [ + { branch: { some: { namePrefix: { contains: query } } } }, + { branch: { some: { firstName: { contains: query } } } }, + { branch: { some: { firstNameEN: { contains: query } } } }, + { branch: { some: { lastName: { contains: query } } } }, + { branch: { some: { lastNameEN: { contains: query } } } }, + ] + : undefined, AND: { customerType, ...filterStatus(status), @@ -160,7 +172,15 @@ export class CustomerController extends Controller { }, orderBy: { createdAt: "asc" }, } - : undefined, + : { + include: { + province: true, + district: true, + subDistrict: true, + }, + take: 1, + orderBy: { createdAt: "asc" }, + }, createdBy: true, updatedBy: true, }, @@ -204,14 +224,14 @@ export class CustomerController extends Controller { @Post() @Security("keycloak", MANAGE_ROLES) async create(@Request() req: RequestWithUser, @Body() body: CustomerCreate) { - const [branch] = await prisma.$transaction([ + const [registeredBranch] = await prisma.$transaction([ prisma.branch.findFirst({ where: { id: body.registeredBranchId }, include: branchRelationPermInclude(req.user), }), ]); - await permissionCheck(req.user, branch); + await permissionCheck(req.user, registeredBranch); const record = await prisma.$transaction( async (tx) => { @@ -225,6 +245,31 @@ export class CustomerController extends Controller { statusOrder: 1, }, }); + + const { branch, ...rest } = body; + + const company = (registeredBranch?.headOffice || registeredBranch)?.code; + const headoffice = branch[0]; + + if (!headoffice) { + throw new HttpError( + HttpStatus.BAD_REQUEST, + "Require at least one branch as headoffice", + "requireOneMinBranch", + ); + } + + const runningKey = `CUSTOMER_BRANCH_${company}_${"citizenId" in headoffice ? headoffice.citizenId : headoffice.legalPersonNo}`; + + const last = await tx.runningNo.upsert({ + where: { key: runningKey }, + create: { + key: runningKey, + value: branch.length, + }, + update: { value: { increment: branch.length } }, + }); + return await tx.customer.create({ include: { branch: { @@ -238,7 +283,16 @@ export class CustomerController extends Controller { updatedBy: true, }, data: { - ...body, + ...rest, + branch: { + create: branch.map((v, i) => ({ + ...v, + code: `${runningKey.replace("CUSTOMER_BRANCH_", "")}-${`${last.value - branch.length + i}`.padStart(2, "0")}`, + codeCustomer: runningKey.replace("CUSTOMER_BRANCH_", ""), + createdBy: { connect: { id: req.user.sub } }, + updatedBy: { connect: { id: req.user.sub } }, + })), + }, statusOrder: +(body.status === "INACTIVE"), createdByUserId: req.user.sub, updatedByUserId: req.user.sub,