Przeglądaj źródła

update dashboard

tags/Baseline_30082024_FRONTEND_UAT
Mac\David 1 rok temu
rodzic
commit
1b1e62a9ec
2 zmienionych plików z 123 dodań i 31 usunięć
  1. +25
    -1
      src/app/api/cashflow/index.ts
  2. +98
    -30
      src/components/ProjectCashFlow/ProjectCashFlow.tsx

+ 25
- 1
src/app/api/cashflow/index.ts Wyświetl plik

@@ -11,12 +11,25 @@ export interface CashFlow {
teamLeader: string;
startDate: string;
startDateFrom: string;
startDateTo: string;
startDateFromTo: string;
targetEndDate: string;
client: string;
subsidiary: string;
}

export interface CashFlowByMonthChartResult {
monthInvoice: string;
invoiceMonth: string;
income: number;
cumulativeIncome:number;
monthExpenditure:string;
recordMonth:string;
expenditure:number;
cumulativeExpenditure:number;
incomeList: any[];
expenditureList: any[];
}

export const preloadProjects = () => {
fetchProjectsCashFlow();
};
@@ -24,3 +37,14 @@ export const preloadProjects = () => {
export const fetchProjectsCashFlow = cache(async () => {
return serverFetchJson<CashFlow[]>(`${BASE_API_URL}/dashboard/searchCashFlowProject`);
});

export const fetchProjectsCashFlowMonthlyChart = cache(async (projectIdList: number[], year: number) => {
if (projectIdList.length !== 0) {
const queryParams = new URLSearchParams();
queryParams.append('projectIdList', projectIdList.join(','));
return serverFetchJson<CashFlowByMonthChartResult[]>(`${BASE_API_URL}/dashboard/searchCashFlowByMonth?${queryParams.toString()}&year=${year}`);
} else {
return [];
}
});

+ 98
- 30
src/components/ProjectCashFlow/ProjectCashFlow.tsx Wyświetl plik

@@ -19,9 +19,10 @@ import SearchBox, { Criterion } from "../SearchBox";
import ProgressByClientSearch from "@/components/ProgressByClientSearch";
import { Suspense } from "react";
import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch";
import { fetchProjectsCashFlow} from "@/app/api/cashflow";
import { fetchProjectsCashFlow,fetchProjectsCashFlowMonthlyChart} from "@/app/api/cashflow";
import { Input, Label } from "reactstrap";
import { CashFlow } from "@/app/api/cashflow";
import dayjs from 'dayjs';

interface Props {
projects: CashFlow[];
@@ -34,19 +35,78 @@ const ProjectCashFlow: React.FC = () => {
const todayDate = new Date();
const [selectionModel, setSelectionModel]: any[] = React.useState([]);
const [projectData, setProjectData]: any[] = React.useState([]);
const [filteredResult, setFilteredResult]:any[] = useState([]);
const [selectedProjectIdList, setSelectedProjectIdList]: any[] = React.useState([]);
const [monthlyIncomeList, setMonthlyIncomeList]: any[] = React.useState([]);
const [monthlyCumulativeIncomeList, setMonthlyCumulativeIncomeList]: any[] = React.useState([]);
const [monthlyExpenditureList, setMonthlyExpenditureList]: any[] = React.useState([]);
const [monthlyCumulativeExpenditureList, setMonthlyCumulativeExpenditureList]: any[] = React.useState([]);
const [monthlyChartLeftMax, setMonthlyChartLeftMax]: any[] = React.useState(0);
const [monthlyChartRightMax, setMonthlyChartRightMax]: any[] = React.useState(0);
const [cashFlowYear, setCashFlowYear]: any[] = React.useState(
todayDate.getFullYear(),
);
const [anticipateCashFlowYear, setAnticipateCashFlowYear]: any[] = React.useState(
todayDate.getFullYear(),
);

const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => {
const selectedRowsData = projectData.filter((row: any) =>
newSelectionModel.includes(row.id),
);
const projectIdList = []
for (var i=0; i<selectedRowsData.length; i++){
projectIdList.push(selectedRowsData[i].id)
}
setSelectedProjectIdList(projectIdList)
};

const fetchData = async () => {
const cashFlowProject = await fetchProjectsCashFlow();
console.log(cashFlowProject)
setProjectData(cashFlowProject)
setFilteredResult(cashFlowProject)
}
const fetchChartData = async () => {
const cashFlowMonthlyChartData = await fetchProjectsCashFlowMonthlyChart(selectedProjectIdList,cashFlowYear);
console.log(cashFlowMonthlyChartData)
const monthlyIncome = []
const cumulativeIncome = []
const monthlyExpenditure = []
const cumulativeExpenditure = []
var leftMax = 0
var rightMax = 0
if (cashFlowMonthlyChartData.length !== 0) {
for (var i = 0; i < cashFlowMonthlyChartData[0].incomeList.length; i++) {
if (leftMax < cashFlowMonthlyChartData[0].incomeList[i].income || leftMax < cashFlowMonthlyChartData[0].expenditureList[i].expenditure){
leftMax = Math.max(cashFlowMonthlyChartData[0].incomeList[i].income,cashFlowMonthlyChartData[0].expenditureList[i].expenditure)
}
monthlyIncome.push(cashFlowMonthlyChartData[0].incomeList[i].income)
cumulativeIncome.push(cashFlowMonthlyChartData[0].incomeList[i].cumulativeIncome)
}
for (var i = 0; i < cashFlowMonthlyChartData[0].expenditureList.length; i++) {
if (rightMax < cashFlowMonthlyChartData[0].incomeList[i].income || rightMax < cashFlowMonthlyChartData[0].expenditureList[i].expenditure){
rightMax = Math.max(cashFlowMonthlyChartData[0].incomeList[i].income,cashFlowMonthlyChartData[0].expenditureList[i].expenditure)
}
monthlyExpenditure.push(cashFlowMonthlyChartData[0].expenditureList[i].expenditure)
cumulativeExpenditure.push(cashFlowMonthlyChartData[0].expenditureList[i].cumulativeExpenditure)
}
setMonthlyIncomeList(monthlyIncome)
setMonthlyCumulativeIncomeList(cumulativeIncome)
setMonthlyExpenditureList(monthlyExpenditure)
setMonthlyCumulativeExpenditureList(cumulativeExpenditure)
setMonthlyChartLeftMax(leftMax)
setMonthlyChartRightMax(rightMax)
}
}
useEffect(() => {
fetchData()
}, []);

useEffect(() => {
fetchChartData()
}, [cashFlowYear,selectedProjectIdList]);
const columns = [
{
id: "projectCode",
@@ -170,7 +230,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Monthly Income and Expenditure(HKD)",
},
min: 0,
max: 350000,
max: monthlyChartLeftMax,
tickAmount: 5,
labels: {
formatter: function (val) {
@@ -185,7 +245,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Monthly Expenditure (HKD)",
},
min: 0,
max: 350000,
max: monthlyChartLeftMax,
tickAmount: 5,
},
{
@@ -195,7 +255,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Cumulative Income and Expenditure(HKD)",
},
min: 0,
max: 850000,
max: monthlyChartRightMax,
tickAmount: 5,
labels: {
formatter: function (val) {
@@ -211,7 +271,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Cumulative Expenditure (HKD)",
},
min: 0,
max: 850000,
max: monthlyChartRightMax,
tickAmount: 5,
},
],
@@ -224,34 +284,25 @@ const ProjectCashFlow: React.FC = () => {
name: "Monthly_Income",
type: "column",
color: "#ffde91",
data: [0, 110000, 0, 0, 185000, 0, 0, 189000, 0, 0, 300000, 0],
data: monthlyIncomeList,
},
{
name: "Monthly_Expenditure",
type: "column",
color: "#82b59a",
data: [
0, 160000, 120000, 120000, 55000, 55000, 55000, 55000, 55000, 70000,
55000, 55000,
],
data: monthlyExpenditureList,
},
{
name: "Cumulative_Income",
type: "line",
color: "#EE6D7A",
data: [
0, 100000, 100000, 100000, 300000, 300000, 300000, 500000, 500000,
500000, 800000, 800000,
],
data: monthlyCumulativeIncomeList,
},
{
name: "Cumulative_Expenditure",
type: "line",
color: "#7cd3f2",
data: [
0, 198000, 240000, 400000, 410000, 430000, 510000, 580000, 600000,
710000, 730000, 790000,
],
data: monthlyCumulativeExpenditureList,
},
],
};
@@ -295,7 +346,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Anticipate Monthly Income and Expenditure(HKD)",
},
min: 0,
max: 350000,
max: monthlyChartLeftMax,
tickAmount: 5,
labels: {
formatter: function (val) {
@@ -310,7 +361,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Monthly Expenditure (HKD)",
},
min: 0,
max: 350000,
max: monthlyChartLeftMax,
tickAmount: 5,
},
{
@@ -320,7 +371,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Cumulative Income and Expenditure(HKD)",
},
min: 0,
max: 850000,
max: monthlyChartRightMax,
tickAmount: 5,
labels: {
formatter: function (val) {
@@ -336,7 +387,7 @@ const ProjectCashFlow: React.FC = () => {
text: "Cumulative Expenditure (HKD)",
},
min: 0,
max: 850000,
max: monthlyChartRightMax,
tickAmount: 5,
},
],
@@ -548,12 +599,6 @@ const ProjectCashFlow: React.FC = () => {
},
];
const [ledgerData, setLedgerData]: any[] = React.useState(ledgerRows);
const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => {
const selectedRowsData = projectData.filter((row: any) =>
newSelectionModel.includes(row.id),
);
console.log(selectedRowsData);
};

