update report
This commit is contained in:
parent
5f65211432
commit
8e4ab5dd69
@ -27,12 +27,12 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
// PDF Font Size Configuration
|
// PDF Font Size Configuration
|
||||||
const PDF_FONT_SIZES = {
|
const PDF_FONT_SIZES = {
|
||||||
heading: 20,
|
heading: 18,
|
||||||
subheading: 20,
|
subheading: 16,
|
||||||
tableContent: 14,
|
tableContent: 12,
|
||||||
tableHeader: 14,
|
tableHeader: 12,
|
||||||
tableFooter: 14,
|
tableFooter: 12,
|
||||||
grandTotal: 18,
|
grandTotal: 16,
|
||||||
footer: 11
|
footer: 11
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,6 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
const handleGeneratePDF = async () => {
|
const handleGeneratePDF = async () => {
|
||||||
const reportElement = reportRef.current
|
const reportElement = reportRef.current
|
||||||
|
|
||||||
if (!reportElement) {
|
if (!reportElement) {
|
||||||
alert('Report element tidak ditemukan')
|
alert('Report element tidak ditemukan')
|
||||||
return
|
return
|
||||||
@ -153,7 +152,7 @@ const DailyPOSReport = () => {
|
|||||||
pdf.text('Ringkasan', 14, currentY)
|
pdf.text('Ringkasan', 14, currentY)
|
||||||
currentY += 15
|
currentY += 15
|
||||||
|
|
||||||
// Summary table
|
// Summary table - TETAP PLAIN (TANPA BORDER)
|
||||||
autoTable(pdf, {
|
autoTable(pdf, {
|
||||||
startY: currentY,
|
startY: currentY,
|
||||||
head: [],
|
head: [],
|
||||||
@ -164,7 +163,10 @@ const DailyPOSReport = () => {
|
|||||||
['Total', formatCurrency(profitLoss?.summary.total_revenue ?? 0)]
|
['Total', formatCurrency(profitLoss?.summary.total_revenue ?? 0)]
|
||||||
],
|
],
|
||||||
theme: 'plain',
|
theme: 'plain',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.subheading,
|
||||||
|
cellPadding: PDF_SPACING.cellPadding
|
||||||
|
},
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
0: { fontStyle: 'normal', textColor: [60, 60, 60] },
|
0: { fontStyle: 'normal', textColor: [60, 60, 60] },
|
||||||
1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] }
|
1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] }
|
||||||
@ -174,7 +176,7 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
currentY = (pdf as any).lastAutoTable.finalY + 20
|
currentY = (pdf as any).lastAutoTable.finalY + 20
|
||||||
|
|
||||||
// Invoice section
|
// Invoice section - TETAP PLAIN (TANPA BORDER)
|
||||||
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
||||||
pdf.text('Invoice', 14, currentY)
|
pdf.text('Invoice', 14, currentY)
|
||||||
currentY += 15
|
currentY += 15
|
||||||
@ -184,7 +186,10 @@ const DailyPOSReport = () => {
|
|||||||
head: [],
|
head: [],
|
||||||
body: [['Total Invoice', String(profitLoss?.summary.total_orders ?? 0)]],
|
body: [['Total Invoice', String(profitLoss?.summary.total_orders ?? 0)]],
|
||||||
theme: 'plain',
|
theme: 'plain',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.subheading,
|
||||||
|
cellPadding: PDF_SPACING.cellPadding
|
||||||
|
},
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
0: { fontStyle: 'normal', textColor: [60, 60, 60] },
|
0: { fontStyle: 'normal', textColor: [60, 60, 60] },
|
||||||
1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] }
|
1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] }
|
||||||
@ -194,7 +199,8 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
pdf.addPage()
|
pdf.addPage()
|
||||||
currentY = 20
|
currentY = 20
|
||||||
// Payment Method Summary
|
|
||||||
|
// Payment Method Summary - DENGAN BORDER HITAM
|
||||||
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
||||||
pdf.text('Ringkasan Metode Pembayaran', 14, currentY)
|
pdf.text('Ringkasan Metode Pembayaran', 14, currentY)
|
||||||
currentY += 15
|
currentY += 15
|
||||||
@ -202,7 +208,6 @@ const DailyPOSReport = () => {
|
|||||||
const paymentBody =
|
const paymentBody =
|
||||||
paymentAnalytics?.data?.map(payment => [
|
paymentAnalytics?.data?.map(payment => [
|
||||||
payment.payment_method_name,
|
payment.payment_method_name,
|
||||||
payment.payment_method_type.toUpperCase(),
|
|
||||||
String(payment.order_count),
|
String(payment.order_count),
|
||||||
formatCurrency(payment.total_amount),
|
formatCurrency(payment.total_amount),
|
||||||
`${(payment.percentage ?? 0).toFixed(1)}%`
|
`${(payment.percentage ?? 0).toFixed(1)}%`
|
||||||
@ -210,30 +215,39 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
autoTable(pdf, {
|
autoTable(pdf, {
|
||||||
startY: currentY,
|
startY: currentY,
|
||||||
head: [['Metode Pembayaran', 'Tipe', 'Jumlah Order', 'Total Amount', 'Persentase']],
|
head: [['Metode', 'Jumlah', 'Total', 'Persentase']],
|
||||||
body: paymentBody,
|
body: paymentBody,
|
||||||
foot: [
|
foot: [
|
||||||
[
|
[
|
||||||
'TOTAL',
|
'TOTAL',
|
||||||
'',
|
|
||||||
String(paymentAnalytics?.summary.total_orders ?? 0),
|
String(paymentAnalytics?.summary.total_orders ?? 0),
|
||||||
formatCurrency(paymentAnalytics?.summary.total_amount ?? 0),
|
formatCurrency(paymentAnalytics?.summary.total_amount ?? 0),
|
||||||
''
|
''
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
theme: 'striped',
|
theme: 'grid',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.tableContent,
|
||||||
|
cellPadding: PDF_SPACING.cellPadding,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
|
},
|
||||||
headStyles: {
|
headStyles: {
|
||||||
fillColor: [54, 23, 94],
|
fillColor: [54, 23, 94],
|
||||||
textColor: 255,
|
textColor: 255,
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
fontSize: PDF_FONT_SIZES.tableHeader
|
fontSize: PDF_FONT_SIZES.tableHeader,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
},
|
},
|
||||||
footStyles: {
|
footStyles: {
|
||||||
fillColor: [220, 220, 220],
|
fillColor: [220, 220, 220],
|
||||||
textColor: [60, 60, 60],
|
textColor: [60, 60, 60],
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
fontSize: PDF_FONT_SIZES.tableFooter
|
fontSize: PDF_FONT_SIZES.tableFooter,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1,
|
||||||
|
halign: 'center'
|
||||||
},
|
},
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
1: { halign: 'center' },
|
1: { halign: 'center' },
|
||||||
@ -246,7 +260,7 @@ const DailyPOSReport = () => {
|
|||||||
|
|
||||||
currentY = (pdf as any).lastAutoTable.finalY + 20
|
currentY = (pdf as any).lastAutoTable.finalY + 20
|
||||||
|
|
||||||
// Category Summary
|
// Category Summary - DENGAN BORDER HITAM
|
||||||
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
pdf.setFontSize(PDF_FONT_SIZES.heading)
|
||||||
pdf.text('Ringkasan Kategori', 14, currentY)
|
pdf.text('Ringkasan Kategori', 14, currentY)
|
||||||
currentY += 15
|
currentY += 15
|
||||||
@ -261,19 +275,29 @@ const DailyPOSReport = () => {
|
|||||||
foot: [
|
foot: [
|
||||||
['TOTAL', String(categorySummary?.totalQuantity ?? 0), formatCurrency(categorySummary?.totalRevenue ?? 0)]
|
['TOTAL', String(categorySummary?.totalQuantity ?? 0), formatCurrency(categorySummary?.totalRevenue ?? 0)]
|
||||||
],
|
],
|
||||||
theme: 'striped',
|
theme: 'grid',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.tableContent,
|
||||||
|
cellPadding: PDF_SPACING.cellPadding,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
|
},
|
||||||
headStyles: {
|
headStyles: {
|
||||||
fillColor: [54, 23, 94],
|
fillColor: [54, 23, 94],
|
||||||
textColor: 255,
|
textColor: 255,
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
fontSize: PDF_FONT_SIZES.tableHeader
|
fontSize: PDF_FONT_SIZES.tableHeader,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
},
|
},
|
||||||
footStyles: {
|
footStyles: {
|
||||||
fillColor: [220, 220, 220],
|
fillColor: [220, 220, 220],
|
||||||
textColor: [60, 60, 60],
|
textColor: [60, 60, 60],
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
fontSize: PDF_FONT_SIZES.tableFooter
|
fontSize: PDF_FONT_SIZES.tableFooter,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1,
|
||||||
|
halign: 'center'
|
||||||
},
|
},
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
1: { halign: 'center' },
|
1: { halign: 'center' },
|
||||||
@ -320,6 +344,7 @@ const DailyPOSReport = () => {
|
|||||||
const skuB = b.product_sku || ''
|
const skuB = b.product_sku || ''
|
||||||
return skuA.localeCompare(skuB)
|
return skuA.localeCompare(skuB)
|
||||||
})
|
})
|
||||||
|
|
||||||
const categoryTotalQty = categoryProducts.reduce((sum, item) => sum + (item.quantity_sold || 0), 0)
|
const categoryTotalQty = categoryProducts.reduce((sum, item) => sum + (item.quantity_sold || 0), 0)
|
||||||
const categoryTotalRevenue = categoryProducts.reduce((sum, item) => sum + (item.revenue || 0), 0)
|
const categoryTotalRevenue = categoryProducts.reduce((sum, item) => sum + (item.revenue || 0), 0)
|
||||||
|
|
||||||
@ -337,27 +362,42 @@ const DailyPOSReport = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Category header
|
// Category header
|
||||||
pdf.setFontSize(20)
|
pdf.setFontSize(PDF_FONT_SIZES.subheading)
|
||||||
pdf.setFont('helvetica', 'bold')
|
pdf.setFont('helvetica', 'bold')
|
||||||
pdf.setTextColor(54, 23, 94)
|
pdf.setTextColor(54, 23, 94)
|
||||||
pdf.text(categoryName.toUpperCase(), 16, currentY)
|
pdf.text(categoryName.toUpperCase(), 16, currentY)
|
||||||
currentY += 15
|
currentY += 15
|
||||||
|
|
||||||
// Category table
|
// Category table - DENGAN BORDER HITAM
|
||||||
autoTable(pdf, {
|
autoTable(pdf, {
|
||||||
startY: currentY,
|
startY: currentY,
|
||||||
head: [['Produk', 'Qty', 'Pendapatan']],
|
head: [['Produk', 'Qty', 'Pendapatan']],
|
||||||
body: productBody,
|
body: productBody,
|
||||||
foot: [[`Subtotal ${categoryName}`, String(categoryTotalQty), formatCurrency(categoryTotalRevenue)]],
|
foot: [[`Subtotal ${categoryName}`, String(categoryTotalQty), formatCurrency(categoryTotalRevenue)]],
|
||||||
theme: 'striped',
|
theme: 'grid',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.tableContent,
|
||||||
|
cellPadding: PDF_SPACING.cellPadding,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
|
},
|
||||||
headStyles: {
|
headStyles: {
|
||||||
fillColor: [54, 23, 94],
|
fillColor: [54, 23, 94],
|
||||||
textColor: 255,
|
textColor: 255,
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
fontSize: PDF_FONT_SIZES.tableHeader
|
fontSize: PDF_FONT_SIZES.tableHeader,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1
|
||||||
|
},
|
||||||
|
footStyles: {
|
||||||
|
fillColor: [200, 200, 200],
|
||||||
|
textColor: [60, 60, 60],
|
||||||
|
fontStyle: 'bold',
|
||||||
|
fontSize: PDF_FONT_SIZES.tableFooter,
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.1,
|
||||||
|
halign: 'center'
|
||||||
},
|
},
|
||||||
footStyles: { fillColor: [200, 200, 200], textColor: [60, 60, 60], fontStyle: 'bold', fontSize: 20 },
|
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
0: { cellWidth: 90 },
|
0: { cellWidth: 90 },
|
||||||
1: { halign: 'center', cellWidth: 40 },
|
1: { halign: 'center', cellWidth: 40 },
|
||||||
@ -369,7 +409,7 @@ const DailyPOSReport = () => {
|
|||||||
currentY = (pdf as any).lastAutoTable.finalY + 15
|
currentY = (pdf as any).lastAutoTable.finalY + 15
|
||||||
})
|
})
|
||||||
|
|
||||||
// Grand Total
|
// Grand Total - DENGAN BORDER HITAM
|
||||||
if (currentY > 250) {
|
if (currentY > 250) {
|
||||||
pdf.addPage()
|
pdf.addPage()
|
||||||
currentY = 20
|
currentY = 20
|
||||||
@ -381,18 +421,21 @@ const DailyPOSReport = () => {
|
|||||||
body: [
|
body: [
|
||||||
['TOTAL KESELURUHAN', String(productSummary.totalQuantitySold), formatCurrency(productSummary.totalRevenue)]
|
['TOTAL KESELURUHAN', String(productSummary.totalQuantitySold), formatCurrency(productSummary.totalRevenue)]
|
||||||
],
|
],
|
||||||
theme: 'plain',
|
theme: 'grid',
|
||||||
styles: { fontSize: PDF_FONT_SIZES.grandTotal, cellPadding: 6, fontStyle: 'bold', textColor: [54, 23, 94] },
|
styles: {
|
||||||
|
fontSize: PDF_FONT_SIZES.grandTotal,
|
||||||
|
cellPadding: 6,
|
||||||
|
fontStyle: 'bold',
|
||||||
|
textColor: [54, 23, 94],
|
||||||
|
lineColor: [0, 0, 0],
|
||||||
|
lineWidth: 0.2
|
||||||
|
},
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
0: { cellWidth: 90 },
|
0: { cellWidth: 90 },
|
||||||
1: { halign: 'center', cellWidth: 40 },
|
1: { halign: 'center', cellWidth: 40 },
|
||||||
2: { halign: 'right', cellWidth: 52 }
|
2: { halign: 'right', cellWidth: 52 }
|
||||||
},
|
},
|
||||||
margin: { left: 14, right: 14 },
|
margin: { left: 14, right: 14 }
|
||||||
didDrawCell: data => {
|
|
||||||
pdf.setDrawColor(54, 23, 94)
|
|
||||||
pdf.setLineWidth(0.5)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Footer
|
// Footer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user