diff --git a/lib/core/utils/printer_service.dart b/lib/core/utils/printer_service.dart index 4a23c3d..d759a7a 100644 --- a/lib/core/utils/printer_service.dart +++ b/lib/core/utils/printer_service.dart @@ -4,12 +4,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart'; import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart'; import 'package:enaklo_pos/data/models/response/print_model.dart'; +import 'package:synchronized/synchronized.dart'; class PrinterService { static final PrinterService _instance = PrinterService._internal(); factory PrinterService() => _instance; PrinterService._internal(); + final Lock _lock = Lock(); + String? _connectedMac; + /// Connect to Bluetooth printer Future connectBluetoothPrinter(String macAddress) async { try { @@ -56,6 +60,57 @@ class PrinterService { } } + /// Print with automatic printer type detection + Future printWithPrinter( + PrintModel printer, List printData, BuildContext context) async { + if (printer.type == 'Bluetooth') { + return await _lock.synchronized(() async { + try { + // Connect hanya kalau beda printer atau belum connected + bool isConnected = await PrintBluetoothThermal.connectionStatus; + if (!isConnected || _connectedMac != printer.address) { + if (isConnected) { + await PrintBluetoothThermal.disconnect; + await Future.delayed(const Duration(milliseconds: 1500)); + } + bool connected = await PrintBluetoothThermal.connect( + macPrinterAddress: printer.address); + if (!connected) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Gagal connect ke ${printer.name}')), + ); + } + return false; + } + _connectedMac = printer.address; + await Future.delayed(const Duration(milliseconds: 500)); + } + + // Print + bool result = await PrintBluetoothThermal.writeBytes(printData); + log("Print result ${printer.name}: $result"); + return result; + } catch (e, stackTrace) { + _connectedMac = null; + FirebaseCrashlytics.instance.recordError( + e, + stackTrace, + reason: 'Error printing ${printer.name}', + information: [ + 'Printer: ${printer.name}', + 'MAC: ${printer.address}' + ], + ); + log("Error printing ${printer.name}: $e"); + return false; + } + }); + } else { + return await printNetwork(printer, printData, context); + } + } + /// Print using Bluetooth printer Future printBluetooth(List printData) async { try { @@ -99,17 +154,18 @@ class PrinterService { } /// Print using Network printer - Future printNetwork(String ipAddress, List printData) async { + Future printNetwork( + PrintModel printer, List printData, BuildContext context) async { try { - final printer = PrinterNetworkManager(ipAddress); - PosPrintResult connect = await printer.connect(); + final networkPrinter = PrinterNetworkManager(printer.address); + PosPrintResult connect = await networkPrinter.connect(); if (connect == PosPrintResult.success) { - PosPrintResult printing = await printer.printTicket(printData); - printer.disconnect(); + PosPrintResult printing = await networkPrinter.printTicket(printData); + networkPrinter.disconnect(); if (printing == PosPrintResult.success) { - log("Successfully printed via Network printer: $ipAddress"); + log("Successfully printed via Network printer: ${printer.address}"); return true; } else { FirebaseCrashlytics.instance.recordError( @@ -117,28 +173,34 @@ class PrinterService { null, reason: 'Failed to print via Network printer', information: [ - 'function: printNetwork(String ipAddress, List printData)', - 'Printer: Network printer', - 'ipAddress: $ipAddress', - 'printData: $printData', + 'Printer: ${printer.name}', + 'ipAddress: ${printer.address}', ], ); log("Failed to print via Network printer: ${printing.msg}"); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Gagal print ke ${printer.name}')), + ); + } return false; } } else { FirebaseCrashlytics.instance.recordError( 'Failed to connect to Network printer: ${connect.msg}', null, - reason: 'Failed to connectNetwork printer', + reason: 'Failed to connect Network printer', information: [ - 'function: printNetwork(String ipAddress, List printData)', - 'Printer: Network printer', - 'ipAddress: $ipAddress', - 'printData: $printData', + 'Printer: ${printer.name}', + 'ipAddress: ${printer.address}', ], ); log("Failed to connect to Network printer: ${connect.msg}"); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Gagal connect ke ${printer.name}')), + ); + } return false; } } catch (e, stackTrace) { @@ -147,10 +209,8 @@ class PrinterService { stackTrace, reason: 'Error printing via Network', information: [ - 'function: printNetwork(String ipAddress, List printData)', - 'Printer: Network printer', - 'ipAddress: $ipAddress', - 'printData: $printData', + 'Printer: ${printer.name}', + 'ipAddress: ${printer.address}', ], ); log("Error printing via Network: $e"); @@ -158,81 +218,6 @@ class PrinterService { } } - /// Print with automatic printer type detection - Future printWithPrinter( - PrintModel printer, List printData, BuildContext context) async { - try { - if (printer.type == 'Bluetooth') { - bool connected = await connectBluetoothPrinter(printer.address); - if (!connected) { - FirebaseCrashlytics.instance.recordError( - 'Failed to connect to Bluetooth printer', - null, - reason: 'Failed to connect to Bluetooth printe', - information: [ - 'function: connectBluetoothPrinter(String macAddress)', - 'Printer: ${printer.name}', - 'macAddress: ${printer.address}', - ], - ); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to connect to ${printer.name}')), - ); - return false; - } - - bool printResult = await printBluetooth(printData); - if (!printResult) { - FirebaseCrashlytics.instance.recordError( - 'Failed to print to ${printer.name}', - null, - information: [ - 'function: await printBluetooth(printData);', - 'print: $printData', - ], - ); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to print to ${printer.name}')), - ); - } - return printResult; - } else { - bool printResult = await printNetwork(printer.address, printData); - if (!printResult) { - FirebaseCrashlytics.instance.recordError( - 'Failed to connect to Network Printer', - null, - reason: 'Failed to connect to Network Printer', - information: [ - 'function: await printNetwork(printer.address, printData);', - 'Printer: ${printer.name}', - 'ipAddress: ${printer.address}', - 'print: $printData', - ], - ); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to print to ${printer.name}')), - ); - } - return printResult; - } - } catch (e, stackTrace) { - FirebaseCrashlytics.instance.recordError( - e, - stackTrace, - reason: 'Error printing with printer ${printer.name}', - information: [ - 'Printer: ${printer.name}', - ], - ); - log("Error printing with printer ${printer.name}: $e"); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Error printing to ${printer.name}: $e')), - ); - return false; - } - } - /// Disconnect from Bluetooth printer Future disconnectBluetooth() async { try { diff --git a/pubspec.lock b/pubspec.lock index 8bdeb93..133848e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -908,10 +908,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1438,13 +1438,13 @@ packages: source: hosted version: "30.2.5" synchronized: - dependency: transitive + dependency: "direct main" description: name: synchronized - sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 url: "https://pub.dev" source: hosted - version: "3.3.0+3" + version: "3.4.0" term_glyph: dependency: transitive description: @@ -1457,10 +1457,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" time: dependency: transitive description: @@ -1622,5 +1622,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.8.0 <4.0.0" flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index 90b4b85..0606dd2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -70,6 +70,7 @@ dependencies: firebase_core: ^4.1.0 firebase_crashlytics: ^5.0.1 path: ^1.9.1 + synchronized: ^3.4.0 # imin_printer: ^0.6.10 dev_dependencies: