From 3497a6346ce6f65dd6da49bcce8cdd42e0b322cb Mon Sep 17 00:00:00 2001 From: rstubryan Date: Thu, 18 Dec 2025 09:47:52 +0700 Subject: [PATCH] refactor(FE-357): Deduplicate totals and supplier aggregation --- .../report/sale/tab/HppPerKandangTab.tsx | 137 ++++++------------ 1 file changed, 46 insertions(+), 91 deletions(-) diff --git a/src/components/pages/report/sale/tab/HppPerKandangTab.tsx b/src/components/pages/report/sale/tab/HppPerKandangTab.tsx index 14945264..3b5cfa28 100644 --- a/src/components/pages/report/sale/tab/HppPerKandangTab.tsx +++ b/src/components/pages/report/sale/tab/HppPerKandangTab.tsx @@ -262,6 +262,43 @@ const HppPerKandangTab = () => { return isResponseSuccess(response) ? response.data : null; }, [tableFilterState]); + // ===== TABLE COLUMNS DEFINITION ===== + const totals: Totals = useMemo(() => { + return { + total_hpp_rp: + data.length > 0 + ? data.reduce((acc, item) => acc + (item.hpp_rp || 0), 0) + : 0, + total_average_doc_price_rp: + data.length > 0 + ? data.reduce( + (acc, item) => acc + (item.average_doc_price_rp || 0), + 0 + ) / data.length + : 0, + }; + }, [summary]); + + const allFeedSuppliers = useMemo(() => { + const suppliers = new Set(); + data.forEach((item) => { + item.feed_suppliers?.forEach((s) => { + suppliers.add(s.alias || s.name); + }); + }); + return Array.from(suppliers).join(' | '); + }, [data]); + + const allDocSuppliers = useMemo(() => { + const suppliers = new Set(); + data.forEach((item) => { + item.doc_suppliers?.forEach((s) => { + suppliers.add(s.alias || s.name); + }); + }); + return Array.from(suppliers).join(' | '); + }, [data]); + // ===== EXPORT HANDLERS ===== const handleExportExcel = useCallback(async () => { setIsExcelExportLoading(true); @@ -280,52 +317,7 @@ const HppPerKandangTab = () => { const allExportData = allDataForExport.rows as HppPerKandangReport['rows']; - const totals = allExportData.reduce( - (acc, item) => ({ - total_remaining_chicken_birds: - acc.total_remaining_chicken_birds + - (item.remaining_chicken_birds || 0), - total_remaining_chicken_weight_kg: - acc.total_remaining_chicken_weight_kg + - (item.remaining_chicken_weight_kg || 0), - total_remaining_value_rp: - acc.total_remaining_value_rp + (item.remaining_value_rp || 0), - total_hpp_rp: acc.total_hpp_rp + (item.hpp_rp || 0), - average_doc_price_rp: - acc.average_doc_price_rp + (item.average_doc_price_rp || 0), - all_feed_suppliers: new Set([ - ...acc.all_feed_suppliers, - ...(item.feed_suppliers?.map((s) => s.alias || s.name) || []), - ]), - all_doc_suppliers: new Set([ - ...acc.all_doc_suppliers, - ...(item.doc_suppliers?.map((s) => s.alias || s.name) || []), - ]), - }), - { - total_remaining_chicken_birds: 0, - total_remaining_chicken_weight_kg: 0, - total_remaining_value_rp: 0, - total_hpp_rp: 0, - average_doc_price_rp: 0, - all_feed_suppliers: new Set(), - all_doc_suppliers: new Set(), - } - ); - - const avgWeight = - totals.total_remaining_chicken_birds > 0 - ? totals.total_remaining_chicken_weight_kg / - totals.total_remaining_chicken_birds - : 0; - const avgDocPrice = - allExportData.length > 0 - ? totals.average_doc_price_rp / allExportData.length - : 0; - const avgHpp = - totals.total_remaining_chicken_birds > 0 - ? totals.total_hpp_rp / totals.total_remaining_chicken_birds - : 0; + const summary = allDataForExport.summary; const excelData: { [key: string]: string | number }[] = allExportData.map( (item, index) => ({ @@ -352,14 +344,14 @@ const HppPerKandangTab = () => { No: 'TOTAL', Kandang: 'ALL', 'Rentang Bobot': '-', - 'Sisa Ayam (Ekor)': totals.total_remaining_chicken_birds, - 'Sisa Ayam (KG)': totals.total_remaining_chicken_weight_kg, - 'Rata-Rata Bobot (KG)': avgWeight, - 'Feed (Supplier)': Array.from(totals.all_feed_suppliers).join(' | '), - 'DOC (Supplier)': Array.from(totals.all_doc_suppliers).join(' | '), - 'Rata-Rata Harga DOC (RP)': avgDocPrice, - 'HPP (RP)': avgHpp, - 'Nilai Nominal Sisa Ayam (RP)': totals.total_remaining_value_rp, + 'Sisa Ayam (Ekor)': summary?.total_remaining_chicken_birds || 0, + 'Sisa Ayam (KG)': summary?.total_remaining_chicken_weight_kg || 0, + 'Rata-Rata Bobot (KG)': summary?.average_weight_kg || 0, + 'Feed (Supplier)': allFeedSuppliers, + 'DOC (Supplier)': allDocSuppliers, + 'Rata-Rata Harga DOC (RP)': totals?.total_average_doc_price_rp || 0, + 'HPP (RP)': totals?.total_hpp_rp || 0, + 'Nilai Nominal Sisa Ayam (RP)': summary?.total_remaining_value_rp || 0, }); const worksheet = XLSX.utils.json_to_sheet(excelData); @@ -474,43 +466,6 @@ const HppPerKandangTab = () => { kandangOptions, ]); - // ===== TABLE COLUMNS DEFINITION ===== - const totals: Totals = useMemo(() => { - return { - total_hpp_rp: - data.length > 0 - ? data.reduce((acc, item) => acc + (item.hpp_rp || 0), 0) - : 0, - total_average_doc_price_rp: - data.length > 0 - ? data.reduce( - (acc, item) => acc + (item.average_doc_price_rp || 0), - 0 - ) / data.length - : 0, - }; - }, [summary]); - - const allFeedSuppliers = useMemo(() => { - const suppliers = new Set(); - data.forEach((item) => { - item.feed_suppliers?.forEach((s) => { - suppliers.add(s.alias || s.name); - }); - }); - return Array.from(suppliers).join(' | '); - }, [data]); - - const allDocSuppliers = useMemo(() => { - const suppliers = new Set(); - data.forEach((item) => { - item.doc_suppliers?.forEach((s) => { - suppliers.add(s.alias || s.name); - }); - }); - return Array.from(suppliers).join(' | '); - }, [data]); - const getTableColumns = (): ColumnDef[] => { const tableColumns: ColumnDef[] = [ {