104 lines
3.6 KiB
TypeScript
104 lines
3.6 KiB
TypeScript
import JsPDF from "jspdf";
|
|
import autoTable from "jspdf-autotable";
|
|
import {useState} from "react";
|
|
import dayjs from "dayjs";
|
|
|
|
|
|
function drawItem(doc: JsPDF, item: {
|
|
title: string;
|
|
content?: string
|
|
}, y: number, align: 'left' | 'right' = 'left', fontSize: number = 13) {
|
|
doc.setFontSize(fontSize);
|
|
// const width = doc.internal.pageSize.getWidth();
|
|
doc.text(item.title, align == 'left' ? 20 : 180, y);
|
|
if (item.content && item.content.length > 0) doc.text(item.content, align == 'left' ? 65 : 230, y, {maxWidth: 150});
|
|
}
|
|
|
|
export function GeneratePdf(bill: BillModel) {
|
|
const doc = new JsPDF({
|
|
orientation: 'landscape',
|
|
format: 'a4'
|
|
});
|
|
// const width = doc.internal.pageSize.getWidth();
|
|
// const height = doc.internal.pageSize.getHeight();
|
|
doc.setFont('Helvetica', 'normal', 'bold');
|
|
doc.setFontSize(20);
|
|
doc.text('ACKNOWLEDGEMENT RECEIPT', 100, 20, {});
|
|
|
|
doc.setFont('Helvetica', 'normal', 'normal');
|
|
drawItem(doc, {title: 'Student Name:', content: bill.student_english_name || bill.student_chinese_name || 'N/A'}, 40)
|
|
drawItem(doc, {title: 'Reference Number:', content: `${bill.id}`}, 40, "right")
|
|
drawItem(doc, {title: `${bill.student_number?"Student":"Bill"} Number:`, content: `${bill.student_number || bill.application_number}`}, 48)
|
|
drawItem(doc, {title: 'Print Date:', content: dayjs().format('YYYY-MM-DD')}, 48, "right")
|
|
|
|
drawItem(doc, {
|
|
title: 'Programme:',
|
|
content: bill.programme_english_name || 'N/A'
|
|
}, 56)
|
|
if(bill.programme_english_name && bill.programme_english_name.length > 0){
|
|
drawItem(doc, {title: 'Mode of Study:', content: bill.attendance_mode == 'FT' ? 'FULL-TIME': bill.attendance_mode}, bill.programme_english_name.length > 70?70:64)
|
|
}
|
|
// draw table
|
|
autoTable(doc, {
|
|
startY: 80,
|
|
theme: 'grid',
|
|
|
|
margin: {top: 37, left: 20, right: 20},
|
|
styles: {
|
|
fontSize: 13,
|
|
fillColor: [255, 255, 255],
|
|
textColor: [0, 0, 0],
|
|
lineColor: [0, 0, 0],
|
|
lineWidth: 0.2,
|
|
minCellHeight: 10,
|
|
valign: 'middle'
|
|
},
|
|
headStyles: {
|
|
fontSize: 15,
|
|
},
|
|
head: [['No.', 'Transaction Date', 'Payment Type', 'Payment Method', 'HK$']],
|
|
body: [
|
|
...(bill.details.map(it=>{
|
|
return [
|
|
`#${it.id}`,
|
|
dayjs(bill.paid_at).format('YYYY-MM-DD'),
|
|
it.bill_type,
|
|
`${bill.payment_channel}` + (bill.payment_method && bill.payment_channel != bill.payment_method ? `(${bill.payment_method})` : ''),
|
|
`${it.amount}`
|
|
];
|
|
})),
|
|
[{
|
|
colSpan: 4,
|
|
content: 'TOTAL:',
|
|
styles: {valign: 'middle', halign: 'right'},
|
|
}, `${bill.amount}`],
|
|
],
|
|
})
|
|
// draw foot
|
|
drawItem(doc, {title: 'Remarks:', content: ''}, 155)
|
|
drawItem(doc, {title: 'Cashier:', content: ''}, 155, "right")
|
|
|
|
doc.setFont('Helvetica', 'italic');
|
|
drawItem(doc, {title: 'Please retain this acknowledgement receipt for your record.'}, 185)
|
|
|
|
doc.save(`Receipt-${bill.id}.pdf`);
|
|
}
|
|
|
|
|
|
// use service work generate pdf and download
|
|
export function useDownloadReceiptPDF() {
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const downloadPDF = (bill: BillModel) => {
|
|
setLoading(true)
|
|
setTimeout(() => {
|
|
GeneratePdf(bill)
|
|
setLoading(false)
|
|
}, 100);
|
|
}
|
|
|
|
return {
|
|
loading,
|
|
downloadPDF
|
|
}
|
|
} |