mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE): Use ExcelJS for customer payment export
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
import ExcelJS from 'exceljs';
|
||||
import { formatDate, formatCurrency, formatNumber } from '@/lib/helper';
|
||||
import { CustomerPaymentReport } from '@/types/api/report/customer-payment';
|
||||
|
||||
@@ -8,104 +8,113 @@ interface CustomerPaymentExportExcelParams {
|
||||
data: CustomerPaymentReport[];
|
||||
}
|
||||
|
||||
export const generateCustomerPaymentExcel = (
|
||||
export const generateCustomerPaymentExcel = async (
|
||||
params: CustomerPaymentExportExcelParams
|
||||
): void => {
|
||||
): Promise<void> => {
|
||||
if (!params.data || params.data.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workbook = XLSX.utils.book_new();
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
|
||||
params.data.forEach((customerReport) => {
|
||||
const columns = [
|
||||
{ header: 'No', key: 'no', width: 5 },
|
||||
{ header: 'Tanggal DO/Bayar', key: 'transDate', width: 15 },
|
||||
{ header: 'Tanggal Realisasi', key: 'deliveryDate', width: 15 },
|
||||
{ header: 'Aging', key: 'aging', width: 8 },
|
||||
{ header: 'Referensi', key: 'reference', width: 12 },
|
||||
{ header: 'Nomor Polisi', key: 'vehicleNumbers', width: 15 },
|
||||
{ header: 'Ekor/Qty', key: 'qty', width: 10 },
|
||||
{ header: 'Berat (Kg)', key: 'weight', width: 12 },
|
||||
{ header: 'AVG', key: 'avgWeight', width: 10 },
|
||||
{ header: 'Harga/Unit', key: 'unitPrice', width: 15 },
|
||||
{ header: 'Harga Akhir', key: 'finalPrice', width: 15 },
|
||||
{ header: 'Total', key: 'totalPrice', width: 15 },
|
||||
{ header: 'Pembayaran', key: 'paymentAmount', width: 15 },
|
||||
{ header: 'Saldo Piutang', key: 'accountsReceivable', width: 15 },
|
||||
{ header: 'Keterangan', key: 'status', width: 20 },
|
||||
{ header: 'Pengambilan', key: 'pickupInfo', width: 15 },
|
||||
{ header: 'Sales/Marketing', key: 'salesPerson', width: 20 },
|
||||
];
|
||||
|
||||
for (const customerReport of params.data) {
|
||||
const customerData = customerReport.rows;
|
||||
const customerName = customerReport.customer.name || 'Unknown Customer';
|
||||
|
||||
const excelData: { [key: string]: string | number }[] = customerData.map(
|
||||
(item, index) => ({
|
||||
No: index + 1,
|
||||
'Tanggal DO/Bayar': item.trans_date
|
||||
const worksheet = workbook.addWorksheet(customerName.substring(0, 31));
|
||||
worksheet.columns = columns;
|
||||
|
||||
customerData.forEach((item, index) => {
|
||||
worksheet.addRow({
|
||||
no: index + 1,
|
||||
transDate: item.trans_date
|
||||
? formatDate(item.trans_date, 'DD MMM YYYY')
|
||||
: '',
|
||||
'Tanggal Realisasi': item.delivery_date
|
||||
deliveryDate: item.delivery_date
|
||||
? formatDate(item.delivery_date, 'DD MMM YYYY')
|
||||
: '',
|
||||
Aging: formatNumber(item.aging_day || 0),
|
||||
Referensi: item.reference || '',
|
||||
'Nomor Polisi': Array.isArray(item.vehicle_numbers)
|
||||
aging: formatNumber(item.aging_day || 0),
|
||||
reference: item.reference || '',
|
||||
vehicleNumbers: Array.isArray(item.vehicle_numbers)
|
||||
? item.vehicle_numbers.join(', ')
|
||||
: '',
|
||||
'Ekor/Qty': formatNumber(item.qty || 0),
|
||||
'Berat (Kg)': formatNumber(item.weight || 0),
|
||||
AVG: formatNumber(item.average_weight || 0),
|
||||
'Harga/Unit': formatCurrency(item.unit_price || 0),
|
||||
'Harga Akhir': formatCurrency(item.final_price || 0),
|
||||
Total: formatCurrency(item.total_price || 0),
|
||||
Pembayaran: formatCurrency(item.payment_amount || 0),
|
||||
'Saldo Piutang': formatCurrency(item.accounts_receivable || 0),
|
||||
Keterangan: item.status || '',
|
||||
Pengambilan: Array.isArray(item.pickup_info)
|
||||
qty: formatNumber(item.qty || 0),
|
||||
weight: formatNumber(item.weight || 0),
|
||||
avgWeight: formatNumber(item.average_weight || 0),
|
||||
unitPrice: formatCurrency(item.unit_price || 0),
|
||||
finalPrice: formatCurrency(item.final_price || 0),
|
||||
totalPrice: formatCurrency(item.total_price || 0),
|
||||
paymentAmount: formatCurrency(item.payment_amount || 0),
|
||||
accountsReceivable: formatCurrency(item.accounts_receivable || 0),
|
||||
status: item.status || '',
|
||||
pickupInfo: Array.isArray(item.pickup_info)
|
||||
? item.pickup_info.join(', ')
|
||||
: '',
|
||||
'Sales/Marketing': item.sales_person || '',
|
||||
})
|
||||
);
|
||||
salesPerson: item.sales_person || '',
|
||||
});
|
||||
});
|
||||
|
||||
if (customerReport.summary) {
|
||||
excelData.push({
|
||||
No: 'Total',
|
||||
'Tanggal DO/Bayar': '',
|
||||
'Tanggal Realisasi': '',
|
||||
Aging: '',
|
||||
Referensi: '',
|
||||
'Nomor Polisi': '',
|
||||
'Ekor/Qty': formatNumber(customerReport.summary.total_qty || 0),
|
||||
'Berat (Kg)': formatNumber(customerReport.summary.total_weight || 0),
|
||||
AVG: '',
|
||||
'Harga/Unit': '',
|
||||
'Harga Akhir': formatCurrency(
|
||||
worksheet.addRow({
|
||||
no: 'Total',
|
||||
transDate: '',
|
||||
deliveryDate: '',
|
||||
aging: '',
|
||||
reference: '',
|
||||
vehicleNumbers: '',
|
||||
qty: formatNumber(customerReport.summary.total_qty || 0),
|
||||
weight: formatNumber(customerReport.summary.total_weight || 0),
|
||||
avgWeight: '',
|
||||
unitPrice: '',
|
||||
finalPrice: formatCurrency(
|
||||
customerReport.summary.total_final_amount || 0
|
||||
),
|
||||
Total: formatCurrency(customerReport.summary.total_grand_amount || 0),
|
||||
Pembayaran: formatCurrency(customerReport.summary.total_payment || 0),
|
||||
'Saldo Piutang': formatCurrency(
|
||||
totalPrice: formatCurrency(
|
||||
customerReport.summary.total_grand_amount || 0
|
||||
),
|
||||
paymentAmount: formatCurrency(
|
||||
customerReport.summary.total_payment || 0
|
||||
),
|
||||
accountsReceivable: formatCurrency(
|
||||
customerReport.summary.total_accounts_receivable || 0
|
||||
),
|
||||
Keterangan: '',
|
||||
Pengambilan: '',
|
||||
'Sales/Marketing': '',
|
||||
status: '',
|
||||
pickupInfo: '',
|
||||
salesPerson: '',
|
||||
});
|
||||
}
|
||||
|
||||
const worksheet = XLSX.utils.json_to_sheet(excelData);
|
||||
|
||||
const colWidths = [
|
||||
{ wch: 5 }, // No
|
||||
{ wch: 15 }, // Tanggal DO/Bayar
|
||||
{ wch: 15 }, // Tanggal Realisasi
|
||||
{ wch: 8 }, // Aging
|
||||
{ wch: 12 }, // Referensi
|
||||
{ wch: 15 }, // Nomor Polisi
|
||||
{ wch: 10 }, // Ekor/Qty
|
||||
{ wch: 12 }, // Berat
|
||||
{ wch: 10 }, // AVG
|
||||
{ wch: 15 }, // Harga/Unit
|
||||
{ wch: 15 }, // Harga Akhir
|
||||
{ wch: 15 }, // Total
|
||||
{ wch: 15 }, // Pembayaran
|
||||
{ wch: 15 }, // Saldo Piutang
|
||||
{ wch: 20 }, // Keterangan
|
||||
{ wch: 15 }, // Pengambilan
|
||||
{ wch: 20 }, // Sales/Marketing
|
||||
];
|
||||
worksheet['!cols'] = colWidths;
|
||||
|
||||
const sheetName =
|
||||
customerName.length > 31 ? customerName.substring(0, 31) : customerName;
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
||||
});
|
||||
}
|
||||
|
||||
const filename = `laporan-kontrol-pembayaran-customer-dicetak-pada-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.xlsx`;
|
||||
|
||||
XLSX.writeFile(workbook, filename);
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
const blob = new Blob([buffer], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
@@ -252,7 +252,7 @@ const CustomerPaymentTab = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
generateCustomerPaymentExcel({ data: allDataForExport });
|
||||
await generateCustomerPaymentExcel({ data: allDataForExport });
|
||||
toast.success('Excel berhasil dibuat dan diunduh.');
|
||||
} catch {
|
||||
toast.error('Gagal membuat Excel. Silakan coba lagi.');
|
||||
|
||||
Reference in New Issue
Block a user