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",