From d7d41e6e62447d7131bd9c79338d08751f5adec8 Mon Sep 17 00:00:00 2001 From: "MSI\\derek" Date: Thu, 23 Jan 2025 17:42:23 +0800 Subject: [PATCH] update financial summ --- src/app/api/financialsummary/index.ts | 1 + .../FinancialSummary.tsx | 173 ++++++++++-------- .../ProjectFinancialSummaryV2/gptFn.tsx | 6 + 3 files changed, 106 insertions(+), 74 deletions(-) diff --git a/src/app/api/financialsummary/index.ts b/src/app/api/financialsummary/index.ts index e964faf..9bf55f2 100644 --- a/src/app/api/financialsummary/index.ts +++ b/src/app/api/financialsummary/index.ts @@ -33,6 +33,7 @@ export type FinancialByProject = { totalBudget: number, manhourExpense: number, invoicedAmount: number, + uninvoicedAmount: number, paidAmount: number, projectExpense: number, } diff --git a/src/components/ProjectFinancialSummaryV2/FinancialSummary.tsx b/src/components/ProjectFinancialSummaryV2/FinancialSummary.tsx index 0c8a1de..ff6e680 100644 --- a/src/components/ProjectFinancialSummaryV2/FinancialSummary.tsx +++ b/src/components/ProjectFinancialSummaryV2/FinancialSummary.tsx @@ -14,36 +14,53 @@ interface Props { financialSummByProject: FinancialByProject[] } - type InputDate = { - startDate: string; - endDate: string; - } +type InputDate = { + startDate: string; + endDate: string; +} + +type DateParams = { + [key: number]: InputDate; +} + +type ComboParams = { + [key: number]: string; +} + - type DateParams = { - 0: InputDate; - 2: InputDate; - 3: InputDate; - 4: InputDate; - 5: InputDate; - } const FinancialSummaryPage: React.FC = ({ _teamId, financialSummByProject }) => { console.log(financialSummByProject) const { t } = useTranslation(); - const curr = useMemo(() => dayjs().format(INPUT_DATE_FORMAT), []) - const currYear = useMemo(() => dayjs().get("year"), []) + var currDate: string = useMemo(() => dayjs().format(INPUT_DATE_FORMAT), []) + var currYear: number = useMemo(() => dayjs().get("year"), []) + // testing date + // currDate = "2024-10-28" + // currYear = 2024 const startDate = "10-01" const endDate = "09-30" - const currFinancialYear = useMemo(() => curr > `${currYear}-${startDate}` ? currYear + 1 : currYear, [currYear]) + const lengthOfCombo = 10 + const currFinancialYear = useMemo(() => currDate > `${currYear}-${startDate}` ? currYear + 1 : currYear, [currYear]) const [mainData, setMainData] = useState(financialSummByProject) const [byTeam, setByTeam] = useState(() => sumUpByTeam(mainData)) // do fetch to set const [byProject, setByProject] = useState(financialSummByProject) const [byClient, setByClient] = useState(() => sumUpByClient(mainData)) const [isLoading, setIsLoading] = useState(false) - const allTeam = useMemo(()=> { - var _allTeam: SumOfByTeam = { + const allTeam = useMemo(() => { + return byTeam.reduce((acc, curr) => ({ + id: 0, + team: "All Team", + totalFee: acc.totalFee + curr.totalFee, + totalBudget: acc.totalBudget + curr.totalBudget, + manhourExpense: acc.manhourExpense + curr.manhourExpense, + projectExpense: acc.projectExpense + curr.projectExpense, + invoicedAmount: acc.invoicedAmount + curr.invoicedAmount, + uninvoicedAmount: acc.uninvoicedAmount + curr.uninvoicedAmount, + paidAmount: acc.paidAmount + curr.paidAmount, + activeProject: acc.activeProject + curr.activeProject + }), { id: 0, team: "All Team", totalFee: 0, @@ -51,34 +68,60 @@ const FinancialSummaryPage: React.FC = ({ manhourExpense: 0, projectExpense: 0, invoicedAmount: 0, + uninvoicedAmount: 0, paidAmount: 0, - activeProject: 0, - } - for (let i = 0; i < byTeam.length; i++) { - var curr = byTeam[i] - _allTeam["totalFee"] += curr.totalFee - _allTeam["totalBudget"] += curr.totalBudget - _allTeam["manhourExpense"] += curr.manhourExpense - _allTeam["projectExpense"] += curr.projectExpense - _allTeam["invoicedAmount"] += curr.invoicedAmount - _allTeam["paidAmount"] += curr.paidAmount - _allTeam["activeProject"] += curr.activeProject - } - return _allTeam + activeProject: 0 + }) }, [mainData]) - console.log(allTeam) const [teamId, setTeamId] = useState(_teamId) const [isCardClickedIndex, setIsCardClickedIndex] = useState(_teamId || 0); const [period, setPeriod] = useState(0); - const dateMap: DateParams = useMemo(() => ({ - 0: {startDate: "", endDate: ""}, - 2: {startDate: `${currFinancialYear-2}-${startDate}`, endDate: `${currFinancialYear-1}-${endDate}`}, - 3: {startDate: `${currFinancialYear-3}-${startDate}`, endDate: `${currFinancialYear-2}-${endDate}`}, - 4: {startDate: `${currFinancialYear-4}-${startDate}`, endDate: `${currFinancialYear-3}-${endDate}`}, - 5: {startDate: "", endDate: `${currFinancialYear-4}-${endDate}`}, - }), [currYear, startDate, endDate]) + const dateMap: DateParams = useMemo(() => { + const thisYear = currDate <= `${currYear}-${endDate}` ? + {startDate: `${currYear-1}-${startDate}`, endDate: `${currYear}-${endDate}`} : + {startDate: `${currYear}-${startDate}`, endDate: `${currFinancialYear}-${endDate}`} + const map: DateParams = { + 0: {startDate: "", endDate: ""}, + 1: thisYear, + [lengthOfCombo - 1]: {startDate: "", endDate: `${currFinancialYear-(lengthOfCombo - 2)}-${endDate}`} + } + for (let i = 2; i < lengthOfCombo - 1; i++) { + map[i] = { + startDate: `${currFinancialYear-i}-${startDate}`, + endDate: `${currFinancialYear-(i - 1)}-${endDate}` + } + } + return map + }, [currDate, currYear, currFinancialYear, startDate, endDate, lengthOfCombo]) + + // const comboList: string[] = useMemo(() => { + // const list = ["All"] + // var lastYear = "" + // for (let i = 1; i < lengthOfCombo; i++) { + // var currYearStr = t(" (current year) ") + // var yearsStr = `${currFinancialYear - i} - ${currFinancialYear - i + 1}` + // var str = yearsStr + // if (i == 1) str = yearsStr + currYearStr + // lastYear = `${currFinancialYear - i}` + // list.push(str) + // } + // list[lengthOfCombo - 1] = `< ${lastYear}` + // return list + // }, []) + + const comboList: string[] = useMemo(() => { + const list = ["All"]; + for (let i = 1; i < lengthOfCombo - 1; i++) { + const yearRange = `${currFinancialYear - i} - ${currFinancialYear - i + 1}`; + const label = i === 1 ? `${yearRange} ${t("(current year)")}` : yearRange; + list.push(label); + } + const oldestYear = currFinancialYear - (lengthOfCombo - 2); + list.push(`< ${oldestYear}`); + return list; + }, [currFinancialYear, lengthOfCombo, t]); const fetchFinancialSummaryByProject = useCallback(async (endDate: string, startDate: string) => { setIsLoading(true) @@ -95,27 +138,14 @@ const FinancialSummaryPage: React.FC = ({ setTeamId(teamId) }, []); - const handleFilter = useCallback((value: number) => { + const handleFilter = useCallback(async (value: number) => { setPeriod(value) console.log(value) - var _startDate: string = "" - var _endDate = "" - if (value == 1) { - if (curr <= `${currYear}-${endDate}`) { - _startDate = `${currYear - 1}-${startDate}` - _endDate = `${currYear}-${endDate}` - } else { - _startDate = `${currYear}-${startDate}` - _endDate = `${currFinancialYear}-${endDate}` - } - } else { - _startDate = dateMap[value as keyof DateParams].startDate - _endDate = dateMap[value as keyof DateParams].endDate - } + var _startDate = dateMap[value as keyof DateParams].startDate + var _endDate = dateMap[value as keyof DateParams].endDate console.log(_startDate) console.log(_endDate) - fetchFinancialSummaryByProject(_endDate, _startDate) - + await fetchFinancialSummaryByProject(_endDate, _startDate) }, [isCardClickedIndex]) useEffect(() => { @@ -144,18 +174,11 @@ const FinancialSummaryPage: React.FC = ({ label="Age" onChange={(e) => handleFilter(Number(e.target.value))} > - {Array.from({ length: 6 }).map((_, i) => { - if (i == 0) { - return {`All`} - } else if (i == 1) { - return {`${currFinancialYear - i} - ${currFinancialYear - i + 1} (current year)`} - } else if (i == 5) { - return {`< ${currYear - i + 1}`} - } else { - return {`${currFinancialYear - i} - ${currFinancialYear - i + 1}`} - } - } - )} + { + comboList.map((str, i) => { + return {str} + }) + } @@ -168,20 +191,21 @@ const FinancialSummaryPage: React.FC = ({ {_teamId == 0 && allTeam &&
handleCardClick(0)}> = (allTeam.projectExpense + allTeam.manhourExpense) ? "Positive" : "Negative"} - CostPerformanceIndex={allTeam.invoicedAmount/(allTeam.projectExpense + allTeam.manhourExpense) || 0} + CostPerformanceIndex={isFinite(allTeam.invoicedAmount/(allTeam.projectExpense + allTeam.manhourExpense)) ? 0 : allTeam.invoicedAmount/(allTeam.projectExpense + allTeam.manhourExpense) || 0} ProjectedCashFlowStatus={allTeam.totalFee >= (allTeam.projectExpense + allTeam.manhourExpense) ? "Positive" : "Negative"} - ProjectedCPI={allTeam.totalFee/(allTeam.projectExpense + allTeam.manhourExpense)} + ProjectedCPI={isFinite(allTeam.totalFee/(allTeam.projectExpense + allTeam.manhourExpense)) ? 0 : allTeam.totalFee/(allTeam.projectExpense + allTeam.manhourExpense) || 0} ClickedIndex={isCardClickedIndex} Index={0}/>
} @@ -196,12 +220,13 @@ const FinancialSummaryPage: React.FC = ({ TotalCumulative={record.projectExpense + record.manhourExpense} TotalProjectExpense={record.projectExpense} TotalInvoicedAmount={record.invoicedAmount} - TotalUnInvoicedAmount={Math.abs(record.totalFee - record.invoicedAmount)} + // TotalUnInvoicedAmount={Math.abs(record.totalFee - record.invoicedAmount)} + TotalUnInvoicedAmount={Math.abs(record.uninvoicedAmount)} TotalReceivedAmount={record.paidAmount} CashFlowStatus={record.invoicedAmount >= (record.projectExpense + record.manhourExpense) ? "Positive" : "Negative"} CostPerformanceIndex={record.invoicedAmount/(record.projectExpense + record.manhourExpense) || 0} ProjectedCashFlowStatus={record.totalFee >= (record.projectExpense + record.manhourExpense) ? "Positive" : "Negative"} - ProjectedCPI={record.totalFee/(record.projectExpense + record.manhourExpense)} + ProjectedCPI={record.totalFee/(record.projectExpense + record.manhourExpense) || 0} ClickedIndex={isCardClickedIndex} Index={record.id}/> diff --git a/src/components/ProjectFinancialSummaryV2/gptFn.tsx b/src/components/ProjectFinancialSummaryV2/gptFn.tsx index 4404029..8965484 100644 --- a/src/components/ProjectFinancialSummaryV2/gptFn.tsx +++ b/src/components/ProjectFinancialSummaryV2/gptFn.tsx @@ -8,6 +8,7 @@ export type SumOfByTeam = { manhourExpense: number, projectExpense: number, invoicedAmount: number, + uninvoicedAmount: number, paidAmount: number, activeProject: number, } @@ -21,6 +22,7 @@ export type SumOfByClient = { manhourExpense: number, projectExpense: number, invoicedAmount: number, + uninvoicedAmount: number, paidAmount: number, sumOfProjects: number, } @@ -36,6 +38,7 @@ export function sumUpByClient(data: FinancialByProject[]): SumOfByClient[] { manhourExpense: 0, projectExpense: 0, invoicedAmount: 0, + uninvoicedAmount: 0, paidAmount: 0, sumOfProjects: 0 }; @@ -46,6 +49,7 @@ export function sumUpByClient(data: FinancialByProject[]): SumOfByClient[] { acc[item.custId].manhourExpense += item.manhourExpense; acc[item.custId].projectExpense += item.projectExpense; acc[item.custId].invoicedAmount += item.invoicedAmount; + acc[item.custId].uninvoicedAmount += item.uninvoicedAmount; acc[item.custId].paidAmount += item.paidAmount; acc[item.custId].sumOfProjects += 1; @@ -64,6 +68,7 @@ export function sumUpByTeam(data: FinancialByProject[]): SumOfByTeam[] { manhourExpense: 0, projectExpense: 0, invoicedAmount: 0, + uninvoicedAmount: 0, paidAmount: 0, activeProject: 0 }; @@ -75,6 +80,7 @@ export function sumUpByTeam(data: FinancialByProject[]): SumOfByTeam[] { acc[item.teamId].manhourExpense += item.manhourExpense; acc[item.teamId].projectExpense += item.projectExpense; acc[item.teamId].invoicedAmount += item.invoicedAmount; + acc[item.teamId].uninvoicedAmount += item.uninvoicedAmount; acc[item.teamId].paidAmount += item.paidAmount; acc[item.teamId].activeProject += 1;