feat(pos): print delivery notes over the network transport

This commit is contained in:
Dave 2026-09-03 17:54:41 +02:00
parent bee80d8ec8
commit d5a48226ff
2 changed files with 48 additions and 1 deletions

View file

@ -137,5 +137,30 @@ window.EposPrint = (function () {
}
}
return { getSettings, setSettings, imageToRaster, buildEposXml, printViaNetwork };
// Mirrors the delivery-note ESC/POS builder in receipt.html's
// printDelivery() — same fields, same "Include prices" toggle.
function buildEposDeliveryXml(s, showPrices) {
const parts = [];
parts.push('<text align="center" width="1" height="2">WFSALES POS&#10;</text>');
parts.push('<text align="center">Delivery Note&#10;</text>');
if (s.customer && s.customer.company) parts.push(`<text align="left">Company: ${xmlEscape(s.customer.company)}&#10;</text>`);
parts.push(`<text align="left">Customer: ${xmlEscape((s.customer && s.customer.name) || '—')}&#10;</text>`);
const d = new Date(s.createdAt);
parts.push(`<text align="left">Date: ${xmlEscape(d.toLocaleDateString('en-ZA'))}&#10;</text>`);
parts.push('<text align="left">--------------------------------&#10;</text>');
const itemLines = s.items.map(it => {
const qtyLine = ` ${it.qty} ${it.unit || 'ea'}`;
const priceSuffix = showPrices ? ` R ${((it.selling_price || 0) * it.qty).toFixed(2)}` : '';
return `${xmlEscape(it.description || it.sku)}&#10;${xmlEscape(qtyLine + priceSuffix)}&#10;`;
}).join('');
parts.push(`<text align="left">${itemLines}</text>`);
parts.push('<text align="left">--------------------------------&#10;</text>');
if (showPrices) parts.push(`<text align="left">TOTAL: R ${s.total.toFixed(2)}&#10;</text>`);
parts.push('<text align="left">Received by: __________ Driver: __________&#10;</text>');
parts.push('<feed line="3"/>');
parts.push('<cut type="feed"/>');
return `<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><epos-print xmlns="http://www.epson-pos.com/schemas/2011/03/epos-print">${parts.join('')}</epos-print></s:Body></s:Envelope>`;
}
return { getSettings, setSettings, imageToRaster, buildEposXml, printViaNetwork, buildEposDeliveryXml };
})();

View file

@ -651,6 +651,28 @@ async function printDelivery(){
errBox.classList.remove('err');
btn.disabled = true;
status.textContent = 'Printing delivery note…';
const printerSettings = window.EposPrint.getSettings();
if(printerSettings.type === 'network'){
if(!printerSettings.ip){
status.textContent = 'Set the printer IP address in Printer settings first.';
errBox.classList.add('err');
btn.disabled = false;
return;
}
const dnToggleNet = document.getElementById('dnShowPrices');
const showPricesNet = dnToggleNet ? !!dnToggleNet.checked : true;
try{
const xml = window.EposPrint.buildEposDeliveryXml(sale, showPricesNet);
await window.EposPrint.printViaNetwork(printerSettings.ip, xml);
status.textContent = 'Delivery note printed · ' + printerSettings.ip;
}catch(e){
errBox.classList.add('err');
status.textContent = 'DN print failed: ' + e.message;
}finally{
btn.disabled = false;
}
return;
}
if(!btChar){
status.textContent = 'Pair a Bluetooth printer first to print.';
errBox.classList.add('err');