// State and defaults window.Pro = { components: [], selected: null, draggedType: null, idCounter: 0, items: [], data: { store: {name: 'ร้านของฉัน', branch: '', address: '', phone: '', taxId: '', logoUrl: '', promptpayId: ''}, receipt: {id: 'INV-' + new Date().getTime(), date: '', time: '', table: '', staff: ''}, vatRate: 7 } }; Pro.now = function() { const d = new Date(); return { date: d.toLocaleDateString('th-TH'), time: d.toLocaleTimeString('th-TH', {hour: '2-digit', minute: '2-digit'}) }; }; Pro.defaults = function(type) { const g = Pro.data; return { heading: {text: 'หัวข้อ', align: 'center', size: '20px', bold: true, inline: true}, text: {text: 'ข้อความ', align: 'left', size: '14px', inline: true}, logo: {url: '', width: '120px', align: 'center'}, image: {url: '', width: '120px', align: 'center'}, divider: {style: 'solid', color: '#ddd', thickness: '1px'}, spacer: {height: '20px'}, 'store-info': {inline: true}, 'receipt-info': {inline: true}, 'items-table': {}, summary: {}, 'payment-info': {method: 'เงินสด', cashReceived: ''}, barcode: {value: g.receipt.id, height: '50', width: '1'}, promptpay: {useTotal: true, amount: ''}, footer: {text: 'ขอบคุณที่ใช้บริการ', align: 'center', size: '14px', inline: true}, box: { padding: 10, margin: 5, borderWidth: 1, borderStyle: 'solid', borderColor: '#ddd', borderRadius: 4, backgroundColor: 'transparent', width: '', height: '', layout: 'block', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'stretch', gap: 10, gridColumns: 'repeat(2, 1fr)' } }[type] || {}; }; Pro.calcSummary = function() { const subtotal = Pro.items.reduce((s, it) => s + (Number(it.qty) || 0) * (Number(it.price) || 0), 0); const vat = subtotal * ((Number(Pro.data.vatRate) || 0) / 100); const total = subtotal + vat; return {subtotal, vat, total, items: Pro.items.length}; };