refactor(FE-357): Deduplicate totals and supplier aggregation

This commit is contained in:
rstubryan
2025-12-18 09:47:52 +07:00
parent 69b4ca455e
commit 3497a6346c
@@ -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<string>();
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<string>();
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<string>(),
all_doc_suppliers: new Set<string>(),
}
);
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<string>();
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<string>();
data.forEach((item) => {
item.doc_suppliers?.forEach((s) => {
suppliers.add(s.alias || s.name);
});
});
return Array.from(suppliers).join(' | ');
}, [data]);
const getTableColumns = (): ColumnDef<HppPerKandangReport['rows'][0]>[] => {
const tableColumns: ColumnDef<HppPerKandangReport['rows'][0]>[] = [
{