|
|
@@ -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<Props> = ({ |
|
|
|
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 <span className={greenColor}>{t("Positive")}</span>; |
|
|
|
} else { |
|
|
|
return <span className={redColor}>{t("Negative")}</span>; |
|
|
@@ -112,7 +115,8 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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 ( |
|
|
|
<span className={cpi >= 1 ? greenColor : redColor}> |
|
|
|
{cpi.toLocaleString(undefined, { |
|
|
@@ -129,7 +133,7 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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 <span className={greenColor}>{t("Positive")}</span>; |
|
|
|
} else { |
|
|
@@ -143,7 +147,8 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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 ( |
|
|
|
<span |
|
|
|
className={(typeof projectedCpi == "number" && projectedCpi >= 1 ? greenColor : redColor)} |
|
|
@@ -199,7 +204,7 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
minWidth: 250, |
|
|
|
type: "number", |
|
|
|
renderCell: (params: any) => { |
|
|
|
var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount |
|
|
|
var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense |
|
|
|
return ( |
|
|
|
<span> |
|
|
|
$ |
|
|
@@ -341,7 +346,7 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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 ? |
|
|
|
<span className={greenColor}>{t("Positive")}</span> |
|
|
|
: <span className={redColor}>{t("Negative")}</span> |
|
|
@@ -353,7 +358,7 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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<Props> = ({ |
|
|
|
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 ? |
|
|
|
<span className={greenColor}>{t("Positive")}</span> |
|
|
|
: <span className={redColor}>{t("Negative")}</span> |
|
|
@@ -383,7 +388,7 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
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<Props> = ({ |
|
|
|
minWidth: 280, |
|
|
|
type: "number", |
|
|
|
renderCell: (params: any) => { |
|
|
|
var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount |
|
|
|
var cumulativeExpenditure = params.row.projectExpense + params.row.manhourExpense |
|
|
|
return ( |
|
|
|
<span> |
|
|
|
$ |
|
|
@@ -544,64 +549,104 @@ const FinancialStatusByProject: React.FC<Props> = ({ |
|
|
|
}, |
|
|
|
]; |
|
|
|
|
|
|
|
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 ( |
|
|
|
<> |
|
|
|
<Box sx={{ mt: 3 }}> |
|
|
|
<SearchBox |
|
|
|
criteria={searchCriteria} |
|
|
|
onSearch={(query) => { |
|
|
|
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) |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}> |
|
|
|
<CustomDatagrid |
|
|
|
rows={filteredByProjectRows} |
|
|
|
columns={columns1} |
|
|
|
columnWidth={200} |
|
|
|
dataGridHeight={300} |
|
|
|
loading={isLoading} |
|
|
|
<Card className="mt-5"> |
|
|
|
<div style={{display:"inline-block"}}> |
|
|
|
<CardHeader className="text-slate-500" title= {t("Financial Status (by Project)")}/> |
|
|
|
</div> |
|
|
|
<div style={{display:"inline-block"}}> |
|
|
|
{filteredByProjectRows.length > 0 && ( |
|
|
|
<button onClick={handleExportByProject} className="hover:cursor-pointer hover:bg-lime-50 text-base bg-transparent border-lime-600 text-lime-600 border-solid rounded-md w-36"> |
|
|
|
{t("Export Excel")} |
|
|
|
</button> |
|
|
|
)} |
|
|
|
</div> |
|
|
|
<SearchBox |
|
|
|
criteria={searchCriteria} |
|
|
|
onSearch={(query) => { |
|
|
|
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) |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}> |
|
|
|
<CustomDatagrid |
|
|
|
rows={filteredByProjectRows} |
|
|
|
columns={columns1} |
|
|
|
columnWidth={200} |
|
|
|
dataGridHeight={300} |
|
|
|
loading={isLoading} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
{/* <SearchResults<StaffResult> items={filteredStaff} columns={columns} /> */} |
|
|
|
</Card> |
|
|
|
</Box> |
|
|
|
<Box sx={{ mt: 3 }}> |
|
|
|
<SearchBox |
|
|
|
criteria={searchCriteria2} |
|
|
|
onSearch={(query) => { |
|
|
|
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) |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}> |
|
|
|
<CustomDatagrid |
|
|
|
rows={filteredByClientRows} |
|
|
|
columns={columns2} |
|
|
|
columnWidth={200} |
|
|
|
dataGridHeight={300} |
|
|
|
loading={isLoading} |
|
|
|
<Card className="mt-5"> |
|
|
|
<div style={{display:"inline-block"}}> |
|
|
|
<CardHeader className="text-slate-500" title= {t("Financial Status (by Client)")}/> |
|
|
|
</div> |
|
|
|
<div style={{display:"inline-block"}}> |
|
|
|
{filteredByProjectRows.length > 0 && ( |
|
|
|
<button onClick={handleExportByClient} className="hover:cursor-pointer hover:bg-lime-50 text-base bg-transparent border-lime-600 text-lime-600 border-solid rounded-md w-36"> |
|
|
|
{t("Export Excel")} |
|
|
|
</button> |
|
|
|
)} |
|
|
|
</div> |
|
|
|
<SearchBox |
|
|
|
criteria={searchCriteria2} |
|
|
|
onSearch={(query) => { |
|
|
|
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) |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}> |
|
|
|
<CustomDatagrid |
|
|
|
rows={filteredByClientRows} |
|
|
|
columns={columns2} |
|
|
|
columnWidth={200} |
|
|
|
dataGridHeight={300} |
|
|
|
loading={isLoading} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</Box> |
|
|
|
</> |
|
|
|
); |
|
|
|