From eecf73aad9f265cbb2d94e9b214fd6538ecab253 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Tue, 21 Jan 2025 16:59:20 +0800 Subject: [PATCH] update financial summary V2 --- src/app/api/financialsummary/actions.ts | 29 ++- .../FinnancialStatusByProject.tsx | 169 +++++++++++------- 2 files changed, 135 insertions(+), 63 deletions(-) diff --git a/src/app/api/financialsummary/actions.ts b/src/app/api/financialsummary/actions.ts index 0ada047..e8a6439 100644 --- a/src/app/api/financialsummary/actions.ts +++ b/src/app/api/financialsummary/actions.ts @@ -6,7 +6,8 @@ import { Dayjs } from "dayjs"; import { cache } from "react"; import { FileResponse } from "../reports/actions"; import { revalidateTag } from "next/cache"; - +import { SumOfByClient } from "@/components/ProjectFinancialSummaryV2/gptFn"; +import { FinancialByProject } from "."; export interface FinancialSummaryByClientResult { teamId:number; @@ -144,6 +145,32 @@ export const exportFinancialSummaryByProjectExcel = cache(async (data: ExportFin return reportBlob }) +export const exportFinancialSummaryV2ByClientExcel = cache(async (data: SumOfByClient[]) => { + const reportBlob = await serverFetchBlob( + `${BASE_API_URL}/dashboard/exportFinancialSummaryV2ByClientExcel`, + { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }, +); + + return reportBlob +}) + +export const exportFinancialSummaryV2ByProjectExcel = cache(async (data: FinancialByProject[]) => { + const reportBlob = await serverFetchBlob( + `${BASE_API_URL}/dashboard/exportFinancialSummaryV2ByProjectExcel`, + { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }, +); + + return reportBlob +}) + export const revalidate = async(tag: string) => { revalidateTag(tag) } diff --git a/src/components/ProjectFinancialSummaryV2/FinnancialStatusByProject.tsx b/src/components/ProjectFinancialSummaryV2/FinnancialStatusByProject.tsx index fe02544..63f53bb 100644 --- a/src/components/ProjectFinancialSummaryV2/FinnancialStatusByProject.tsx +++ b/src/components/ProjectFinancialSummaryV2/FinnancialStatusByProject.tsx @@ -8,8 +8,10 @@ import { useEffect, useMemo, useState } from "react"; import CustomDatagrid from "../CustomDatagrid"; import { useTranslation } from "react-i18next"; import { useRouter } from "next/navigation"; -import { Box } from "@mui/material"; +import { Box, Card, CardHeader } from "@mui/material"; import { SumOfByClient } from "./gptFn"; +import { exportFinancialSummaryV2ByClientExcel, exportFinancialSummaryV2ByProjectExcel } from "@/app/api/financialsummary/actions"; +import { downloadFile } from "@/app/utils/commonUtil"; // import { summarizeFinancialData } from "./gptFn"; interface Props { @@ -99,7 +101,8 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Cash Flow Status"), minWidth: 80, renderCell: (params: any) => { - if (params.row.invoicedAmount >= params.row.cumulativeExpenditure) { + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense + if (params.row.invoicedAmount >= cumulativeExpenditure) { return {t("Positive")}; } else { return {t("Negative")}; @@ -112,7 +115,8 @@ const FinancialStatusByProject: React.FC = ({ headerName: "CPI", minWidth: 50, renderCell: (params: any) => { - var cpi = params.row.invoicedAmount/(params.row.projectExpense + params.row.invoicedAmount) || 0 + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense + var cpi = params.row.invoicedAmount/cumulativeExpenditure || 0 return ( = 1 ? greenColor : redColor}> {cpi.toLocaleString(undefined, { @@ -129,7 +133,7 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Projected Cash Flow Status"), minWidth: 100, renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense if (params.row.totalFee >= cumulativeExpenditure) { return {t("Positive")}; } else { @@ -143,7 +147,8 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Projected CPI"), minWidth: 50, renderCell: (params: any) => { - var projectedCpi = params.row.totalFee/(params.row.projectExpense + params.row.invoicedAmount) == Infinity ? 'N/A' : params.row.totalFee/(params.row.projectExpense + params.row.invoicedAmount) + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense + var projectedCpi = params.row.totalFee/cumulativeExpenditure == Infinity ? 'N/A' : params.row.totalFee/cumulativeExpenditure return ( = 1 ? greenColor : redColor)} @@ -199,7 +204,7 @@ const FinancialStatusByProject: React.FC = ({ minWidth: 250, type: "number", renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense return ( $ @@ -341,7 +346,7 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Cash Flow Status"), minWidth: 100, renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense return params.row.invoicedAmount >= cumulativeExpenditure ? {t("Positive")} : {t("Negative")} @@ -353,7 +358,7 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("CPI"), minWidth: 50, renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense var cpi = cumulativeExpenditure != 0 ? params.row.invoicedAmount/cumulativeExpenditure : 0 var cpiString = cpi.toLocaleString(undefined, { minimumFractionDigits: 2, @@ -370,8 +375,8 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Projected Cash Flow Status"), minWidth: 100, renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount - var status = params.row.invoiceAmount >= cumulativeExpenditure + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense + var status = params.row.totalFee >= cumulativeExpenditure return status ? {t("Positive")} : {t("Negative")} @@ -383,7 +388,7 @@ const FinancialStatusByProject: React.FC = ({ headerName: t("Projected CPI"), minWidth: 50, renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense var projectCpi = cumulativeExpenditure != 0 ? params.row.totalFee/cumulativeExpenditure : 0 var projectCpiString = projectCpi.toLocaleString(undefined, { minimumFractionDigits: 2, @@ -439,7 +444,7 @@ const FinancialStatusByProject: React.FC = ({ minWidth: 280, type: "number", renderCell: (params: any) => { - var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount + var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense return ( $ @@ -544,64 +549,104 @@ const FinancialStatusByProject: React.FC = ({ }, ]; + const handleExportByClient = async () => { + const response = await exportFinancialSummaryV2ByClientExcel(filteredByClientRows) + if (response) { + downloadFile(new Uint8Array(response.blobValue), response.filename!!) + } + console.log(filteredByClientRows) + }; + + const handleExportByProject = async () => { + const response = await exportFinancialSummaryV2ByProjectExcel(filteredByProjectRows) + if (response) { + downloadFile(new Uint8Array(response.blobValue), response.filename!!) + } + console.log(filteredByProjectRows) + }; + return ( <> - { - console.log(query) - if (query.projectCode.length > 0 || query.projectName.length > 0) { - setFilteredByProjectRows( - financialSummByProject.filter( - (cp) => - cp.projectCode.toLowerCase().includes(query.projectCode.trim().toLowerCase()) && - cp.projectName.toLowerCase().includes(query.projectName.trim().toLowerCase()) - ), - ); - } else { - setFilteredByProjectRows(financialSummByProject) - } - }} - /> -
- +
+ +
+
+ {filteredByProjectRows.length > 0 && ( + + )} +
+ { + console.log(query) + if (query.projectCode.length > 0 || query.projectName.length > 0) { + setFilteredByProjectRows( + financialSummByProject.filter( + (cp) => + cp.projectCode.toLowerCase().includes(query.projectCode.trim().toLowerCase()) && + cp.projectName.toLowerCase().includes(query.projectName.trim().toLowerCase()) + ), + ); + } else { + setFilteredByProjectRows(financialSummByProject) + } + }} /> -
+
+ +
{/* items={filteredStaff} columns={columns} /> */} +
- { - console.log(query) - if (query.customerCode.length > 0 || query.customerName.length > 0) { - setFilteredByClientRows( - financialSummByClient.filter( - (cp) => - cp.customerCode.toLowerCase().includes(query.customerCode.trim().toLowerCase()) && - cp.customerName.toLowerCase().includes(query.customerName.trim().toLowerCase()) - ), - ); - } else { - setFilteredByClientRows(financialSummByClient) - } - }} - /> -
- +
+ +
+
+ {filteredByProjectRows.length > 0 && ( + + )} +
+ { + console.log(query) + if (query.customerCode.length > 0 || query.customerName.length > 0) { + setFilteredByClientRows( + financialSummByClient.filter( + (cp) => + cp.customerCode.toLowerCase().includes(query.customerCode.trim().toLowerCase()) && + cp.customerName.toLowerCase().includes(query.customerName.trim().toLowerCase()) + ), + ); + } else { + setFilteredByClientRows(financialSummByClient) + } + }} /> -
+
+ +
+
);