diff --git a/prisma/migrations/20250418095201_add/migration.sql b/prisma/migrations/20250418095201_add/migration.sql new file mode 100644 index 0000000..be3e4d0 --- /dev/null +++ b/prisma/migrations/20250418095201_add/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "TaskOrder" ADD COLUMN "codeProductReceived" TEXT; diff --git a/prisma/migrations/20250418103300_add/migration.sql b/prisma/migrations/20250418103300_add/migration.sql new file mode 100644 index 0000000..2e63034 --- /dev/null +++ b/prisma/migrations/20250418103300_add/migration.sql @@ -0,0 +1,18 @@ +-- AlterTable +ALTER TABLE "Institution" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "createdByUserId" TEXT, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updatedByUserId" TEXT; + +-- AlterTable +ALTER TABLE "Payment" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updatedByUserId" TEXT; + +-- AddForeignKey +ALTER TABLE "Institution" ADD CONSTRAINT "Institution_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Institution" ADD CONSTRAINT "Institution_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Payment" ADD CONSTRAINT "Payment_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d40957e..f51e7fa 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -484,12 +484,15 @@ model User { flowCreated WorkflowTemplate[] @relation("FlowCreatedByUser") flowUpdated WorkflowTemplate[] @relation("FlowUpdatedByUser") invoiceCreated Invoice[] - paymentCreated Payment[] + paymentCreated Payment[] @relation("PaymentCreatedByUser") + paymentUpdated Payment[] @relation("PaymentUpdatedByUser") notificationReceive Notification[] @relation("NotificationReceiver") notificationRead Notification[] @relation("NotificationRead") notificationDelete Notification[] @relation("NotificationDelete") taskOrderCreated TaskOrder[] @relation("TaskOrderCreatedByUser") creditNoteCreated CreditNote[] @relation("CreditNoteCreatedByUser") + institutionCreated Institution[] @relation("InstitutionCreatedByUser") + institutionUpdated Institution[] @relation("InstitutionUpdatedByUser") requestWorkStepStatus RequestWorkStepStatus[] userTask UserTask[] @@ -1015,6 +1018,13 @@ model Institution { contactEmail String? contactTel String? + createdAt DateTime @default(now()) + createdBy User? @relation(name: "InstitutionCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) + createdByUserId String? + updatedAt DateTime @default(now()) @updatedAt + updatedBy User? @relation(name: "InstitutionUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? + bank InstitutionBank[] } @@ -1463,8 +1473,12 @@ model Payment { date DateTime? createdAt DateTime @default(now()) - createdBy User? @relation(fields: [createdByUserId], references: [id], onDelete: SetNull) + createdBy User? @relation(name: "PaymentCreatedByUser", fields: [createdByUserId], references: [id], onDelete: SetNull) createdByUserId String? + + updatedAt DateTime @default(now()) @updatedAt + updatedBy User? @relation(name: "PaymentUpdatedByUser", fields: [updatedByUserId], references: [id], onDelete: SetNull) + updatedByUserId String? } enum RequestDataStatus { @@ -1617,7 +1631,8 @@ model TaskProduct { model TaskOrder { id String @id @default(cuid()) - code String + code String + codeProductReceived String? taskName String taskOrderStatus TaskOrderStatus @default(Pending) diff --git a/src/controllers/04-institution-controller.ts b/src/controllers/04-institution-controller.ts index 76c0fc4..21611a7 100644 --- a/src/controllers/04-institution-controller.ts +++ b/src/controllers/04-institution-controller.ts @@ -17,7 +17,7 @@ import { } from "tsoa"; import prisma from "../db"; import { isUsedError, notFoundError } from "../utils/error"; -import { queryOrNot } from "../utils/relation"; +import { queryOrNot, whereDateQuery } from "../utils/relation"; import { RequestWithUser } from "../interfaces/user"; import { deleteFile, fileLocation, getFile, getPresigned, listFile, setFile } from "../utils/minio"; import HttpError from "../interfaces/http-error"; @@ -108,8 +108,19 @@ export class InstitutionController extends Controller { @Query() status?: Status, @Query() activeOnly?: boolean, @Query() group?: string, + @Query() startDate?: Date, + @Query() endDate?: Date, ) { - return this.getInstitutionListByCriteria(query, page, pageSize, status, activeOnly, group); + return this.getInstitutionListByCriteria( + query, + page, + pageSize, + status, + activeOnly, + group, + startDate, + endDate, + ); } @Post("list") @@ -122,6 +133,8 @@ export class InstitutionController extends Controller { @Query() status?: Status, @Query() activeOnly?: boolean, @Query() group?: string, + @Query() startDate?: Date, + @Query() endDate?: Date, @Body() body?: { group?: string[]; @@ -134,6 +147,7 @@ export class InstitutionController extends Controller { { name: { contains: query, mode: "insensitive" } }, { code: { contains: query, mode: "insensitive" } }, ]), + ...whereDateQuery(startDate, endDate), } satisfies Prisma.InstitutionWhereInput; const [result, total] = await prisma.$transaction([ @@ -178,6 +192,7 @@ export class InstitutionController extends Controller { body: InstitutionPayload & { status?: Status; }, + @Request() req: RequestWithUser, ) { return await prisma.$transaction(async (tx) => { const last = await tx.runningNo.upsert({ @@ -194,6 +209,8 @@ export class InstitutionController extends Controller { return await tx.institution.create({ include: { bank: true, + createdBy: true, + updatedBy: true, }, data: { ...body, @@ -204,6 +221,8 @@ export class InstitutionController extends Controller { data: body.bank ?? [], }, }, + createdByUserId: req.user.sub, + updatedByUserId: req.user.sub, }, }); }); diff --git a/src/controllers/04-receipt-controller.ts b/src/controllers/04-receipt-controller.ts index caad04b..55a52c6 100644 --- a/src/controllers/04-receipt-controller.ts +++ b/src/controllers/04-receipt-controller.ts @@ -4,6 +4,7 @@ import { Prisma } from "@prisma/client"; import { notFoundError } from "../utils/error"; import { RequestWithUser } from "../interfaces/user"; import { createPermCondition } from "../services/permission"; +import { whereDateQuery } from "../utils/relation"; const permissionCondCompany = createPermCondition((_) => true); @@ -21,6 +22,8 @@ export class ReceiptController extends Controller { @Query() quotationId?: string, @Query() debitNoteId?: string, @Query() debitNoteOnly?: boolean, + @Query() startDate?: Date, + @Query() endDate?: Date, ) { const where: Prisma.PaymentWhereInput = { paymentStatus: "PaymentSuccess", @@ -33,6 +36,7 @@ export class ReceiptController extends Controller { }, }, }, + ...whereDateQuery(startDate, endDate), }; const [result, total] = await prisma.$transaction([ diff --git a/src/controllers/05-payment-controller.ts b/src/controllers/05-payment-controller.ts index a4b7339..e5bf0a4 100644 --- a/src/controllers/05-payment-controller.ts +++ b/src/controllers/05-payment-controller.ts @@ -105,6 +105,7 @@ export class QuotationPayment extends Controller { async updatePayment( @Path() paymentId: string, @Body() body: { amount?: number; date?: Date; paymentStatus?: PaymentStatus }, + @Request() req: RequestWithUser, ) { const record = await prisma.payment.findUnique({ where: { id: paymentId }, @@ -164,6 +165,7 @@ export class QuotationPayment extends Controller { code: lastReceipt ? `RE${year}${month}${lastReceipt.value.toString().padStart(6, "0")}` : undefined, + updatedByUserId: req.user.sub, }, }); diff --git a/src/controllers/07-task-controller.ts b/src/controllers/07-task-controller.ts index 58acbbe..92fc696 100644 --- a/src/controllers/07-task-controller.ts +++ b/src/controllers/07-task-controller.ts @@ -697,12 +697,31 @@ export class TaskActionController extends Controller { if (!record) throw notFoundError("Task Order"); await prisma.$transaction(async (tx) => { + const last = await tx.runningNo.upsert({ + where: { + key: "TASK_RI", + }, + create: { + key: "TASK_RI", + value: 1, + }, + update: { + value: { increment: 1 }, + }, + }); + const current = new Date(); + const year = `${current.getFullYear()}`.padStart(2, "0"); + const month = `${current.getMonth() + 1}`.padStart(2, "0"); + + const code = `RI${year}${month}${last.value.toString().padStart(6, "0")}`; + await Promise.all([ tx.taskOrder.update({ where: { id: taskOrderId }, data: { urgent: false, taskOrderStatus: TaskOrderStatus.Complete, + codeProductReceived: code, userTask: { updateMany: { where: { taskOrderId },