refactor: customer create and update process

This commit is contained in:
Methapon Metanipat 2024-08-20 15:41:48 +07:00
parent b167a612b4
commit 5bb8da818c
6 changed files with 261 additions and 462 deletions

View file

@ -0,0 +1,56 @@
/*
Warnings:
- You are about to drop the column `customerName` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `customerNameEN` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `personName` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `personNameEN` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `taxNo` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `branchNo` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `bussinessType` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `bussinessTypeEN` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `name` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `nameEN` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `taxNo` on the `CustomerBranch` table. All the data in the column will be lost.
- You are about to drop the column `zipCode` on the `CustomerBranch` table. All the data in the column will be lost.
- Added the required column `birthDate` to the `Customer` table without a default value. This is not possible if the table is not empty.
- Added the required column `firstName` to the `Customer` table without a default value. This is not possible if the table is not empty.
- Added the required column `gender` to the `Customer` table without a default value. This is not possible if the table is not empty.
- Added the required column `lastName` to the `Customer` table without a default value. This is not possible if the table is not empty.
- Added the required column `businessType` to the `CustomerBranch` table without a default value. This is not possible if the table is not empty.
- Added the required column `businessTypeEN` to the `CustomerBranch` table without a default value. This is not possible if the table is not empty.
- Added the required column `workplace` to the `CustomerBranch` table without a default value. This is not possible if the table is not empty.
- Added the required column `workplaceEN` to the `CustomerBranch` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Customer" DROP COLUMN "customerName",
DROP COLUMN "customerNameEN",
DROP COLUMN "personName",
DROP COLUMN "personNameEN",
DROP COLUMN "taxNo",
ADD COLUMN "birthDate" TIMESTAMP(3) NOT NULL,
ADD COLUMN "firstName" TEXT NOT NULL,
ADD COLUMN "firstNameEN" TEXT,
ADD COLUMN "gender" TEXT NOT NULL,
ADD COLUMN "lastName" TEXT NOT NULL,
ADD COLUMN "lastNameEN" TEXT,
ADD COLUMN "namePrefix" TEXT;
-- AlterTable
ALTER TABLE "CustomerBranch" DROP COLUMN "branchNo",
DROP COLUMN "bussinessType",
DROP COLUMN "bussinessTypeEN",
DROP COLUMN "name",
DROP COLUMN "nameEN",
DROP COLUMN "taxNo",
DROP COLUMN "zipCode",
ADD COLUMN "businessType" TEXT NOT NULL,
ADD COLUMN "businessTypeEN" TEXT NOT NULL,
ADD COLUMN "citizenId" TEXT,
ADD COLUMN "workplace" TEXT NOT NULL,
ADD COLUMN "workplaceEN" TEXT NOT NULL,
ALTER COLUMN "legalPersonNo" DROP NOT NULL,
ALTER COLUMN "registerName" DROP NOT NULL,
ALTER COLUMN "registerDate" DROP NOT NULL,
ALTER COLUMN "authorizedCapital" DROP NOT NULL;

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "CustomerBranch" ADD COLUMN "legalPersonName" TEXT;

View file

@ -0,0 +1,13 @@
/*
Warnings:
- You are about to drop the column `code` on the `Customer` table. All the data in the column will be lost.
- You are about to drop the column `legalPersonName` on the `CustomerBranch` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Customer" DROP COLUMN "code";
-- AlterTable
ALTER TABLE "CustomerBranch" DROP COLUMN "legalPersonName",
ADD COLUMN "registerNameEN" TEXT;

View file

@ -403,14 +403,17 @@ enum CustomerType {
}
model Customer {
id String @id @default(uuid())
code String
personName String
personNameEN String?
customerType CustomerType
customerName String
customerNameEN String
taxNo String?
id String @id @default(uuid())
customerType CustomerType
namePrefix String?
firstName String
firstNameEN String?
lastName String
lastNameEN String?
gender String
birthDate DateTime
status Status @default(CREATED)
statusOrder Int @default(0)
@ -430,24 +433,25 @@ model Customer {
}
model CustomerBranch {
id String @id @default(uuid())
branchNo Int
code String
legalPersonNo String
name String
nameEN String
id String @id @default(uuid())
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
customerId String
taxNo String?
registerName String
registerDate DateTime
authorizedCapital String
code String
address String
addressEN String
// NOTE: About (Natural Person)
citizenId String?
// NOTE: About (Legal Entity)
legalPersonNo String?
registerName String?
registerNameEN String?
registerDate DateTime?
authorizedCapital String?
workplace String
workplaceEN String
address String
addressEN String
province Province? @relation(fields: [provinceId], references: [id], onDelete: SetNull)
provinceId String?
@ -458,14 +462,12 @@ model CustomerBranch {
subDistrict SubDistrict? @relation(fields: [subDistrictId], references: [id], onDelete: SetNull)
subDistrictId String?
zipCode String
email String
telephoneNo String
employmentOffice String
bussinessType String
bussinessTypeEN String
businessType String
businessTypeEN String
jobPosition String
jobPositionEN String
jobDescription String

View file

@ -137,27 +137,30 @@ export class CustomerBranchController extends Controller {
const where = {
OR: [
{ nameEN: { contains: query }, zipCode, ...filterStatus(status) },
{ name: { contains: query }, zipCode, ...filterStatus(status) },
{ email: { contains: query }, zipCode, ...filterStatus(status) },
{ code: { contains: query }, zipCode, ...filterStatus(status) },
{ address: { contains: query }, zipCode, ...filterStatus(status) },
{ addressEN: { contains: query }, zipCode, ...filterStatus(status) },
{ province: { name: { contains: query } }, zipCode, ...filterStatus(status) },
{ province: { nameEN: { contains: query } }, zipCode, ...filterStatus(status) },
{ district: { name: { contains: query } }, zipCode, ...filterStatus(status) },
{ district: { nameEN: { contains: query } }, zipCode, ...filterStatus(status) },
{ subDistrict: { name: { contains: query } }, zipCode, ...filterStatus(status) },
{ subDistrict: { nameEN: { contains: query } }, zipCode, ...filterStatus(status) },
{ registerName: { contains: query } },
{ registerNameEN: { contains: query } },
{ email: { contains: query } },
{ code: { contains: query } },
{ address: { contains: query } },
{ addressEN: { contains: query } },
{ province: { name: { contains: query } } },
{ province: { nameEN: { contains: query } } },
{ district: { name: { contains: query } } },
{ district: { nameEN: { contains: query } } },
{ subDistrict: { name: { contains: query } } },
{ subDistrict: { nameEN: { contains: query } } },
{
customer: {
OR: [{ customerName: { contains: query } }, { customerNameEN: { contains: query } }],
OR: [
{ firstName: { contains: query } },
{ firstNameEN: { contains: query } },
{ lastName: { contains: query } },
{ lastNameEN: { contains: query } },
],
},
zipCode,
status,
},
],
AND: { customerId },
AND: { customerId, subDistrict: zipCode ? { zipCode } : undefined, ...filterStatus(status) },
} satisfies Prisma.CustomerBranchWhereInput;
const [result, total] = await prisma.$transaction([
@ -263,7 +266,15 @@ export class CustomerBranchController extends Controller {
prisma.province.findFirst({ where: { id: body.provinceId || undefined } }),
prisma.district.findFirst({ where: { id: body.districtId || undefined } }),
prisma.subDistrict.findFirst({ where: { id: body.subDistrictId || undefined } }),
prisma.customer.findFirst({ where: { id: body.customerId || undefined } }),
prisma.customer.findFirst({
where: { id: body.customerId || undefined },
include: {
branch: {
take: 1,
orderBy: { createdAt: "asc" },
},
},
}),
]);
if (body.provinceId && !province)
throw new HttpError(
@ -294,48 +305,37 @@ export class CustomerBranchController extends Controller {
const record = await prisma.$transaction(
async (tx) => {
const conflict = await tx.customerBranch.findFirst({
where: { customerId, branchNo: rest.branchNo },
});
if (conflict) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Branch with current no already exists.",
"branchSameNoExist",
);
}
const last = await tx.runningNo.upsert({
where: {
key: `CUSTOMER_${customer.code.slice(0, -6)}`,
},
create: {
key: `CUSTOMER_${customer.code.slice(0, -6)}`,
value: 1,
},
update: { value: { increment: 1 } },
});
return await tx.customerBranch.create({
include: {
province: true,
district: true,
subDistrict: true,
createdBy: true,
updatedBy: true,
},
data: {
...rest,
statusOrder: +(rest.status === "INACTIVE"),
code: `${customer.code.slice(0, -6)}${`${last.value - 1}`.padStart(6, "0")}`,
customer: { connect: { id: customerId } },
province: { connect: provinceId ? { id: provinceId } : undefined },
district: { connect: districtId ? { id: districtId } : undefined },
subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined },
createdBy: { connect: { id: req.user.sub } },
updatedBy: { connect: { id: req.user.sub } },
},
});
// const last = await tx.runningNo.upsert({
// where: {
// key: `CUSTOMER_${customer.code.slice(0, -6)}`,
// },
// create: {
// key: `CUSTOMER_${customer.code.slice(0, -6)}`,
// value: 1,
// },
// update: { value: { increment: 1 } },
// });
//
// return await tx.customerBranch.create({
// include: {
// province: true,
// district: true,
// subDistrict: true,
// createdBy: true,
// updatedBy: true,
// },
// data: {
// ...rest,
// statusOrder: +(rest.status === "INACTIVE"),
// code: `${customer.code.slice(0, -6)}${`${last.value - 1}`.padStart(6, "0")}`,
// customer: { connect: { id: customerId } },
// province: { connect: provinceId ? { id: provinceId } : undefined },
// district: { connect: districtId ? { id: districtId } : undefined },
// subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined },
// createdBy: { connect: { id: req.user.sub } },
// updatedBy: { connect: { id: req.user.sub } },
// },
// });
},
{ isolationLevel: Prisma.TransactionIsolationLevel.Serializable },
);
@ -352,6 +352,12 @@ export class CustomerBranchController extends Controller {
@Body() body: CustomerBranchUpdate,
@Path() branchId: string,
) {
const branch = await prisma.customerBranch.findUnique({ where: { id: branchId } });
if (!branch) {
throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound");
}
if (body.provinceId || body.districtId || body.subDistrictId || body.customerId) {
const [province, district, subDistrict, customer] = await prisma.$transaction([
prisma.province.findFirst({ where: { id: body.provinceId || undefined } }),
@ -385,44 +391,41 @@ export class CustomerBranchController extends Controller {
);
}
const { provinceId, districtId, subDistrictId, customerId, ...rest } = body;
if (!(await prisma.customerBranch.findUnique({ where: { id: branchId } }))) {
throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound");
}
const record = await prisma.customerBranch.update({
where: { id: branchId },
include: {
province: true,
district: true,
subDistrict: true,
createdBy: true,
updatedBy: true,
},
data: {
...rest,
statusOrder: +(rest.status === "INACTIVE"),
customer: { connect: customerId ? { id: customerId } : undefined },
province: {
connect: provinceId ? { id: provinceId } : undefined,
disconnect: provinceId === null || undefined,
},
district: {
connect: districtId ? { id: districtId } : undefined,
disconnect: districtId === null || undefined,
},
subDistrict: {
connect: subDistrictId ? { id: subDistrictId } : undefined,
disconnect: subDistrictId === null || undefined,
},
updatedBy: { connect: { id: req.user.sub } },
},
});
this.setStatus(HttpStatus.CREATED);
return record;
// const { provinceId, districtId, subDistrictId, customerId, ...rest } = body;
//
//
// const record = await prisma.customerBranch.update({
// where: { id: branchId },
// include: {
// province: true,
// district: true,
// subDistrict: true,
// createdBy: true,
// updatedBy: true,
// },
// data: {
// ...rest,
// statusOrder: +(rest.status === "INACTIVE"),
// customer: { connect: customerId ? { id: customerId } : undefined },
// province: {
// connect: provinceId ? { id: provinceId } : undefined,
// disconnect: provinceId === null || undefined,
// },
// district: {
// connect: districtId ? { id: districtId } : undefined,
// disconnect: districtId === null || undefined,
// },
// subDistrict: {
// connect: subDistrictId ? { id: subDistrictId } : undefined,
// disconnect: subDistrictId === null || undefined,
// },
// updatedBy: { connect: { id: req.user.sub } },
// },
// });
//
// this.setStatus(HttpStatus.CREATED);
//
// return record;
}
@Delete("{branchId}")

View file

@ -15,7 +15,7 @@ import {
} from "tsoa";
import { RequestWithUser } from "../interfaces/user";
import prisma from "../db";
import minio, { presignedGetObjectIfExist } from "../services/minio";
import minio, { deleteFolder, presignedGetObjectIfExist } from "../services/minio";
import HttpStatus from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
@ -37,95 +37,31 @@ const MANAGE_ROLES = [
export type CustomerCreate = {
registeredBranchId?: string;
code: string;
status?: Status;
personName: string;
personNameEN?: string;
customerType: CustomerType;
customerName: string;
customerNameEN: string;
taxNo?: string | null;
customerBranch?: {
status?: Status;
legalPersonNo: string;
branchNo: number;
taxNo: string | null;
name: string;
nameEN: string;
addressEN: string;
address: string;
zipCode: string;
email: string;
telephoneNo: string;
registerName: string;
registerDate: Date;
authorizedCapital: string;
employmentOffice: string;
bussinessType: string;
bussinessTypeEN: string;
jobPosition: string;
jobPositionEN: string;
jobDescription: string;
saleEmployee: string;
payDate: Date;
wageRate: number;
subDistrictId?: string | null;
districtId?: string | null;
provinceId?: string | null;
}[];
namePrefix: string;
firstName: string;
firstNameEN?: string;
lastName: string;
lastNameEN?: string;
gender: string;
birthDate: Date;
};
export type CustomerUpdate = {
registeredBranchId?: string;
status?: "ACTIVE" | "INACTIVE";
personName?: string;
personNameEN?: string;
customerType?: CustomerType;
customerName?: string;
customerNameEN?: string;
taxNo?: string | null;
customerBranch?: {
id?: string;
status?: Status;
legalPersonNo: string;
branchNo: number;
taxNo: string | null;
name: string;
nameEN: string;
addressEN: string;
address: string;
zipCode: string;
email: string;
telephoneNo: string;
registerName: string;
registerDate: Date;
authorizedCapital: string;
employmentOffice: string;
bussinessType: string;
bussinessTypeEN: string;
jobPosition: string;
jobPositionEN: string;
jobDescription: string;
saleEmployee: string;
payDate: Date;
wageRate: number;
subDistrictId?: string | null;
districtId?: string | null;
provinceId?: string | null;
}[];
customerType: CustomerType;
namePrefix: string;
firstName: string;
firstNameEN?: string;
lastName: string;
lastNameEN?: string;
gender: string;
birthDate: Date;
};
function imageLocation(id: string) {
@ -167,16 +103,17 @@ export class CustomerController extends Controller {
) {
const filterStatus = (val?: Status) => {
if (!val) return {};
return val !== Status.CREATED && val !== Status.ACTIVE
? { status: val }
: { OR: [{ status: Status.CREATED }, { status: Status.ACTIVE }] };
};
const where = {
OR: [
{ customerName: { contains: query }, customerType, ...filterStatus(status) },
{ customerNameEN: { contains: query }, customerType, ...filterStatus(status) },
{ namePrefix: { contains: query } },
{ firstName: { contains: query } },
{ firstNameEN: { contains: query } },
],
AND: { customerType, ...filterStatus(status) },
} satisfies Prisma.CustomerWhereInput;
const [result, total] = await prisma.$transaction([
@ -190,9 +127,7 @@ export class CustomerController extends Controller {
district: true,
subDistrict: true,
},
orderBy: {
branchNo: "asc",
},
orderBy: { createdAt: "asc" },
}
: undefined,
createdBy: true,
@ -206,21 +141,7 @@ export class CustomerController extends Controller {
prisma.customer.count({ where }),
]);
return {
result: await Promise.all(
result.map(async (v) => ({
...v,
imageUrl: await presignedGetObjectIfExist(
MINIO_BUCKET,
imageLocation(v.id),
12 * 60 * 60,
),
})),
),
page,
pageSize,
total,
};
return { result, page, pageSize, total };
}
@Get("{customerId}")
@ -234,71 +155,27 @@ export class CustomerController extends Controller {
district: true,
subDistrict: true,
},
orderBy: { branchNo: "asc" },
orderBy: { createdAt: "asc" },
},
createdBy: true,
updatedBy: true,
},
where: { id: customerId },
});
if (!record)
if (!record) {
throw new HttpError(HttpStatus.NOT_FOUND, "Customer cannot be found.", "customerNotFound");
return Object.assign(record, {
imageUrl: await presignedGetObjectIfExist(
MINIO_BUCKET,
imageLocation(record.id),
12 * 60 * 60,
),
});
}
return record;
}
@Post()
@Security("keycloak", MANAGE_ROLES)
async create(@Request() req: RequestWithUser, @Body() body: CustomerCreate) {
const { customerBranch, ...payload } = body;
const provinceId = body.customerBranch?.reduce<string[]>((acc, cur) => {
if (cur.provinceId && !acc.includes(cur.provinceId)) return acc.concat(cur.provinceId);
return acc;
}, []);
const districtId = body.customerBranch?.reduce<string[]>((acc, cur) => {
if (cur.districtId && !acc.includes(cur.districtId)) return acc.concat(cur.districtId);
return acc;
}, []);
const subDistrictId = body.customerBranch?.reduce<string[]>((acc, cur) => {
if (cur.subDistrictId && !acc.includes(cur.subDistrictId))
return acc.concat(cur.subDistrictId);
return acc;
}, []);
const [province, district, subDistrict, branch] = await prisma.$transaction([
prisma.province.findMany({ where: { id: { in: provinceId } } }),
prisma.district.findMany({ where: { id: { in: districtId } } }),
prisma.subDistrict.findMany({ where: { id: { in: subDistrictId } } }),
const [branch] = await prisma.$transaction([
prisma.branch.findFirst({ where: { id: body.registeredBranchId } }),
]);
if (provinceId && province.length !== provinceId?.length) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some province cannot be found.",
"relationProvinceNotFound",
);
}
if (districtId && district.length !== districtId?.length) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some district cannot be found.",
"relationDistrictNotFound",
);
}
if (subDistrictId && subDistrict.length !== subDistrictId?.length) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some sub district cannot be found.",
"relationSubDistrictNotFound",
);
}
if (!!body.registeredBranchId && !branch) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
@ -306,27 +183,24 @@ export class CustomerController extends Controller {
"relationBranchNotFound",
);
}
if (!body.registeredBranchId) {
body.registeredBranchId = undefined;
}
const record = await prisma.$transaction(
async (tx) => {
body.code = body.code.toLocaleUpperCase();
const exist = await tx.customer.findFirst({
where: { code: body.code },
await tx.branch.updateMany({
where: {
id: body.registeredBranchId,
status: "CREATED",
},
data: {
status: "INACTIVE",
statusOrder: 1,
},
});
if (exist) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Customer with same code already exists.",
"sameCustomerCodeExists",
);
}
return await prisma.customer.create({
return await tx.customer.create({
include: {
branch: {
include: {
@ -339,20 +213,8 @@ export class CustomerController extends Controller {
updatedBy: true,
},
data: {
...payload,
statusOrder: +(payload.status === "INACTIVE"),
code: `${body.code}000000`,
branch: {
createMany: {
data:
customerBranch?.map((v) => ({
...v,
code: body.code,
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
})) || [],
},
},
...body,
statusOrder: +(body.status === "INACTIVE"),
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
},
@ -363,18 +225,7 @@ export class CustomerController extends Controller {
this.setStatus(HttpStatus.CREATED);
return Object.assign(record, {
imageUrl: await presignedGetObjectIfExist(
MINIO_BUCKET,
imageLocation(record.id),
12 * 60 * 60,
),
imageUploadUrl: await minio.presignedPutObject(
MINIO_BUCKET,
imageLocation(record.id),
12 * 60 * 60,
),
});
return record;
}
@Put("{customerId}")
@ -390,80 +241,25 @@ export class CustomerController extends Controller {
throw new HttpError(HttpStatus.NOT_FOUND, "Customer cannot be found.", "customerNotFound");
}
const provinceId = body.customerBranch?.reduce<string[]>((acc, cur) => {
if (cur.provinceId && !acc.includes(cur.provinceId)) return acc.concat(cur.provinceId);
return acc;
}, []);
const districtId = body.customerBranch?.reduce<string[]>((acc, cur) => {
if (cur.districtId && !acc.includes(cur.districtId)) return acc.concat(cur.districtId);
return acc;
}, []);
const subDistrictId = body.customerBranch?.reduce<string[]>((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 } } }),
const [branch] = await prisma.$transaction([
prisma.customer.findUnique({ where: { id: customerId } }),
prisma.branch.findFirst({ where: { id: body.registeredBranchId } }),
]);
if (provinceId && province.length !== provinceId?.length) {
if (!!body.registeredBranchId && !branch) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some province cannot be found.",
"relationProvinceNotFound",
);
}
if (districtId && district.length !== districtId?.length) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some district cannot be found.",
"relationDistrictNotFound",
);
}
if (subDistrictId && subDistrict.length !== subDistrictId?.length) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Some sub district cannot be found.",
"relationSubDistrictNotFound",
"Branch cannot be found.",
"relationBranchNotFound",
);
}
const { customerBranch, ...payload } = body;
const relation = await prisma.customerBranch.findMany({
where: {
customerId,
},
});
if (
customerBranch &&
relation.find((a) => !customerBranch.find((b) => a.id === b.id) && a.status !== "CREATED")
) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"One or more branch cannot be delete and is missing.",
"oneOrMoreBranchMissing",
);
if (!body.registeredBranchId) {
body.registeredBranchId = undefined;
}
if (
customerBranch &&
relation.find((a) => customerBranch.find((b) => a.id !== b.id && a.branchNo === b.branchNo))
) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Branch cannot have same number.",
"oneOrMoreBranchNoExist",
);
}
const record = await prisma.customer
.update({
const record = await prisma.$transaction(async (tx) => {
return await tx.customer.update({
include: {
branch: {
include: {
@ -477,74 +273,14 @@ export class CustomerController extends Controller {
},
where: { id: customerId },
data: {
...payload,
statusOrder: +(payload.status === "INACTIVE"),
branch:
(customerBranch && {
deleteMany: {
id: {
notIn: customerBranch.map((v) => v.id).filter((v): v is string => !!v) || [],
},
status: Status.CREATED,
},
upsert: customerBranch.map((v) => ({
where: { id: v.id || "" },
create: {
...v,
code: `${customer.code}-${v.branchNo.toString().padStart(2, "0")}`,
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
id: undefined,
},
update: {
...v,
code: undefined,
branchNo: undefined,
updatedByUserId: req.user.sub,
},
})),
}) ||
undefined,
...body,
statusOrder: +(body.status === "INACTIVE"),
updatedByUserId: req.user.sub,
},
})
.then((v) => {
if (customerBranch) {
relation
.filter((a) => !customerBranch.find((b) => b.id === a.id))
.forEach((deleted) => {
new Promise<string[]>((resolve, reject) => {
const item: string[] = [];
const stream = minio.listObjectsV2(MINIO_BUCKET, `customer/${deleted.id}`);
stream.on("data", (v) => v && v.name && item.push(v.name));
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("MinIO error.")));
}).then((list) => {
list.map(async (v) => {
await minio.removeObject(MINIO_BUCKET, v, {
forceDelete: true,
});
});
});
});
}
return v;
});
return Object.assign(record, {
imageUrl: await presignedGetObjectIfExist(
MINIO_BUCKET,
imageLocation(record.id),
12 * 60 * 60,
),
imageUploadUrl: await minio.presignedPutObject(
MINIO_BUCKET,
imageLocation(record.id),
12 * 60 * 60,
),
});
return record;
}
@Delete("{customerId}")
@ -560,24 +296,11 @@ export class CustomerController extends Controller {
throw new HttpError(HttpStatus.FORBIDDEN, "Customer is in used.", "customerInUsed");
}
return await prisma.customer.delete({ where: { id: customerId } }).then((v) => {
new Promise<string[]>((resolve, reject) => {
const item: string[] = [];
const stream = minio.listObjectsV2(MINIO_BUCKET, `customer/${customerId}`);
stream.on("data", (v) => v && v.name && item.push(v.name));
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("MinIO error.")));
}).then((list) => {
list.map(async (v) => {
await minio.removeObject(MINIO_BUCKET, v, {
forceDelete: true,
});
});
});
return v;
});
return await prisma.customer
.delete({ where: { id: customerId } })
.then(
async (data) => await deleteFolder(MINIO_BUCKET, `customer/${customerId}`).then(() => data),
);
}
@Get("{customerId}/image")