diff --git a/src/components/pages/report/finance/export/DebtSupllierExportPDF.tsx b/src/components/pages/report/finance/export/DebtSupllierExportPDF.tsx index edcd360f..b44c8060 100644 --- a/src/components/pages/report/finance/export/DebtSupllierExportPDF.tsx +++ b/src/components/pages/report/finance/export/DebtSupllierExportPDF.tsx @@ -2,7 +2,6 @@ import { Page, - Text, View, Document, StyleSheet, @@ -12,6 +11,15 @@ import { import { formatDate, formatCurrency, formatNumber } from '@/lib/helper'; import { DebtSupplier } from '@/types/api/report/debt-supplier'; +import { PdfParamBadge } from '@/components/helper/pdf/badge/PdfParamBadge'; +import { PdfTypography } from '@/components/helper/pdf/typography/PdfTypography'; +import { PdfStatusBadge } from '@/components/helper/pdf/badge/PdfStatusBadge'; +import { + PdfTable, + PdfColumn, + PdfTbodyCell, + PdfTfootCell, +} from '@/components/helper/pdf/table'; Font.register({ family: 'Helvetica', @@ -69,133 +77,6 @@ const pdfStyles = StyleSheet.create({ titleSection: { marginBottom: 10, }, - mainTitle: { - fontSize: 14, - fontWeight: 'bold', - marginBottom: 5, - color: '#1f74bf', - }, - supplierTitle: { - fontSize: 12, - fontWeight: 'bold', - marginBottom: 8, - color: '#1f74bf', - }, - supplierInfo: { - fontSize: 9, - marginBottom: 5, - color: '#333333', - }, - table: { - borderWidth: 1, - borderColor: '#000000', - marginBottom: 15, - }, - tableRow: { - flexDirection: 'row', - }, - tableHeader: { - backgroundColor: '#F5F5F5', - }, - tableCell: { - flex: 1, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - textAlign: 'left', - }, - tableCellNo: { - flex: 0.5, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - textAlign: 'center', - }, - tableCellLast: { - flex: 1, - padding: 4, - fontSize: 7, - }, - tableCellHeader: { - flex: 1, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - fontWeight: 'bold', - backgroundColor: '#F5F5F5', - borderBottomWidth: 1, - borderBottomColor: '#000000', - borderBottomStyle: 'solid', - paddingVertical: 12, - textAlign: 'center', - }, - tableCellHeaderRight: { - flex: 1, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - fontWeight: 'bold', - backgroundColor: '#F5F5F5', - textAlign: 'right', - borderBottomWidth: 1, - borderBottomColor: '#000000', - borderBottomStyle: 'solid', - paddingVertical: 12, - }, - tableCellRight: { - flex: 1, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - textAlign: 'right', - }, - tableCellCenter: { - flex: 1, - borderRightWidth: 1, - borderRightColor: '#000000', - borderRightStyle: 'solid', - padding: 4, - fontSize: 7, - textAlign: 'center', - }, - tableBorderBottom: { - borderBottomWidth: 1, - borderBottomColor: '#000000', - borderBottomStyle: 'solid', - }, - summaryRow: { - backgroundColor: '#F0F0F0', - fontWeight: 'bold', - }, - badge: { - paddingVertical: 2, - paddingHorizontal: 4, - borderRadius: 12, - fontSize: 5, - fontWeight: 'bold', - borderWidth: 1, - textAlign: 'center', - whiteSpace: 'nowrap', - }, - parameterBadge: { - backgroundColor: '#F5F5F5', - color: '#333333', - padding: 4, - borderRadius: 4, - fontSize: 8, - marginRight: 8, - marginBottom: 4, - }, parameterContainer: { flexDirection: 'row', flexWrap: 'wrap', @@ -203,6 +84,153 @@ const pdfStyles = StyleSheet.create({ }, }); +const getTableColumns = (): PdfColumn[] => [ + { key: 'no', header: 'No', flex: 0.5, align: 'center' }, + { key: 'pr_number', header: 'No. PR', flex: 1, align: 'left' }, + { key: 'po_number', header: 'No. PO', flex: 1, align: 'left' }, + { + key: 'received_date', + header: 'Tgl Terima/Bayar', + flex: 0.7, + align: 'center', + }, + { key: 'po_date', header: 'Tgl PO', flex: 0.7, align: 'center' }, + { key: 'aging', header: 'Aging', flex: 0.6, align: 'center' }, + { key: 'area', header: 'Area', flex: 1, align: 'left' }, + { key: 'warehouse', header: 'Gudang', flex: 1, align: 'left' }, + { key: 'due_date', header: 'Jatuh Tempo', flex: 1, align: 'center' }, + { key: 'due_status', header: 'Status Jatuh Tempo', flex: 2, align: 'left' }, + { + key: 'total_price', + header: 'Nominal Pembelian (Rp)', + flex: 1.5, + align: 'right', + }, + { + key: 'payment_price', + header: 'Pembayaran (Rp)', + flex: 1.5, + align: 'right', + }, + { + key: 'balance', + header: 'Sisa Saldo Hutang (Rp)', + flex: 1.5, + align: 'right', + }, + { key: 'status', header: 'Status', flex: 1.2, align: 'center' }, + { key: 'travel_number', header: 'No. Perjalanan', flex: 1, align: 'left' }, +]; + +const getTableData = (rows: DebtSupplier['rows']): PdfTbodyCell[][] => { + return rows.map((item, index) => [ + { key: 'no', value: index + 1 }, + { key: 'pr_number', value: item.pr_number || '-' }, + { key: 'po_number', value: item.po_number || '-' }, + { + key: 'received_date', + value: item.received_date + ? formatDate(item.received_date, 'DD MMM YY') + : '-', + }, + { + key: 'po_date', + value: item.po_date ? formatDate(item.po_date, 'DD MMM YY') : '-', + }, + { + key: 'aging', + value: item.aging != null ? `${formatNumber(item.aging)}` : '-', + }, + { key: 'area', value: item.area?.name || '-' }, + { key: 'warehouse', value: item.warehouse?.name || '-' }, + { + key: 'due_date', + value: item.due_date ? formatDate(item.due_date, 'DD MMM YY') : '-', + }, + { + key: 'due_status', + value: + item.due_status && item.due_status !== '-' ? ( + + {item.due_status} + + ) : ( + '-' + ), + }, + { + key: 'total_price', + value: formatCurrency(item.total_price), + align: 'right', + color: item.total_price < 0 ? 'red' : undefined, + }, + { + key: 'payment_price', + value: formatCurrency(item.payment_price), + align: 'right', + color: item.payment_price < 0 ? 'red' : undefined, + }, + { + key: 'balance', + value: formatCurrency(item.balance), + align: 'right', + color: item.balance < 0 ? 'red' : undefined, + }, + { + key: 'status', + value: + item.status && item.status !== '-' ? ( + + + {item.status} + + + ) : ( + '-' + ), + }, + { key: 'travel_number', value: item.travel_number || '-' }, + ]); +}; + +const getTableFooter = (total: DebtSupplier['total']): PdfTfootCell[] => [ + { key: 'no', value: 'Total' }, + { key: 'pr_number', value: '' }, + { key: 'po_number', value: '' }, + { key: 'received_date', value: '' }, + { key: 'po_date', value: '' }, + { key: 'aging', value: formatNumber(total?.aging || 0) + ' Hari' }, + { key: 'area', value: '' }, + { key: 'warehouse', value: '' }, + { key: 'due_date', value: '' }, + { key: 'due_status', value: '' }, + { + key: 'total_price', + value: formatCurrency(total?.total_price || 0), + align: 'right', + }, + { + key: 'payment_price', + value: formatCurrency(total?.payment_price || 0), + align: 'right', + }, + { + key: 'balance', + value: formatCurrency(total?.debt_price || 0), + align: 'right', + }, + { key: 'status', value: '' }, + { key: 'travel_number', value: '' }, +]; + interface DebtSupplierExportPDFParams { data: DebtSupplier[]; params?: { @@ -219,418 +247,74 @@ const createPDFDocument = (params: DebtSupplierExportPDFParams) => { {params.data.map((supplierReport, supplierIndex) => ( {/* Title and Supplier Info */} - + Laporan > Rekapitulasi Hutang ke Supplier - + - - - Periode:{' '} - {params.params?.start_date - ? formatDate(params.params.start_date, 'DD MMM YYYY') - : '-'}{' '} - s.d{' '} - {params.params?.end_date - ? formatDate(params.params.end_date, 'DD MMM YYYY') - : '-'} - - + + Periode:{' '} + {params.params?.start_date + ? formatDate(params.params.start_date, 'DD MMM YYYY') + : '-'}{' '} + s.d{' '} + {params.params?.end_date + ? formatDate(params.params.end_date, 'DD MMM YYYY') + : '-'} + {params.params?.filter_by && ( - - - Filter Tanggal:{' '} - {params.params.filter_by === 'po_date' - ? 'Tanggal PO' - : params.params.filter_by === 'received_date' - ? 'Tanggal Terima' - : params.params.filter_by === 'due_date' - ? 'Tanggal Jatuh Tempo' - : params.params.filter_by} - - + + Filter Tanggal:{' '} + {params.params.filter_by === 'po_date' + ? 'Tanggal PO' + : params.params.filter_by === 'received_date' + ? 'Tanggal Terima' + : params.params.filter_by === 'due_date' + ? 'Tanggal Jatuh Tempo' + : params.params.filter_by} + )} - - - Supplier: {params.params?.supplier_name || 'Semua Supplier'} - - - - - Dicetak: {formatDate(new Date(), 'DD MMM YYYY HH:mm')} - - + + Supplier: {params.params?.supplier_name || 'Semua Supplier'} + + + Dicetak: {formatDate(new Date(), 'DD MMM YYYY HH:mm')} + - + {supplierReport.supplier.name} - - + + {supplierReport.supplier.category} - + {/* Table */} - - {/* Table Header */} - - - No - - - No. PR - - - No. PO - - - Tgl Terima/Bayar - - - Tgl PO - - - Aging - - - Area - - - Gudang - - - Jatuh Tempo - - - Status Jatuh Tempo - - - Nominal Pembelian (Rp) - - - Pembayaran (Rp) - - - Sisa Saldo Hutang (Rp) - - - Status - - - No. Perjalanan - - - - {/* Initial Balance Row */} - - - {/* NO */} - - - {/* No. PR */} - - - {/* No. PO */} - - - {/* Tgl Terima/Bayar */} - - - {/* Tgl PO */} - - - {/* Aging */} - - - {/* Area */} - - - {/* Gudang */} - - - {/* Jatuh Tempo */} - - - {/* Status Jatuh Tempo */} - - - {/* Nominal Pembelian (Rp) */} - - - {/* Pembayaran (Rp) */} - - - - {' '} - {/* Sisa Saldo Hutang (Rp) */} - {formatCurrency(supplierReport.initial_balance || 0)} - - - - {/* Status */} - - - - - - - {/* Table Body */} - {supplierReport.rows.map((item, index) => ( - - - {index + 1} - - - {item.pr_number || '-'} - - - {item.po_number || '-'} - - - - {item.received_date - ? item.received_date != '-' - ? formatDate(item.received_date, 'DD MMM YY') - : '-' - : '-'} - - - - - {item.po_date - ? item.po_date != '-' - ? formatDate(item.po_date, 'DD MMM YY') - : '-' - : '-'} - - - - {formatNumber(item.aging)} Hari - - - {item.area?.name || '-'} - - - {item.warehouse?.name || '-'} - - - - {item.due_date - ? item.due_date != '-' - ? formatDate(item.due_date, 'DD MMM YY') - : '-' - : '-'} - - - - {item.due_status && item.due_status !== '-' ? ( - - - {item.due_status} - - - ) : ( - - - )} - - - {formatCurrency(item.total_price)} - - - {formatCurrency(item.payment_price)} - - - {formatCurrency(item.balance)} - - - {item.status && item.status !== '-' ? ( - - - {item.status} - - - ) : ( - - - )} - - - {item.travel_number || '-'} - - - ))} - - {/* Summary Row */} - {supplierReport.total && ( - - - Total - - - - - - - - - - - - - - - {formatNumber(supplierReport.total.aging)} Hari - - - - - - - - - - - - - - - - {formatCurrency(supplierReport.total.total_price)} - - - - - {formatCurrency(supplierReport.total.payment_price)} - - - - {formatCurrency(supplierReport.total.debt_price)} - - - - - - - - - )} - + } + : undefined + } + /> ))}