mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE): Add initial balance row and normalize empty values
This commit is contained in:
@@ -320,110 +320,203 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => {
|
|||||||
<View style={[pdfStyles.tableCellHeader, { flex: 1 }]}>
|
<View style={[pdfStyles.tableCellHeader, { flex: 1 }]}>
|
||||||
<Text>Pengambilan</Text>
|
<Text>Pengambilan</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellHeader, { flex: 1.5 }]}>
|
<View
|
||||||
|
style={[
|
||||||
|
pdfStyles.tableCellHeader,
|
||||||
|
{ flex: 1.5, borderRightWidth: 0 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<Text>Sales</Text>
|
<Text>Sales</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Table Body */}
|
{/* Table Body */}
|
||||||
{customerReport.rows.map((item, index) => (
|
<>
|
||||||
<View
|
{/* Initial Balance Row */}
|
||||||
key={index}
|
<View style={[pdfStyles.tableRow, pdfStyles.tableBorderBottom]}>
|
||||||
style={[
|
|
||||||
pdfStyles.tableRow,
|
|
||||||
index < customerReport.rows.length - 1
|
|
||||||
? pdfStyles.tableBorderBottom
|
|
||||||
: {},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<View style={[pdfStyles.tableCellNo, { flex: 0.5 }]}>
|
<View style={[pdfStyles.tableCellNo, { flex: 0.5 }]}>
|
||||||
<Text>{index + 1}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
||||||
<Text>
|
<Text></Text>
|
||||||
{item.trans_date
|
|
||||||
? formatDate(item.trans_date, 'DD MMM YY')
|
|
||||||
: '-'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
||||||
<Text>
|
<Text></Text>
|
||||||
{item.delivery_date
|
|
||||||
? formatDate(item.delivery_date, 'DD MMM YY')
|
|
||||||
: '-'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellCenter, { flex: 0.8 }]}>
|
<View style={[pdfStyles.tableCellCenter, { flex: 0.8 }]}>
|
||||||
<Text>
|
<Text></Text>
|
||||||
{item.aging_day ? formatNumber(item.aging_day) : '-'} hari
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
||||||
<Text>{item.reference || '-'}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCell, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCell, { flex: 1.2 }]}>
|
||||||
<Text>
|
<Text></Text>
|
||||||
{Array.isArray(item.vehicle_numbers)
|
|
||||||
? item.vehicle_numbers.join(', ')
|
|
||||||
: item.vehicle_numbers || '-'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
||||||
<Text>{formatNumber(item.qty)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 1 }]}>
|
||||||
<Text>{formatNumber(item.weight)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
||||||
<Text>{formatNumber(item.average_weight)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
<Text>{formatCurrency(item.unit_price)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
<Text>{formatCurrency(item.final_price)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
<Text>{formatCurrency(item.total_price)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
<Text>{formatCurrency(item.payment_amount)}</Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
<View
|
||||||
<Text style={pdfStyles.textError}>
|
style={[
|
||||||
{formatCurrency(item.accounts_receivable)}
|
pdfStyles.tableCellRight,
|
||||||
|
{
|
||||||
|
flex: 1.2,
|
||||||
|
color:
|
||||||
|
typeof customerReport.initial_balance === 'number' &&
|
||||||
|
customerReport.initial_balance < 0
|
||||||
|
? 'red'
|
||||||
|
: 'black',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
{formatCurrency(customerReport.initial_balance || 0)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
||||||
{item.status ? (
|
<Text></Text>
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
pdfStyles.badge,
|
|
||||||
item.status === 'LUNAS'
|
|
||||||
? pdfStyles.badgeLunas
|
|
||||||
: pdfStyles.badgeBelumLunas,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Text>
|
|
||||||
{item.status === 'LUNAS' ? 'Lunas' : 'Belum Lunas'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
) : (
|
|
||||||
<Text>-</Text>
|
|
||||||
)}
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
||||||
<Text>
|
<Text></Text>
|
||||||
{Array.isArray(item.pickup_info)
|
|
||||||
? item.pickup_info.join(', ')
|
|
||||||
: item.pickup_info || '-'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
<View
|
||||||
<Text>{item.sales_person || '-'}</Text>
|
style={[
|
||||||
|
pdfStyles.tableCell,
|
||||||
|
{ flex: 1.5, borderRightWidth: 0 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
))}
|
|
||||||
|
{/* Data Rows */}
|
||||||
|
{customerReport.rows.map((item, index) => (
|
||||||
|
<View
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
pdfStyles.tableRow,
|
||||||
|
index < customerReport.rows.length - 1
|
||||||
|
? pdfStyles.tableBorderBottom
|
||||||
|
: {},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<View style={[pdfStyles.tableCellNo, { flex: 0.5 }]}>
|
||||||
|
<Text>{index + 1}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
||||||
|
<Text>
|
||||||
|
{item.trans_date
|
||||||
|
? formatDate(item.trans_date, 'DD MMM YY')
|
||||||
|
: '-'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellCenter, { flex: 1.2 }]}>
|
||||||
|
<Text>
|
||||||
|
{item.delivery_date
|
||||||
|
? formatDate(item.delivery_date, 'DD MMM YY')
|
||||||
|
: '-'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellCenter, { flex: 0.8 }]}>
|
||||||
|
<Text>
|
||||||
|
{item.aging_day != null
|
||||||
|
? `${formatNumber(item.aging_day)} hari`
|
||||||
|
: '-'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
||||||
|
<Text>{item.reference || '-'}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCell, { flex: 1.2 }]}>
|
||||||
|
<Text>
|
||||||
|
{Array.isArray(item.vehicle_numbers)
|
||||||
|
? item.vehicle_numbers.length > 0
|
||||||
|
? item.vehicle_numbers.join(', ')
|
||||||
|
: '-'
|
||||||
|
: '-'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
||||||
|
<Text>{formatNumber(item.qty)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1 }]}>
|
||||||
|
<Text>{formatNumber(item.weight)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 0.8 }]}>
|
||||||
|
<Text>{formatNumber(item.average_weight)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
|
<Text>{formatCurrency(item.unit_price)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
|
<Text>{formatCurrency(item.final_price)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
|
<Text>{formatCurrency(item.total_price)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
|
<Text>{formatCurrency(item.payment_amount)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { flex: 1.2 }]}>
|
||||||
|
<Text style={pdfStyles.textError}>
|
||||||
|
{formatCurrency(item.accounts_receivable)}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCell, { flex: 1.5 }]}>
|
||||||
|
{item.status ? (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
pdfStyles.badge,
|
||||||
|
item.status === 'LUNAS'
|
||||||
|
? pdfStyles.badgeLunas
|
||||||
|
: pdfStyles.badgeBelumLunas,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
{item.status === 'LUNAS' ? 'Lunas' : 'Belum Lunas'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<Text>-</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
||||||
|
<Text>
|
||||||
|
{Array.isArray(item.pickup_info)
|
||||||
|
? item.pickup_info.length > 0
|
||||||
|
? item.pickup_info.join(', ')
|
||||||
|
: '-'
|
||||||
|
: '-'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
pdfStyles.tableCell,
|
||||||
|
{ flex: 1.5, borderRightWidth: 0 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text>{item.sales_person || '-'}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
|
||||||
{/* Summary Row */}
|
{/* Summary Row */}
|
||||||
{customerReport.summary && (
|
{customerReport.summary && (
|
||||||
@@ -488,7 +581,12 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => {
|
|||||||
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
||||||
<Text></Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[pdfStyles.tableCellLast, { flex: 1.5 }]}>
|
<View
|
||||||
|
style={[
|
||||||
|
pdfStyles.tableCell,
|
||||||
|
{ flex: 1.5, borderRightWidth: 0 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<Text></Text>
|
<Text></Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -44,20 +44,50 @@ export const generateCustomerPaymentExcel = async (
|
|||||||
const worksheet = workbook.addWorksheet(customerName.substring(0, 31));
|
const worksheet = workbook.addWorksheet(customerName.substring(0, 31));
|
||||||
worksheet.columns = columns;
|
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) => {
|
customerData.forEach((item, index) => {
|
||||||
const row = worksheet.addRow({
|
const row = worksheet.addRow({
|
||||||
no: index + 1,
|
no: index + 1,
|
||||||
transDate: item.trans_date
|
transDate: item.trans_date
|
||||||
? formatDate(item.trans_date, 'DD MMM YYYY')
|
? formatDate(item.trans_date, 'DD MMM YYYY')
|
||||||
: '',
|
: '-',
|
||||||
deliveryDate: item.delivery_date
|
deliveryDate: item.delivery_date
|
||||||
? formatDate(item.delivery_date, 'DD MMM YYYY')
|
? formatDate(item.delivery_date, 'DD MMM YYYY')
|
||||||
: '',
|
: '-',
|
||||||
aging: formatNumber(item.aging_day || 0),
|
aging: item.aging_day != null ? formatNumber(item.aging_day) : '-',
|
||||||
reference: item.reference || '',
|
reference: item.reference || '-',
|
||||||
vehicleNumbers: Array.isArray(item.vehicle_numbers)
|
vehicleNumbers: Array.isArray(item.vehicle_numbers)
|
||||||
? item.vehicle_numbers.join(', ')
|
? item.vehicle_numbers.length > 0
|
||||||
: '',
|
? item.vehicle_numbers.join(', ')
|
||||||
|
: '-'
|
||||||
|
: '-',
|
||||||
qty: formatNumber(item.qty || 0),
|
qty: formatNumber(item.qty || 0),
|
||||||
weight: formatNumber(item.weight || 0),
|
weight: formatNumber(item.weight || 0),
|
||||||
avgWeight: formatNumber(item.average_weight || 0),
|
avgWeight: formatNumber(item.average_weight || 0),
|
||||||
@@ -66,11 +96,13 @@ export const generateCustomerPaymentExcel = async (
|
|||||||
totalPrice: formatCurrency(item.total_price || 0),
|
totalPrice: formatCurrency(item.total_price || 0),
|
||||||
paymentAmount: formatCurrency(item.payment_amount || 0),
|
paymentAmount: formatCurrency(item.payment_amount || 0),
|
||||||
accountsReceivable: formatCurrency(item.accounts_receivable || 0),
|
accountsReceivable: formatCurrency(item.accounts_receivable || 0),
|
||||||
status: item.status || '',
|
status: item.status || '-',
|
||||||
pickupInfo: Array.isArray(item.pickup_info)
|
pickupInfo: Array.isArray(item.pickup_info)
|
||||||
? item.pickup_info.join(', ')
|
? item.pickup_info.length > 0
|
||||||
: '',
|
? item.pickup_info.join(', ')
|
||||||
salesPerson: item.sales_person || '',
|
: '-'
|
||||||
|
: '-',
|
||||||
|
salesPerson: item.sales_person || '-',
|
||||||
});
|
});
|
||||||
|
|
||||||
const accountsReceivableCell = row.getCell('accountsReceivable');
|
const accountsReceivableCell = row.getCell('accountsReceivable');
|
||||||
|
|||||||
@@ -364,7 +364,11 @@ const CustomerPaymentTab = () => {
|
|||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
cell: (props) => {
|
cell: (props) => {
|
||||||
const value = props.row.original.vehicle_numbers;
|
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,
|
enableSorting: false,
|
||||||
cell: (props) => {
|
cell: (props) => {
|
||||||
const value = props.row.original.pickup_info;
|
const value = props.row.original.pickup_info;
|
||||||
return Array.isArray(value) ? value.join(', ') : value || '-';
|
return Array.isArray(value)
|
||||||
|
? value.length > 0
|
||||||
|
? value.join(', ')
|
||||||
|
: '-'
|
||||||
|
: '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user