shopify-custom-email-plugin/pdfGenerator.js
2026-05-18 22:14:41 +05:30

91 lines
4.0 KiB
JavaScript

const PDFDocument = require('pdfkit');
/**
* Generates a PDF invoice based on Shopify order data.
* @param {Object} orderData - The Shopify order payload
* @returns {Promise<Buffer>} - A promise that resolves to a Buffer containing the PDF data
*/
const generateInvoicePDF = (orderData) => {
return new Promise((resolve, reject) => {
try {
const doc = new PDFDocument({ margin: 50 });
let buffers = [];
doc.on('data', buffers.push.bind(buffers));
doc.on('end', () => {
const pdfData = Buffer.concat(buffers);
resolve(pdfData);
});
// Invoice Header
doc.fontSize(20).text('Invoice', { align: 'right' });
doc.moveDown();
doc.fontSize(12)
.text(`Order Number: ${orderData.name || orderData.order_number}`)
.text(`Date: ${new Date(orderData.created_at).toLocaleDateString()}`)
.moveDown();
// Store Info (You can customize this)
const shopName = process.env.SHOP_NAME || 'Your Store Name';
doc.fontSize(14).text(shopName);
doc.moveDown();
// Customer Info
doc.fontSize(14).text('Billed To:');
doc.fontSize(12).text(`${orderData.billing_address?.first_name || ''} ${orderData.billing_address?.last_name || ''}`);
doc.text(`${orderData.billing_address?.address1 || ''}`);
if (orderData.billing_address?.address2) {
doc.text(`${orderData.billing_address.address2}`);
}
doc.text(`${orderData.billing_address?.city || ''}, ${orderData.billing_address?.province || ''} ${orderData.billing_address?.zip || ''}`);
doc.text(`${orderData.billing_address?.country || ''}`);
doc.moveDown(2);
// Line Items Table Header
doc.fontSize(12).font('Helvetica-Bold');
doc.text('Item', 50, doc.y, { continued: true });
doc.text('Qty', 300, doc.y, { continued: true, width: 50, align: 'right' });
doc.text('Price', 350, doc.y, { continued: true, width: 100, align: 'right' });
doc.text('Total', 450, doc.y, { width: 100, align: 'right' });
doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
doc.moveDown(0.5);
// Line Items Table Rows
doc.font('Helvetica');
let currentY = doc.y;
if (orderData.line_items && orderData.line_items.length > 0) {
orderData.line_items.forEach(item => {
doc.text(item.name, 50, currentY, { width: 250 });
doc.text(item.quantity.toString(), 300, currentY, { width: 50, align: 'right' });
doc.text(`${orderData.currency} ${parseFloat(item.price).toFixed(2)}`, 350, currentY, { width: 100, align: 'right' });
const total = parseFloat(item.price) * item.quantity;
doc.text(`${orderData.currency} ${total.toFixed(2)}`, 450, currentY, { width: 100, align: 'right' });
doc.moveDown(0.5);
currentY = doc.y;
});
}
doc.moveTo(50, currentY).lineTo(550, currentY).stroke();
doc.moveDown(1);
// Totals
doc.text(`Subtotal: ${orderData.currency} ${orderData.subtotal_price}`, { align: 'right' });
if (orderData.total_tax > 0) {
doc.text(`Tax: ${orderData.currency} ${orderData.total_tax}`, { align: 'right' });
}
doc.text(`Shipping: ${orderData.currency} ${orderData.total_shipping_price_set?.shop_money?.amount || '0.00'}`, { align: 'right' });
doc.font('Helvetica-Bold').text(`Total: ${orderData.currency} ${orderData.total_price}`, { align: 'right' });
doc.end();
} catch (error) {
reject(error);
}
});
};
module.exports = { generateInvoicePDF };