refactor(FE-363): Use snake_case for totals in purchases tab

This commit is contained in:
rstubryan
2025-12-16 15:19:47 +07:00
parent d17c11e2f2
commit c04cd29ac7
@@ -26,14 +26,21 @@ import Menu from '@/components/menu/Menu';
import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExport'; import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExport';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { Supplier } from '@/types/api/master-data/supplier';
interface Totals { interface Totals {
totalQty: number; total_qty: number;
totalPrice: number; total_price: number;
totalPurchaseAmount: number; total_purchase_amount: number;
totalTransport: number; total_transport: number;
totalValueTransport: number; total_value_transport: number;
totalJumlah: number; total_jumlah: number;
}
interface GroupedSupplierData {
id: number;
supplier: Supplier;
items: LogisticPurchasePerSupplierReport['rows'];
} }
const PurchasesPerSupplierTab = () => { const PurchasesPerSupplierTab = () => {
@@ -314,6 +321,7 @@ const PurchasesPerSupplierTab = () => {
[allDataForExport] [allDataForExport]
); );
// ===== EXPORT HANDLERS =====
const handleExportExcel = useCallback(() => { const handleExportExcel = useCallback(() => {
if (allExportData.length === 0) { if (allExportData.length === 0) {
toast.error('Tidak ada data untuk diekspor.'); toast.error('Tidak ada data untuk diekspor.');
@@ -352,23 +360,23 @@ const PurchasesPerSupplierTab = () => {
([supplierName, supplierData]) => { ([supplierName, supplierData]) => {
const totals = supplierData.reduce( const totals = supplierData.reduce(
(acc, item) => ({ (acc, item) => ({
totalQty: acc.totalQty + (item.qty || 0), total_qty: acc.total_qty + (item.qty || 0),
totalPrice: acc.totalPrice + (item.unit_price || 0), total_price: acc.total_price + (item.unit_price || 0),
totalPurchaseAmount: total_purchase_amount:
acc.totalPurchaseAmount + (item.purchase_value || 0), acc.total_purchase_amount + (item.purchase_value || 0),
totalTransport: total_transport:
acc.totalTransport + (item.transport_unit_price || 0), acc.total_transport + (item.transport_unit_price || 0),
totalValueTransport: total_value_transport:
acc.totalValueTransport + (item.transport_value || 0), acc.total_value_transport + (item.transport_value || 0),
totalJumlah: acc.totalJumlah + (item.total_amount || 0), total_jumlah: acc.total_jumlah + (item.total_amount || 0),
}), }),
{ {
totalQty: 0, total_qty: 0,
totalPrice: 0, total_price: 0,
totalPurchaseAmount: 0, total_purchase_amount: 0,
totalTransport: 0, total_transport: 0,
totalValueTransport: 0, total_value_transport: 0,
totalJumlah: 0, total_jumlah: 0,
} }
); );
@@ -401,12 +409,12 @@ const PurchasesPerSupplierTab = () => {
'No. Referensi': '', 'No. Referensi': '',
'Nama Produk': '', 'Nama Produk': '',
Tujuan: '', Tujuan: '',
QTY: totals.totalQty, QTY: totals.total_qty,
'Harga Beli (Rp)': totals.totalPrice, 'Harga Beli (Rp)': totals.total_price,
'Value Harga Beli (Rp)': totals.totalPurchaseAmount, 'Value Harga Beli (Rp)': totals.total_purchase_amount,
'Transport (Rp)': totals.totalTransport, 'Transport (Rp)': totals.total_transport,
'Value Transport (Rp)': totals.totalValueTransport, 'Value Transport (Rp)': totals.total_value_transport,
'Jumlah (Rp)': totals.totalJumlah, 'Jumlah (Rp)': totals.total_jumlah,
Ekspedisi: '', Ekspedisi: '',
'Surat Jalan': '', 'Surat Jalan': '',
}); });
@@ -514,15 +522,13 @@ const PurchasesPerSupplierTab = () => {
} }
}; };
interface GroupedSupplierData { const handlePrevPage = () => {
id: number; if (currentPage > 1) {
supplier: { setCurrentPage(currentPage - 1);
id: number; }
name: string; };
};
items: LogisticPurchasePerSupplierReport['rows'];
}
// ===== TABLE COLUMNS DEFINITION =====
const groupedData = useMemo(() => { const groupedData = useMemo(() => {
const groups: { [key: number]: GroupedSupplierData } = {}; const groups: { [key: number]: GroupedSupplierData } = {};
@@ -542,13 +548,6 @@ const PurchasesPerSupplierTab = () => {
return Object.values(groups); return Object.values(groups);
}, [data]); }, [data]);
const handlePrevPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
const getTableColumns = ( const getTableColumns = (
totals: Totals totals: Totals
): ColumnDef<LogisticPurchasePerSupplierReport['rows'][0]>[] => { ): ColumnDef<LogisticPurchasePerSupplierReport['rows'][0]>[] => {
@@ -617,7 +616,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatNumber(totals.totalQty)} {formatNumber(totals.total_qty)}
</div> </div>
), ),
}, },
@@ -631,7 +630,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalPrice)} {formatCurrency(totals.total_price)}
</div> </div>
), ),
}, },
@@ -645,7 +644,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalPurchaseAmount)} {formatCurrency(totals.total_purchase_amount)}
</div> </div>
), ),
}, },
@@ -659,7 +658,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalTransport)} {formatCurrency(totals.total_transport)}
</div> </div>
), ),
}, },
@@ -673,7 +672,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalValueTransport)} {formatCurrency(totals.total_value_transport)}
</div> </div>
), ),
}, },
@@ -687,7 +686,7 @@ const PurchasesPerSupplierTab = () => {
}, },
footer: () => ( footer: () => (
<div className='text-right font-semibold text-gray-900'> <div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalJumlah)} {formatCurrency(totals.total_jumlah)}
</div> </div>
), ),
}, },
@@ -853,37 +852,37 @@ const PurchasesPerSupplierTab = () => {
</div> </div>
) : ( ) : (
groupedData.map((supplier) => { groupedData.map((supplier) => {
const totalQty = supplier.items.reduce( const total_qty = supplier.items.reduce(
(sum, item) => sum + (item.qty || 0), (sum, item) => sum + (item.qty || 0),
0 0
); );
const totalPrice = supplier.items.reduce( const total_price = supplier.items.reduce(
(sum, item) => sum + (item.purchase_value || 0), (sum, item) => sum + (item.purchase_value || 0),
0 0
); );
const totalTransport = supplier.items.reduce( const total_transport = supplier.items.reduce(
(sum, item) => sum + (item.transport_value || 0), (sum, item) => sum + (item.transport_value || 0),
0 0
); );
const totalValueTransport = supplier.items.reduce( const total_value_transport = supplier.items.reduce(
(sum, item) => sum + (item.transport_value || 0), (sum, item) => sum + (item.transport_value || 0),
0 0
); );
const totalJumlah = supplier.items.reduce( const total_jumlah = supplier.items.reduce(
(sum, item) => sum + (item.total_amount || 0), (sum, item) => sum + (item.total_amount || 0),
0 0
); );
const totals = { const totals = {
totalQty, total_qty,
totalPrice, total_price,
totalPurchaseAmount: totalPrice, total_purchase_amount: total_price,
totalTransport, total_transport,
totalValueTransport, total_value_transport,
totalJumlah, total_jumlah,
}; };
const totalPurchase = totals.totalJumlah; const totalPurchase = totals.total_jumlah;
const tableColumns = getTableColumns(totals); const tableColumns = getTableColumns(totals);
return ( return (