|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- "use client";
-
- import {
- FinancialSummaryByProject,
- FinancialSummaryByClient,
- FinancialByProject,
- } from "@/app/api/financialsummary";
- import SearchBox, { Criterion } from "../SearchBox";
- import { useEffect, useMemo, useState } from "react";
- import CustomDatagrid from "../CustomDatagrid";
- import { useTranslation } from "react-i18next";
- import { useRouter } from "next/navigation";
- import { Box, Grid } from "@mui/material";
- import { SumOfByClient } from "./gptFn";
- // import { summarizeFinancialData } from "./gptFn";
-
- interface Props {
- financialSummByProject: FinancialByProject[];
- financialSummByClient: SumOfByClient[];
- }
- type SearchQuery = Partial<Omit<FinancialSummaryByProject, "id">>;
- type SearchParamNames = keyof SearchQuery;
-
- type SearchQuery2 = Partial<Omit<SumOfByClient, "id">>;
- type SearchParamNames2 = keyof SearchQuery2;
-
- const FinancialStatusByProject: React.FC<Props> = ({
- financialSummByProject,
- financialSummByClient
- }) => {
- console.log(financialSummByProject);
- // console.log(financialSummByClient);
- const { t } = useTranslation("dashboard");
- const router = useRouter();
- const [filteredByProjectRows, setFilteredByProjectRows] = useState(financialSummByProject);
- const [filteredByClientRows, setFilteredByClientRows] = useState(financialSummByClient);
- console.log(filteredByProjectRows);
- console.log(filteredByClientRows);
-
- // const testing = useMemo(() => summarizeFinancialData(filteredByProjectRows), [])
- const greenColor = "text-lime-500";
- const redColor = "text-red-500";
- const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
- () => [
- { label: t("Project Code"), paramName: "projectCode", type: "text" },
- { label: t("Project Name"), paramName: "projectName", type: "text" },
- ],
- [t],
- );
-
- const searchCriteria2: Criterion<SearchParamNames2>[] = useMemo(
- () => [
- { label: t("Client Code"), paramName: "customerCode", type: "text" },
- { label: t("Client Name"), paramName: "customerName", type: "text" },
- ],
- [t],
- );
-
- useEffect(() => {
- setFilteredByProjectRows(financialSummByProject);
- setFilteredByClientRows(financialSummByClient)
- }, [financialSummByProject, financialSummByClient]);
-
- const columns1 = [
- {
- id: "projectCode",
- field: "projectCode",
- headerName: t("Project Code"),
- minWidth: 50,
- renderCell: (params: any) => (
- <div
- className="text-blue-600 hover:underline cursor-pointer"
- onClick={() => {
- router.push(
- `/dashboard/ProjectCashFlow?projectId=${params.row.id}`
- );
- }}
- >
- {params.value}
- </div>
- ),
- },
- {
- id: "projectName",
- field: "projectName",
- headerName: t("Project Name"),
- minWidth: 50,
- },
- {
- id: "customerName",
- field: "customerName",
- headerName: t("Client Name"),
- minWidth: 50,
- },
- {
- id: "subsidiaryName",
- field: "subsidiaryName",
- headerName: t("Subsidiary"),
- minWidth: 50,
- },
- {
- id: "cashFlowStatus",
- field: "cashFlowStatus",
- headerName: t("Cash Flow Status"),
- minWidth: 80,
- renderCell: (params: any) => {
- if (params.row.invoicedAmount >= params.row.cumulativeExpenditure) {
- return <span className={greenColor}>{t("Positive")}</span>;
- } else {
- return <span className={redColor}>{t("Negative")}</span>;
- }
- },
- },
- {
- id: "cpi",
- field: "cpi",
- headerName: "CPI",
- minWidth: 50,
- renderCell: (params: any) => {
- var cpi = params.invoicedAmount/(params.projectExpense + params.invoicedAmount) || 0
- return (
- <span className={cpi >= 1 ? greenColor : redColor}>
- {cpi.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "projectedCashFlowStatus",
- field: "projectedCashFlowStatus",
- headerName: t("Projected Cash Flow Status"),
- minWidth: 100,
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- if (params.row.totalFee >= cumulativeExpenditure) {
- return <span className={greenColor}>{t("Positive")}</span>;
- } else {
- return <span className={redColor}>{t("Negative")}</span>;
- }
- },
- },
- {
- id: "projectedCpi",
- field: "projectedCpi",
- headerName: t("Projected CPI"),
- minWidth: 50,
- renderCell: (params: any) => {
- var projectedCpi = params.row.totalFee/(params.row.projectExpense + params.row.invoicedAmount)
- return (
- <span
- className={projectedCpi >= 1 ? greenColor : redColor}
- >
- {projectedCpi.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "totalFee",
- field: "totalFee",
- headerName: t("Total Fees") + t("HKD"),
- type: "number",
- minWidth: 50,
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.totalFee.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "totalBudget",
- field: "totalBudget",
- headerName: t("Total Budget") + t("HKD"),
- minWidth: 50,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.totalBudget.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "cumulativeExpenditure",
- field: "cumulativeExpenditure",
- headerName: t("Total Cumulative Expenditure") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- return (
- <span>
- $
- {cumulativeExpenditure.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "manhourExpense",
- field: "manhourExpense",
- headerName: t("Manpower Expenses") + t("HKD"),
- minWidth: 280,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.manhourExpense.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "projectExpense",
- field: "projectExpense",
- headerName: t("Project Expense") + t("HKD"),
- minWidth: 280,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {(params.row.projectExpense ?? 0).toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "invoicedAmount",
- field: "invoicedAmount",
- headerName: t("Total Invoiced Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.invoicedAmount.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "nonInvoicedAmount",
- field: "nonInvoicedAmount",
- headerName: t("Total Un-Invoiced Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- var nonInvoiced = params.row.totalFee - params.row.invoicedAmount
- return (
- <span>
- $
- {nonInvoiced.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "paidAmount",
- field: "paidAmount",
- headerName: t("Total Received Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.paidAmount.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- ];
-
- const columns2 = [
- {
- id: "customerCode",
- field: "customerCode",
- headerName: t("Client Code"),
- minWidth: 50,
- renderCell: (params: any) => (
- <div
- className="text-blue-600 hover:underline cursor-pointer"
- onClick={() => {
- router.push(
- `/dashboard/ProjectStatusByClient?customerId=${params.row.id}`
- );
- }}
- >
- {params.value}
- </div>
- ),
- },
- {
- id: "customerName",
- field: "customerName",
- headerName: t("Client Name"),
- minWidth: 80,
- },
- {
- id: "sumOfProjects",
- field: "sumOfProjects",
- headerName: t("Total Project Involved"),
- minWidth: 80,
- },
- {
- id: "cashFlowStatus",
- field: "cashFlowStatus",
- headerName: t("Cash Flow Status"),
- minWidth: 100,
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- return params.row.invoicedAmount >= cumulativeExpenditure ?
- <span className={greenColor}>{t("Positive")}</span>
- : <span className={redColor}>{t("Negative")}</span>
- },
- },
- {
- id: "cpi",
- field: "cpi",
- headerName: t("CPI"),
- minWidth: 50,
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- var cpi = cumulativeExpenditure != 0 ? params.row.invoicedAmount/cumulativeExpenditure : 0
- var cpiString = cpi.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })
- return (cpi >= 1) ?
- <span className={greenColor}>{cpiString}</span>:
- <span className={redColor}>{cpiString}</span>
- },
- },
- {
- id: "projectedCashFlowStatus",
- field: "projectedCashFlowStatus",
- 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
- return status ?
- <span className={greenColor}>{t("Positive")}</span>
- : <span className={redColor}>{t("Negative")}</span>
- },
- },
- {
- id: "projectedCpi",
- field: "projectedCpi",
- headerName: t("Projected CPI"),
- minWidth: 50,
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- var projectCpi = cumulativeExpenditure != 0 ? params.row.totalFee/cumulativeExpenditure : 0
- var projectCpiString = projectCpi.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })
- if (projectCpi >= 1) {
- return <span className={greenColor}>{projectCpiString}</span>;
- } else {
- return <span className={redColor}>{projectCpiString}</span>;
- }
- },
- },
- {
- id: "totalFee",
- field: "totalFee",
- headerName: t("Total Fees") + t("HKD"),
- minWidth: 50,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.totalFee.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "totalBudget",
- field: "totalBudget",
- headerName: t("Total Budget") + t("HKD"),
- minWidth: 50,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.totalBudget.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "cumulativeExpenditure",
- field: "cumulativeExpenditure",
- headerName: t("Total Cumulative Expenditure") + t("HKD"),
- minWidth: 280,
- type: "number",
- renderCell: (params: any) => {
- var cumulativeExpenditure = params.row.projectExpense + params.row.invoicedAmount
- return (
- <span>
- $
- {cumulativeExpenditure.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "manhourExpense",
- field: "manhourExpense",
- headerName: t("Manpower Expenses") + t("HKD"),
- minWidth: 280,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.manhourExpense.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "projectExpense",
- field: "projectExpense",
- headerName: t("Project Expense") + t("HKD"),
- minWidth: 280,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {(params.row.projectExpense ?? 0).toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "invoicedAmount",
- field: "invoicedAmount",
- headerName: t("Total Invoiced Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.invoicedAmount.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "nonInvoicedAmount",
- field: "nonInvoicedAmount",
- headerName: t("Total Un-Invoiced Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- var uninvoiced = params.row.totalFee - params.row.invoicedAmount
- return (
- <span>
- $
- {uninvoiced.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- {
- id: "paidAmount",
- field: "paidAmount",
- headerName: t("Total Received Amount") + t("HKD"),
- minWidth: 250,
- type: "number",
- renderCell: (params: any) => {
- return (
- <span>
- $
- {params.row.paidAmount.toLocaleString(undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- })}
- </span>
- );
- },
- },
- ];
-
- return (
- <>
- <Box sx={{ mt: 3 }}>
- <SearchBox
- criteria={searchCriteria}
- onSearch={(query) => {
- setFilteredByProjectRows(
- filteredByProjectRows.filter(
- (cp:any) =>
- cp.projectCode.toLowerCase().includes(query.projectCode.toLowerCase()) &&
- cp.projectName.toLowerCase().includes(query.projectName.toLowerCase())
- ),
- );
- }}
- />
- <div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}>
- <CustomDatagrid
- rows={filteredByProjectRows}
- columns={columns1}
- columnWidth={200}
- dataGridHeight={300}
- />
- </div>
- {/* <SearchResults<StaffResult> items={filteredStaff} columns={columns} /> */}
- </Box>
- <Box sx={{ mt: 3 }}>
- <SearchBox
- criteria={searchCriteria2}
- onSearch={(query) => {
- setFilteredByClientRows(
- filteredByClientRows.filter(
- (cp:any) =>
- cp.customerCode.toLowerCase().includes(query.customerCode.toLowerCase()) &&
- cp.customerName.toLowerCase().includes(query.customerName.toLowerCase())
- ),
- );
- }}
- />
- <div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}>
- <CustomDatagrid
- rows={filteredByClientRows}
- columns={columns2}
- columnWidth={200}
- dataGridHeight={300}
- />
- </div>
- </Box>
- </>
- );
- };
- export default FinancialStatusByProject;
|