`;
pdfContentWrapper.appendChild(summarySection);
// Add distribution charts
const chartsSection = document.createElement('div');
chartsSection.classList.add('grid', 'grid-cols-2', 'gap-6', 'mb-6');
chartsSection.innerHTML = `
Compliance Status Distribution
Duty Paid by Product Category
`;
pdfContentWrapper.appendChild(chartsSection);
// Populate PDF charts (re-use logic but target PDF elements)
const totalShipments = customsRecords.length;
const complianceStatusCounts = customsRecords.reduce((acc, record) => { acc[record.complianceStatus] = (acc[record.complianceStatus] || 0) + 1; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfComplianceStatusChart'), complianceStatusCounts, 'compliance_status');
const dutyByProductCategory = customsRecords.reduce((acc, record) => { acc[record.productCategory] = (acc[record.productCategory] || 0) + record.dutyPaid; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfDutyByProductCategoryChart'), dutyByProductCategory, 'currency');
const penaltiesByReason = customsRecords
.filter(record => record.penaltyAmount > 0 && record.penaltyReason !== 'N/A')
.reduce((acc, record) => { acc[record.penaltyReason] = (acc[record.penaltyReason] || 0) + record.penaltyAmount; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfPenaltiesByReasonChart'), penaltiesByReason, 'currency');
// Add detailed customs records list table
const customsListSection = document.createElement('div');
customsListSection.innerHTML = `
Detailed Customs Records
| ID |
Shipment Date |
Origin Country |
Destination Country |
Product Category |
Declared Value ($) |
Duty Paid ($) |
Compliance Status |
Penalty ($) |
Penalty Reason |
${dashboardCustomsTableBody.innerHTML}
`;
pdfContentWrapper.appendChild(customsListSection);
// Options for html2pdf
const options = {
margin: 10,
filename: 'Customs_Compliance_Dashboard.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, logging: true, dpi: 192, letterRendering: true },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
// Generate PDF from the temporary content wrapper
html2pdf().from(pdfContentWrapper).set(options).save();
// Clean up the temporary div (optional, as it's not appended to the DOM)
pdfContentWrapper.remove();
}
/**
* Loads initial sample data for the dashboard.
* Relevant to USA context.
*/
function loadSampleData() {
customsRecords = [
{ id: 'SHIP001', shipmentDate: '2024-06-01', originCountry: 'China', destinationCountry: 'USA', productCategory: 'Electronics', declaredValue: 15000.00, dutyPaid: 750.00, complianceStatus: 'Compliant', penaltyAmount: 0, penaltyReason: 'N/A' },
{ id: 'SHIP002', shipmentDate: '2024-06-05', originCountry: 'Mexico', destinationCountry: 'USA', productCategory: 'Apparel', declaredValue: 5000.00, dutyPaid: 150.00, complianceStatus: 'Compliant', penaltyAmount: 0, penaltyReason: 'N/A' },
{ id: 'SHIP003', shipmentDate: '2024-06-10', originCountry: 'Germany', destinationCountry: 'USA', productCategory: 'Machinery', declaredValue: 25000.00, dutyPaid: 1250.00, complianceStatus: 'Non-Compliant', penaltyAmount: 500.00, penaltyReason: 'Incorrect HS Code' },
{ id: 'SHIP004', shipmentDate: '2024-06-12', originCountry: 'Canada', destinationCountry: 'USA', productCategory: 'Raw Materials', declaredValue: 8000.00, dutyPaid: 0.00, complianceStatus: 'Compliant', penaltyAmount: 0, penaltyReason: 'N/A' },
{ id: 'SHIP005', shipmentDate: '2024-06-15', originCountry: 'India', destinationCountry: 'USA', productCategory: 'Textiles', declaredValue: 7000.00, dutyPaid: 210.00, complianceStatus: 'Under Review', penaltyAmount: 0, penaltyReason: 'Missing Documentation' },
{ id: 'SHIP006', shipmentDate: '2024-06-20', originCountry: 'USA', destinationCountry: 'UK', productCategory: 'Software', declaredValue: 10000.00, dutyPaid: 0.00, complianceStatus: 'Compliant', penaltyAmount: 0, penaltyReason: 'N/A' },
{ id: 'SHIP007', shipmentDate: '2024-06-25', originCountry: 'China', destinationCountry: 'USA', productCategory: 'Electronics', declaredValue: 12000.00, dutyPaid: 600.00, complianceStatus: 'Non-Compliant', penaltyAmount: 250.00, penaltyReason: 'Under-declared Value' }
];
}