|
- "use client";
- import * as React from "react";
- import Grid from "@mui/material/Grid";
- import { useState, useEffect, useMemo } from "react";
- import Paper from "@mui/material/Paper";
- import { TFunction } from "i18next";
- import { useTranslation } from "react-i18next";
- import { Card, CardHeader } from "@mui/material";
- import CustomSearchForm from "../CustomSearchForm/CustomSearchForm";
- import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
- import ReactApexChart from "react-apexcharts";
- import { ApexOptions } from "apexcharts";
- import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
- import ReportProblemIcon from "@mui/icons-material/ReportProblem";
- import dynamic from "next/dynamic";
- import "../../app/global.css";
- import { AnyARecord, AnyCnameRecord } from "dns";
- import SearchBox, { Criterion } from "../SearchBox";
- import ProgressByClientSearch from "@/components/ProgressByClientSearch";
- import { Suspense } from "react";
- import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch";
- import { CardFooter, Input, Label } from "reactstrap";
- import Select, { components } from "react-select";
- import { fetchTeamCombo, fetchTeamCashFlowChartData } from "@/app/api/teamCashflow";
- import { VIEW_DASHBOARD_ALL } from "@/middleware";
- import { SessionStaff } from "@/config/authConfig";
- import Typography from "@mui/material/Typography";
-
- interface Props {
- abilities: string[],
- staff: SessionStaff,
- }
-
- const CompanyTeamCashFlow: React.FC<Props> = ({ abilities, staff }) => {
- const { t } = useTranslation("dashboard");
- const todayDate = new Date();
- const [selectionModel, setSelectionModel]: any[] = React.useState([]);
- const [teamOptions, setTeamOptions]: any[] = React.useState([]);
- const [teamId, setTeamId]: any = React.useState(null);
- 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 fetchChartData = async () => {
- if (teamOptions.length > 0) {
- const tempTeamId = abilities.includes(VIEW_DASHBOARD_ALL) ? teamId : teamOptions[0]?.value
- const cashFlowMonthlyChartData: any = await fetchTeamCashFlowChartData(cashFlowYear, tempTeamId);
- console.log(cashFlowMonthlyChartData[0])
- 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].teamCashFlowIncome.length; i++) {
- if (leftMax < cashFlowMonthlyChartData[0].teamCashFlowIncome[i].income || leftMax < cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].expenditure) {
- leftMax = Math.max(cashFlowMonthlyChartData[0].teamCashFlowIncome[i].income, cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].expenditure)
- }
- monthlyIncome.push(cashFlowMonthlyChartData[0].teamCashFlowIncome[i].income)
- cumulativeIncome.push(cashFlowMonthlyChartData[0].teamCashFlowIncome[i].cumulativeIncome)
- }
- for (var i = 0; i < cashFlowMonthlyChartData[0].teamCashFlowExpenditure.length; i++) {
- if (rightMax < cashFlowMonthlyChartData[0].teamCashFlowIncome[i].cumulativeIncome || rightMax < cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].cumulativeExpenditure) {
- rightMax = Math.max(cashFlowMonthlyChartData[0].teamCashFlowIncome[i].cumulativeIncome, cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].cumulativeExpenditure)
- }
- monthlyExpenditure.push(cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].expenditure)
- cumulativeExpenditure.push(cashFlowMonthlyChartData[0].teamCashFlowExpenditure[i].cumulativeExpenditure)
- }
- setMonthlyIncomeList(monthlyIncome)
- setMonthlyCumulativeIncomeList(cumulativeIncome)
- setMonthlyExpenditureList(monthlyExpenditure)
- setMonthlyCumulativeExpenditureList(cumulativeExpenditure)
- setMonthlyChartLeftMax(leftMax)
- setMonthlyChartRightMax(rightMax)
- // } else {
- // setMonthlyIncomeList([0,0,0,0,0,0,0,0,0,0,0,0])
- // setMonthlyCumulativeIncomeList([0,0,0,0,0,0,0,0,0,0,0,0])
- // setMonthlyExpenditureList([0,0,0,0,0,0,0,0,0,0,0,0])
- // setMonthlyCumulativeExpenditureList([0,0,0,0,0,0,0,0,0,0,0,0])
- // }
- }
- }
-
- const fetchComboData = async () => {
- const teamComboList = []
- const teamCombo = await fetchTeamCombo();
-
- if (abilities.includes(VIEW_DASHBOARD_ALL)) {
- for (var i = 0; i < teamCombo.records.length; i++) {
- teamComboList.push({ value: teamCombo.records[i].id, label: teamCombo.records[i].label })
- }
- } else {
- const tempTeam = teamCombo.records.find(record => record.id === staff.teamId)
- teamComboList.push({ value: tempTeam?.id, label: tempTeam?.label })
- }
-
- setTeamOptions(teamComboList)
- }
-
- useEffect(() => {
- fetchComboData()
- }, []);
-
- useEffect(() => {
- fetchChartData()
- }, [cashFlowYear, teamId, teamOptions]);
-
- const columns = [
- {
- id: "projectCode",
- field: "projectCode",
- headerName: "Project Code",
- flex: 1,
- },
- {
- id: "projectName",
- field: "projectName",
- headerName: "Project Name",
- flex: 1,
- },
- {
- id: "team",
- field: "team",
- headerName: "Team",
- flex: 1,
- },
- {
- id: "teamLeader",
- field: "teamLeader",
- headerName: "Team Leader",
- flex: 1,
- },
- {
- id: "startDate",
- field: "startDate",
- headerName: "Start Date",
- flex: 1,
- },
- {
- id: "targetEndDate",
- field: "targetEndDate",
- headerName: "Target End Date",
- flex: 1,
- },
- {
- id: "client",
- field: "client",
- headerName: "Client",
- flex: 1,
- },
- {
- id: "subsidiary",
- field: "subsidiary",
- headerName: "Subsidiary",
- flex: 1,
- },
- ];
-
- const ledgerColumns = [
- {
- id: "date",
- field: "date",
- headerName: "Date",
- flex: 0.5,
- },
- {
- id: "expenditure",
- field: "expenditure",
- headerName: "Expenditure (HKD)",
- flex: 0.6,
- },
- {
- id: "income",
- field: "income",
- headerName: "Income (HKD)",
- flex: 0.6,
- },
- {
- id: "cashFlowBalance",
- field: "cashFlowBalance",
- headerName: "Cash Flow Balance (HKD)",
- flex: 0.6,
- },
- {
- id: "remarks",
- field: "remarks",
- headerName: "Remarks",
- flex: 1,
- },
- ];
-
- const options: ApexOptions = {
- tooltip: {
- y: {
- formatter: function (val) {
- return val.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
- }
- }
- },
- chart: {
- height: 350,
- type: "line",
- },
- stroke: {
- width: [0, 0, 2, 2],
- },
- plotOptions: {
- bar: {
- horizontal: false,
- distributed: false,
- },
- },
- dataLabels: {
- enabled: false,
- },
- xaxis: {
- categories: [
- t("JAN"),
- t("FEB"),
- t("MAR"),
- t("APR"),
- t("MAY"),
- t("JUN"),
- t("JUL"),
- t("AUG"),
- t("SEP"),
- t("OCT"),
- t("NOV"),
- t("DEC"),
- ],
- },
- yaxis: [
- {
- title: {
- text:t("Monthly Income and Expenditure (HKD)"),
- style: {
- fontSize: '15px'
- }
- },
- min: 0,
- max: monthlyChartLeftMax,
- tickAmount: 5,
- labels: {
- formatter: function (val) {
- return val.toLocaleString()
- }
- }
- },
- {
- show: false,
- seriesName: "Monthly Expenditure",
- title: {
- text: t("Monthly Expenditure (HKD)"),
- },
- min: 0,
- max: monthlyChartLeftMax,
- tickAmount: 5,
- },
- {
- seriesName: "Cumulative Income",
- opposite: true,
- title: {
- text: t("Cumulative Income and Expenditure (HKD)"),
- style: {
- fontSize: '15px'
- }
- },
- min: 0,
- max: monthlyChartRightMax,
- tickAmount: 5,
- labels: {
- formatter: function (val) {
- return val.toLocaleString()
- }
- }
- },
- {
- show: false,
- seriesName: "Cumulative Expenditure",
- opposite: true,
- title: {
- text: t("Cumulative Expenditure (HKD)"),
- },
- min: 0,
- max: monthlyChartRightMax,
- tickAmount: 5,
- },
- ],
- grid: {
- borderColor: "#f1f1f1",
- },
- annotations: {},
- series: [
- {
- name: t("Monthly Income"),
- type: "column",
- color: "#ffde91",
- data: monthlyIncomeList,
- },
- {
- name: t("Monthly Expenditure"),
- type: "column",
- color: "#82b59a",
- data: monthlyExpenditureList,
- },
- {
- name: t("Cumulative Income"),
- type: "line",
- color: "#EE6D7A",
- data: monthlyCumulativeIncomeList,
- },
- {
- name: t("Cumulative Expenditure"),
- type: "line",
- color: "#7cd3f2",
- data: monthlyCumulativeExpenditureList,
- },
- ],
- };
-
- return (
- <>
- <Grid item sm>
- <Typography variant="h4" marginInlineEnd={2}>
- {t("Company / Team Cash Flow")}
- </Typography>
- <div style={{ display: "inline-block", width: "100%" }} className={"mt-5"}>
- <Grid item xs={12} md={12} lg={12}>
- <Card>
- <CardHeader
- className="text-slate-500"
- title={t("Company and Team Cash Flow By Month")}
- />
- <div style={{ display: "inline-block", width: "99%" }}>
- <div className="inline-block">
- <Label className="text-slate-500 font-medium ml-6">
- {t("Year")}:
- </Label>
- <Input
- id={"cashFlowYear"}
- value={cashFlowYear}
- readOnly={true}
- bsSize="lg"
- className="rounded-md text-base w-12"
- />
- </div>
- <div className="inline-block ml-1">
- <button
- onClick={() => setCashFlowYear(cashFlowYear - 1)}
- className="hover:cursor-pointer hover:bg-slate-200 bg-transparent rounded-md w-8 h-8 text-base"
- >
- <
- </button>
- </div>
- <div className="inline-block ml-1">
- <button
- onClick={() => setCashFlowYear(cashFlowYear + 1)}
- className="hover:cursor-pointer hover:bg-slate-200 bg-transparent rounded-md w-8 h-8 text-base"
- >
- >
- </button>
- </div>
- {abilities.includes(VIEW_DASHBOARD_ALL) && <div className="inline-block">
- <div className="inline-block ml-2">
- <Label className="text-slate-500 font-medium">
- {t("Team")}:
- </Label>
- </div>
- <div className="inline-block ml-1 w-60">
- <Select
- placeholder={t("All Team")}
- options={teamOptions}
- isClearable={true}
- onChange={(selectedOption: any) => {
- if (selectedOption === null) {
- setTeamId(null);
- } else {
- setTeamId(selectedOption.value);
- }
- }}
- />
- </div>
- </div>}
- <ReactApexChart
- options={options}
- series={options.series}
- type="line"
- height="500"
- />
- </div>
- <CardFooter>
- <Grid sx={{ ml: 2, mb: 2, fontSize: '0.8rem' }}>
- * Cumulative Expenditure: Manpower Expense + Other Expense
- </Grid>
- </CardFooter>
- </Card>
- </Grid>
- </div>
- </Grid>
- </>
- );
- };
-
- export default CompanyTeamCashFlow;
|