From 4245bcaca86960ff9c4f93daaa9eeef7d0fbc1bf Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:32:53 +0700 Subject: [PATCH] refactor: update flow-account api function --- src/services/flowaccount.ts | 138 ++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 55 deletions(-) diff --git a/src/services/flowaccount.ts b/src/services/flowaccount.ts index 5bdb0c9..d45aceb 100644 --- a/src/services/flowaccount.ts +++ b/src/services/flowaccount.ts @@ -1,5 +1,6 @@ import prisma from "../db"; import config from "../config.json"; +import { CustomerType } from "@prisma/client"; if (!process.env.FLOW_ACCOUNT_URL) throw new Error("Require FLOW_ACCOUNT_URL"); if (!process.env.FLOW_ACCOUNT_CLIENT_ID) throw new Error("Require FLOW_ACCOUNT_CLIENT_ID"); @@ -50,6 +51,13 @@ enum ProductAndServiceType { ProductInv = 5, } +enum PaymentDeductionType { + SpecialDiscount = 1, + Commission = 3, + Process = 5, + Round = 7, +} + type ProductAndService = { type?: ProductAndServiceType; name: string; @@ -144,6 +152,10 @@ const flowAccountAPI = { documentStructureType?: "SimpleDocument" | null; saleAndPurchaseChannel?: SaleAndPurchaseChannel; items: ProductAndService[]; + /** This must be in yyyy-MM-dd format if pass as string */ + paymentDate: Date | string; + paymentDeductionType?: PaymentDeductionType; + collected: number; }, withPayment?: boolean, ) { @@ -163,7 +175,14 @@ const flowAccountAPI = { data.dueDate = `${year}-${String(month).padStart(2, "0")}-${String(date).padStart(2, "0")}`; } - const res = await fetch(api + "/tax-invoices/inline" + withPayment ? "/with-payment" : "", { + if (data.paymentDate instanceof Date) { + let date = data.paymentDate.getDate(); + let month = data.paymentDate.getMonth() + 1; + let year = data.paymentDate.getFullYear(); + data.paymentDate = `${year}-${String(month).padStart(2, "0")}-${String(date).padStart(2, "0")}`; + } + + const res = await fetch(api + "/tax-invoices/inline" + (withPayment ? "/with-payment" : ""), { method: "POST", headers: { ["Content-Type"]: `application/json`, @@ -180,14 +199,16 @@ const flowAccountAPI = { }, async getInvoiceDocument(recordId: string) { - const res = await fetch(api + "tax-invoices/shareddocument", { + const { token } = await flowAccountAPI.auth(); + + const res = await fetch(api + "/tax-invoices/sharedocument", { method: "POST", headers: { ["Content-Type"]: `application/json`, ["Authorization"]: `Bearer ${token}`, }, body: JSON.stringify({ - recordId, + documentId: recordId, culture: "th", }), }); @@ -195,13 +216,13 @@ const flowAccountAPI = { return { ok: res.ok, status: res.status, - body: await res.json(), + body: await res.text(), }; }, }; const flowAccount = { - issueInvoiceWithPayment: async (invoiceId: string) => { + issueInvoice: async (invoiceId: string) => { const data = await prisma.invoice.findFirst({ where: { id: invoiceId }, include: { @@ -240,67 +261,74 @@ const flowAccount = { const branch = quotation.registeredBranch; const product = quotation.productServiceList; - return await flowAccountAPI.createInvoice( - { - contactCode: customer.code, - contactName: [customer.firstName, customer.lastName].join(" "), - contactAddress: [ - customer.address, - !!customer.moo ? "หมู่" + customer.moo : null, - !!customer.soi ? "ซอย" + customer.soi : null, - !!customer.street ? "ถนน" + customer.street : null, - (customer.province?.id === "10" ? "แขวง" : "อำเภอ") + customer.subDistrict?.name, - (customer.province?.id === "10" ? "เขต" : "ตำบล") + customer.district?.name, - customer.province?.name, - customer.subDistrict?.zipCode, - ] - .filter(Boolean) - .join(" "), - contactTaxId: customer.citizenId || customer.code, - contactBranch: customer.authorizedName ?? undefined, - contactPerson: branch.contactName ?? undefined, - contactEmail: branch.email, - contactNumber: branch.telephoneNo, - contactZipCode: branch.subDistrict?.zipCode, - contactGroup: - customer.customer.customerType === "PERS" ? ContactGroup.PERS : ContactGroup.CORP, - dueDate: quotation.dueDate, - salesName: [quotation.createdBy?.firstName, quotation.createdBy?.lastName].join(" "), + const payload = { + contactCode: customer.code, + contactName: + (customer.customer.customerType === CustomerType.PERS + ? [customer.firstName, customer.lastName].join(" ").trim() + : customer.registerName) || "-", + contactAddress: [ + customer.address, + !!customer.moo ? "หมู่" + customer.moo : null, + !!customer.soi ? "ซอย" + customer.soi : null, + !!customer.street ? "ถนน" + customer.street : null, + (customer.province?.id === "10" ? "แขวง" : "อำเภอ") + customer.subDistrict?.name, + (customer.province?.id === "10" ? "เขต" : "ตำบล") + customer.district?.name, + customer.province?.name, + customer.subDistrict?.zipCode, + ] + .filter(Boolean) + .join(" "), + contactTaxId: customer.citizenId || customer.code, + contactBranch: + (customer.customer.customerType === CustomerType.PERS + ? [customer.firstName, customer.lastName].join(" ").trim() + : customer.registerName) || "-", + contactPerson: customer.contactName ?? undefined, + contactEmail: customer.email, + contactNumber: customer.telephoneNo, + contactZipCode: customer.subDistrict?.zipCode, + contactGroup: + customer.customer.customerType === "PERS" ? ContactGroup.PERS : ContactGroup.CORP, + dueDate: quotation.dueDate, + salesName: [quotation.createdBy?.firstName, quotation.createdBy?.lastName].join(" "), - isVatInclusive: true, - isVat: true, + isVatInclusive: true, + isVat: true, - useReceiptDeduction: true, + useReceiptDeduction: true, - discounPercentage: 0, - discountAmount: quotation.totalDiscount, + discounPercentage: 0, + discountAmount: quotation.totalDiscount, - subTotal: quotation.totalPrice, - totalAfterDiscount: quotation.finalPrice, - vatAmount: quotation.vat, - grandTotal: quotation.finalPrice, + subTotal: quotation.totalPrice, + totalAfterDiscount: quotation.finalPrice, + vatAmount: quotation.vat, + grandTotal: quotation.finalPrice, - items: product.map((v) => ({ - type: ProductAndServiceType.ProductNonInv, - name: v.product.name, - pricePerUnit: v.pricePerUnit, - quantity: v.amount, - discountAmount: v.discount, - total: (v.pricePerUnit - (v.discount || 0)) * v.amount + v.vat, - vatRate: VAT_DEFAULT * 100, - })), - }, - true, - ); + paymentDate: data.payment?.createdAt ?? new Date(), + collected: quotation.finalPrice, + + items: product.map((v) => ({ + type: ProductAndServiceType.ProductNonInv, + name: v.product.name, + pricePerUnit: v.pricePerUnit, + quantity: v.amount, + discountAmount: v.discount, + total: (v.pricePerUnit - (v.discount || 0)) * v.amount + v.vat, + vatRate: Math.round(VAT_DEFAULT * 100), + })), + }; + + return await flowAccountAPI.createInvoice(payload, false); }, getInvoiceDocument: async (recordId: string) => { const ret = await flowAccountAPI.getInvoiceDocument(recordId); - + console.log(ret); if (ret && ret.ok) { - return ret.body.data.link; + return ret.body; } - return null; }, };