refactor: customer structure

This commit is contained in:
Methapon Metanipat 2024-09-13 13:27:12 +07:00
parent eaf8ce3fd1
commit 4dee7bfe71
4 changed files with 156 additions and 79 deletions

View file

@ -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;

View file

@ -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

View file

@ -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: {

View file

@ -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,