import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart'; import '../../../common/extension/extension.dart'; import '../../../domain/order/order.dart'; import '../../../domain/outlet/outlet.dart'; import 'receipt_component_builder.dart'; class PrintUi { Future> printOrder({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); bytes += builder.header( outletName: outlet.name, address: outlet.address, phoneNumber: outlet.phoneNumber, ); bytes += builder.orderInfo( orderNumber: order.orderNumber, customerName: order.metadata['customer_name'] ?? '-', cashierName: cashierName, paymentMethod: order.payments.last.paymentMethodName, tableNumber: order.tableNumber, ); bytes += builder.orderType(order.orderType); bytes += builder.emptyLines(1); for (final item in order.orderItemNotCancelled) { bytes += builder.orderItem( productName: item.productName, quantity: item.quantity, unitPrice: item.unitPrice.currencyFormatRpV2, totalPrice: item.totalPrice.currencyFormatRpV2, variantName: item.productVariantName, notes: item.notes, ); } bytes += builder.summary( totalItems: order.orderItems.length, subtotal: order.subtotal.currencyFormatRpV2, discount: order.discountAmount.currencyFormatRpV2, total: order.totalAmount.currencyFormatRpV2, paid: order.totalPaid.currencyFormatRpV2, ); bytes += builder.footer(); return bytes; } Future> printChecker({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); // Header bytes += builder.textCenter('Table Checker', bold: true); bytes += builder.separator(); bytes += builder.textCenter( 'Table : ${order.tableNumber.isNotEmpty ? order.tableNumber : '-'}', bold: true, ); bytes += builder.separator(); // Order info — label : value, left aligned bytes += builder.orderInfoSimple( orderNumber: order.orderNumber, orderType: order.orderType, cashierName: cashierName, customerName: order.metadata['customer_name'] ?? '-', ); bytes += builder.separator(); // Items — qty NAMA (uppercase), variant indent for (final item in order.orderItems) { final name = item.productName.toUpperCase(); bytes += builder.itemText('${item.quantity} $name'); if (item.productVariantName.isNotEmpty) { bytes += builder.itemText(' ${item.productVariantName.toUpperCase()}', bold: false); } if (item.notes.isNotEmpty) { bytes += builder.itemText(' *${item.notes}', bold: false); } } bytes += builder.separator(); bytes += builder.cutOnly(); return bytes; } Future> printKitchen({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); for (final item in order.orderItems) { bytes += generator.reset(); // Header bytes += builder.row2Columns('Kitchen', order.orderType.toUpperCase(), bold: true); bytes += builder.separator(); bytes += builder.textCenter( 'Table : ${order.tableNumber.isNotEmpty ? order.tableNumber : '-'}', bold: true, ); bytes += builder.separator(); // Order info bytes += builder.orderInfoSimple( orderNumber: order.orderNumber, cashierName: cashierName, ); bytes += builder.separator(); // Single item final name = item.productName.toUpperCase(); bytes += builder.itemText('${item.quantity} $name'); if (item.productVariantName.isNotEmpty) { bytes += builder.itemText(' ${item.productVariantName.toUpperCase()}', bold: false); } if (item.notes.isNotEmpty) { bytes += builder.itemText(' *${item.notes}', bold: false); } bytes += builder.separator(); bytes += builder.cutOnly(); } return bytes; } Future> printBar({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); for (final item in order.orderItems) { bytes += generator.reset(); // Header bytes += builder.textCenter('Bar', bold: true); bytes += builder.separator(); bytes += builder.textCenter( 'Table : ${order.tableNumber.isNotEmpty ? order.tableNumber : '-'}', bold: true, ); bytes += builder.separator(); // Order info bytes += builder.orderInfoSimple( orderNumber: order.orderNumber, orderType: order.orderType, cashierName: cashierName, ); bytes += builder.separator(); // Single item final name = item.productName.toUpperCase(); bytes += builder.itemText('${item.quantity} $name'); if (item.productVariantName.isNotEmpty) { bytes += builder.itemText(' ${item.productVariantName.toUpperCase()}', bold: false); } if (item.notes.isNotEmpty) { bytes += builder.itemText(' *${item.notes}', bold: false); } bytes += builder.separator(); bytes += builder.cutOnly(); } return bytes; } Future> printTicket({ required Order order, required Outlet outlet, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); bytes += builder.header( outletName: outlet.name, address: outlet.address, phoneNumber: outlet.phoneNumber, ); bytes += builder.dateTime(DateTime.now()); bytes += builder.row2Columns('Code No.', order.orderNumber); bytes += builder.separator(); bytes += builder.emptyLines(2); bytes += builder.qrCode('1267128127182182'); bytes += builder.emptyLines(1); bytes += builder.textCenter('1267128127182182'); bytes += builder.emptyLines(2); bytes += builder.footer(); return bytes; } Future> printCashier({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); bytes += builder.header( outletName: outlet.name, address: outlet.address, phoneNumber: outlet.phoneNumber, ); bytes += builder.orderInfo( orderNumber: order.orderNumber, customerName: order.metadata['customer_name'] ?? '-', cashierName: cashierName, paymentMethod: order.payments.isEmpty ? null : order.payments.last.paymentMethodName, tableNumber: order.tableNumber, ); bytes += builder.orderType(order.orderType); bytes += builder.emptyLines(1); for (final item in order.orderItemNotCancelled) { bytes += builder.orderItem( productName: item.productName, quantity: item.quantity, unitPrice: item.unitPrice.currencyFormatRpV2, totalPrice: item.totalPrice.currencyFormatRpV2, variantName: item.productVariantName, notes: item.notes, ); } bytes += builder.summary( totalItems: order.orderItems.length, subtotal: order.subtotal.currencyFormatRpV2, discount: order.discountAmount.currencyFormatRpV2, total: order.totalAmount.currencyFormatRpV2, paid: order.totalPaid.currencyFormatRpV2, ); bytes += builder.footer(message: 'Kasir'); return bytes; } Future> printVoid({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); bytes += builder.header( outletName: outlet.name, address: outlet.address, phoneNumber: outlet.phoneNumber, ); bytes += builder.dateTime(DateTime.now()); bytes += builder.orderInfo( orderNumber: order.orderNumber, customerName: order.metadata['customer_name'] ?? '-', cashierName: cashierName, paymentMethod: order.payments.isEmpty ? null : order.payments.last.paymentMethodName, tableNumber: order.tableNumber, ); bytes += builder.orderType('Void'); bytes += builder.emptyLines(1); for (final item in order.orderItems) { bytes += builder.orderItem( productName: item.productName, quantity: item.quantity, unitPrice: item.unitPrice.currencyFormatRpV2, totalPrice: item.totalPrice.currencyFormatRpV2, variantName: item.productVariantName, notes: item.notes, ); } bytes += builder.summary( totalItems: order.orderItems.length, subtotal: order.subtotal.currencyFormatRpV2, discount: order.discountAmount.currencyFormatRpV2, total: order.totalAmount.currencyFormatRpV2, paid: order.totalPaid.currencyFormatRpV2, ); bytes += builder.footer(message: 'Kasir'); return bytes; } Future> printSplit({ required Order order, required Outlet outlet, required String cashierName, int paper = 58, }) async { List bytes = []; final profile = await CapabilityProfile.load(); final generator = Generator( paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile, ); final builder = ReceiptComponentBuilder( generator: generator, paperSize: paper, ); bytes += generator.reset(); bytes += builder.header( outletName: outlet.name, address: outlet.address, phoneNumber: outlet.phoneNumber, ); bytes += builder.dateTime(DateTime.now()); bytes += builder.orderInfo( orderNumber: order.orderNumber, customerName: order.metadata['customer_name'] ?? '-', cashierName: cashierName, paymentMethod: order.payments.isEmpty ? null : order.payments.last.paymentMethodName, tableNumber: order.tableNumber, ); bytes += builder.orderType('Split'); bytes += builder.row2Columns( 'Split', '${order.payments.last.splitNumber} / ${order.payments.last.splitTotal}', ); bytes += builder.separator(); bytes += builder.emptyLines(1); for (final item in order.orderItems) { bytes += builder.orderItem( productName: item.productName, quantity: item.quantity, unitPrice: item.unitPrice.currencyFormatRpV2, totalPrice: item.totalPrice.currencyFormatRpV2, variantName: item.productVariantName, notes: item.notes, ); } bytes += builder.emptyLines(1); bytes += builder.summary( totalItems: 0, subtotal: order.payments.last.amount.currencyFormatRpV2, discount: 0.currencyFormatRpV2, total: order.payments.last.amount.currencyFormatRpV2, paid: order.payments.last.amount.currencyFormatRpV2, ); bytes += builder.footer(message: 'Terima Kasih'); return bytes; } }