Merge branch 'develop'
All checks were successful
Spell Check / Spell Check with Typos (push) Successful in 4s

This commit is contained in:
Methapon2001 2025-07-11 13:36:52 +07:00
commit 0032ff4658
13 changed files with 157 additions and 22 deletions

View file

@ -36,6 +36,7 @@ const quotationData = (id: string) =>
customerBranch: { customerBranch: {
include: { include: {
customer: true, customer: true,
businessType: true,
province: true, province: true,
district: true, district: true,
subDistrict: true, subDistrict: true,
@ -367,6 +368,9 @@ function gender(text: string, lang: "th" | "en" = "en") {
} }
} }
/**
* @deprecated
*/
function businessType(text: string, lang: "th" | "en" = "en") { function businessType(text: string, lang: "th" | "en" = "en") {
switch (lang) { switch (lang) {
case "th": case "th":

View file

@ -87,7 +87,6 @@ export type CustomerBranchCreate = {
authorizedCapital?: string; authorizedCapital?: string;
authorizedName?: string; authorizedName?: string;
authorizedNameEN?: string; authorizedNameEN?: string;
customerName?: string;
telephoneNo: string; telephoneNo: string;
@ -111,7 +110,7 @@ export type CustomerBranchCreate = {
contactName: string; contactName: string;
agentUserId?: string; agentUserId?: string;
businessType: string; businessTypeId?: string;
jobPosition: string; jobPosition: string;
jobDescription: string; jobDescription: string;
payDate: string; payDate: string;
@ -145,7 +144,6 @@ export type CustomerBranchUpdate = {
authorizedCapital?: string; authorizedCapital?: string;
authorizedName?: string; authorizedName?: string;
authorizedNameEN?: string; authorizedNameEN?: string;
customerName?: string;
telephoneNo: string; telephoneNo: string;
@ -169,7 +167,7 @@ export type CustomerBranchUpdate = {
contactName?: string; contactName?: string;
agentUserId?: string; agentUserId?: string;
businessType?: string; businessTypeId?: string;
jobPosition?: string; jobPosition?: string;
jobDescription?: string; jobDescription?: string;
payDate?: string; payDate?: string;
@ -204,7 +202,6 @@ export class CustomerBranchController extends Controller {
) { ) {
const where = { const where = {
OR: queryOrNot<Prisma.CustomerBranchWhereInput[]>(query, [ OR: queryOrNot<Prisma.CustomerBranchWhereInput[]>(query, [
{ customerName: { contains: query, mode: "insensitive" } },
{ registerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } },
{ registerNameEN: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } },
{ email: { contains: query, mode: "insensitive" } }, { email: { contains: query, mode: "insensitive" } },
@ -249,6 +246,7 @@ export class CustomerBranchController extends Controller {
createdBy: true, createdBy: true,
updatedBy: true, updatedBy: true,
_count: true, _count: true,
businessType: true,
}, },
where, where,
take: pageSize, take: pageSize,
@ -271,6 +269,7 @@ export class CustomerBranchController extends Controller {
subDistrict: true, subDistrict: true,
createdBy: true, createdBy: true,
updatedBy: true, updatedBy: true,
businessType: true,
}, },
where: { id: branchId }, where: { id: branchId },
}); });
@ -381,7 +380,15 @@ export class CustomerBranchController extends Controller {
(v) => (v.headOffice || v).code, (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( const record = await prisma.$transaction(
async (tx) => { async (tx) => {
@ -424,6 +431,7 @@ export class CustomerBranchController extends Controller {
subDistrict: true, subDistrict: true,
createdBy: true, createdBy: true,
updatedBy: true, updatedBy: true,
businessType: true,
}, },
data: { data: {
...rest, ...rest,
@ -435,6 +443,7 @@ export class CustomerBranchController extends Controller {
province: connectOrNot(provinceId), province: connectOrNot(provinceId),
district: connectOrNot(districtId), district: connectOrNot(districtId),
subDistrict: connectOrNot(subDistrictId), subDistrict: connectOrNot(subDistrictId),
businessType: connectOrNot(businessTypeId),
createdBy: { connect: { id: req.user.sub } }, createdBy: { connect: { id: req.user.sub } },
updatedBy: { connect: { id: req.user.sub } }, updatedBy: { connect: { id: req.user.sub } },
}, },
@ -465,6 +474,7 @@ export class CustomerBranchController extends Controller {
}, },
}, },
}, },
businessType: true,
}, },
}); });
@ -509,7 +519,15 @@ export class CustomerBranchController extends Controller {
await permissionCheck(req.user, customer.registeredBranch); 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({ return await prisma.customerBranch.update({
where: { id: branchId }, where: { id: branchId },
@ -519,6 +537,7 @@ export class CustomerBranchController extends Controller {
subDistrict: true, subDistrict: true,
createdBy: true, createdBy: true,
updatedBy: true, updatedBy: true,
businessType: true,
}, },
data: { data: {
...rest, ...rest,
@ -528,6 +547,7 @@ export class CustomerBranchController extends Controller {
province: connectOrDisconnect(provinceId), province: connectOrDisconnect(provinceId),
district: connectOrDisconnect(districtId), district: connectOrDisconnect(districtId),
subDistrict: connectOrDisconnect(subDistrictId), subDistrict: connectOrDisconnect(subDistrictId),
businessType: connectOrNot(businessTypeId),
updatedBy: { connect: { id: req.user.sub } }, updatedBy: { connect: { id: req.user.sub } },
}, },
}); });
@ -546,6 +566,7 @@ export class CustomerBranchController extends Controller {
}, },
}, },
}, },
businessType: true,
}, },
}); });
@ -598,6 +619,7 @@ export class CustomerBranchFileController extends Controller {
}, },
}, },
}, },
businessType: true,
}, },
}); });
if (!data) throw notFoundError("Customer Branch"); if (!data) throw notFoundError("Customer Branch");

