From 50fca4d540fd1b56b0b38a65b96b7eb16562d919 Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 9 Jul 2025 16:02:45 +0700 Subject: [PATCH 1/9] feat: remove customerName add reportDate --- .../03-customer-branch-controller.ts | 31 ++++++++++++++----- src/controllers/03-customer-controller.ts | 5 ++- .../03-employee-visa-controller.ts | 1 + src/controllers/04-invoice-controller.ts | 1 - src/controllers/05-quotation-controller.ts | 1 - src/controllers/06-request-list-controller.ts | 1 - src/controllers/08-credit-note-controller.ts | 1 - src/controllers/09-debit-note-controller.ts | 1 - src/controllers/09-line-controller.ts | 3 +- src/controllers/09-web-hook-controller.ts | 8 ++--- 10 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/controllers/03-customer-branch-controller.ts b/src/controllers/03-customer-branch-controller.ts index 7f13048..f8c8a6b 100644 --- a/src/controllers/03-customer-branch-controller.ts +++ b/src/controllers/03-customer-branch-controller.ts @@ -57,7 +57,7 @@ const MANAGE_ROLES = [ ]; function globalAllow(user: RequestWithUser["user"]) { - const listAllowed = MANAGE_ROLES; + const listAllowed = ["system", "head_of_admin", "admin", "executive", "accountant"]; return user.roles?.some((v) => listAllowed.includes(v)) || false; } @@ -87,7 +87,6 @@ export type CustomerBranchCreate = { authorizedCapital?: string; authorizedName?: string; authorizedNameEN?: string; - customerName?: string; telephoneNo: string; @@ -111,7 +110,7 @@ export type CustomerBranchCreate = { contactName: string; agentUserId?: string; - businessType: string; + businessTypeId?: string; jobPosition: string; jobDescription: string; payDate: string; @@ -145,7 +144,6 @@ export type CustomerBranchUpdate = { authorizedCapital?: string; authorizedName?: string; authorizedNameEN?: string; - customerName?: string; telephoneNo: string; @@ -169,7 +167,7 @@ export type CustomerBranchUpdate = { contactName?: string; agentUserId?: string; - businessType?: string; + businessTypeId?: string; jobPosition?: string; jobDescription?: string; payDate?: string; @@ -204,7 +202,6 @@ export class CustomerBranchController extends Controller { ) { const where = { OR: queryOrNot(query, [ - { customerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } }, { email: { contains: query, mode: "insensitive" } }, @@ -381,7 +378,15 @@ export class CustomerBranchController extends Controller { (v) => (v.headOffice || v).code, ); - const { provinceId, districtId, subDistrictId, customerId, agentUserId, ...rest } = body; + const { + provinceId, + districtId, + subDistrictId, + customerId, + agentUserId, + businessTypeId, + ...rest + } = body; const record = await prisma.$transaction( async (tx) => { @@ -435,6 +440,7 @@ export class CustomerBranchController extends Controller { province: connectOrNot(provinceId), district: connectOrNot(districtId), subDistrict: connectOrNot(subDistrictId), + businessType: connectOrNot(businessTypeId), createdBy: { connect: { id: req.user.sub } }, updatedBy: { connect: { id: req.user.sub } }, }, @@ -509,7 +515,15 @@ export class CustomerBranchController extends Controller { await permissionCheck(req.user, customer.registeredBranch); } - const { provinceId, districtId, subDistrictId, customerId, agentUserId, ...rest } = body; + const { + provinceId, + districtId, + subDistrictId, + customerId, + agentUserId, + businessTypeId, + ...rest + } = body; return await prisma.customerBranch.update({ where: { id: branchId }, @@ -528,6 +542,7 @@ export class CustomerBranchController extends Controller { province: connectOrDisconnect(provinceId), district: connectOrDisconnect(districtId), subDistrict: connectOrDisconnect(subDistrictId), + businessType: connectOrNot(businessTypeId), updatedBy: { connect: { id: req.user.sub } }, }, }); diff --git a/src/controllers/03-customer-controller.ts b/src/controllers/03-customer-controller.ts index 082b067..580e60f 100644 --- a/src/controllers/03-customer-controller.ts +++ b/src/controllers/03-customer-controller.ts @@ -85,7 +85,6 @@ export type CustomerCreate = { authorizedCapital?: string; authorizedName?: string; authorizedNameEN?: string; - customerName?: string; telephoneNo: string; @@ -109,7 +108,7 @@ export type CustomerCreate = { contactName: string; agentUserId?: string; - businessType: string; + businessTypeId?: string | null; jobPosition: string; jobDescription: string; payDate: string; @@ -174,7 +173,6 @@ export class CustomerController extends Controller { const where = { OR: queryOrNot(query, [ { branch: { some: { namePrefix: { contains: query, mode: "insensitive" } } } }, - { branch: { some: { customerName: { contains: query, mode: "insensitive" } } } }, { branch: { some: { registerName: { contains: query, mode: "insensitive" } } } }, { branch: { some: { registerNameEN: { contains: query, mode: "insensitive" } } } }, { branch: { some: { firstName: { contains: query, mode: "insensitive" } } } }, @@ -220,6 +218,7 @@ export class CustomerController extends Controller { }, createdBy: true, updatedBy: true, + // businessType:true }, orderBy: [{ statusOrder: "asc" }, { createdAt: "asc" }], where, diff --git a/src/controllers/03-employee-visa-controller.ts b/src/controllers/03-employee-visa-controller.ts index eafb22a..7c51bf2 100644 --- a/src/controllers/03-employee-visa-controller.ts +++ b/src/controllers/03-employee-visa-controller.ts @@ -44,6 +44,7 @@ type EmployeeVisaPayload = { issuePlace: string; issueDate: Date; expireDate: Date; + reportDate?: Date | null; mrz?: string | null; remark?: string | null; diff --git a/src/controllers/04-invoice-controller.ts b/src/controllers/04-invoice-controller.ts index 5902521..cff9d20 100644 --- a/src/controllers/04-invoice-controller.ts +++ b/src/controllers/04-invoice-controller.ts @@ -117,7 +117,6 @@ export class InvoiceController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/05-quotation-controller.ts b/src/controllers/05-quotation-controller.ts index 5a375e5..04353bb 100644 --- a/src/controllers/05-quotation-controller.ts +++ b/src/controllers/05-quotation-controller.ts @@ -225,7 +225,6 @@ export class QuotationController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/06-request-list-controller.ts b/src/controllers/06-request-list-controller.ts index a20020f..37fd8e2 100644 --- a/src/controllers/06-request-list-controller.ts +++ b/src/controllers/06-request-list-controller.ts @@ -95,7 +95,6 @@ export class RequestDataController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/08-credit-note-controller.ts b/src/controllers/08-credit-note-controller.ts index f1bef3c..fd7a2a3 100644 --- a/src/controllers/08-credit-note-controller.ts +++ b/src/controllers/08-credit-note-controller.ts @@ -163,7 +163,6 @@ export class CreditNoteController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/09-debit-note-controller.ts b/src/controllers/09-debit-note-controller.ts index badb52e..5fcdee9 100644 --- a/src/controllers/09-debit-note-controller.ts +++ b/src/controllers/09-debit-note-controller.ts @@ -211,7 +211,6 @@ export class DebitNoteController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/09-line-controller.ts b/src/controllers/09-line-controller.ts index 91c06bb..8e708be 100644 --- a/src/controllers/09-line-controller.ts +++ b/src/controllers/09-line-controller.ts @@ -189,7 +189,6 @@ export class LineController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, @@ -624,7 +623,7 @@ export class LineController extends Controller { customerBranch: { OR: [ { code: { contains: query, mode: "insensitive" } }, - { customerName: { contains: query, mode: "insensitive" } }, + { registerName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } }, diff --git a/src/controllers/09-web-hook-controller.ts b/src/controllers/09-web-hook-controller.ts index 2914e20..028bf75 100644 --- a/src/controllers/09-web-hook-controller.ts +++ b/src/controllers/09-web-hook-controller.ts @@ -90,7 +90,7 @@ export class WebHookController extends Controller { firstNameEN: true, lastName: true, lastNameEN: true, - customerName: true, + registerName: true, customer: { select: { customerType: true, @@ -133,13 +133,13 @@ export class WebHookController extends Controller { let textData = ""; if (dataEmployee.length > 0) { - const customerName = - dataEmployee[0]?.employee?.customerBranch?.customerName ?? "ไม่ระบุ"; + const registerName = + dataEmployee[0]?.employee?.customerBranch?.registerName ?? "ไม่ระบุ"; const telephoneNo = dataEmployee[0]?.employee?.customerBranch?.customer.registeredBranch.telephoneNo ?? "ไม่ระบุ"; - const textEmployer = `เรียน คุณ${customerName}`; + const textEmployer = `เรียน คุณ${registerName}`; const textAlert = "ขอแจ้งให้ทราบว่าหนังสือเดินทางของลูกจ้าง"; const textAlert2 = "และจำเป็นต้องดำเนินการต่ออายุในเร็ว ๆ นี้"; const textExpDate = From 73fea9d9ed2a56901fe799cb2fc8368d90a0ab17 Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 9 Jul 2025 16:12:13 +0700 Subject: [PATCH 2/9] feat: add businessType --- src/controllers/03-customer-branch-controller.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/controllers/03-customer-branch-controller.ts b/src/controllers/03-customer-branch-controller.ts index f8c8a6b..d07f0ce 100644 --- a/src/controllers/03-customer-branch-controller.ts +++ b/src/controllers/03-customer-branch-controller.ts @@ -246,6 +246,7 @@ export class CustomerBranchController extends Controller { createdBy: true, updatedBy: true, _count: true, + businessType: true, }, where, take: pageSize, @@ -268,6 +269,7 @@ export class CustomerBranchController extends Controller { subDistrict: true, createdBy: true, updatedBy: true, + businessType: true, }, where: { id: branchId }, }); @@ -429,6 +431,7 @@ export class CustomerBranchController extends Controller { subDistrict: true, createdBy: true, updatedBy: true, + businessType: true, }, data: { ...rest, @@ -471,6 +474,7 @@ export class CustomerBranchController extends Controller { }, }, }, + businessType: true, }, }); @@ -533,6 +537,7 @@ export class CustomerBranchController extends Controller { subDistrict: true, createdBy: true, updatedBy: true, + businessType: true, }, data: { ...rest, @@ -561,6 +566,7 @@ export class CustomerBranchController extends Controller { }, }, }, + businessType: true, }, }); @@ -613,6 +619,7 @@ export class CustomerBranchFileController extends Controller { }, }, }, + businessType: true, }, }); if (!data) throw notFoundError("Customer Branch"); From 126e00baf15a9c4ae51bd24afe5de2ea2cccb11a Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:34:00 +0700 Subject: [PATCH 3/9] fix: stats does not account for permission --- src/controllers/07-task-controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/07-task-controller.ts b/src/controllers/07-task-controller.ts index bac70dd..6707781 100644 --- a/src/controllers/07-task-controller.ts +++ b/src/controllers/07-task-controller.ts @@ -70,8 +70,9 @@ const permissionCheckCompany = createPermCheck((_) => true); @Tags("Task Order") export class TaskController extends Controller { @Get("stats") - async getTaskOrderStats() { + async getTaskOrderStats(@Request() req: RequestWithUser) { const task = await prisma.taskOrder.groupBy({ + where: { registeredBranch: { OR: permissionCondCompany(req.user) } }, by: ["taskOrderStatus"], _count: true, }); From 15e0e34a47ebf9be6d582188dad490a52dcd64ab Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 9 Jul 2025 17:26:49 +0700 Subject: [PATCH 4/9] feat: change listAllowed --- src/controllers/03-customer-branch-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/03-customer-branch-controller.ts b/src/controllers/03-customer-branch-controller.ts index d07f0ce..aada50c 100644 --- a/src/controllers/03-customer-branch-controller.ts +++ b/src/controllers/03-customer-branch-controller.ts @@ -57,7 +57,7 @@ const MANAGE_ROLES = [ ]; function globalAllow(user: RequestWithUser["user"]) { - const listAllowed = ["system", "head_of_admin", "admin", "executive", "accountant"]; + const listAllowed = MANAGE_ROLES; return user.roles?.some((v) => listAllowed.includes(v)) || false; } From 7112a545b181d73c8b7017c54406c114699e3084 Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 9 Jul 2025 17:31:46 +0700 Subject: [PATCH 5/9] feat: add crud businessType --- .../10-business-type-controller.ts | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/controllers/10-business-type-controller.ts diff --git a/src/controllers/10-business-type-controller.ts b/src/controllers/10-business-type-controller.ts new file mode 100644 index 0000000..2cd80a6 --- /dev/null +++ b/src/controllers/10-business-type-controller.ts @@ -0,0 +1,111 @@ +import { + Body, + Controller, + Delete, + Get, + Path, + Post, + Put, + Query, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { RequestWithUser } from "../interfaces/user"; +import prisma from "../db"; +import { Prisma } from "@prisma/client"; +import { queryOrNot } from "../utils/relation"; +import { notFoundError } from "../utils/error"; + +type BusinessTypePayload = { + name: string; + nameEN: string; +}; + +@Route("api/v1/business-type") +@Tags("Business Type") +export class businessTypeController extends Controller { + @Get() + @Security("keycloak") + async getList( + @Request() req: RequestWithUser, + @Query() query: string = "", + @Query() page: number = 1, + @Query() pageSize: number = 30, + ) { + const where = { + OR: queryOrNot(query, [ + { name: { contains: query, mode: "insensitive" } }, + { nameEN: { contains: query, mode: "insensitive" } }, + ]), + } satisfies Prisma.BusinessTypeWhereInput; + + const [result, total] = await prisma.$transaction([ + prisma.businessType.findMany({ + where, + }), + prisma.businessType.count({ where }), + ]); + + return { result, page, pageSize, total }; + } + + @Post() + @Security("keycloak") + async createBusinessType(@Request() req: RequestWithUser, @Body() body: BusinessTypePayload) { + return await prisma.businessType.create({ + data: { + ...body, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, + }, + }); + } + + @Get(":businessTypeId") + @Security("keycloak") + async getBusinessTypeById(@Path() businessTypeId: string) { + return await prisma.businessType.findUnique({ + where: { id: businessTypeId }, + }); + } + + @Put(":businessTypeId") + @Security("keycloak") + async updateBusinessType( + @Request() req: RequestWithUser, + @Path() businessTypeId: string, + @Body() body: BusinessTypePayload, + ) { + return await prisma.$transaction(async (tx) => { + const record = await tx.businessType.findUnique({ + where: { id: businessTypeId }, + }); + + if (!record) throw notFoundError("BusinessType"); + return await prisma.businessType.update({ + where: { id: businessTypeId }, + data: { + ...body, + updatedByUserId: req.user.sub, + }, + }); + }); + } + + @Delete(":businessTypeId") + @Security("keycloak") + async deleteBusinessType(@Path() businessTypeId: string) { + return await prisma.$transaction(async (tx) => { + const record = await tx.businessType.findUnique({ + where: { id: businessTypeId }, + }); + + if (!record) throw notFoundError("BusinessType"); + return await prisma.businessType.delete({ + where: { id: businessTypeId }, + }); + }); + } +} From 1f63089363b675e42c6cdb40f7abf01d38edf27d Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 9 Jul 2025 17:40:24 +0700 Subject: [PATCH 6/9] fest: add page --- src/controllers/10-business-type-controller.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/controllers/10-business-type-controller.ts b/src/controllers/10-business-type-controller.ts index 2cd80a6..6d7373c 100644 --- a/src/controllers/10-business-type-controller.ts +++ b/src/controllers/10-business-type-controller.ts @@ -44,6 +44,8 @@ export class businessTypeController extends Controller { const [result, total] = await prisma.$transaction([ prisma.businessType.findMany({ where, + take: pageSize, + skip: (page - 1) * pageSize, }), prisma.businessType.count({ where }), ]); @@ -84,7 +86,7 @@ export class businessTypeController extends Controller { }); if (!record) throw notFoundError("BusinessType"); - return await prisma.businessType.update({ + return await tx.businessType.update({ where: { id: businessTypeId }, data: { ...body, @@ -103,7 +105,7 @@ export class businessTypeController extends Controller { }); if (!record) throw notFoundError("BusinessType"); - return await prisma.businessType.delete({ + return await tx.businessType.delete({ where: { id: businessTypeId }, }); }); From 1cf53c91aa451a0fc82bfc7c7a96d0884c50e16c Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Wed, 9 Jul 2025 17:45:14 +0700 Subject: [PATCH 7/9] feat: doc template now include business type relation --- src/controllers/00-doc-template-controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/00-doc-template-controller.ts b/src/controllers/00-doc-template-controller.ts index 7f05110..f457372 100644 --- a/src/controllers/00-doc-template-controller.ts +++ b/src/controllers/00-doc-template-controller.ts @@ -36,6 +36,7 @@ const quotationData = (id: string) => customerBranch: { include: { customer: true, + businessType: true, province: true, district: true, subDistrict: true, From ccee3092681ae0d151ec7cada66cb79b654cd262 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Wed, 9 Jul 2025 17:46:27 +0700 Subject: [PATCH 8/9] feat: deprecated business type helper --- src/controllers/00-doc-template-controller.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controllers/00-doc-template-controller.ts b/src/controllers/00-doc-template-controller.ts index f457372..bda7956 100644 --- a/src/controllers/00-doc-template-controller.ts +++ b/src/controllers/00-doc-template-controller.ts @@ -368,6 +368,9 @@ function gender(text: string, lang: "th" | "en" = "en") { } } +/** + * @deprecated + */ function businessType(text: string, lang: "th" | "en" = "en") { switch (lang) { case "th": From 1f34ea7ecbaa47c2401398e5dd54b9aaf72e794e Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:13:18 +0700 Subject: [PATCH 9/9] feat: include business relation --- src/controllers/03-customer-controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/03-customer-controller.ts b/src/controllers/03-customer-controller.ts index 580e60f..0ff2b19 100644 --- a/src/controllers/03-customer-controller.ts +++ b/src/controllers/03-customer-controller.ts @@ -201,6 +201,7 @@ export class CustomerController extends Controller { branch: includeBranch ? { include: { + businessType: true, province: true, district: true, subDistrict: true,