From 5de969bd59027dfa891a8d5d3d4536375e59f3ab Mon Sep 17 00:00:00 2001 From: "MSI\\derek" Date: Fri, 22 Nov 2024 14:29:04 +0800 Subject: [PATCH] add: project manhour summary report remove: old codes --- .../ProjectManhourSummaryReport/page.tsx | 29 +++++++ .../ProjectFinancialSummaryV2/page.tsx | 2 +- src/app/api/financialsummary/index.ts | 76 ------------------- src/app/api/reports/actions.ts | 16 +++- src/app/api/reports/index.ts | 10 +++ .../ProjectManhourSummaryReport.tsx | 71 +++++++++++++++++ .../ProjectManhourSummaryReportLoading.tsx | 41 ++++++++++ .../ProjectManhourSummaryReportWrapper.tsx | 17 +++++ .../index.ts | 1 + .../NavigationContent/NavigationContent.tsx | 6 ++ 10 files changed, 191 insertions(+), 78 deletions(-) create mode 100644 src/app/(main)/analytics/ProjectManhourSummaryReport/page.tsx create mode 100644 src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReport.tsx create mode 100644 src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportLoading.tsx create mode 100644 src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportWrapper.tsx create mode 100644 src/components/GenerateProjectManhourSummaryReport/index.ts diff --git a/src/app/(main)/analytics/ProjectManhourSummaryReport/page.tsx b/src/app/(main)/analytics/ProjectManhourSummaryReport/page.tsx new file mode 100644 index 0000000..28cf20d --- /dev/null +++ b/src/app/(main)/analytics/ProjectManhourSummaryReport/page.tsx @@ -0,0 +1,29 @@ +import { Metadata } from "next"; +import { Suspense } from "react"; +import { I18nProvider, getServerI18n } from "@/i18n"; +import { fetchProjects } from "@/app/api/projects"; +import { Typography } from "@mui/material"; +import GenerateProjectManhourSummaryReport from "@/components/GenerateProjectManhourSummaryReport"; + +export const metadata: Metadata = { + title: "Project Manhour Summary Report", +}; + +const ProjectManhourSummaryReport: React.FC = async () => { + const { t } = await getServerI18n("reports"); + + return ( + <> + + {t("Project Manhour Summary Report")} + + + }> + + + + + ); +}; + +export default ProjectManhourSummaryReport; \ No newline at end of file diff --git a/src/app/(main)/dashboard/ProjectFinancialSummaryV2/page.tsx b/src/app/(main)/dashboard/ProjectFinancialSummaryV2/page.tsx index b538cca..8978097 100644 --- a/src/app/(main)/dashboard/ProjectFinancialSummaryV2/page.tsx +++ b/src/app/(main)/dashboard/ProjectFinancialSummaryV2/page.tsx @@ -1,8 +1,8 @@ import { Metadata } from "next"; import { I18nProvider } from "@/i18n"; -import ProjectFinancialSummaryV2 from "@/components/ProjectFinancialSummaryV2"; import { preloadClientProjects } from "@/app/api/clientprojects"; import { searchParamsProps } from "@/app/utils/fetchUtil"; +import ProjectFinancialSummaryV2 from "@/components/ProjectFinancialSummaryV2"; export const metadata: Metadata = { title: "Project Status by Client", diff --git a/src/app/api/financialsummary/index.ts b/src/app/api/financialsummary/index.ts index ecd5768..e964faf 100644 --- a/src/app/api/financialsummary/index.ts +++ b/src/app/api/financialsummary/index.ts @@ -19,65 +19,6 @@ export interface FinancialSummaryCardResult { cpi: number; } -export type FinancialSummaryType = { - team: IndividualTeam; - activeProject: number; - totalFees: number; - totalBudget: number; - cumulativeExpenditure: number; - manpowerExpense: number; - projectExpense: number; - invoicedAmount: number; - nonInvoicedAmount: number; - receivedAmount: number; - cashFlowStatus: String; - costPerformanceIndex: number; - projectedCashFlowStatus: String; - projectedCostPerformanceIndex: number; -} - -export type FinancialSummaryByProject = { - // project data - id: number, - projectCode: string, - projectName: string, - custId: number, - totalFee: number, - totalBudget: number, - customerCode: string, - customerName: string, - subsidiaryName: string, - // timesheet data - cumulativeExpenditure: number, - manhourExpense: number, - projectExpense: number, - // invoice data - invoicedAmount: number, - nonInvoicedAmount: number, - receivedAmount: number, - // calculation - cashFlowStatus: string, - projectedCashFlowStatus: string, - cpi: number, - projectedCpi: number, -} - -export interface FinancialSummaryByClient { - id: number; - customerName: string; - customerCode: string; - subsidiaryName: string; - totalFee: number, - totalBudget: number, - cumulativeExpenditure: number - manhourExpense: number; - projectExpense: number; - invoicedAmount: number; - nonInvoicedAmount: number - receivedAmount: number; - numberOfRecords: number; -} - export type FinancialByProject = { id: number, projectName: string, @@ -104,23 +45,6 @@ export const fetchFinancialSummaryCard = cache(async () => { return serverFetchJson(`${BASE_API_URL}/dashboard/searchFinancialSummaryCard`); }); -export const fetchFinancialSummary = cache(async (endDate: string, teamId: number | null, startDate: string | null) => { - var endpoint = `${BASE_API_URL}/dashboard/getFinancialSummary?endDate=${endDate}` - if (teamId) endpoint += `&teamIds=${teamId}` - if (startDate) endpoint += `&startDate=${startDate}` - return serverFetchJson(endpoint, { - next: { tags: ["financialSummary"] }, - }); -}) - -export const fetchFinancialSummaryByProject = cache(async (endDate: string, teamId: string, startDate?: string ) => { - var endpoint = `${BASE_API_URL}/dashboard/getFinancialSummaryByProject?endDate=${endDate}&teamId=${teamId}` - if (startDate) endpoint += `&startDate=${startDate}` - return serverFetchJson(endpoint, { - next: { tags: ["financialSummaryByProject"] }, - }); -}) - export const fetchFinancialSummaryByProjectV2 = cache(async (teamId: number, endDate: string, startDate: string) => { var endpoint = `${BASE_API_URL}/dashboard/getFinancialSummary-final?` if (startDate.length > 0) endpoint += `&startDate=${startDate}` diff --git a/src/app/api/reports/actions.ts b/src/app/api/reports/actions.ts index 77fc7b1..994547d 100644 --- a/src/app/api/reports/actions.ts +++ b/src/app/api/reports/actions.ts @@ -1,7 +1,7 @@ "use server"; import { serverFetchBlob } from "@/app/utils/fetchUtil"; -import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest, ProjectPotentialDelayReportRequest, CostAndExpenseReportRequest, CrossTeamChargeReportRequest } from "."; +import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest, ProjectPotentialDelayReportRequest, CostAndExpenseReportRequest, CrossTeamChargeReportRequest, ProjectManhourSummaryReportRequest } from "."; import { BASE_API_URL } from "@/config/api"; export interface FileResponse { @@ -133,5 +133,19 @@ export const fetchCrossTeamChargeReport = async (data: CrossTeamChargeReportRequ }, ); + return reportBlob +}; + +export const fetchProjectManhourSummaryReport = async (data: ProjectManhourSummaryReportRequest) => { + console.log(data) + const reportBlob = await serverFetchBlob( + `${BASE_API_URL}/reports/ProjectManhourSummary`, + { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }, + ); + return reportBlob }; \ No newline at end of file diff --git a/src/app/api/reports/index.ts b/src/app/api/reports/index.ts index 7db4809..7d18325 100644 --- a/src/app/api/reports/index.ts +++ b/src/app/api/reports/index.ts @@ -126,4 +126,14 @@ export interface CrossTeamChargeReportFilter { export interface CrossTeamChargeReportRequest { month: string; teamId: number | "All"; +} +export interface ProjectManhourSummaryReportFilter { + teamId: number; + startDate: string; + endDate: string; +} +export interface ProjectManhourSummaryReportRequest { + teamId: number; + startDate: string; + endDate: string; } \ No newline at end of file diff --git a/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReport.tsx b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReport.tsx new file mode 100644 index 0000000..05f752f --- /dev/null +++ b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReport.tsx @@ -0,0 +1,71 @@ +"use client"; + +import { ProjectManhourSummaryReportFilter } from "@/app/api/reports"; +import SearchBox, { Criterion } from "../SearchBox"; +import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { TeamResult } from "@/app/api/team"; +import { fetchProjectManhourSummaryReport } from "@/app/api/reports/actions"; +import { downloadFile } from "@/app/utils/commonUtil"; + +interface Props { + teams: TeamResult[] +} + +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const ProjectManhourSummaryReport: React.FC = ({ teams }) => { + const { t } = useTranslation("report"); + const teamsCombo = teams.map((team) => ({label: `${team.code} - ${team.name}`, value: team.id})) + + const searchCriteria: Criterion[] = useMemo( + () => [ + { + label: t("Start Date"), + paramName: "startDate", + type: "monthYear", + }, + { + label: t("End Date"), + paramName: "endDate", + type: "monthYear", + }, + { + label: t("Team"), + paramName: "teamId", + type: "autocomplete", + options: teamsCombo, + needAll: false, + }, + ], + [t] + ); + return ( + <> + { + console.log(query); + var start = query.startDate + var start = query.startDate + const args = { + teamId: query.teamId, + startDate: query.startDate + "-01", + endDate: query.endDate + "-01", + } + console.log(args) + const response = await fetchProjectManhourSummaryReport(args);// + if (response) { + console.log("asdasdas") + downloadFile( + new Uint8Array(response.blobValue), + response.filename!! + ); + } + }} + /> + ) +} +export default ProjectManhourSummaryReport \ No newline at end of file diff --git a/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportLoading.tsx b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportLoading.tsx new file mode 100644 index 0000000..ac294b7 --- /dev/null +++ b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportLoading.tsx @@ -0,0 +1,41 @@ +//src\components\LateStartReportGen\LateStartReportGenLoading.tsx +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const ProjectManhourSummaryReportLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ProjectManhourSummaryReportLoading; diff --git a/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportWrapper.tsx b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportWrapper.tsx new file mode 100644 index 0000000..bb36dd9 --- /dev/null +++ b/src/components/GenerateProjectManhourSummaryReport/ProjectManhourSummaryReportWrapper.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import ProjectManhourSummaryReportLoading from "./ProjectManhourSummaryReportLoading"; +import ProjectManhourSummaryReport from "./ProjectManhourSummaryReport"; +import { fetchTeam } from "@/app/api/team"; + +interface SubComponents { + Loading: typeof ProjectManhourSummaryReportLoading; + } + +const ProjectManhourSummaryReportWrapper: React.FC & SubComponents = async () => { + const teams = await fetchTeam() + return +} + +ProjectManhourSummaryReportWrapper.Loading = ProjectManhourSummaryReportLoading; + +export default ProjectManhourSummaryReportWrapper; \ No newline at end of file diff --git a/src/components/GenerateProjectManhourSummaryReport/index.ts b/src/components/GenerateProjectManhourSummaryReport/index.ts new file mode 100644 index 0000000..ee56524 --- /dev/null +++ b/src/components/GenerateProjectManhourSummaryReport/index.ts @@ -0,0 +1 @@ +export { default } from "./ProjectManhourSummaryReportWrapper"; diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index 3a905bc..f533e20 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -312,6 +312,12 @@ const NavigationContent: React.FC = ({ abilities, username }) => { abilities!.includes(ability), ), }, + { + icon: , + label: "Project Manhour Summary Report", + path: "/analytics/ProjectManhourSummaryReport", + isHidden: false + }, { icon: , label: "Staff Monthly Work Hours Analysis Report",