fix bug in user, employee, institution,requestList

This commit is contained in:
Kanjana 2025-04-04 14:35:28 +07:00 committed by Methapon Metanipat
parent 116fa02bd9
commit 709c21082a
9 changed files with 230 additions and 17 deletions

View file

@ -0,0 +1,29 @@
-- AlterTable
ALTER TABLE "Employee" ALTER COLUMN "firstName" DROP NOT NULL,
ALTER COLUMN "lastName" DROP NOT NULL;
-- AlterTable
ALTER TABLE "Institution" ADD COLUMN "contactEmail" TEXT,
ADD COLUMN "contactName" TEXT,
ADD COLUMN "contactTel" TEXT;
-- AlterTable
ALTER TABLE "User" ADD COLUMN "agencyStatus" TEXT,
ADD COLUMN "remark" TEXT;
-- CreateTable
CREATE TABLE "InstitutionBank" (
"id" TEXT NOT NULL,
"bankName" TEXT NOT NULL,
"bankBranch" TEXT NOT NULL,
"accountName" TEXT NOT NULL,
"accountNumber" TEXT NOT NULL,
"accountType" TEXT NOT NULL,
"currentlyUse" BOOLEAN NOT NULL,
"institutionId" TEXT NOT NULL,
CONSTRAINT "InstitutionBank_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "InstitutionBank" ADD CONSTRAINT "InstitutionBank_institutionId_fkey" FOREIGN KEY ("institutionId") REFERENCES "Institution"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Employee" ALTER COLUMN "dateOfBirth" DROP NOT NULL;

View file

@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "InstitutionBank" DROP CONSTRAINT "InstitutionBank_institutionId_fkey";
-- AddForeignKey
ALTER TABLE "InstitutionBank" ADD CONSTRAINT "InstitutionBank_institutionId_fkey" FOREIGN KEY ("institutionId") REFERENCES "Institution"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View file

@ -494,6 +494,9 @@ model User {
requestWorkStepStatus RequestWorkStepStatus[]
userTask UserTask[]
RequestData RequestData[]
remark String?
agencyStatus String?
}
model UserResponsibleArea {
@ -763,14 +766,14 @@ model Employee {
nrcNo String?
namePrefix String?
firstName String
firstName String?
firstNameEN String
middleName String?
middleNameEN String?
lastName String
lastName String?
lastNameEN String
dateOfBirth DateTime @db.Date
dateOfBirth DateTime? @db.Date
gender String
nationality String
@ -1004,6 +1007,25 @@ model Institution {
selectedImage String?
taskOrder TaskOrder[]
contactName String?
contactEmail String?
contactTel String?
bank InstitutionBank[]
}
model InstitutionBank {
id String @id @default(cuid())
bankName String
bankBranch String
accountName String
accountNumber String
accountType String
currentlyUse Boolean
institution Institution @relation(fields: [institutionId], references: [id], onDelete: Cascade)
institutionId String
}
model Property {

View file

@ -120,6 +120,9 @@ type UserCreate = {
selectedImage?: string;
branchId: string | string[];
remark?: string;
agencyStatus?: string;
};
type UserUpdate = {
@ -176,6 +179,9 @@ type UserUpdate = {
provinceId?: string | null;
branchId?: string | string[];
remark?: string;
agencyStatus?: string;
};
const permissionCondCompany = createPermCondition((_) => true);

View file

@ -70,16 +70,16 @@ type EmployeeCreate = {
nrcNo?: string | null;
dateOfBirth: Date;
dateOfBirth?: Date | null;
gender: string;
nationality: string;
namePrefix?: string | null;
firstName: string;
firstName?: string;
firstNameEN: string;
middleName?: string | null;
middleNameEN?: string | null;
lastName: string;
lastName?: string;
lastNameEN: string;
addressEN: string;
@ -112,11 +112,11 @@ type EmployeeUpdate = {
namePrefix?: string | null;
firstName?: string;
firstNameEN?: string;
firstNameEN: string;
middleName?: string | null;
middleNameEN?: string | null;
lastName?: string;
lastNameEN?: string;
lastNameEN: string;
addressEN?: string;
address?: string;
@ -364,9 +364,10 @@ export class EmployeeController extends Controller {
},
}),
]);
if (body.provinceId !== province?.id) throw relationError("Province");
if (body.districtId !== district?.id) throw relationError("District");
if (body.subDistrictId !== subDistrict?.id) throw relationError("SubDistrict");
if (!!body.provinceId && body.provinceId !== province?.id) throw relationError("Province");
if (!!body.districtId && body.districtId !== district?.id) throw relationError("District");
if (!!body.subDistrictId && body.subDistrictId !== subDistrict?.id)
throw relationError("SubDistrict");
if (!customerBranch) throw relationError("Customer Branch");
await permissionCheck(req.user, customerBranch.customer.registeredBranch);

View file

@ -44,6 +44,55 @@ type InstitutionPayload = {
provinceId: string;
selectedImage?: string | null;
contactName?: string;
contactEmail?: string;
contactTel?: string;
bank?: {
bankName: string;
bankBranch: string;
accountName: string;
accountNumber: string;
accountType: string;
currentlyUse: boolean;
}[];
};
type InstitutionUpdatePayload = {
name: string;
nameEN: string;
code: string;
addressEN: string;
address: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
subDistrictId: string;
districtId: string;
provinceId: string;
selectedImage?: string | null;
contactName?: string;
contactEmail?: string;
contactTel?: string;
bank?: {
id?: string;
bankName: string;
bankBranch: string;
accountName: string;
accountNumber: string;
accountType: string;
currentlyUse: boolean;
}[];
};
@Route("api/v1/institution")
@ -94,6 +143,7 @@ export class InstitutionController extends Controller {
province: true,
district: true,
subDistrict: true,
bank: true,
},
orderBy: [{ statusOrder: "asc" }, { code: "asc" }],
take: pageSize,
@ -114,6 +164,7 @@ export class InstitutionController extends Controller {
province: true,
district: true,
subDistrict: true,
bank: true,
},
where: { id: institutionId, group },
});
@ -141,10 +192,18 @@ export class InstitutionController extends Controller {
});
return await tx.institution.create({
include: {
bank: true,
},
data: {
...body,
code: `${body.code}${last.value.toString().padStart(5, "0")}`,
group: body.code,
bank: {
createMany: {
data: body.bank ?? [],
},
},
},
});
});
@ -156,13 +215,46 @@ export class InstitutionController extends Controller {
async updateInstitution(
@Path() institutionId: string,
@Body()
body: InstitutionPayload & {
body: InstitutionUpdatePayload & {
status?: "ACTIVE" | "INACTIVE";
},
) {
return await prisma.institution.update({
where: { id: institutionId },
data: { ...body, statusOrder: +(body.status === "INACTIVE") },
const { bank } = body;
return await prisma.$transaction(async (tx) => {
const listDeleted = bank
? await tx.institutionBank.findMany({
where: {
id: { not: { in: bank.flatMap((v) => (!!v.id ? v.id : [])) } },
institutionId,
},
})
: [];
await Promise.all(
listDeleted.map((v) => deleteFile(fileLocation.institution.bank(v.institutionId, v.id))),
);
return await prisma.institution.update({
include: {
bank: true,
},
where: { id: institutionId },
data: {
...body,
statusOrder: +(body.status === "INACTIVE"),
bank: bank
? {
deleteMany:
listDeleted.length > 0 ? { id: { in: listDeleted.map((v) => v.id) } } : undefined,
upsert: bank.map((v) => ({
where: { id: v.id || "" },
create: { ...v, id: undefined },
update: v,
})),
}
: undefined,
},
});
});
}
@ -185,9 +277,18 @@ export class InstitutionController extends Controller {
throw isUsedError("Institution");
}
return await tx.institution.delete({
const data = await tx.institution.delete({
include: {
bank: true,
},
where: { id: institutionId },
});
await Promise.all([
...data.bank.map((v) => deleteFile(fileLocation.institution.bank(institutionId, v.id))),
]);
return data;
});
}
}
@ -294,4 +395,49 @@ export class InstitutionFileController extends Controller {
await this.checkPermission(req.user, institutionId);
return await deleteFile(fileLocation.institution.attachment(institutionId, name));
}
@Get("bank-qr/{bankId}")
async getBankImage(
@Request() req: RequestWithUser,
@Path() institutionId: string,
@Path() bankId: string,
) {
return req.res?.redirect(await getFile(fileLocation.institution.bank(institutionId, bankId)));
}
@Head("bank-qr/{bankId}")
async headBankImage(
@Request() req: RequestWithUser,
@Path() institutionId: string,
@Path() bankId: string,
) {
return req.res?.redirect(
await getPresigned("head", fileLocation.institution.bank(institutionId, bankId)),
);
}
@Put("bank-qr/{bankId}")
@Security("keycloak")
async putBankImage(
@Request() req: RequestWithUser,
@Path() institutionId: string,
@Path() bankId: string,
) {
if (!req.headers["content-type"]?.startsWith("image/")) {
throw new HttpError(HttpStatus.BAD_REQUEST, "Not a valid image.", "notValidImage");
}
await this.checkPermission(req.user, institutionId);
return req.res?.redirect(await setFile(fileLocation.institution.bank(institutionId, bankId)));
}
@Delete("bank-qr/{bankId}")
@Security("keycloak")
async delBankImage(
@Request() req: RequestWithUser,
@Path() institutionId: string,
@Path() bankId: string,
) {
await this.checkPermission(req.user, institutionId);
return await deleteFile(fileLocation.institution.bank(institutionId, bankId));
}
}

View file

@ -85,7 +85,7 @@ export class RequestDataController extends Controller {
OR: queryOrNot<Prisma.RequestDataWhereInput[]>(query, [
{ code: { contains: query, mode: "insensitive" } },
{ quotation: { code: { contains: query, mode: "insensitive" } } },
{ quotation: { workName: { contains: query } } },
{ quotation: { workName: { contains: query, mode: "insensitive" } } },
{
quotation: {
customerBranch: {

View file

@ -127,6 +127,8 @@ export const fileLocation = {
`${ROOT}/institution/attachment-${institutionId}/${name || ""}`,
img: (institutionId: string, name?: string) =>
`${ROOT}/institution/img-${institutionId}/${name || ""}`,
bank: (institutionId: string, bankId: string) =>
`${ROOT}/institution/bank-qr-${institutionId}-${bankId}`,
},
task: {
attachment: (taskId: string, name?: string) =>