import 'dart:developer'; import 'dart:typed_data'; import 'package:barcode_image/barcode_image.dart'; import 'package:enaklo_pos/core/extensions/string_ext.dart'; import 'package:enaklo_pos/core/utils/printer_service.dart'; import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart'; import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart'; import 'package:enaklo_pos/data/datasources/outlet_local_datasource.dart'; import 'package:enaklo_pos/data/datasources/product_local_datasource.dart'; import 'package:enaklo_pos/data/datasources/settings_local_datasource.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart'; import 'package:enaklo_pos/data/type/bussines_type.dart'; import 'package:enaklo_pos/presentation/home/models/product_quantity.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:barcode/barcode.dart'; import 'package:image/image.dart' as img; Future onPrint( BuildContext context, { required List productQuantity, required Order order, }) async { final outlet = await OutletLocalDatasource().get(); final settings = await SettingsLocalDatasource().getTax(); final authData = await AuthLocalDataSource().getAuthData(); if (outlet.businessType == BusinessType.restaurant) { final checkerPrinter = await ProductLocalDatasource.instance.getPrinterByCode('checker'); final kitchenPrinter = await ProductLocalDatasource.instance.getPrinterByCode('kitchen'); final barPrinter = await ProductLocalDatasource.instance.getPrinterByCode('bar'); final receiptPrinter = await ProductLocalDatasource.instance.getPrinterByCode('receipt'); if (receiptPrinter != null) { try { final printValue = await PrintDataoutputs.instance.printOrderV4( order, authData.user?.name ?? "", '', 0, 0, settings.value, receiptPrinter.paper.toIntegerFromText, order.orderType ?? "", outlet, productQuantity); await PrinterService() .printWithPrinter(receiptPrinter, printValue, context); } catch (e, stackTrace) { FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Print receipt failed', information: [ 'Order ID: ${order.id}', 'Printer: ${receiptPrinter.name}', ], ); log("Error printing receipt order: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing receipt order: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Receipt printer not found', null, reason: 'Receipt printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer receipt')), ); } // Checker printer if (checkerPrinter != null) { try { final printValue = await PrintDataoutputs.instance.printChecker( productQuantity, order.tableNumber ?? "", order.orderNumber ?? "", authData.user?.name ?? "", order.metadata?['customer_name'] ?? "", checkerPrinter.paper.toIntegerFromText, order.orderType ?? "", ); if (productQuantity.isNotEmpty) { await PrinterService() // ignore: use_build_context_synchronously .printWithPrinter(checkerPrinter, printValue, context); } } catch (e, stackTrace) { log("Error printing checker: $e"); FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Error printing checker ${checkerPrinter.name}', information: [ 'Printer: checker', 'data: ${checkerPrinter.toMap()}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing checker: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Checker printer not found', null, reason: 'Checker printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer checker')), ); } // Kitchen printer if (kitchenPrinter != null) { try { final productByPrinter = productQuantity .where((item) => item.product.printerType == 'kitchen') .toList(); final printValue = await PrintDataoutputs.instance.printKitchen( productByPrinter, order.tableNumber ?? "", order.orderNumber ?? "", authData.user?.name ?? "", order.metadata?['customer_name'] ?? "", kitchenPrinter.paper.toIntegerFromText, order.orderType ?? "", ); if (productByPrinter.isNotEmpty) { await PrinterService() .printWithPrinter(kitchenPrinter, printValue, context); } } catch (e, stackTrace) { log("Error printing kitchen order: $e"); FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Error printing kitchen ${kitchenPrinter.name}', information: [ 'Printer: kitchen', 'data: ${kitchenPrinter.toMap()}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing kitchen order: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Kitchen printer not found', null, reason: 'Kitchen printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer kitchen')), ); } // Bar printer if (barPrinter != null) { try { final productByPrinter = productQuantity .where((item) => item.product.printerType == 'bar') .toList(); final printValue = await PrintDataoutputs.instance.printBar( productByPrinter, order.tableNumber ?? "", order.orderNumber ?? "", authData.user?.name ?? "", order.metadata?['customer_name'] ?? "", barPrinter.paper.toIntegerFromText, order.orderType ?? "", ); if (productByPrinter.isNotEmpty) { await PrinterService() .printWithPrinter(barPrinter, printValue, context); } } catch (e, stackTrace) { log("Error printing bar order: $e"); FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Error printing bar ${barPrinter.name}', information: [ 'Printer: bar', 'data: ${barPrinter.toMap()}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing bar order: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Bar printer not found', null, reason: 'Bar printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer bar')), ); } } if (outlet.businessType == BusinessType.ticketing) { final ticketPrinter = await ProductLocalDatasource.instance.getPrinterByCode('ticket'); final barcode = await generateBarcodeAsUint8List(order.orderNumber ?? ""); if (ticketPrinter != null) { try { final printValue = await PrintDataoutputs.instance.printTicket( order.totalAmount ?? 0, barcode, ticketPrinter.paper.toIntegerFromText, ); await PrinterService() // ignore: use_build_context_synchronously .printWithPrinter(ticketPrinter, printValue, context); } catch (e, stackTrace) { FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Error printing ticket ${ticketPrinter.name}', information: [ 'Printer: ticket', 'data: ${ticketPrinter.toMap()}', ], ); log("Error printing ticket: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing ticket: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Ticket printer not found', null, reason: 'Ticket printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer ticket')), ); } } } Future onPrintRecipt( context, { required Order order, required String paymentMethod, required int nominalBayar, required int kembalian, required List productQuantity, }) async { final receiptPrinter = await ProductLocalDatasource.instance.getPrinterByCode('receipt'); final authData = await AuthLocalDataSource().getAuthData(); final settings = await SettingsLocalDatasource().getTax(); final outlet = await OutletLocalDatasource().get(); if (receiptPrinter != null) { try { final printValue = await PrintDataoutputs.instance.printOrderV4( order, authData.user?.name ?? "", paymentMethod, nominalBayar, kembalian, settings.value, receiptPrinter.paper.toIntegerFromText, order.orderType ?? "", outlet, productQuantity); await PrinterService() .printWithPrinter(receiptPrinter, printValue, context); } catch (e, stackTrace) { FirebaseCrashlytics.instance.recordError( e, stackTrace, reason: 'Print receipt failed', information: [ 'Order ID: ${order.id}', 'Payment Method: $paymentMethod', 'Printer: ${receiptPrinter.name}', ], ); log("Error printing receipt order: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing receipt order: $e')), ); } } else { FirebaseCrashlytics.instance.recordError( 'Kitchen printer not found', null, reason: 'Kitchen printer not found / Printer not setting in printer page', information: [ 'Order ID: ${order.id}', ], ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Anda belum menghubungkan printer kitchen')), ); } } Future onPrinVoidRecipt( context, { required Order order, required List productItemVoid, required int totalVoid, }) async { final receiptPrinter = await ProductLocalDatasource.instance.getPrinterByCode('receipt'); final authData = await AuthLocalDataSource().getAuthData(); final settings = await SettingsLocalDatasource().getTax(); final outlet = await OutletLocalDatasource().get(); if (receiptPrinter != null) { try { final printValue = await PrintDataoutputs.instance.printVoidOrder( order, authData.user?.name ?? "", settings.value, receiptPrinter.paper.toIntegerFromText, totalVoid, outlet, productItemVoid); await PrinterService() .printWithPrinter(receiptPrinter, printValue, context); } catch (e) { log("Error printing receipt order: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error printing receipt order: $e')), ); } } } Future generateBarcodeAsUint8List(String data) async { // 1. Buat barcode instance (code128, qrCode, dll) final barcode = Barcode.code128(); // 2. Siapkan canvas image dari package `image` final image = img.Image(width: 600, height: 200); // 3. Gambar barcode ke canvas menggunakan barcode_image drawBarcode( image, barcode, data, ); // 4. Encode image ke Uint8List PNG return Uint8List.fromList(img.encodePng(image)); }