This commit is contained in:
efrilm 2025-11-25 18:43:12 +07:00
parent 16deaf1890
commit fe4176621c

View File

@ -210,148 +210,148 @@ const DailyPOSReport = () => {
currentY = 20 currentY = 20
// === TREN PENJUALAN (berdasarkan data sales analytics) === // === TREN PENJUALAN (berdasarkan data sales analytics) ===
if (profitLoss7Days?.data && profitLoss7Days.data.length > 0) { // if (profitLoss7Days?.data && profitLoss7Days.data.length > 0) {
pdf.setFontSize(PDF_FONT_SIZES.heading) // pdf.setFontSize(PDF_FONT_SIZES.heading)
pdf.text('Tren Penjualan 7 Hari Terakhir', 14, currentY) // pdf.text('Tren Penjualan 7 Hari Terakhir', 14, currentY)
currentY += 10 // currentY += 10
// Create canvas for chart // // Create canvas for chart
const canvas = document.createElement('canvas') // const canvas = document.createElement('canvas')
canvas.width = 800 // canvas.width = 800
canvas.height = 400 // canvas.height = 400
const ctx = canvas.getContext('2d') // const ctx = canvas.getContext('2d')
if (ctx) { // if (ctx) {
const { Chart, registerables } = await import('chart.js') // const { Chart, registerables } = await import('chart.js')
Chart.register(...registerables) // Chart.register(...registerables)
// Prepare chart data // // Prepare chart data
const chartLabels = profitLoss7Days.data.map(day => // const chartLabels = profitLoss7Days.data.map(day =>
new Date(day.date).toLocaleDateString('id-ID', { day: '2-digit', month: 'short' }) // new Date(day.date).toLocaleDateString('id-ID', { day: '2-digit', month: 'short' })
) // )
const revenueData = profitLoss7Days.data.map(day => day.revenue) // const revenueData = profitLoss7Days.data.map(day => day.revenue)
const ordersData = profitLoss7Days.data.map(day => day.orders) // const ordersData = profitLoss7Days.data.map(day => day.orders)
// Create chart // // Create chart
new Chart(ctx, { // new Chart(ctx, {
type: 'bar', // type: 'bar',
data: { // data: {
labels: chartLabels, // labels: chartLabels,
datasets: [ // datasets: [
{ // {
label: 'Total Penjualan (Rp)', // label: 'Total Penjualan (Rp)',
data: revenueData, // data: revenueData,
backgroundColor: 'rgba(54, 23, 94, 0.8)', // backgroundColor: 'rgba(54, 23, 94, 0.8)',
borderColor: 'rgba(54, 23, 94, 1)', // borderColor: 'rgba(54, 23, 94, 1)',
borderWidth: 1, // borderWidth: 1,
yAxisID: 'y' // yAxisID: 'y'
}, // },
{ // {
label: 'Jumlah Invoice', // label: 'Jumlah Invoice',
data: ordersData, // data: ordersData,
type: 'line', // type: 'line',
borderColor: 'rgba(59, 130, 246, 1)', // borderColor: 'rgba(59, 130, 246, 1)',
backgroundColor: 'rgba(59, 130, 246, 0.1)', // backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 2, // borderWidth: 2,
tension: 0.4, // tension: 0.4,
yAxisID: 'y1', // yAxisID: 'y1',
pointRadius: 4, // pointRadius: 4,
pointBackgroundColor: 'rgba(59, 130, 246, 1)' // pointBackgroundColor: 'rgba(59, 130, 246, 1)'
} // }
] // ]
}, // },
options: { // options: {
responsive: false, // responsive: false,
animation: false, // animation: false,
plugins: { // plugins: {
legend: { // legend: {
display: true, // display: true,
position: 'top', // position: 'top',
labels: { // labels: {
font: { size: 12 }, // font: { size: 12 },
padding: 15 // padding: 15
} // }
}, // },
title: { // title: {
display: false // display: false
} // }
}, // },
scales: { // scales: {
y: { // y: {
type: 'linear', // type: 'linear',
position: 'left', // position: 'left',
beginAtZero: true, // beginAtZero: true,
ticks: { // ticks: {
callback: function (value) { // callback: function (value) {
if (typeof value !== 'number') return '' // if (typeof value !== 'number') return ''
return 'Rp ' + (value / 1000).toFixed(0) + 'k' // return 'Rp ' + (value / 1000).toFixed(0) + 'k'
} // }
}, // },
title: { // title: {
display: true, // display: true,
text: 'Total Penjualan' // text: 'Total Penjualan'
} // }
}, // },
y1: { // y1: {
type: 'linear', // type: 'linear',
position: 'right', // position: 'right',
beginAtZero: true, // beginAtZero: true,
grid: { // grid: {
drawOnChartArea: false // drawOnChartArea: false
}, // },
title: { // title: {
display: true, // display: true,
text: 'Jumlah Invoice' // text: 'Jumlah Invoice'
} // }
}, // },
x: { // x: {
grid: { // grid: {
display: false // display: false
} // }
} // }
} // }
} // }
}) // })
// Wait for chart to render // // Wait for chart to render
await new Promise(resolve => setTimeout(resolve, 500)) // await new Promise(resolve => setTimeout(resolve, 500))
// Convert chart to image // // Convert chart to image
const chartImage = canvas.toDataURL('image/png', 1.0) // const chartImage = canvas.toDataURL('image/png', 1.0)
const chartWidth = 180 // const chartWidth = 180
const chartHeight = 90 // const chartHeight = 90
pdf.addImage(chartImage, 'PNG', 15, currentY, chartWidth, chartHeight) // pdf.addImage(chartImage, 'PNG', 15, currentY, chartWidth, chartHeight)
currentY += chartHeight + 10 // currentY += chartHeight + 10
// Add summary table below chart // // Add summary table below chart
autoTable(pdf, { // autoTable(pdf, {
startY: currentY, // startY: currentY,
head: [['Total Invoice', 'Total Penjualan']], // head: [['Total Invoice', 'Total Penjualan']],
body: [ // body: [
[String(profitLoss7Days.summary.total_orders), formatCurrency(profitLoss7Days.summary.total_revenue)] // [String(profitLoss7Days.summary.total_orders), formatCurrency(profitLoss7Days.summary.total_revenue)]
], // ],
theme: 'grid', // theme: 'grid',
styles: { // styles: {
fontSize: PDF_FONT_SIZES.tableContent, // fontSize: PDF_FONT_SIZES.tableContent,
cellPadding: PDF_SPACING.cellPadding, // cellPadding: PDF_SPACING.cellPadding,
lineColor: [0, 0, 0], // lineColor: [0, 0, 0],
lineWidth: 0.1, // lineWidth: 0.1,
halign: 'center' // halign: 'center'
}, // },
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
}, // },
margin: { left: 14, right: 14 } // margin: { left: 14, right: 14 }
}) // })
currentY = (pdf as any).lastAutoTable.finalY + 20 // currentY = (pdf as any).lastAutoTable.finalY + 20
} // }
} // }
// Payment Method Summary - DENGAN BORDER HITAM // Payment Method Summary - DENGAN BORDER HITAM
pdf.setFontSize(PDF_FONT_SIZES.heading) pdf.setFontSize(PDF_FONT_SIZES.heading)