482 lines
13 KiB
Dart
482 lines
13 KiB
Dart
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<List<int>> printOrder({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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<List<int>> printChecker({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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,
|
|
);
|
|
|
|
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<List<int>> printKitchen({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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, 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<List<int>> printBar({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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<List<int>> printTicket({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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<List<int>> printCashier({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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<List<int>> printVoid({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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<List<int>> printSplit({
|
|
required Order order,
|
|
required Outlet outlet,
|
|
required String cashierName,
|
|
int paper = 58,
|
|
}) async {
|
|
List<int> 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;
|
|
}
|
|
}
|