From a82860cb68c4e4a746f9f126e39dec72e60e42bc Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 23 Jan 2026 10:34:53 +0700 Subject: [PATCH] refactor(FE): Add initial balance row and normalize empty values --- .../export/CustomerPaymentExportPDF.tsx | 230 +++++++++++++----- .../export/CustomerPaymentExportXLSX.tsx | 52 +++- .../report/finance/tab/CustomerPaymentTab.tsx | 12 +- 3 files changed, 216 insertions(+), 78 deletions(-) diff --git a/src/components/pages/report/finance/export/CustomerPaymentExportPDF.tsx b/src/components/pages/report/finance/export/CustomerPaymentExportPDF.tsx index aa04b4f0..77e33866 100644 --- a/src/components/pages/report/finance/export/CustomerPaymentExportPDF.tsx +++ b/src/components/pages/report/finance/export/CustomerPaymentExportPDF.tsx @@ -320,110 +320,203 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => { Pengambilan - + Sales {/* Table Body */} - {customerReport.rows.map((item, index) => ( - + <> + {/* Initial Balance Row */} + - {index + 1} + - - {item.trans_date - ? formatDate(item.trans_date, 'DD MMM YY') - : '-'} - + - - {item.delivery_date - ? formatDate(item.delivery_date, 'DD MMM YY') - : '-'} - + - - {item.aging_day ? formatNumber(item.aging_day) : '-'} hari - + - {item.reference || '-'} + - - {Array.isArray(item.vehicle_numbers) - ? item.vehicle_numbers.join(', ') - : item.vehicle_numbers || '-'} - + - {formatNumber(item.qty)} + - {formatNumber(item.weight)} + - {formatNumber(item.average_weight)} + - {formatCurrency(item.unit_price)} + - {formatCurrency(item.final_price)} + - {formatCurrency(item.total_price)} + - {formatCurrency(item.payment_amount)} + - - - {formatCurrency(item.accounts_receivable)} + + + {formatCurrency(customerReport.initial_balance || 0)} - {item.status ? ( - - - {item.status === 'LUNAS' ? 'Lunas' : 'Belum Lunas'} - - - ) : ( - - - )} + - - {Array.isArray(item.pickup_info) - ? item.pickup_info.join(', ') - : item.pickup_info || '-'} - + - - {item.sales_person || '-'} + + - ))} + + {/* Data Rows */} + {customerReport.rows.map((item, index) => ( + + + {index + 1} + + + + {item.trans_date + ? formatDate(item.trans_date, 'DD MMM YY') + : '-'} + + + + + {item.delivery_date + ? formatDate(item.delivery_date, 'DD MMM YY') + : '-'} + + + + + {item.aging_day != null + ? `${formatNumber(item.aging_day)} hari` + : '-'} + + + + {item.reference || '-'} + + + + {Array.isArray(item.vehicle_numbers) + ? item.vehicle_numbers.length > 0 + ? item.vehicle_numbers.join(', ') + : '-' + : '-'} + + + + {formatNumber(item.qty)} + + + {formatNumber(item.weight)} + + + {formatNumber(item.average_weight)} + + + {formatCurrency(item.unit_price)} + + + {formatCurrency(item.final_price)} + + + {formatCurrency(item.total_price)} + + + {formatCurrency(item.payment_amount)} + + + + {formatCurrency(item.accounts_receivable)} + + + + {item.status ? ( + + + {item.status === 'LUNAS' ? 'Lunas' : 'Belum Lunas'} + + + ) : ( + - + )} + + + + {Array.isArray(item.pickup_info) + ? item.pickup_info.length > 0 + ? item.pickup_info.join(', ') + : '-' + : '-'} + + + + {item.sales_person || '-'} + + + ))} + {/* Summary Row */} {customerReport.summary && ( @@ -488,7 +581,12 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => { - + diff --git a/src/components/pages/report/finance/export/CustomerPaymentExportXLSX.tsx b/src/components/pages/report/finance/export/CustomerPaymentExportXLSX.tsx index fec4dc6b..3238d46e 100644 --- a/src/components/pages/report/finance/export/CustomerPaymentExportXLSX.tsx +++ b/src/components/pages/report/finance/export/CustomerPaymentExportXLSX.tsx @@ -44,20 +44,50 @@ export const generateCustomerPaymentExcel = async ( const worksheet = workbook.addWorksheet(customerName.substring(0, 31)); worksheet.columns = columns; + const initialRow = worksheet.addRow({ + no: '', + transDate: '', + deliveryDate: '', + aging: '', + reference: '', + vehicleNumbers: '', + qty: '', + weight: '', + avgWeight: '', + unitPrice: '', + finalPrice: '', + totalPrice: '', + paymentAmount: '', + accountsReceivable: formatCurrency(customerReport.initial_balance || 0), + status: '', + pickupInfo: '', + salesPerson: '', + }); + + const initialBalanceCell = initialRow.getCell('accountsReceivable'); + if ( + typeof customerReport.initial_balance === 'number' && + customerReport.initial_balance < 0 + ) { + initialBalanceCell.font = { color: { argb: 'FFFF0000' } }; + } + customerData.forEach((item, index) => { const row = worksheet.addRow({ no: index + 1, transDate: item.trans_date ? formatDate(item.trans_date, 'DD MMM YYYY') - : '', + : '-', deliveryDate: item.delivery_date ? formatDate(item.delivery_date, 'DD MMM YYYY') - : '', - aging: formatNumber(item.aging_day || 0), - reference: item.reference || '', + : '-', + aging: item.aging_day != null ? formatNumber(item.aging_day) : '-', + reference: item.reference || '-', vehicleNumbers: Array.isArray(item.vehicle_numbers) - ? item.vehicle_numbers.join(', ') - : '', + ? item.vehicle_numbers.length > 0 + ? item.vehicle_numbers.join(', ') + : '-' + : '-', qty: formatNumber(item.qty || 0), weight: formatNumber(item.weight || 0), avgWeight: formatNumber(item.average_weight || 0), @@ -66,11 +96,13 @@ export const generateCustomerPaymentExcel = async ( totalPrice: formatCurrency(item.total_price || 0), paymentAmount: formatCurrency(item.payment_amount || 0), accountsReceivable: formatCurrency(item.accounts_receivable || 0), - status: item.status || '', + status: item.status || '-', pickupInfo: Array.isArray(item.pickup_info) - ? item.pickup_info.join(', ') - : '', - salesPerson: item.sales_person || '', + ? item.pickup_info.length > 0 + ? item.pickup_info.join(', ') + : '-' + : '-', + salesPerson: item.sales_person || '-', }); const accountsReceivableCell = row.getCell('accountsReceivable'); diff --git a/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx b/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx index c6bad2a4..7b94de7d 100644 --- a/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx +++ b/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx @@ -364,7 +364,11 @@ const CustomerPaymentTab = () => { enableSorting: false, cell: (props) => { const value = props.row.original.vehicle_numbers; - return Array.isArray(value) ? value.join(', ') : value || '-'; + return Array.isArray(value) + ? value.length > 0 + ? value.join(', ') + : '-' + : '-'; }, }, { @@ -528,7 +532,11 @@ const CustomerPaymentTab = () => { enableSorting: false, cell: (props) => { const value = props.row.original.pickup_info; - return Array.isArray(value) ? value.join(', ') : value || '-'; + return Array.isArray(value) + ? value.length > 0 + ? value.join(', ') + : '-' + : '-'; }, }, {