From 0affb5337f1aa2c06be6480f9d2d49e5e462fcba Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 13 May 2025 14:31:37 +0700 Subject: [PATCH 1/3] fix: barcode font no display correctly --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 951bb52..7b7967d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,8 @@ ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable -RUN apt-get update && apt-get install -y openssl +RUN apt-get update && apt-get install -y openssl fontconfig +RUN fc-cache -f -v RUN pnpm i -g prisma prisma-kysely WORKDIR /app From 897ef335b4f57577c0040018f756fcd476ff1cc2 Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 14 May 2025 09:28:57 +0700 Subject: [PATCH 2/3] add notification expireDate passport, visa --- .../20250513084929_add/migration.sql | 3 + prisma/schema.prisma | 3 + src/controllers/07-task-controller.ts | 30 ++++- src/services/schedule.ts | 114 ++++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 prisma/migrations/20250513084929_add/migration.sql diff --git a/prisma/migrations/20250513084929_add/migration.sql b/prisma/migrations/20250513084929_add/migration.sql new file mode 100644 index 0000000..f982e5b --- /dev/null +++ b/prisma/migrations/20250513084929_add/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "QuotationWorker" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 73be520..47f82d6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1410,6 +1410,9 @@ model QuotationWorker { employeeId String quotation Quotation @relation(fields: [quotationId], references: [id], onDelete: Cascade) quotationId String + + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt } model QuotationProductServiceList { diff --git a/src/controllers/07-task-controller.ts b/src/controllers/07-task-controller.ts index 5e9977c..3f15e07 100644 --- a/src/controllers/07-task-controller.ts +++ b/src/controllers/07-task-controller.ts @@ -606,7 +606,21 @@ export class TaskActionController extends Controller { return await prisma.$transaction(async (tx) => { const promises = body.map(async (v) => { const record = await tx.task.findFirst({ - include: { requestWorkStep: true }, + include: { + requestWorkStep: { + include: { + requestWork: { + include: { + request: { + include: { + quotation: true, + }, + }, + }, + }, + }, + }, + }, where: { step: v.step, requestWorkId: v.requestWorkId, @@ -624,6 +638,20 @@ export class TaskActionController extends Controller { data: { userTaskStatus: UserTaskStatus.Restart }, }); } + + if (v.taskStatus === TaskStatus.Failed) { + const code = record.requestWorkStep.requestWork.request.quotation.code; + const name = record.requestWorkStep.requestWork.request.quotation.workName; + + await tx.notification.create({ + data: { + title: "ใบรายการคำขอที่จัดการเกิดปัญหา / Task Failed", + detail: `ใบรายการคำขอรหัส / code : ${code} - ${name} ใบรายการคำขอเกิดปัญหา`, + receiverId: record.requestWorkStep.requestWork.request.quotation.updatedByUserId, + }, + }); + } + return await tx.task.update({ where: { id: record.id }, data: { diff --git a/src/services/schedule.ts b/src/services/schedule.ts index bd12bf8..40e8763 100644 --- a/src/services/schedule.ts +++ b/src/services/schedule.ts @@ -38,6 +38,120 @@ const jobs = [ .catch((e) => console.error("[ERR]: Update expired quotation status, FAILED.", e)); }, }), + CronJob.from({ + cronTime: "0 0 0 * * *", + runOnInit: true, + onTick: async () => { + const employeeExpireData = await prisma.employee.findMany({ + include: { + employeePassport: { + orderBy: { + expireDate: "desc", + }, + take: 1, + }, + customerBranch: { + include: { + customer: true, + }, + }, + }, + where: { + employeePassport: { + some: { + expireDate: dayjs().add(90, "day").toDate(), + }, + }, + }, + }); + + await employeeExpireData.map(async (record) => { + const fullName = `${record.namePrefix}${record.firstNameEN} ${record.lastNameEN}`; + const expireDate = `${dayjs(record.employeePassport[0].expireDate).format("DD/MM")}/${dayjs(record.employeePassport[0].expireDate).year() + 543}`; + const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} หนังสือเดินทางจะหมดอายุในวันที่ ${expireDate}`; + const duplicateText = await prisma.notification.findFirst({ + where: { + detail: textDetail, + }, + }); + + if (!duplicateText) { + await prisma.notification + .create({ + data: { + title: "หนังสือเดินทางลูกจ้างหมดอายุ / Employee Passport Expire", + detail: textDetail, + groupReceiver: { + create: [{ name: "sale" }, { name: "head_of_sale" }], + }, + registeredBranchId: record.customerBranch.customer.registeredBranchId, + }, + }) + .then(() => console.log("[INFO]: Create notification employee passport expired, OK.")) + .catch((e) => + console.error("[ERR]: Create notification employee passport expired, FAILED.", e), + ); + } + }); + }, + }), + CronJob.from({ + cronTime: "0 0 0 * * *", + runOnInit: true, + onTick: async () => { + const employeeVisaData = await prisma.employee.findMany({ + include: { + employeeVisa: { + orderBy: { + expireDate: "desc", + }, + take: 1, + }, + customerBranch: { + include: { + customer: true, + }, + }, + }, + where: { + employeeVisa: { + some: { + expireDate: dayjs().add(90, "day").toDate(), + }, + }, + }, + }); + + await employeeVisaData.map(async (record) => { + const fullName = `${record.namePrefix}${record.firstNameEN} ${record.lastNameEN}`; + const expireDate = `${dayjs(record.employeeVisa[0].expireDate).format("DD/MM")}/${dayjs(record.employeeVisa[0].expireDate).year() + 543}`; + const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} ข้อมูลการตรวจลงตราจะหมดอายุในวันที่ ${expireDate}`; + const duplicateText = await prisma.notification.findFirst({ + where: { + detail: textDetail, + }, + }); + + if (!duplicateText) { + await prisma.notification + .create({ + data: { + title: "ข้อมูลการตรวจลงตราลูกจ้างหมดอายุ / Employee Visa Expire", + detail: textDetail, + groupReceiver: { + create: [{ name: "sale" }, { name: "head_of_sale" }], + }, + registeredBranchId: record.customerBranch.customer.registeredBranchId, + }, + }) + .then(() => console.log("[INFO]: Create notification employee visa expired, OK.")) + .catch((e) => + console.error("[ERR]: Create notification employee visa expired, FAILED.", e), + ); + } + }); + }, + }), ]; export function initSchedule() { From 0aa20d3728e25aa469b7adae2622c450ea30ad56 Mon Sep 17 00:00:00 2001 From: Kanjana Date: Wed, 14 May 2025 14:18:08 +0700 Subject: [PATCH 3/3] change detail notification task --- src/controllers/07-task-controller.ts | 19 +++- src/services/schedule.ts | 151 +++++++++++++++++--------- 2 files changed, 112 insertions(+), 58 deletions(-) diff --git a/src/controllers/07-task-controller.ts b/src/controllers/07-task-controller.ts index 3f15e07..e806797 100644 --- a/src/controllers/07-task-controller.ts +++ b/src/controllers/07-task-controller.ts @@ -614,12 +614,19 @@ export class TaskActionController extends Controller { request: { include: { quotation: true, + employee: true, + }, + }, + productService: { + include: { + product: true, }, }, }, }, }, }, + taskOrder: true, }, where: { step: v.step, @@ -640,14 +647,18 @@ export class TaskActionController extends Controller { } if (v.taskStatus === TaskStatus.Failed) { - const code = record.requestWorkStep.requestWork.request.quotation.code; - const name = record.requestWorkStep.requestWork.request.quotation.workName; + const taskCode = record.taskOrder.code; + const taskName = record.taskOrder.taskName; + const productCode = record.requestWorkStep.requestWork.productService.product.code; + const productName = record.requestWorkStep.requestWork.productService.product.name; + const employeeName = `${record.requestWorkStep.requestWork.request.employee.namePrefix}.${record.requestWorkStep.requestWork.request.employee.firstNameEN} ${record.requestWorkStep.requestWork.request.employee.lastNameEN}`; await tx.notification.create({ data: { title: "ใบรายการคำขอที่จัดการเกิดปัญหา / Task Failed", - detail: `ใบรายการคำขอรหัส / code : ${code} - ${name} ใบรายการคำขอเกิดปัญหา`, - receiverId: record.requestWorkStep.requestWork.request.quotation.updatedByUserId, + detail: `ใบรายการคำขอรหัส ${taskCode}: ${taskName} รหัสสินค้า ${productCode}: ${productName} ของลูกจ้าง ${employeeName} เกิดข้อผิดพลาด`, + groupReceiver: { create: { name: "document_checker" } }, + registeredBranchId: record.taskOrder.registeredBranchId, }, }); } diff --git a/src/services/schedule.ts b/src/services/schedule.ts index 40e8763..dd0591e 100644 --- a/src/services/schedule.ts +++ b/src/services/schedule.ts @@ -2,6 +2,7 @@ import dayjs from "dayjs"; import { CronJob } from "cron"; import prisma from "../db"; +import { Prisma } from "@prisma/client"; const jobs = [ CronJob.from({ @@ -55,6 +56,15 @@ const jobs = [ customer: true, }, }, + quotationWorker: { + include: { + quotation: true, + }, + orderBy: { + createdAt: "desc", + }, + take: 1, + }, }, where: { employeePassport: { @@ -65,34 +75,46 @@ const jobs = [ }, }); - await employeeExpireData.map(async (record) => { - const fullName = `${record.namePrefix}${record.firstNameEN} ${record.lastNameEN}`; - const expireDate = `${dayjs(record.employeePassport[0].expireDate).format("DD/MM")}/${dayjs(record.employeePassport[0].expireDate).year() + 543}`; - const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} หนังสือเดินทางจะหมดอายุในวันที่ ${expireDate}`; - const duplicateText = await prisma.notification.findFirst({ - where: { - detail: textDetail, - }, - }); + await Promise.all( + employeeExpireData.map(async (record) => { + const fullName = `${record.namePrefix}.${record.firstNameEN} ${record.lastNameEN}`; + const expireDate = `${dayjs(record.employeePassport[0].expireDate).format("DD/MM")}/${dayjs(record.employeePassport[0].expireDate).year() + 543}`; + const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} หนังสือเดินทางจะหมดอายุในวันที่ ${expireDate}`; + const duplicateText = await prisma.notification.findFirst({ + where: { + detail: textDetail, + }, + }); - if (!duplicateText) { - await prisma.notification - .create({ - data: { - title: "หนังสือเดินทางลูกจ้างหมดอายุ / Employee Passport Expire", - detail: textDetail, - groupReceiver: { - create: [{ name: "sale" }, { name: "head_of_sale" }], - }, - registeredBranchId: record.customerBranch.customer.registeredBranchId, - }, - }) - .then(() => console.log("[INFO]: Create notification employee passport expired, OK.")) - .catch((e) => - console.error("[ERR]: Create notification employee passport expired, FAILED.", e), - ); - } - }); + const dataNotification: Prisma.NotificationCreateArgs["data"] = { + title: "หนังสือเดินทางลูกจ้างหมดอายุ / Employee Passport Expire", + detail: textDetail, + }; + + if (record.quotationWorker && record.quotationWorker.length > 0) { + dataNotification.receiverId = record.quotationWorker[0].quotation.updatedByUserId; + dataNotification.registeredBranchId = + record.quotationWorker[0].quotation.registeredBranchId; + } else { + (dataNotification.groupReceiver = { + create: [{ name: "sale" }, { name: "head_of_sale" }], + }), + (dataNotification.registeredBranchId = + record.customerBranch.customer.registeredBranchId); + } + + if (!duplicateText) { + await prisma.notification + .create({ + data: dataNotification, + }) + .then(() => console.log("[INFO]: Create notification employee passport expired, OK.")) + .catch((e) => + console.error("[ERR]: Create notification employee passport expired, FAILED.", e), + ); + } + }), + ); }, }), CronJob.from({ @@ -112,6 +134,15 @@ const jobs = [ customer: true, }, }, + quotationWorker: { + include: { + quotation: true, + }, + orderBy: { + createdAt: "desc", + }, + take: 1, + }, }, where: { employeeVisa: { @@ -122,34 +153,46 @@ const jobs = [ }, }); - await employeeVisaData.map(async (record) => { - const fullName = `${record.namePrefix}${record.firstNameEN} ${record.lastNameEN}`; - const expireDate = `${dayjs(record.employeeVisa[0].expireDate).format("DD/MM")}/${dayjs(record.employeeVisa[0].expireDate).year() + 543}`; - const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} ข้อมูลการตรวจลงตราจะหมดอายุในวันที่ ${expireDate}`; - const duplicateText = await prisma.notification.findFirst({ - where: { - detail: textDetail, - }, - }); + await Promise.all( + employeeVisaData.map(async (record) => { + const fullName = `${record.namePrefix}.${record.firstNameEN} ${record.lastNameEN}`; + const expireDate = `${dayjs(record.employeeVisa[0].expireDate).format("DD/MM")}/${dayjs(record.employeeVisa[0].expireDate).year() + 543}`; + const textDetail = `ลูกจ้างรหัส / code : ${record.code} ชื่อ : ${fullName} ข้อมูลการตรวจลงตราจะหมดอายุในวันที่ ${expireDate}`; + const duplicateText = await prisma.notification.findFirst({ + where: { + detail: textDetail, + }, + }); - if (!duplicateText) { - await prisma.notification - .create({ - data: { - title: "ข้อมูลการตรวจลงตราลูกจ้างหมดอายุ / Employee Visa Expire", - detail: textDetail, - groupReceiver: { - create: [{ name: "sale" }, { name: "head_of_sale" }], - }, - registeredBranchId: record.customerBranch.customer.registeredBranchId, - }, - }) - .then(() => console.log("[INFO]: Create notification employee visa expired, OK.")) - .catch((e) => - console.error("[ERR]: Create notification employee visa expired, FAILED.", e), - ); - } - }); + const dataNotification: Prisma.NotificationCreateArgs["data"] = { + title: "ข้อมูลการตรวจลงตราลูกจ้างหมดอายุ / Employee Visa Expire", + detail: textDetail, + }; + + if (record.quotationWorker && record.quotationWorker.length > 0) { + dataNotification.receiverId = record.quotationWorker[0].quotation.updatedByUserId; + dataNotification.registeredBranchId = + record.quotationWorker[0].quotation.registeredBranchId; + } else { + (dataNotification.groupReceiver = { + create: [{ name: "sale" }, { name: "head_of_sale" }], + }), + (dataNotification.registeredBranchId = + record.customerBranch.customer.registeredBranchId); + } + + if (!duplicateText) { + await prisma.notification + .create({ + data: dataNotification, + }) + .then(() => console.log("[INFO]: Create notification employee visa expired, OK.")) + .catch((e) => + console.error("[ERR]: Create notification employee visa expired, FAILED.", e), + ); + } + }), + ); }, }), ];