Files
bodyshop/client/src/components/production-board-kanban/production-board-kanban.statistics.jsx
Dave Richer bbc446ef01 - Finish up with Statistics
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-07-30 17:24:55 -04:00

146 lines
5.4 KiB
JavaScript

import React, { useMemo } from "react";
import { Statistic, Card } from "antd";
import { useTranslation } from "react-i18next";
const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
const { t } = useTranslation();
const calculateTotal = (items, key, subKey) => {
return items.reduce((acc, item) => acc + (item[key]?.aggregate?.sum?.[subKey] || 0), 0);
};
const calculateTotalAmount = (items, key) => {
return items.reduce((acc, item) => acc + (item[key]?.totals?.subtotal?.amount || 0), 0);
};
const calculateReducerTotal = (lanes, key, subKey) => {
return lanes.reduce((acc, lane) => {
return (
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata[key]?.aggregate?.sum?.[subKey] || 0), 0)
);
}, 0);
};
const calculateReducerTotalAmount = (lanes, key) => {
return lanes.reduce((acc, lane) => {
return (
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata[key]?.totals?.subtotal?.amount || 0), 0)
);
}, 0);
};
const formatValue = (value, type) => {
if (type === "Jobs") {
return value.toFixed(0);
}
if (type === "Hrs") {
return value.toFixed(2);
}
return value;
};
const totalHrs = useMemo(() => {
if (!cardSettings.totalHrs) return null;
const total = calculateTotal(data, "labhrs", "mod_lb_hrs") + calculateTotal(data, "larhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [data, cardSettings.totalHrs]);
const totalLAB = useMemo(() => {
if (!cardSettings.totalLAB) return null;
const total = calculateTotal(data, "labhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [data, cardSettings.totalLAB]);
const totalLAR = useMemo(() => {
if (!cardSettings.totalLAR) return null;
const total = calculateTotal(data, "larhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [data, cardSettings.totalLAR]);
const jobsInProduction = useMemo(
() => (cardSettings.jobsInProduction ? data.length : null),
[data, cardSettings.jobsInProduction]
);
const totalAmountInProduction = useMemo(() => {
if (!cardSettings.totalAmountInProduction) return null;
const total = calculateTotalAmount(data, "job_totals");
return parseFloat(total.toFixed(2));
}, [data, cardSettings.totalAmountInProduction]);
const totalHrsOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalHrsOnBoard) return null;
const total =
calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs") +
calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [reducerData, cardSettings.totalHrsOnBoard]);
const totalLABOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalLABOnBoard) return null;
const total = calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [reducerData, cardSettings.totalLABOnBoard]);
const totalLAROnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalLAROnBoard) return null;
const total = calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
return parseFloat(total.toFixed(2));
}, [reducerData, cardSettings.totalLAROnBoard]);
const jobsOnBoard = useMemo(
() =>
reducerData && cardSettings.jobsOnBoard
? reducerData.lanes.reduce((acc, lane) => acc + lane.cards.length, 0)
: null,
[reducerData, cardSettings.jobsOnBoard]
);
const totalAmountOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalAmountOnBoard) return null;
const total = calculateReducerTotalAmount(reducerData.lanes, "job_totals");
return parseFloat(total.toFixed(2));
}, [reducerData, cardSettings.totalAmountOnBoard]);
const statistics = [
{ value: totalHrs, title: t("total_hours_in_production"), suffix: t("production.statistics.hours") },
{
value: totalAmountInProduction,
title: t("total_amount_in_production"),
prefix: t("production.statistics.currency_symbol")
},
{ value: totalLAB, title: t("total_lab_in_production"), suffix: t("production.statistics.hours") },
{ value: totalLAR, title: t("total_lar_in_production"), suffix: t("production.statistics.hours") },
{ value: jobsInProduction, title: t("jobs_in_production"), suffix: "Jobs" },
{ value: totalHrsOnBoard, title: t("total_hours_on_board"), suffix: t("production.statistics.hours") },
{
value: totalAmountOnBoard,
title: t("total_amount_on_board"),
prefix: t("production.statistics.currency_symbol")
},
{ value: totalLABOnBoard, title: t("total_lab_on_board"), suffix: t("production.statistics.hours") },
{ value: totalLAROnBoard, title: t("total_lar_on_board"), suffix: t("production.statistics.hours") },
{ value: jobsOnBoard, title: t("total_jobs_on_board"), suffix: "Jobs" }
];
return (
<div style={{ display: "flex", gap: "5px", flexWrap: "wrap", marginBottom: "5px" }}>
{statistics.map(
(stat, index) =>
stat.value !== null && (
<Card key={index}>
<Statistic
title={t(`production.statistics.${stat.title}`)}
value={formatValue(stat.value, stat.suffix)}
prefix={stat.prefix}
suffix={stat.suffix}
/>
</Card>
)
)}
</div>
);
};
export default ProductionStatistics;