diff --git a/static/src/js/escpos_generator.js b/static/src/js/escpos_generator.js index e2e5d9f..ef5e455 100755 --- a/static/src/js/escpos_generator.js +++ b/static/src/js/escpos_generator.js @@ -305,6 +305,50 @@ export class EscPosGenerator { : subName; cmds.push(...this.addLine(prefix + displaySub, { bold: true })); } + + // Print subline notes if any! + if (sub.note) { + const rawSubNote = String(sub.note); + const rawSubLines = rawSubNote.split('\n'); + const wrappedSubLines = []; + + // Prefix will be " * " (6 chars width) + const prefixText = ' * '; + const maxSubNoteWidth = W - prefixText.length; + + rawSubLines.forEach(rawLine => { + const words = rawLine.split(/\s+/); + let currentLine = ''; + for (const word of words) { + if (!word) continue; + if ((currentLine + (currentLine ? ' ' : '') + word).length <= maxSubNoteWidth) { + currentLine += (currentLine ? ' ' : '') + word; + } else { + if (currentLine) { + wrappedSubLines.push(currentLine); + } + let tempWord = word; + while (tempWord.length > maxSubNoteWidth) { + wrappedSubLines.push(tempWord.substring(0, maxSubNoteWidth)); + tempWord = tempWord.substring(maxSubNoteWidth); + } + currentLine = tempWord; + } + } + if (currentLine) { + wrappedSubLines.push(currentLine); + } + }); + + wrappedSubLines.forEach((l, i) => { + const prefix = i === 0 ? prefixText : ' '; + if (receiptData.isBasicReceipt) { + cmds.push(...this.addLine(prefix + l, { bold: true, height: 2 })); + } else { + cmds.push(...this.addLine(prefix + l, { bold: true })); + } + }); + } }); } diff --git a/static/src/js/pos_receipt_printer.js b/static/src/js/pos_receipt_printer.js index 30fcde3..45aa887 100755 --- a/static/src/js/pos_receipt_printer.js +++ b/static/src/js/pos_receipt_printer.js @@ -880,9 +880,25 @@ patch(PosPrinterService.prototype, { (line.id && parent.id && parent.id === line.id); }) .map(subLine => { + // Construct combined sub-line note + let subNote = ''; + const subNoteParts = []; + const subCustomerNote = subLine.customer_note || subLine.customerNote || ''; + if (subCustomerNote) { + subNoteParts.push(subCustomerNote); + } + if (subLine.note) { + const subInternalNote = pos?.getStrNotes ? pos.getStrNotes(subLine.note) : (typeof subLine.note === 'string' ? subLine.note : ''); + if (subInternalNote) { + subNoteParts.push(subInternalNote); + } + } + subNote = subNoteParts.join(' | '); + return { productName: subLine.full_product_name || subLine.product_id?.display_name || '', quantity: subLine.qty || 0, + note: subNote, }; }) .filter(sub => sub.productName); @@ -1126,6 +1142,7 @@ patch(PosPrinterService.prototype, { lastParentLine.comboLines.push({ productName, quantity: qty, + note: note, }); console.log(`[BluetoothPrint] Added combo subline to parent:`, productName); } else {