Merge branch 'develop'

This commit is contained in:
Methapon2001 2025-01-17 19:28:04 +07:00
commit 2acd1e156a
7 changed files with 91 additions and 7 deletions

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "CreditNote" ADD COLUMN "paybackDate" TIMESTAMP(3);

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "CreditNote" ADD COLUMN "remark" TEXT;

View file

@ -1606,12 +1606,14 @@ model CreditNote {
value Float @default(0) value Float @default(0)
reason String? reason String?
detail String? detail String?
remark String?
paybackType CreditNotePaybackType? paybackType CreditNotePaybackType?
paybackBank String? paybackBank String?
paybackAccount String? paybackAccount String?
paybackAccountName String? paybackAccountName String?
paybackStatus PaybackStatus @default(Pending) paybackStatus PaybackStatus @default(Pending)
paybackDate DateTime?
quotation Quotation @relation(fields: [quotationId], references: [id], onDelete: Cascade) quotation Quotation @relation(fields: [quotationId], references: [id], onDelete: Cascade)
quotationId String quotationId String

View file

@ -38,7 +38,13 @@ export class ReceiptController extends Controller {
invoice: { invoice: {
include: { include: {
installments: true, installments: true,
quotation: true, quotation: {
include: {
customerBranch: {
include: { customer: true },
},
},
},
createdBy: true, createdBy: true,
}, },
}, },

View file

@ -32,7 +32,15 @@ import {
} from "../services/permission"; } from "../services/permission";
import HttpError from "../interfaces/http-error"; import HttpError from "../interfaces/http-error";
import HttpStatus from "../interfaces/http-status"; import HttpStatus from "../interfaces/http-status";
import { deleteFile, fileLocation, getFile, getPresigned, listFile, setFile } from "../utils/minio"; import {
deleteFile,
deleteFolder,
fileLocation,
getFile,
getPresigned,
listFile,
setFile,
} from "../utils/minio";
import { queryOrNot } from "../utils/relation"; import { queryOrNot } from "../utils/relation";
const MANAGE_ROLES = ["system", "head_of_admin", "admin", "document_checker"]; const MANAGE_ROLES = ["system", "head_of_admin", "admin", "document_checker"];
@ -429,6 +437,9 @@ export class TaskController extends Controller {
if (!record) throw notFoundError("Task Order"); if (!record) throw notFoundError("Task Order");
await permissionCheck(req.user, record.registeredBranch); await permissionCheck(req.user, record.registeredBranch);
await Promise.all([deleteFolder(fileLocation.task.attachment(taskOrderId))]);
await tx.taskOrder.delete({ where: { id: taskOrderId } });
}); });
} }
} }

View file

