diff --git a/src/app/api/invoices/actions.ts b/src/app/api/invoices/actions.ts index dc45104..e82ab1c 100644 --- a/src/app/api/invoices/actions.ts +++ b/src/app/api/invoices/actions.ts @@ -92,4 +92,16 @@ export const importReceivedInovice = async (data: FormData) => { ); return importReceivedInovice; +}; + +export const importInvoices = async (data: FormData) => { + const importInvoices = await serverFetchJson( + `${BASE_API_URL}/invoices/import/v2`, + { + method: "POST", + body: data, + }, + ); + + return importInvoices; }; \ No newline at end of file diff --git a/src/app/api/invoices/index.ts b/src/app/api/invoices/index.ts index 8d68557..930557e 100644 --- a/src/app/api/invoices/index.ts +++ b/src/app/api/invoices/index.ts @@ -15,6 +15,25 @@ export interface InvoiceResult { reminder: string; } +export interface InvoiceResultV2 { + id: number; + invoiceNo: string; + projectCode: string; + projectName: string; + team: string; + stage: string; + paymentMilestone: string; + paymentMilestoneDate: string; + client: string; + address: string; + attention: string; + invoiceDate: string; + receiptDate: string; + dueDate: number[]; + issueAmount: number; + paidAmount: number; +} + export interface issuedInvoiceResult { id: number; invoiceNo: string; @@ -42,6 +61,18 @@ export interface receivedInvoiceResult { receivedAmount: number; } +export interface invoiceList { + id: number; + invoiceNo: string; + projectCode: string; + projectName: string; + // stage: string; + issuedDate: string; + receiptDate: string; + issuedAmount: string; + receivedAmount: string; + team: string; +} export interface issuedInvoiceList { @@ -82,6 +113,7 @@ export interface issuedInvoiceSearchForm { invoiceNo: string; projectCode: string; projectName: string; + team: string; // team: string; // stage: string; // paymentMilestone: string; @@ -145,4 +177,10 @@ export const fetchReceivedInvoices = cache(async () => { return serverFetchJson(`${BASE_API_URL}/invoices/v2/allInvoices/paid`, { next: { tags: ["invoices"] }, }); +}); + +export const fetchInvoicesV3 = cache(async () => { + return serverFetchJson(`${BASE_API_URL}/invoices/v3/allInvoices`, { + next: { tags: ["invoices"] }, + }); }); \ No newline at end of file diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts index ff9cc19..d5edb6f 100644 --- a/src/app/utils/formatUtil.ts +++ b/src/app/utils/formatUtil.ts @@ -45,6 +45,9 @@ export const convertDateArrayToString = ( return dayjs(dateString).format(format); } } + if (dateArray.length === 0){ + return "-" + } }; export const convertTimeArrayToString = ( @@ -132,6 +135,6 @@ export function timestampToDateString(timestamp: string): string { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); - console.log(`${year}-${month}-${day}`); + // console.log(`${year}-${month}-${day}`); return `${year}-${month}-${day}`; } diff --git a/src/components/InvoiceSearch/InvoiceSearch.tsx b/src/components/InvoiceSearch/InvoiceSearch.tsx index 885e71b..0e1409a 100644 --- a/src/components/InvoiceSearch/InvoiceSearch.tsx +++ b/src/components/InvoiceSearch/InvoiceSearch.tsx @@ -10,13 +10,14 @@ import { Button, ButtonGroup, Stack, Tab, Tabs, TabsProps } from "@mui/material" import FileDownloadIcon from '@mui/icons-material/FileDownload'; import FileUploadIcon from '@mui/icons-material/FileUpload'; import { dateInRange, downloadFile } from "@/app/utils/commonUtil"; -import { importIssuedInovice, importReceivedInovice } from "@/app/api/invoices/actions"; +import { importInvoices, importIssuedInovice, importReceivedInovice } from "@/app/api/invoices/actions"; import { errorDialogWithContent, successDialog } from "../Swal/CustomAlerts"; -import { issuedInvoiceList, issuedInvoiceResult, issuedInvoiceSearchForm, receivedInvoiceList, receivedInvoiceSearchForm } from "@/app/api/invoices"; +import { invoiceList, issuedInvoiceList, issuedInvoiceResult, issuedInvoiceSearchForm, receivedInvoiceList, receivedInvoiceSearchForm } from "@/app/api/invoices"; interface Props { issuedInvoice: issuedInvoiceList[]; receivedInvoice: receivedInvoiceList[]; + invoices: invoiceList[]; } type SearchQuery = Partial>; @@ -25,19 +26,21 @@ type SearchParamNames = keyof SearchQuery; type SearchQuery2 = Partial>; type SearchParamNames2 = keyof SearchQuery2; -const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice }) => { +const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice, invoices }) => { const { t } = useTranslation("invoices"); const [tabIndex, setTabIndex] = useState(0); const [filteredIssuedInvoices, setFilteredIssuedInvoices] = useState(issuedInvoice); const [filteredReceivedInvoices, setFilteredReceivedInvoices] = useState(receivedInvoice); + const [filteredIvoices, setFilterInovices] = useState(invoices); const searchCriteria: Criterion[] = useMemo( () => [ { label: t("Invoice No"), paramName: "invoiceNo", type: "text" }, { label: t("Project Code"), paramName: "projectCode", type: "text" }, - { label: t("Invoice Date"), label2: t("Invoice Date To"), paramName: "invoiceDate", type: "dateRange" }, - { label: t("Due Date"), label2: t("Due Date To"), paramName: "dueDate", type: "dateRange" }, + { label: t("Team"), paramName: "team", type: "text" }, + { label: t("Issue Date"), label2: t("Issue Date To"), paramName: "invoiceDate", type: "dateRange" }, + { label: t("Settle Date"), label2: t("Settle Date To"), paramName: "dueDate", type: "dateRange" }, ], [t, issuedInvoice], ); @@ -52,8 +55,9 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice }) => { ); const onReset = useCallback(() => { - setFilteredIssuedInvoices(issuedInvoice); - }, [issuedInvoice]); + // setFilteredIssuedInvoices(issuedInvoice); + setFilterInovices(invoices) + }, [invoices]); function concatListOfObject(obj: any[]): string { return obj.map(obj => `Cannot find "${obj.paymentMilestone}" in ${obj.invoiceNo}`).join(", ") @@ -82,7 +86,7 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice }) => { const formData = new FormData(); formData.append('multipartFileList', file); - const response = await importIssuedInovice(formData); + const response = await importInvoices(formData); // response: status, message, projectList, emptyRowList, invoiceList console.log(response) @@ -225,6 +229,20 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice }) => { [t], ); + const combinedColumns = useMemo[]>( + () => [ + { name: "invoiceNo", label: t("Invoice No") }, + { name: "projectCode", label: t("Project Code") }, + { name: "projectName", label: t("Project Name") }, + { name: "team", label: t("Team") }, + { name: "issuedDate", label: t("Issue Date") }, + { name: "receivedAmount", label: t("Amount (HKD)") }, + { name: "receiptDate", label: t("Settle Date") }, + { name: "receivedAmount", label: t("Actual Received Amount (HKD)") }, + ], + [t] + ) + function isDateInRange(dateToCheck: string, startDate: string, endDate: string): boolean { if ((!startDate || startDate === "Invalid Date") && (!endDate || endDate === "Invalid Date")) { @@ -254,7 +272,7 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice }) => { spacing={2} > {/* */} - + */} {/* */} + { - tabIndex == 0 && + // tabIndex == 0 && { console.log(query) - setFilteredIssuedInvoices( - issuedInvoice.filter( + setFilterInovices( + invoices.filter( (s) => - (isDateInRange(s.invoiceDate, query.invoiceDate ?? undefined, query.invoiceDateTo ?? undefined)) && - (isDateInRange(s.dueDate, query.dueDate ?? undefined, query.dueDateTo ?? undefined)) && + (isDateInRange(s.issuedDate, query.invoiceDate ?? undefined, query.invoiceDateTo ?? undefined)) && + (isDateInRange(s.receiptDate, query.dueDate ?? undefined, query.dueDateTo ?? undefined)) && (s.invoiceNo.toLowerCase().includes(query.invoiceNo.toLowerCase())) && - (s.projectCode.toLowerCase().includes(query.projectCode.toLowerCase())) + (s.projectCode.toLowerCase().includes(query.projectCode.toLowerCase())) && + (s.team.toLowerCase().includes(query.team.toLowerCase())) ), ); }} onReset={onReset} /> } - { + {/* { tabIndex == 1 && = ({ issuedInvoice, receivedInvoice }) => { }} onReset={onReset} /> - } - + } */} + {/* { - + } */} { - tabIndex == 0 && - - items={filteredIssuedInvoices} - columns={columns} + // tabIndex == 0 && + + items={filteredIvoices} + columns={combinedColumns} /> } - { + {/* { tabIndex == 1 && items={filteredReceivedInvoices} columns={columns2} /> - } + } */} ); diff --git a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx index 8680599..ad3c49c 100644 --- a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx +++ b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx @@ -2,8 +2,8 @@ import React from "react"; import InvoiceSearch from "./InvoiceSearch"; import InvoiceSearchLoading from "./InvoiceSearchLoading"; -import { fetchIssuedInvoices, fetchReceivedInvoices, issuedInvoiceList, issuedInvoiceResult } from "@/app/api/invoices"; -import { INPUT_DATE_FORMAT, convertDateArrayToString, moneyFormatter } from "@/app/utils/formatUtil"; +import { fetchInvoicesV3, fetchIssuedInvoices, fetchReceivedInvoices, issuedInvoiceList, issuedInvoiceResult } from "@/app/api/invoices"; +import { INPUT_DATE_FORMAT, convertDateArrayToString, convertDateToString, moneyFormatter, timestampToDateString } from "@/app/utils/formatUtil"; interface SubComponents { @@ -18,7 +18,10 @@ interface SubComponents { const InvoiceSearchWrapper: React.FC & SubComponents = async () => { const issuedInvoices = await fetchIssuedInvoices() const receivedInvoices = await fetchReceivedInvoices() + const invoices = await fetchInvoicesV3() + // console.log(invoices) + const convertedIssedInvoices = issuedInvoices.map((invoice)=>{ return{ id: invoice.id, @@ -45,9 +48,24 @@ const InvoiceSearchWrapper: React.FC & SubComponents = async () => { } }) + const convertedInvoices = invoices.map((invoice)=>{ + return{ + id: invoice.id, + invoiceNo: invoice.invoiceNo, + projectCode: invoice.projectCode, + projectName: invoice.projectName, + team: invoice.team, + issuedDate: timestampToDateString(invoice.invoiceDate)!!, + receiptDate: timestampToDateString(invoice.receiptDate??0)!!, + issuedAmount: moneyFormatter.format(invoice.issueAmount), + receivedAmount: moneyFormatter.format(invoice.paidAmount) + } + }) + return };