update wallets statement
This commit is contained in:
@ -171,8 +171,8 @@ const ListToolbar = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</DefaultTooltip>
|
</DefaultTooltip>
|
||||||
|
|
||||||
<Button variant="outline" className="h-8" onClick={handleApplyFilters}>
|
<Button variant="default" className="h-8" onClick={handleApplyFilters}>
|
||||||
Filter Dataaaaa
|
Filter Data
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -245,7 +245,7 @@ const ShowDetailWalletDialog = () => {
|
|||||||
[''],
|
[''],
|
||||||
['Wallet Statement Details'],
|
['Wallet Statement Details'],
|
||||||
[`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`],
|
[`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`],
|
||||||
[`Wallet ID: ${selectedWallet?.ID || '-'}`],
|
[`Wallet Name: ${selectedWallet?.name || '-'}`],
|
||||||
['']
|
['']
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -478,10 +478,10 @@ const ShowDetailWalletDialog = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const doExportPDF = async () => {
|
const doExportPDF = async () => {
|
||||||
try {
|
try {
|
||||||
const allData = await getAllTransactionData();
|
const allData = await getAllTransactionData();
|
||||||
const formattedData = formatTransactionData(allData);
|
const formattedData = formatTransactionData(allData);
|
||||||
|
|
||||||
const pdf = new jsPDF({
|
const pdf = new jsPDF({
|
||||||
orientation: 'landscape',
|
orientation: 'landscape',
|
||||||
@ -489,10 +489,70 @@ const ShowDetailWalletDialog = () => {
|
|||||||
format: 'a4'
|
format: 'a4'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Pindahkan deklarasi variabel ke luar block try-catch
|
||||||
|
const pageWidth = pdf.internal.pageSize.getWidth();
|
||||||
|
const pageHeight = pdf.internal.pageSize.getHeight();
|
||||||
|
|
||||||
const headerImageUrl = toAbsoluteUrl('/media/avatars/KopDetailWalletStatement.png');
|
const headerImageUrl = toAbsoluteUrl('/media/avatars/KopDetailWalletStatement.png');
|
||||||
|
|
||||||
|
// Definisikan table configuration yang akan digunakan berkali-kali
|
||||||
|
const tableHeaders = [
|
||||||
|
'Transaction Code',
|
||||||
|
'MSISDN Reffer',
|
||||||
|
'Transaction Type',
|
||||||
|
'Type',
|
||||||
|
'Pre Amount',
|
||||||
|
'Amount',
|
||||||
|
'Post Amount',
|
||||||
|
'Category',
|
||||||
|
'Date',
|
||||||
|
'Purpose',
|
||||||
|
'Notes'
|
||||||
|
];
|
||||||
|
|
||||||
|
const tableData = formattedData.map((item) => [
|
||||||
|
item['Transaction Code'],
|
||||||
|
item['MSISDN Reffer'],
|
||||||
|
item['Transaction Type'],
|
||||||
|
item['Type'],
|
||||||
|
item['Pre Amount'],
|
||||||
|
item['Amount'],
|
||||||
|
item['Post Amount'],
|
||||||
|
item['Category'],
|
||||||
|
item['Date'],
|
||||||
|
item['Purpose'],
|
||||||
|
item['Notes']
|
||||||
|
]);
|
||||||
|
|
||||||
|
const columnStyles = {
|
||||||
|
0: { cellWidth: 25, halign: 'left' as const },
|
||||||
|
1: { cellWidth: 20, halign: 'left' as const },
|
||||||
|
2: { cellWidth: 25, halign: 'left' as const },
|
||||||
|
3: { cellWidth: 15, halign: 'left' as const },
|
||||||
|
4: { cellWidth: 18, halign: 'left' as const },
|
||||||
|
5: { cellWidth: 18, halign: 'left' as const },
|
||||||
|
6: { cellWidth: 18, halign: 'left' as const },
|
||||||
|
7: { cellWidth: 20, halign: 'left' as const },
|
||||||
|
8: { cellWidth: 30, halign: 'left' as const },
|
||||||
|
9: { cellWidth: 25, halign: 'left' as const },
|
||||||
|
10: { cellWidth: 25, halign: 'left' as const }
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateLeftMargin = (
|
||||||
|
columnStyles: Record<number, { cellWidth: number }>,
|
||||||
|
pageWidth: number
|
||||||
|
): number => {
|
||||||
|
const totalTableWidth = Object.values(columnStyles).reduce(
|
||||||
|
(sum, col) => sum + col.cellWidth,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
return (pageWidth - totalTableWidth) / 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
const leftMargin = calculateLeftMargin(columnStyles, pageWidth);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const pageWidth = pdf.internal.pageSize.getWidth();
|
// Coba tambahkan header image
|
||||||
const imageWidth = 250;
|
const imageWidth = 250;
|
||||||
const imageHeight = 40;
|
const imageHeight = 40;
|
||||||
const xPosition = (pageWidth - imageWidth) / 2;
|
const xPosition = (pageWidth - imageWidth) / 2;
|
||||||
@ -501,18 +561,21 @@ const ShowDetailWalletDialog = () => {
|
|||||||
|
|
||||||
let currentY = 55;
|
let currentY = 55;
|
||||||
|
|
||||||
|
// Garis pemisah
|
||||||
pdf.setDrawColor(0, 0, 0);
|
pdf.setDrawColor(0, 0, 0);
|
||||||
pdf.setLineWidth(0.5);
|
pdf.setLineWidth(0.5);
|
||||||
pdf.line(20, currentY, pageWidth - 20, currentY);
|
pdf.line(20, currentY, pageWidth - 20, currentY);
|
||||||
|
|
||||||
currentY += 10;
|
currentY += 10;
|
||||||
|
|
||||||
|
// Title
|
||||||
pdf.setFontSize(16);
|
pdf.setFontSize(16);
|
||||||
pdf.setFont('helvetica', 'bold');
|
pdf.setFont('helvetica', 'bold');
|
||||||
pdf.text('Wallet Statement Details', pageWidth / 2, currentY, { align: 'center' });
|
pdf.text('Wallet Statement Details', pageWidth / 2, currentY, { align: 'center' });
|
||||||
|
|
||||||
currentY += 10;
|
currentY += 10;
|
||||||
|
|
||||||
|
// Info export
|
||||||
pdf.setFontSize(10);
|
pdf.setFontSize(10);
|
||||||
pdf.setFont('helvetica', 'normal');
|
pdf.setFont('helvetica', 'normal');
|
||||||
pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, currentY);
|
pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, currentY);
|
||||||
@ -520,70 +583,71 @@ const ShowDetailWalletDialog = () => {
|
|||||||
|
|
||||||
currentY += 20;
|
currentY += 20;
|
||||||
|
|
||||||
const tableHeaders = [
|
// Render table dengan header image
|
||||||
'Transaction Code',
|
|
||||||
'MSISDN Reffer',
|
|
||||||
'Transaction Type',
|
|
||||||
'Type',
|
|
||||||
'Pre Amount',
|
|
||||||
'Amount',
|
|
||||||
'Post Amount',
|
|
||||||
'Category',
|
|
||||||
'Date',
|
|
||||||
'Purpose',
|
|
||||||
'Notes'
|
|
||||||
];
|
|
||||||
|
|
||||||
const tableData = formattedData.map((item) => [
|
|
||||||
item['Transaction Code'],
|
|
||||||
item['MSISDN Reffer'],
|
|
||||||
item['Transaction Type'],
|
|
||||||
item['Type'],
|
|
||||||
item['Pre Amount'],
|
|
||||||
item['Amount'],
|
|
||||||
item['Post Amount'],
|
|
||||||
item['Category'],
|
|
||||||
item['Date'],
|
|
||||||
item['Purpose'],
|
|
||||||
item['Notes']
|
|
||||||
]);
|
|
||||||
|
|
||||||
const calculateLeftMargin = (
|
|
||||||
columnStyles: Record<number, { cellWidth: number }>,
|
|
||||||
pageWidth: number
|
|
||||||
): number => {
|
|
||||||
const totalTableWidth = Object.values(columnStyles).reduce(
|
|
||||||
(sum, col) => sum + col.cellWidth,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
return (pageWidth - totalTableWidth) / 2;
|
|
||||||
};
|
|
||||||
const columnStyles = {
|
|
||||||
0: { cellWidth: 25, halign: 'left' as const },
|
|
||||||
1: { cellWidth: 20, halign: 'left' as const },
|
|
||||||
2: { cellWidth: 25, halign: 'left' as const },
|
|
||||||
3: { cellWidth: 15, halign: 'center' as const },
|
|
||||||
4: { cellWidth: 18, halign: 'right' as const },
|
|
||||||
5: { cellWidth: 18, halign: 'right' as const },
|
|
||||||
6: { cellWidth: 18, halign: 'right' as const },
|
|
||||||
7: { cellWidth: 20, halign: 'left' as const },
|
|
||||||
8: { cellWidth: 30, halign: 'left' as const },
|
|
||||||
9: { cellWidth: 25, halign: 'left' as const },
|
|
||||||
10: { cellWidth: 25, halign: 'left' as const }
|
|
||||||
};
|
|
||||||
|
|
||||||
const leftMargin = calculateLeftMargin(columnStyles, pageWidth);
|
|
||||||
|
|
||||||
autoTable(pdf, {
|
autoTable(pdf, {
|
||||||
head: [tableHeaders],
|
head: [tableHeaders],
|
||||||
body: tableData,
|
body: tableData,
|
||||||
startY: currentY,
|
startY: currentY,
|
||||||
styles: {
|
styles: {
|
||||||
fontSize: 7,
|
fontSize: 7,
|
||||||
cellPadding: 2,
|
cellPadding: 1.5,
|
||||||
overflow: 'linebreak',
|
overflow: 'linebreak',
|
||||||
halign: 'center'
|
halign: 'left',
|
||||||
|
lineWidth: 0.1,
|
||||||
|
lineColor: [200, 200, 200]
|
||||||
|
},
|
||||||
|
headStyles: {
|
||||||
|
fillColor: [68, 114, 196],
|
||||||
|
textColor: [255, 255, 255],
|
||||||
|
fontStyle: 'bold',
|
||||||
|
halign: 'center',
|
||||||
|
cellPadding: 1.5
|
||||||
|
},
|
||||||
|
columnStyles: columnStyles,
|
||||||
|
tableWidth: 'wrap',
|
||||||
|
margin: {
|
||||||
|
left: leftMargin,
|
||||||
|
right: leftMargin,
|
||||||
|
top: 10,
|
||||||
|
bottom: 10
|
||||||
|
},
|
||||||
|
didDrawPage: (data: any) => {
|
||||||
|
if (data.pageNumber > 1) {
|
||||||
|
pdf.setFontSize(10);
|
||||||
|
pdf.setFont('helvetica', 'normal');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
theme: 'grid',
|
||||||
|
didDrawCell: (data: any) => {
|
||||||
|
if (data.section === 'body') {
|
||||||
|
pdf.setDrawColor(200, 200, 200);
|
||||||
|
pdf.setLineWidth(0.1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showHead: 'everyPage'
|
||||||
|
});
|
||||||
|
} catch (imageError) {
|
||||||
|
console.error('Error loading header image:', imageError);
|
||||||
|
|
||||||
|
// Fallback tanpa gambar header
|
||||||
|
pdf.setFontSize(16);
|
||||||
|
pdf.setFont('helvetica', 'bold');
|
||||||
|
pdf.text('Wallet Statement Details', pageWidth / 2, 20, { align: 'center' });
|
||||||
|
|
||||||
|
pdf.setFontSize(10);
|
||||||
|
pdf.setFont('helvetica', 'normal');
|
||||||
|
pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, 30);
|
||||||
|
pdf.text(`Wallet ID: ${selectedWallet?.ID || '-'}`, 20, 36);
|
||||||
|
|
||||||
|
autoTable(pdf, {
|
||||||
|
head: [tableHeaders],
|
||||||
|
body: tableData,
|
||||||
|
startY: 45,
|
||||||
|
styles: {
|
||||||
|
fontSize: 7,
|
||||||
|
cellPadding: 1.5,
|
||||||
|
overflow: 'linebreak',
|
||||||
|
halign: 'left'
|
||||||
},
|
},
|
||||||
headStyles: {
|
headStyles: {
|
||||||
fillColor: [68, 114, 196],
|
fillColor: [68, 114, 196],
|
||||||
@ -591,22 +655,22 @@ const ShowDetailWalletDialog = () => {
|
|||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
halign: 'center'
|
halign: 'center'
|
||||||
},
|
},
|
||||||
columnStyles,
|
columnStyles: columnStyles,
|
||||||
tableWidth: 'wrap',
|
tableWidth: 'wrap',
|
||||||
margin: { top: currentY, left: leftMargin },
|
margin: { left: leftMargin, right: leftMargin, top: 10, bottom: 10 },
|
||||||
didDrawCell: (data: any) => {
|
theme: 'grid',
|
||||||
if (data.section === 'body') {
|
showHead: 'everyPage',
|
||||||
pdf.setDrawColor(200, 200, 200);
|
didDrawPage: (data: any) => {
|
||||||
pdf.setLineWidth(0.1);
|
if (data.pageNumber > 1) {
|
||||||
|
pdf.setFontSize(10);
|
||||||
|
pdf.setFont('helvetica', 'normal');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`;
|
|
||||||
pdf.save(fileName);
|
|
||||||
} catch (imageError) {
|
|
||||||
console.error('Error loading header image:', imageError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`;
|
||||||
|
pdf.save(fileName);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error exporting to PDF:', error);
|
console.error('Error exporting to PDF:', error);
|
||||||
toast.error('Failed to export PDF');
|
toast.error('Failed to export PDF');
|
||||||
@ -663,7 +727,7 @@ const ShowDetailWalletDialog = () => {
|
|||||||
<Dialog open={showDetailDialog} onOpenChange={setShowDetailDialog}>
|
<Dialog open={showDetailDialog} onOpenChange={setShowDetailDialog}>
|
||||||
<DialogContent className="w-screen max-w-screen max-h-screen p-4 overflow-hidden">
|
<DialogContent className="w-screen max-w-screen max-h-screen p-4 overflow-hidden">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Details Walletsss Statementssss</DialogTitle>
|
<DialogTitle>Details Wallets Statement</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<DialogDescription />
|
<DialogDescription />
|
||||||
|
|
||||||
@ -695,4 +759,4 @@ const ShowDetailWalletDialog = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ShowDetailWalletDialog;
|
export default ShowDetailWalletDialog;
|
||||||
Reference in New Issue
Block a user