@ -24,7 +24,15 @@ import {
} from "../services/permission"; } from "../services/permission";
import HttpError from "../interfaces/http-error"; import HttpError from "../interfaces/http-error";
import HttpStatus from "../interfaces/http-status"; import HttpStatus from "../interfaces/http-status";
import { deleteFile, fileLocation, getFile, getPresigned, listFile, setFile } from "../utils/minio"; import {
deleteFile,
deleteFolder,
fileLocation,
getFile,
getPresigned,
listFile,
setFile,
} from "../utils/minio";
import { notFoundError } from "../utils/error"; import { notFoundError } from "../utils/error";
import { CreditNotePaybackType, CreditNoteStatus, Prisma } from "@prisma/client"; import { CreditNotePaybackType, CreditNoteStatus, Prisma } from "@prisma/client";
import { queryOrNot } from "../utils/relation"; import { queryOrNot } from "../utils/relation";
@ -56,6 +64,7 @@ type CreditNoteCreate = {
quotationId: string; quotationId: string;
reason?: string; reason?: string;
detail?: string; detail?: string;
remark?: string;
paybackType?: CreditNotePaybackType; paybackType?: CreditNotePaybackType;
paybackBank?: string; paybackBank?: string;
paybackAccount?: string; paybackAccount?: string;
@ -66,6 +75,7 @@ type CreditNoteUpdate = {
quotationId: string; quotationId: string;
reason?: string; reason?: string;
detail?: string; detail?: string;
remark?: string;
paybackType?: CreditNotePaybackType; paybackType?: CreditNotePaybackType;
paybackBank?: string; paybackBank?: string;
paybackAccount?: string; paybackAccount?: string;
@ -355,6 +365,7 @@ export class CreditNoteController extends Controller {
data: { data: {
reason: body.reason, reason: body.reason,
detail: body.detail, detail: body.detail,
remark: body.remark,
paybackType: body.paybackType, paybackType: body.paybackType,
paybackBank: body.paybackBank, paybackBank: body.paybackBank,
paybackAccount: body.paybackAccount, paybackAccount: body.paybackAccount,
@ -471,6 +482,7 @@ export class CreditNoteController extends Controller {
data: { data: {
reason: body.reason, reason: body.reason,
detail: body.detail, detail: body.detail,
remark: body.remark,
paybackType: body.paybackType, paybackType: body.paybackType,
paybackBank: body.paybackBank, paybackBank: body.paybackBank,
paybackAccount: body.paybackAccount, paybackAccount: body.paybackAccount,
@ -511,6 +523,11 @@ export class CreditNoteController extends Controller {
if (!record) throw notFoundError("Credit Note"); if (!record) throw notFoundError("Credit Note");
await permissionCheck(req.user, record.quotation.registeredBranch); await permissionCheck(req.user, record.quotation.registeredBranch);
await Promise.all([
deleteFolder(fileLocation.creditNote.slip(creditNoteId)),
deleteFolder(fileLocation.creditNote.attachment(creditNoteId)),
]);
return await prisma.creditNote.delete({ where: { id: creditNoteId } }); return await prisma.creditNote.delete({ where: { id: creditNoteId } });
} }
} }
@ -540,7 +557,7 @@ export class CreditNoteActionController extends Controller {
async updateStatus( async updateStatus(
@Request() req: RequestWithUser, @Request() req: RequestWithUser,
@Path() creditNoteId: string, @Path() creditNoteId: string,
@Body() body: PaybackStatus, @Body() body: { paybackStatus: PaybackStatus },
) { ) {
await this.#checkPermission(req.user, creditNoteId); await this.#checkPermission(req.user, creditNoteId);
return await prisma.creditNote.update({ return await prisma.creditNote.update({
@ -554,8 +571,10 @@ export class CreditNoteActionController extends Controller {
quotation: true, quotation: true,
}, },
data: { data: {
creditNoteStatus: body === PaybackStatus.Done ? CreditNoteStatus.Success : undefined, creditNoteStatus:
paybackStatus: body, body.paybackStatus === PaybackStatus.Done ? CreditNoteStatus.Success : undefined,
paybackStatus: body.paybackStatus,
paybackDate: body.paybackStatus === PaybackStatus.Done ? new Date() : undefined,
}, },
}); });
} }
@ -620,4 +639,44 @@ export class CreditNoteAttachmentController extends Controller {
await this.#checkPermission(req.user, creditNoteId); await this.#checkPermission(req.user, creditNoteId);
return await deleteFile(fileLocation.creditNote.attachment(creditNoteId, name)); return await deleteFile(fileLocation.creditNote.attachment(creditNoteId, name));
} }
@Get("file-slip")
@Security("keycloak")
async listSlip(@Request() req: RequestWithUser, @Path() creditNoteId: string) {
await this.#checkPermission(req.user, creditNoteId);
return await listFile(fileLocation.creditNote.slip(creditNoteId));
}
@Get("file-slip/{name}")
@Security("keycloak")
async getSlip(@Path() creditNoteId: string, @Path() name: string) {
return await getFile(fileLocation.creditNote.slip(creditNoteId, name));
}
@Head("file-slip/{name}")
async headSlip(@Path() creditNoteId: string, @Path() name: string) {
return await getPresigned("head", fileLocation.creditNote.slip(creditNoteId, name));
}
@Put("file-slip/{name}")
@Security("keycloak")
async putSlip(
@Request() req: RequestWithUser,
@Path() creditNoteId: string,
@Path() name: string,
) {
await this.#checkPermission(req.user, creditNoteId);
return await setFile(fileLocation.creditNote.slip(creditNoteId, name));
}
@Delete("file-slip/{name}")
@Security("keycloak")
async delSlip(
@Request() req: RequestWithUser,
@Path() creditNoteId: string,
@Path() name: string,
) {
await this.#checkPermission(req.user, creditNoteId);
return await deleteFile(fileLocation.creditNote.slip(creditNoteId, name));
}
} }

View file

@ -113,6 +113,8 @@ export const fileLocation = {
attachment: (taskId: string, name?: string) => `task/attachment-${taskId}/${name || ""}`, attachment: (taskId: string, name?: string) => `task/attachment-${taskId}/${name || ""}`,
}, },
creditNote: { creditNote: {
attachment: (taskId: string, name?: string) => `credit-note/attachment-${taskId}/${name || ""}`, slip: (creditNoteId: string, name?: string) => `credit-note/slip-${creditNoteId}/${name || ""}`,
attachment: (creditNoteId: string, name?: string) =>
`credit-note/attachment-${creditNoteId}/${name || ""}`,
}, },
}; };