Update: 2026-05-15 04:35:25

This commit is contained in:
Hamza-Ayed
2026-05-15 04:35:25 +03:00
parent 1ca7e01ce0
commit 2f1ecca593
14 changed files with 858 additions and 10 deletions

View File

@@ -0,0 +1,109 @@
import 'package:esc_pos_printer/esc_pos_printer.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import '../utils/logger.dart';
class ThermalPrinterService {
/// Prints an invoice to a WiFi thermal printer
Future<bool> printInvoice({
required String ip,
required Map<String, dynamic> invoice,
int port = 9100,
PaperSize paperSize = PaperSize.mm80,
}) async {
try {
final profile = await CapabilityProfile.load();
final printer = NetworkPrinter(paperSize, profile);
final PosPrintResult res = await printer.connect(ip, port: port);
if (res != PosPrintResult.success) {
AppLogger.error('Could not connect to printer at $ip:$port');
return false;
}
AppLogger.print('Connected to printer, generating ticket...');
// Generate Ticket
_buildInvoiceTicket(printer, invoice);
printer.feed(2);
printer.cut();
printer.disconnect();
return true;
} catch (e) {
AppLogger.error('Thermal printing failed', e);
return false;
}
}
void _buildInvoiceTicket(NetworkPrinter printer, Map<String, dynamic> invoice) {
// Header
printer.text(
'M U S A D A Q',
styles: const PosStyles(
align: PosAlign.center,
height: PosTextSize.size2,
width: PosTextSize.size2,
bold: true,
),
);
printer.text(
'نظام الفوترة الإلكترونية',
styles: const PosStyles(align: PosAlign.center),
);
printer.hr();
// Invoice Info
printer.text('رقم الفاتورة: ${invoice['invoice_number'] ?? '-'}');
printer.text('التاريخ: ${invoice['invoice_date'] ?? '-'}');
printer.text('المورد: ${invoice['supplier_name'] ?? '-'}');
if (invoice['supplier_tin'] != null) {
printer.text('الرقم الضريبي: ${invoice['supplier_tin']}');
}
printer.hr();
// Table Header
printer.row([
PosColumn(text: 'البند', width: 6),
PosColumn(text: 'الكمية', width: 2, styles: const PosStyles(align: PosAlign.center)),
PosColumn(text: 'الإجمالي', width: 4, styles: const PosStyles(align: PosAlign.right)),
]);
printer.hr();
// Items
final items = invoice['items'] as List? ?? [];
for (var item in items) {
printer.row([
PosColumn(text: item['description'] ?? '-', width: 6),
PosColumn(text: item['quantity']?.toString() ?? '1', width: 2, styles: const PosStyles(align: PosAlign.center)),
PosColumn(text: item['line_total']?.toString() ?? '0', width: 4, styles: const PosStyles(align: PosAlign.right)),
]);
}
printer.hr();
// Totals
printer.row([
PosColumn(text: 'المجموع الجزئي:', width: 8),
PosColumn(text: '${invoice['subtotal'] ?? 0}', width: 4, styles: const PosStyles(align: PosAlign.right)),
]);
printer.row([
PosColumn(text: 'الضريبة:', width: 8),
PosColumn(text: '${invoice['tax_amount'] ?? 0}', width: 4, styles: const PosStyles(align: PosAlign.right)),
]);
printer.row([
PosColumn(text: 'الإجمالي الكلي:', width: 8, styles: const PosStyles(bold: true)),
PosColumn(text: '${invoice['grand_total'] ?? 0} JOD', width: 4, styles: const PosStyles(align: PosAlign.right, bold: true)),
]);
printer.hr();
printer.text(
'شكراً لاستخدامكم مُصادَق',
styles: const PosStyles(align: PosAlign.center, italic: true),
);
printer.text(
'www.musadaq.com',
styles: const PosStyles(align: PosAlign.center),
);
}
}