View file

@ -85,7 +85,6 @@ export type CustomerCreate = {
authorizedCapital?: string; authorizedCapital?: string;
authorizedName?: string; authorizedName?: string;
authorizedNameEN?: string; authorizedNameEN?: string;
customerName?: string;
telephoneNo: string; telephoneNo: string;
@ -109,7 +108,7 @@ export type CustomerCreate = {
contactName: string; contactName: string;
agentUserId?: string; agentUserId?: string;
businessType: string; businessTypeId?: string | null;
jobPosition: string; jobPosition: string;
jobDescription: string; jobDescription: string;
payDate: string; payDate: string;
@ -174,7 +173,6 @@ export class CustomerController extends Controller {
const where = { const where = {
OR: queryOrNot<Prisma.CustomerWhereInput[]>(query, [ OR: queryOrNot<Prisma.CustomerWhereInput[]>(query, [
{ branch: { some: { namePrefix: { contains: query, mode: "insensitive" } } } }, { branch: { some: { namePrefix: { contains: query, mode: "insensitive" } } } },
{ branch: { some: { customerName: { contains: query, mode: "insensitive" } } } },
{ branch: { some: { registerName: { contains: query, mode: "insensitive" } } } }, { branch: { some: { registerName: { contains: query, mode: "insensitive" } } } },
{ branch: { some: { registerNameEN: { contains: query, mode: "insensitive" } } } }, { branch: { some: { registerNameEN: { contains: query, mode: "insensitive" } } } },
{ branch: { some: { firstName: { contains: query, mode: "insensitive" } } } }, { branch: { some: { firstName: { contains: query, mode: "insensitive" } } } },
@ -203,6 +201,7 @@ export class CustomerController extends Controller {
branch: includeBranch branch: includeBranch
? { ? {
include: { include: {
businessType: true,
province: true, province: true,
district: true, district: true,
subDistrict: true, subDistrict: true,
@ -220,6 +219,7 @@ export class CustomerController extends Controller {
}, },
createdBy: true, createdBy: true,
updatedBy: true, updatedBy: true,
// businessType:true
}, },
orderBy: [{ statusOrder: "asc" }, { createdAt: "asc" }], orderBy: [{ statusOrder: "asc" }, { createdAt: "asc" }],
where, where,

View file

@ -44,6 +44,7 @@ type EmployeeVisaPayload = {
issuePlace: string; issuePlace: string;
issueDate: Date; issueDate: Date;
expireDate: Date; expireDate: Date;
reportDate?: Date | null;
mrz?: string | null; mrz?: string | null;
remark?: string | null; remark?: string | null;

View file

@ -117,7 +117,6 @@ export class InvoiceController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ registerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } },
{ registerNameEN: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },

View file

@ -225,7 +225,6 @@ export class QuotationController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },
{ firstNameEN: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } },
{ lastName: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } },

View file

@ -95,7 +95,6 @@ export class RequestDataController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ registerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } },
{ registerNameEN: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },

View file

@ -70,8 +70,9 @@ const permissionCheckCompany = createPermCheck((_) => true);
@Tags("Task Order") @Tags("Task Order")
export class TaskController extends Controller { export class TaskController extends Controller {
@Get("stats") @Get("stats")
async getTaskOrderStats() { async getTaskOrderStats(@Request() req: RequestWithUser) {
const task = await prisma.taskOrder.groupBy({ const task = await prisma.taskOrder.groupBy({
where: { registeredBranch: { OR: permissionCondCompany(req.user) } },
by: ["taskOrderStatus"], by: ["taskOrderStatus"],
_count: true, _count: true,
}); });

View file

@ -163,7 +163,6 @@ export class CreditNoteController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },
{ firstNameEN: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } },
{ lastName: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } },

View file

@ -211,7 +211,6 @@ export class DebitNoteController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },
{ firstNameEN: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } },
{ lastName: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } },

View file

@ -189,7 +189,6 @@ export class LineController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } },
{ registerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } },
{ registerNameEN: { contains: query, mode: "insensitive" } }, { registerNameEN: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },
@ -624,7 +623,7 @@ export class LineController extends Controller {
customerBranch: { customerBranch: {
OR: [ OR: [
{ code: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query, mode: "insensitive" } }, { registerName: { contains: query, mode: "insensitive" } },
{ firstName: { contains: query, mode: "insensitive" } }, { firstName: { contains: query, mode: "insensitive" } },
{ firstNameEN: { contains: query, mode: "insensitive" } }, { firstNameEN: { contains: query, mode: "insensitive" } },
{ lastName: { contains: query, mode: "insensitive" } }, { lastName: { contains: query, mode: "insensitive" } },

View file

@ -90,7 +90,7 @@ export class WebHookController extends Controller {
firstNameEN: true, firstNameEN: true,
lastName: true, lastName: true,
lastNameEN: true, lastNameEN: true,
customerName: true, registerName: true,
customer: { customer: {
select: { select: {
customerType: true, customerType: true,
@ -133,13 +133,13 @@ export class WebHookController extends Controller {
let textData = ""; let textData = "";
if (dataEmployee.length > 0) { if (dataEmployee.length > 0) {
const customerName = const registerName =
dataEmployee[0]?.employee?.customerBranch?.customerName ?? "ไม่ระบุ"; dataEmployee[0]?.employee?.customerBranch?.registerName ?? "ไม่ระบุ";
const telephoneNo = const telephoneNo =
dataEmployee[0]?.employee?.customerBranch?.customer.registeredBranch.telephoneNo ?? dataEmployee[0]?.employee?.customerBranch?.customer.registeredBranch.telephoneNo ??
"ไม่ระบุ"; "ไม่ระบุ";
const textEmployer = `เรียน คุณ${customerName}`; const textEmployer = `เรียน คุณ${registerName}`;
const textAlert = "ขอแจ้งให้ทราบว่าหนังสือเดินทางของลูกจ้าง"; const textAlert = "ขอแจ้งให้ทราบว่าหนังสือเดินทางของลูกจ้าง";
const textAlert2 = "และจำเป็นต้องดำเนินการต่ออายุในเร็ว ๆ นี้"; const textAlert2 = "และจำเป็นต้องดำเนินการต่ออายุในเร็ว ๆ นี้";
const textExpDate = const textExpDate =

View file

@ -0,0 +1,113 @@
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<Prisma.BusinessTypeWhereInput[]>(query, [
{ name: { contains: query, mode: "insensitive" } },
{ nameEN: { contains: query, mode: "insensitive" } },
]),
} satisfies Prisma.BusinessTypeWhereInput;
const [result, total] = await prisma.$transaction([
prisma.businessType.findMany({
where,
take: pageSize,
skip: (page - 1) * pageSize,
}),
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 tx.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 tx.businessType.delete({
where: { id: businessTypeId },
});
});
}
}