From 83fc92d48be4eb0399910ea436a30242dc89284f Mon Sep 17 00:00:00 2001 From: rstubryan Date: Thu, 18 Dec 2025 11:12:30 +0700 Subject: [PATCH] refactor(FE-356): Refactor weight-range grouping and format currency --- .../sale/export/HppPerkandangExport.tsx | 230 +++++++----------- 1 file changed, 83 insertions(+), 147 deletions(-) diff --git a/src/components/pages/report/sale/export/HppPerkandangExport.tsx b/src/components/pages/report/sale/export/HppPerkandangExport.tsx index 6fb0f914..d6bd3e25 100644 --- a/src/components/pages/report/sale/export/HppPerkandangExport.tsx +++ b/src/components/pages/report/sale/export/HppPerkandangExport.tsx @@ -10,7 +10,7 @@ import { pdf, } from '@react-pdf/renderer'; import { HppPerKandangReport } from '@/types/api/report/hpp-per-kandang'; -import { formatDate, formatNumber } from '@/lib/helper'; +import { formatDate, formatNumber, formatCurrency } from '@/lib/helper'; Font.register({ family: 'Helvetica', @@ -148,88 +148,72 @@ interface HppPerKandangExportParams { }; } -interface WeightRangeGroup { - weight_min: number; - weight_max: number; - items: HppPerKandangReport['rows']; - totals: { - total_remaining_chicken_birds: number; - total_remaining_chicken_weight_kg: number; - average_weight_kg: number; - total_hpp_rp: number; - total_remaining_value_rp: number; - all_feed_suppliers: string[]; - all_doc_suppliers: string[]; - average_doc_price_rp: number; - }; -} - -const groupDataByWeightRange = ( - data: HppPerKandangReport['rows'], - summary: HppPerKandangReport['summary'] -): WeightRangeGroup[] => { - const groups: { - [key: string]: WeightRangeGroup; - } = {}; +const rekapitulasiData = (data: HppPerKandangReport['rows']) => { + const groups: { [key: string]: HppPerKandangReport['rows'] } = {}; data.forEach((item) => { const key = `${item.weight_range.weight_min}-${item.weight_range.weight_max}`; if (!groups[key]) { - groups[key] = { - weight_min: item.weight_range.weight_min, - weight_max: item.weight_range.weight_max, - items: [], - totals: { - total_remaining_chicken_birds: 0, - total_remaining_chicken_weight_kg: 0, - average_weight_kg: 0, - total_hpp_rp: 0, - total_remaining_value_rp: 0, - all_feed_suppliers: [], - all_doc_suppliers: [], - average_doc_price_rp: 0, - }, - }; + groups[key] = []; } - - groups[key].items.push(item); - - groups[key].totals.total_remaining_chicken_birds += - item.remaining_chicken_birds; - groups[key].totals.total_remaining_chicken_weight_kg += - item.remaining_chicken_weight_kg; - groups[key].totals.total_hpp_rp += item.hpp_rp; - groups[key].totals.total_remaining_value_rp += item.remaining_value_rp; - - item.feed_suppliers?.forEach((supplier) => { - const alias = supplier.alias || supplier.name; - if (!groups[key].totals.all_feed_suppliers.includes(alias)) { - groups[key].totals.all_feed_suppliers.push(alias); - } - }); - - item.doc_suppliers?.forEach((supplier) => { - const alias = supplier.alias || supplier.name; - if (!groups[key].totals.all_doc_suppliers.includes(alias)) { - groups[key].totals.all_doc_suppliers.push(alias); - } - }); + groups[key].push(item); }); - Object.values(groups).forEach((group) => { - group.totals.average_weight_kg = - group.totals.total_remaining_chicken_weight_kg / - group.totals.total_remaining_chicken_birds; - group.totals.average_doc_price_rp = - group.items.length > 0 - ? group.items.reduce( - (sum, item) => sum + item.average_doc_price_rp, - 0 - ) / group.items.length - : 0; - }); - - return Object.values(groups).sort((a, b) => a.weight_min - b.weight_min); + return Object.entries(groups) + .map(([key, items]) => ({ + weight_min: items[0].weight_range.weight_min, + weight_max: items[0].weight_range.weight_max, + items, + total_remaining_chicken_birds: items.reduce( + (sum, item) => sum + item.remaining_chicken_birds, + 0 + ), + total_remaining_chicken_weight_kg: items.reduce( + (sum, item) => sum + item.remaining_chicken_weight_kg, + 0 + ), + average_weight_kg: + items.reduce((sum, item) => sum + item.remaining_chicken_weight_kg, 0) / + items.reduce((sum, item) => sum + item.remaining_chicken_birds, 0), + total_hpp_rp: items.reduce((sum, item) => sum + item.hpp_rp, 0), + total_remaining_value_rp: items.reduce( + (sum, item) => sum + item.remaining_value_rp, + 0 + ), + total_egg_production_pieces: items.reduce( + (sum, item) => sum + (item.egg_production_pieces || 0), + 0 + ), + total_egg_production_kg: items.reduce( + (sum, item) => sum + (item.egg_production_kg || 0), + 0 + ), + total_egg_value_rp: items.reduce( + (sum, item) => sum + (item.egg_value_rp || 0), + 0 + ), + average_egg_hpp_rp_per_kg: + items.reduce((sum, item) => sum + (item.egg_hpp_rp_per_kg || 0), 0) / + items.length, + average_doc_price_rp: + items.reduce((sum, item) => sum + item.average_doc_price_rp, 0) / + items.length, + all_feed_suppliers: [ + ...new Set( + items.flatMap( + (item) => item.feed_suppliers?.map((s) => s.alias || s.name) || [] + ) + ), + ], + all_doc_suppliers: [ + ...new Set( + items.flatMap( + (item) => item.doc_suppliers?.map((s) => s.alias || s.name) || [] + ) + ), + ], + })) + .sort((a, b) => a.weight_min - b.weight_min); }; const getParameterText = (params: HppPerKandangExportParams['params']) => { @@ -246,27 +230,11 @@ const getParameterText = (params: HppPerKandangExportParams['params']) => { return paramsText; }; -const getTotalsForExport = (data: HppPerKandangReport['rows']) => { - const totalHppRp = data.reduce((sum, item) => sum + (item.hpp_rp || 0), 0); - const avgDocPrice = - data.length > 0 - ? data.reduce((sum, item) => sum + (item.average_doc_price_rp || 0), 0) / - data.length - : 0; - - return { - total_hpp_rp: totalHppRp, - total_average_doc_price_rp: avgDocPrice, - }; -}; - const createPDFDocument = ( data: HppPerKandangExportParams['data'], params: HppPerKandangExportParams['params'] ) => { - const summary = data.summary; - const exportTotals = getTotalsForExport(data.rows); - const groupedByWeightRange = groupDataByWeightRange(data.rows, summary); + const rekapitulasiByWeightRange = rekapitulasiData(data.rows); return ( @@ -334,12 +302,12 @@ const createPDFDocument = ( {/* Table Body - Rekapitulasi */} - {groupedByWeightRange.map((group, index) => ( + {rekapitulasiByWeightRange.map((group, index) => ( - {formatNumber(group.totals.total_remaining_chicken_birds)} + {formatNumber(group.total_remaining_chicken_birds)} - {formatNumber( - group.totals.total_remaining_chicken_weight_kg - )} + {formatNumber(group.total_remaining_chicken_weight_kg)} - {formatNumber(group.totals.average_weight_kg)} + {formatNumber(group.average_weight_kg)} - - {formatNumber( - group.items.reduce( - (sum, item) => sum + (item.egg_production_pieces || 0), - 0 - ) - )} - + {formatNumber(group.total_egg_production_pieces)} - - {formatNumber( - group.items.reduce( - (sum, item) => sum + (item.egg_production_kg || 0), - 0 - ) - )} - + {formatNumber(group.total_egg_production_kg)} - {group.totals.all_feed_suppliers.join(' | ')} + {group.all_feed_suppliers.join(' | ')} - {group.totals.all_doc_suppliers.join(' | ')} + {group.all_doc_suppliers.join(' | ')} - {formatNumber(group.totals.average_doc_price_rp)} + {formatCurrency(group.average_doc_price_rp)} - - {formatNumber( - group.items.reduce( - (sum, item) => sum + (item.egg_value_rp || 0), - 0 - ) - )} - + {formatCurrency(group.total_egg_value_rp)} - {formatNumber( - group.totals.total_remaining_chicken_birds > 0 - ? group.totals.total_hpp_rp / - group.totals.total_remaining_chicken_birds + {formatCurrency( + group.total_remaining_chicken_birds > 0 + ? group.total_hpp_rp / + group.total_remaining_chicken_birds : 0 )} - - {formatNumber( - group.items.reduce( - (sum, item) => sum + (item.egg_hpp_rp_per_kg || 0), - 0 - ) / group.items.length || 0 - )} - + {formatCurrency(group.average_egg_hpp_rp_per_kg)} - - {formatNumber(group.totals.total_remaining_value_rp)} - + {formatCurrency(group.total_remaining_value_rp)} ))} @@ -541,19 +477,19 @@ const createPDFDocument = ( - {formatNumber(item.average_doc_price_rp)} + {formatCurrency(item.average_doc_price_rp)} - {formatNumber(item.egg_value_rp)} + {formatCurrency(item.egg_value_rp)} - {formatNumber(item.hpp_rp)} + {formatCurrency(item.hpp_rp)} - {formatNumber(item.egg_hpp_rp_per_kg)} + {formatCurrency(item.egg_hpp_rp_per_kg)} - {formatNumber(item.remaining_value_rp)} + {formatCurrency(item.remaining_value_rp)} ))}