Merged in bugfix/dinero-for-production-board-amounts (pull request #1680)

- Use Dinero in place of straight math in production board
This commit is contained in:
Dave Richer
2024-09-05 16:48:21 +00:00

View File

@@ -3,6 +3,7 @@ import { Card, Statistic } from "antd";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { defaultKanbanSettings, statisticsItems } from "./settings/defaultKanbanSettings.js"; import { defaultKanbanSettings, statisticsItems } from "./settings/defaultKanbanSettings.js";
import Dinero from "dinero.js";
export const StatisticType = { export const StatisticType = {
HOURS: "hours", HOURS: "hours",
@@ -32,7 +33,31 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
}; };
const calculateTotalAmount = (items, key) => { const calculateTotalAmount = (items, key) => {
return items.reduce((acc, item) => acc + (item[key]?.totals?.subtotal?.amount || 0), 0); return items.reduce(
(acc, item) => {
const amountInCents = item[key]?.totals?.subtotal?.amount || 0;
const dineroAmount = Dinero({ amount: amountInCents });
return acc.add(dineroAmount);
},
Dinero({ amount: 0 })
);
};
const calculateReducerTotalAmount = (lanes, key) => {
return lanes.reduce(
(acc, lane) => {
const laneTotal = lane.cards.reduce(
(laneAcc, card) => {
const amountInCents = card.metadata[key]?.totals?.subtotal?.amount || 0;
const dineroAmount = Dinero({ amount: amountInCents });
return laneAcc.add(dineroAmount);
},
Dinero({ amount: 0 })
);
return acc.add(laneTotal);
},
Dinero({ amount: 0 })
);
}; };
const calculateReducerTotal = (lanes, key, subKey) => { const calculateReducerTotal = (lanes, key, subKey) => {
@@ -43,14 +68,6 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
}, 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) => { const formatValue = (value, type) => {
if (type === StatisticType.JOBS) { if (type === StatisticType.JOBS) {
return value.toFixed(0); return value.toFixed(0);
@@ -87,9 +104,15 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
const totalAmountInProduction = useMemo(() => { const totalAmountInProduction = useMemo(() => {
if (!cardSettings.totalAmountInProduction) return null; if (!cardSettings.totalAmountInProduction) return null;
const total = calculateTotalAmount(data, "job_totals"); const total = calculateTotalAmount(data, "job_totals");
return parseFloat(total.toFixed(2)); return total.toFormat("$0,0.00"); // Formatting the Dinero object to a string
}, [data, cardSettings.totalAmountInProduction]); }, [data, cardSettings.totalAmountInProduction]);
const totalAmountOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalAmountOnBoard) return null;
const total = calculateReducerTotalAmount(reducerData.lanes, "job_totals");
return total.toFormat("$0,0.00"); // Formatting the Dinero object to a string
}, [reducerData, cardSettings.totalAmountOnBoard]);
const totalHrsOnBoard = useMemo(() => { const totalHrsOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.totalHrsOnBoard) return null; if (!reducerData || !cardSettings.totalHrsOnBoard) return null;
const total = const total =
@@ -118,12 +141,6 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
[reducerData, cardSettings.jobsOnBoard] [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 tasksInProduction = useMemo(() => { const tasksInProduction = useMemo(() => {
if (!data || !cardSettings.tasksInProduction) return null; if (!data || !cardSettings.tasksInProduction) return null;
return data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0); return data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0);
@@ -191,7 +208,6 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
<Statistic <Statistic
title={t(`production.statistics.${stat.label}`)} title={t(`production.statistics.${stat.label}`)}
value={formatValue(stat.value, stat.type)} value={formatValue(stat.value, stat.type)}
prefix={stat.type === StatisticType.AMOUNT ? t("production.statistics.currency_symbol") : undefined}
suffix={ suffix={
stat.type === StatisticType.HOURS stat.type === StatisticType.HOURS
? t("production.statistics.hours") ? t("production.statistics.hours")