mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE): Refactor DailyMarketingReportPDF component for cleaner
structure
This commit is contained in:
@@ -1,275 +1,226 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Document,
|
||||
Image,
|
||||
Page,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from '@react-pdf/renderer';
|
||||
|
||||
import { Page, View, Document, StyleSheet, Font } from '@react-pdf/renderer';
|
||||
import {
|
||||
DailyMarketingReport,
|
||||
SalesSummary,
|
||||
} from '@/types/api/report/marketing';
|
||||
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
||||
import {
|
||||
formatCurrency,
|
||||
formatDate,
|
||||
formatNumber,
|
||||
formatTitleCase,
|
||||
} from '@/lib/helper';
|
||||
import {
|
||||
PdfTable,
|
||||
PdfColumn,
|
||||
PdfTbodyCell,
|
||||
PdfTfootCell,
|
||||
} from '@/components/helper/pdf/table';
|
||||
import { PdfParamBadge } from '@/components/helper/pdf/badge/PdfParamBadge';
|
||||
import { PdfStatusBadge } from '@/components/helper/pdf/badge/PdfStatusBadge';
|
||||
import { PdfTypography } from '@/components/helper/pdf/typography/PdfTypography';
|
||||
import { PdfPageNumber } from '@/components/helper/pdf/layout/PdfPageNumber';
|
||||
|
||||
Font.register({
|
||||
family: 'Helvetica',
|
||||
src: 'helvetica',
|
||||
});
|
||||
|
||||
const pdfStyles = StyleSheet.create({
|
||||
page: {
|
||||
fontSize: 10,
|
||||
fontFamily: 'Helvetica',
|
||||
padding: 20,
|
||||
backgroundColor: '#FFFFFF',
|
||||
},
|
||||
titleSection: {
|
||||
marginBottom: 10,
|
||||
},
|
||||
parameterContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginBottom: 8,
|
||||
},
|
||||
});
|
||||
|
||||
interface DailyMarketingReportPDFProps {
|
||||
data?: DailyMarketingReport;
|
||||
total?: SalesSummary;
|
||||
}
|
||||
|
||||
const DailyMarketingReportPDFStyle = StyleSheet.create({
|
||||
page: {
|
||||
paddingTop: 24,
|
||||
paddingBottom: 64,
|
||||
paddingHorizontal: 16, // Reduce padding to fit more columns
|
||||
orientation: 'landscape',
|
||||
const getTableColumns = (): PdfColumn[] => [
|
||||
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
|
||||
{ key: 'so_date', header: 'Tanggal Sales Order', flex: 1.3, align: 'center' },
|
||||
{
|
||||
key: 'do_date',
|
||||
header: 'Tanggal Delivery Order',
|
||||
flex: 1.3,
|
||||
align: 'center',
|
||||
},
|
||||
{ key: 'aging', header: 'Aging (Hari)', flex: 0.7, align: 'center' },
|
||||
{ key: 'warehouse', header: 'Gudang', flex: 1.2, align: 'left' },
|
||||
{ key: 'customer', header: 'Pelanggan', flex: 1.5, align: 'left' },
|
||||
{ key: 'sales', header: 'Sales', flex: 1, align: 'left' },
|
||||
{ key: 'product', header: 'Produk', flex: 1.3, align: 'left' },
|
||||
{ key: 'do_number', header: 'Nomor DO', flex: 1.2, align: 'left' },
|
||||
{ key: 'vehicle', header: 'Nomor Polisi', flex: 1, align: 'left' },
|
||||
{ key: 'marketing_type', header: 'Tipe Marketing', flex: 1, align: 'center' },
|
||||
{ key: 'qty', header: 'Quantity', flex: 0.7, align: 'right' },
|
||||
{ key: 'avg_weight', header: 'Rata-Rata (Kg)', flex: 0.8, align: 'right' },
|
||||
{
|
||||
key: 'total_weight',
|
||||
header: 'Total Berat (Kg)',
|
||||
flex: 0.9,
|
||||
align: 'right',
|
||||
},
|
||||
{ key: 'sales_price', header: 'Harga Jual (Rp)', flex: 0.9, align: 'right' },
|
||||
{ key: 'hpp_price', header: 'HPP (Rp)', flex: 1.3, align: 'right' },
|
||||
{ key: 'sales_amount', header: 'Total Jual (Rp)', flex: 1, align: 'right' },
|
||||
{ key: 'hpp_amount', header: 'Total HPP (Rp)', flex: 1.3, align: 'right' },
|
||||
];
|
||||
|
||||
companyInfoHeader: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
marginBottom: 8,
|
||||
},
|
||||
companyLogo: {
|
||||
width: 64,
|
||||
height: 'auto',
|
||||
},
|
||||
companyInfoHeaderDate: {
|
||||
paddingTop: 8,
|
||||
fontSize: 10,
|
||||
},
|
||||
companyName: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 4,
|
||||
},
|
||||
companyAddress: {
|
||||
fontSize: 8,
|
||||
maxWidth: 400,
|
||||
marginBottom: 10,
|
||||
},
|
||||
const getTableData = (rows: DailyMarketingReport): PdfTbodyCell[][] => {
|
||||
return rows.map((row, index) => [
|
||||
{ key: 'no', value: index + 1 },
|
||||
{
|
||||
key: 'so_date',
|
||||
value: row.so_date ? formatDate(row.so_date, 'DD MMM YY') : '-',
|
||||
},
|
||||
{
|
||||
key: 'do_date',
|
||||
value: row.realization_date
|
||||
? formatDate(row.realization_date, 'DD MMM YY')
|
||||
: '-',
|
||||
},
|
||||
{ key: 'aging', value: row.aging_days ?? '-' },
|
||||
{ key: 'warehouse', value: row.warehouse?.name ?? '-' },
|
||||
{ key: 'customer', value: row.customer?.name ?? '-' },
|
||||
{ key: 'sales', value: row.sales?.name ?? '-' },
|
||||
{ key: 'product', value: row.product?.name ?? '-' },
|
||||
{ key: 'do_number', value: row.do_number ?? '-' },
|
||||
{ key: 'vehicle', value: row.vehicle_number ?? '-' },
|
||||
{
|
||||
key: 'marketing_type',
|
||||
value: row.marketing_type ? (
|
||||
<View style={{ alignItems: 'center' }}>
|
||||
<PdfStatusBadge
|
||||
style={{
|
||||
backgroundColor:
|
||||
row.marketing_type.toLowerCase() === 'ayam'
|
||||
? '#FEF3C7'
|
||||
: row.marketing_type.toLowerCase() === 'trading'
|
||||
? '#DBEAFE'
|
||||
: row.marketing_type.toLowerCase() === 'telur'
|
||||
? '#D1FAE5'
|
||||
: '#F5F5F5',
|
||||
color:
|
||||
row.marketing_type.toLowerCase() === 'ayam'
|
||||
? '#92400E'
|
||||
: row.marketing_type.toLowerCase() === 'trading'
|
||||
? '#1E40AF'
|
||||
: row.marketing_type.toLowerCase() === 'telur'
|
||||
? '#065F46'
|
||||
: '#333333',
|
||||
borderColor:
|
||||
row.marketing_type.toLowerCase() === 'ayam'
|
||||
? '#FBBF24'
|
||||
: row.marketing_type.toLowerCase() === 'trading'
|
||||
? '#60A5FA'
|
||||
: row.marketing_type.toLowerCase() === 'telur'
|
||||
? '#34D399'
|
||||
: '#E5E7EB',
|
||||
}}
|
||||
>
|
||||
{formatTitleCase(row.marketing_type)}
|
||||
</PdfStatusBadge>
|
||||
</View>
|
||||
) : (
|
||||
'-'
|
||||
),
|
||||
},
|
||||
{ key: 'qty', value: formatNumber(row.qty ?? 0), align: 'right' },
|
||||
{
|
||||
key: 'avg_weight',
|
||||
value: formatNumber(row.average_weight_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'total_weight',
|
||||
value: formatNumber(row.total_weight_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'sales_price',
|
||||
value: formatCurrency(row.sales_price_per_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'hpp_price',
|
||||
value: formatCurrency(row.hpp_price_per_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'sales_amount',
|
||||
value: formatCurrency(row.sales_amount ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'hpp_amount',
|
||||
value: formatCurrency(row.hpp_amount ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
title: {
|
||||
marginTop: 16,
|
||||
fontSize: 14,
|
||||
lineHeight: '150%',
|
||||
textAlign: 'center',
|
||||
fontFamily: 'Times-Roman',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
const getTableFooter = (summary?: SalesSummary): PdfTfootCell[] => {
|
||||
if (!summary) return [];
|
||||
|
||||
footer: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
|
||||
position: 'absolute',
|
||||
fontSize: 8,
|
||||
bottom: 30,
|
||||
left: 0,
|
||||
right: 0,
|
||||
textAlign: 'center',
|
||||
color: 'grey',
|
||||
},
|
||||
|
||||
// Table Styles
|
||||
table: {
|
||||
width: '100%',
|
||||
marginTop: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#000000',
|
||||
borderBottomWidth: 0,
|
||||
fontSize: 7, // Smaller font for report
|
||||
},
|
||||
tableRow: {
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#000000',
|
||||
alignItems: 'center',
|
||||
minHeight: 20,
|
||||
},
|
||||
tableHeader: {
|
||||
backgroundColor: '#f0f0f0',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
||||
// Columns definition (Total 100%)
|
||||
colNo: {
|
||||
width: '3%',
|
||||
padding: 2,
|
||||
textAlign: 'center',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colSoDate: {
|
||||
width: '6%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colDoDate: {
|
||||
width: '6%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colAging: {
|
||||
width: '3%',
|
||||
padding: 2,
|
||||
textAlign: 'center',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colWarehouse: {
|
||||
width: '7%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colCustomer: {
|
||||
width: '9%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
}, // Reduced slightly
|
||||
colSales: {
|
||||
width: '6%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colProduct: {
|
||||
width: '8%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
}, // Reduced slightly
|
||||
colDoNumber: {
|
||||
width: '7%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colVehicle: {
|
||||
width: '5%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colMarketingType: {
|
||||
width: '5%',
|
||||
padding: 2,
|
||||
textAlign: 'left',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colQty: {
|
||||
width: '4%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colAvgWeight: {
|
||||
width: '4%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colTotalWeight: {
|
||||
width: '5%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colSalesPrice: {
|
||||
width: '5%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colHppPrice: {
|
||||
width: '5%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colSalesAmount: {
|
||||
width: '6%',
|
||||
padding: 2,
|
||||
textAlign: 'right',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: '#000000',
|
||||
},
|
||||
colHppAmount: { width: '6%', padding: 2, textAlign: 'right' }, // Last column
|
||||
|
||||
// Text inside columns
|
||||
cellText: {
|
||||
fontSize: 6,
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 7,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
},
|
||||
|
||||
// Utils
|
||||
doubleDivider: {
|
||||
width: '100%',
|
||||
height: 6,
|
||||
borderTop: '2px solid black',
|
||||
borderBottom: '2px solid black',
|
||||
},
|
||||
|
||||
// Summary
|
||||
summaryContainer: {
|
||||
marginTop: 12,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
width: '100%',
|
||||
},
|
||||
summaryTable: {
|
||||
width: '30%',
|
||||
borderWidth: 1,
|
||||
borderColor: '#000000',
|
||||
fontSize: 8,
|
||||
},
|
||||
summaryRow: {
|
||||
flexDirection: 'row',
|
||||
padding: 2,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#eee',
|
||||
},
|
||||
summaryLabel: {
|
||||
width: '50%',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
summaryValue: {
|
||||
width: '50%',
|
||||
textAlign: 'right',
|
||||
},
|
||||
});
|
||||
return [
|
||||
{ key: 'no', value: 'TOTAL' },
|
||||
{ key: 'so_date', value: '' },
|
||||
{ key: 'do_date', value: '' },
|
||||
{ key: 'aging', value: '' },
|
||||
{ key: 'warehouse', value: '' },
|
||||
{ key: 'customer', value: '' },
|
||||
{ key: 'sales', value: '' },
|
||||
{ key: 'product', value: '' },
|
||||
{ key: 'do_number', value: '' },
|
||||
{ key: 'vehicle', value: '' },
|
||||
{ key: 'marketing_type', value: '' },
|
||||
{
|
||||
key: 'qty',
|
||||
value: formatNumber(summary.total_qty ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'avg_weight',
|
||||
value: formatNumber(summary.total_weight_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'total_weight',
|
||||
value: formatNumber(summary.total_weight_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{ key: 'sales_price', value: '' },
|
||||
{
|
||||
key: 'hpp_price',
|
||||
value: formatCurrency(summary.total_hpp_price_per_kg ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'sales_amount',
|
||||
value: formatCurrency(summary.total_sales_amount ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
key: 'hpp_amount',
|
||||
value: formatCurrency(summary.total_hpp_amount ?? 0),
|
||||
align: 'right',
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const DailyMarketingReportPDF = ({
|
||||
data,
|
||||
@@ -280,288 +231,31 @@ const DailyMarketingReportPDF = ({
|
||||
|
||||
return (
|
||||
<Document>
|
||||
<Page
|
||||
style={DailyMarketingReportPDFStyle.page}
|
||||
orientation='landscape'
|
||||
size='A4'
|
||||
>
|
||||
<View>
|
||||
<View style={DailyMarketingReportPDFStyle.companyInfoHeader}>
|
||||
<Image
|
||||
style={DailyMarketingReportPDFStyle.companyLogo}
|
||||
src='/assets/img/lti-logo.png'
|
||||
/>
|
||||
|
||||
<Text style={DailyMarketingReportPDFStyle.companyInfoHeaderDate}>
|
||||
{formatDate(Date.now(), 'DD MMMM YYYY')}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text style={DailyMarketingReportPDFStyle.companyName}>
|
||||
PT LUMBUNG TELUR INDONESIA
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.companyAddress}>
|
||||
SOHO Building Lt.3 (Paris Van Java), Jalan Karang Tinggal, Kel.
|
||||
Cipedes, Kec. Sukajadi, Kota Bandung 40162
|
||||
</Text>
|
||||
|
||||
<View style={DailyMarketingReportPDFStyle.doubleDivider} />
|
||||
<Page size='A3' orientation='landscape' style={pdfStyles.page}>
|
||||
{/* Title and Parameters */}
|
||||
<View style={pdfStyles.titleSection}>
|
||||
<PdfTypography size='h1' variant='primary'>
|
||||
Laporan > Penjualan Harian
|
||||
</PdfTypography>
|
||||
<View style={pdfStyles.parameterContainer}>
|
||||
<PdfParamBadge>
|
||||
Tanggal: {formatDate(Date.now(), 'DD MMMM YYYY')}
|
||||
</PdfParamBadge>
|
||||
<PdfParamBadge>
|
||||
Dicetak: {formatDate(new Date(), 'DD MMM YYYY HH:mm')}
|
||||
</PdfParamBadge>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Text style={DailyMarketingReportPDFStyle.title}>
|
||||
Laporan Penjualan Harian
|
||||
</Text>
|
||||
{/* Table */}
|
||||
<PdfTable
|
||||
columns={getTableColumns()}
|
||||
data={getTableData(rows)}
|
||||
footer={getTableFooter(summary)}
|
||||
footerLabel='TOTAL'
|
||||
/>
|
||||
|
||||
{/* Data Table */}
|
||||
<View style={DailyMarketingReportPDFStyle.table}>
|
||||
{/* Header */}
|
||||
<View
|
||||
style={[
|
||||
DailyMarketingReportPDFStyle.tableRow,
|
||||
DailyMarketingReportPDFStyle.tableHeader,
|
||||
]}
|
||||
>
|
||||
<View style={DailyMarketingReportPDFStyle.colNo}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>No</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSoDate}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Tgl SO
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colDoDate}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Tgl DO
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colAging}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>Aging</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colWarehouse}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Gudang
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colCustomer}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Pelanggan
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSales}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>Sales</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colProduct}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Produk
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colDoNumber}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>No DO</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colVehicle}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Plat No
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colMarketingType}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>Tipe</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colQty}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>Qty</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colAvgWeight}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Rerata
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colTotalWeight}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>Berat</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSalesPrice}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Hrg Jual
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colHppPrice}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
HPP/kg
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSalesAmount}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Total Jual
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colHppAmount}>
|
||||
<Text style={DailyMarketingReportPDFStyle.headerText}>
|
||||
Total HPP
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Rows */}
|
||||
{rows.map((row, index) => (
|
||||
<View style={DailyMarketingReportPDFStyle.tableRow} key={index}>
|
||||
<View style={DailyMarketingReportPDFStyle.colNo}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{index + 1}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSoDate}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatDate(row.so_date, 'DD/MM/YYYY')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colDoDate}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatDate(row.realization_date, 'DD/MM/YYYY')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colAging}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.aging_days}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colWarehouse}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.warehouse?.name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colCustomer}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.customer?.name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSales}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.sales.name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colProduct}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.product?.name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colDoNumber}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.do_number}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colVehicle}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.vehicle_number}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colMarketingType}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.marketing_type}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colQty}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatNumber(row.qty)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colAvgWeight}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatNumber(row.average_weight_kg)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colTotalWeight}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatNumber(row.total_weight_kg)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSalesPrice}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatCurrency(row.sales_price_per_kg)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colHppPrice}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatCurrency(row.hpp_price_per_kg)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSalesAmount}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatCurrency(row.sales_amount)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colHppAmount}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatCurrency(row.hpp_amount)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* Summary */}
|
||||
<View style={DailyMarketingReportPDFStyle.summaryContainer}>
|
||||
<View style={DailyMarketingReportPDFStyle.summaryTable}>
|
||||
<View style={DailyMarketingReportPDFStyle.summaryRow}>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total Qty:
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatNumber(summary?.total_qty ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.summaryRow}>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total Berat (kg):
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatNumber(summary?.total_weight_kg ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.summaryRow}>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total Penjualan:
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatCurrency(summary?.total_sales_amount ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
DailyMarketingReportPDFStyle.summaryRow,
|
||||
{ borderBottomWidth: 0 },
|
||||
]}
|
||||
>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total HPP Per KG:
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatCurrency(summary?.total_hpp_price_per_kg ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
DailyMarketingReportPDFStyle.summaryRow,
|
||||
{ borderBottomWidth: 0 },
|
||||
]}
|
||||
>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total HPP:
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatCurrency(summary?.total_hpp_amount ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={DailyMarketingReportPDFStyle.footer} fixed>
|
||||
<Text
|
||||
render={({ pageNumber, totalPages }) =>
|
||||
`${pageNumber} / ${totalPages}`
|
||||
}
|
||||
fixed
|
||||
/>
|
||||
</View>
|
||||
<PdfPageNumber />
|
||||
</Page>
|
||||
</Document>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user