const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
() => [
@@ -569,6 +614,19 @@ const ProjectCashFlow: React.FC = () => {
[t],
);

function isDateInRange(dateToCheck: string, startDate: string, endDate: string): boolean {
console.log(startDate)
console.log(endDate)
if (!startDate || !endDate) {
return false;
}
const dateToCheckObj = new Date(dateToCheck);
const startDateObj = new Date(startDate);
const endDateObj = new Date(endDate);
console.log(dateToCheckObj)
return dateToCheckObj >= startDateObj && dateToCheckObj <= endDateObj;
}

return (
<>
{/* <Suspense fallback={<ProgressCashFlowSearch.Loading />}>
@@ -577,11 +635,21 @@ const ProjectCashFlow: React.FC = () => {
<SearchBox
criteria={searchCriteria}
onSearch={(query) => {
console.log(query);
console.log(query)
setFilteredResult(
projectData.filter(
(cp:any) =>
cp.projectCode.toLowerCase().includes(query.projectCode.toLowerCase()) &&
cp.projectName.toLowerCase().includes(query.projectName.toLowerCase()) &&
(query.startDateFrom || query.startDateFromTo
? isDateInRange(cp.startDate, query.startDateFrom, query.startDateFromTo)
: true)
),
);
}}
/>
<CustomDatagrid
rows={projectData}
rows={filteredResult}
columns={columns}
columnWidth={200}
dataGridHeight={300}


Ładowanie…
Anuluj
Zapisz