fix printer

This commit is contained in:
Efril 2026-02-24 00:10:02 +07:00
parent 86d2196a04
commit 0bccec8a1e
3 changed files with 88 additions and 102 deletions

View File

@ -4,12 +4,16 @@ import 'package:flutter/material.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart'; import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart'; import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:enaklo_pos/data/models/response/print_model.dart'; import 'package:enaklo_pos/data/models/response/print_model.dart';
import 'package:synchronized/synchronized.dart';
class PrinterService { class PrinterService {
static final PrinterService _instance = PrinterService._internal(); static final PrinterService _instance = PrinterService._internal();
factory PrinterService() => _instance; factory PrinterService() => _instance;
PrinterService._internal(); PrinterService._internal();
final Lock _lock = Lock();
String? _connectedMac;
/// Connect to Bluetooth printer /// Connect to Bluetooth printer
Future<bool> connectBluetoothPrinter(String macAddress) async { Future<bool> connectBluetoothPrinter(String macAddress) async {
try { try {
@ -56,6 +60,57 @@ class PrinterService {
} }
} }
/// Print with automatic printer type detection
Future<bool> printWithPrinter(
PrintModel printer, List<int> 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 /// Print using Bluetooth printer
Future<bool> printBluetooth(List<int> printData) async { Future<bool> printBluetooth(List<int> printData) async {
try { try {
@ -99,17 +154,18 @@ class PrinterService {
} }
/// Print using Network printer /// Print using Network printer
Future<bool> printNetwork(String ipAddress, List<int> printData) async { Future<bool> printNetwork(
PrintModel printer, List<int> printData, BuildContext context) async {
try { try {
final printer = PrinterNetworkManager(ipAddress); final networkPrinter = PrinterNetworkManager(printer.address);
PosPrintResult connect = await printer.connect(); PosPrintResult connect = await networkPrinter.connect();
if (connect == PosPrintResult.success) { if (connect == PosPrintResult.success) {
PosPrintResult printing = await printer.printTicket(printData); PosPrintResult printing = await networkPrinter.printTicket(printData);
printer.disconnect(); networkPrinter.disconnect();
if (printing == PosPrintResult.success) { if (printing == PosPrintResult.success) {
log("Successfully printed via Network printer: $ipAddress"); log("Successfully printed via Network printer: ${printer.address}");
return true; return true;
} else { } else {
FirebaseCrashlytics.instance.recordError( FirebaseCrashlytics.instance.recordError(
@ -117,28 +173,34 @@ class PrinterService {
null, null,
reason: 'Failed to print via Network printer', reason: 'Failed to print via Network printer',
information: [ information: [
'function: printNetwork(String ipAddress, List<int> printData)', 'Printer: ${printer.name}',
'Printer: Network printer', 'ipAddress: ${printer.address}',
'ipAddress: $ipAddress',
'printData: $printData',
], ],
); );
log("Failed to print via Network printer: ${printing.msg}"); 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; return false;
} }
} else { } else {
FirebaseCrashlytics.instance.recordError( FirebaseCrashlytics.instance.recordError(
'Failed to connect to Network printer: ${connect.msg}', 'Failed to connect to Network printer: ${connect.msg}',
null, null,
reason: 'Failed to connectNetwork printer', reason: 'Failed to connect Network printer',
information: [ information: [
'function: printNetwork(String ipAddress, List<int> printData)', 'Printer: ${printer.name}',
'Printer: Network printer', 'ipAddress: ${printer.address}',
'ipAddress: $ipAddress',
'printData: $printData',
], ],
); );
log("Failed to connect to Network printer: ${connect.msg}"); 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; return false;
} }
} catch (e, stackTrace) { } catch (e, stackTrace) {
@ -147,10 +209,8 @@ class PrinterService {
stackTrace, stackTrace,
reason: 'Error printing via Network', reason: 'Error printing via Network',
information: [ information: [
'function: printNetwork(String ipAddress, List<int> printData)', 'Printer: ${printer.name}',
'Printer: Network printer', 'ipAddress: ${printer.address}',
'ipAddress: $ipAddress',
'printData: $printData',
], ],
); );
log("Error printing via Network: $e"); log("Error printing via Network: $e");
@ -158,81 +218,6 @@ class PrinterService {
} }
} }
/// Print with automatic printer type detection
Future<bool> printWithPrinter(
PrintModel printer, List<int> 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 /// Disconnect from Bluetooth printer
Future<bool> disconnectBluetooth() async { Future<bool> disconnectBluetooth() async {
try { try {

View File

@ -908,10 +908,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.16.0" version: "1.17.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -1438,13 +1438,13 @@ packages:
source: hosted source: hosted
version: "30.2.5" version: "30.2.5"
synchronized: synchronized:
dependency: transitive dependency: "direct main"
description: description:
name: synchronized name: synchronized
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.0+3" version: "3.4.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -1457,10 +1457,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.6" version: "0.7.7"
time: time:
dependency: transitive dependency: transitive
description: description:
@ -1622,5 +1622,5 @@ packages:
source: hosted source: hosted
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.8.0-0 <4.0.0" dart: ">=3.8.0 <4.0.0"
flutter: ">=3.29.0" flutter: ">=3.29.0"

View File

@ -70,6 +70,7 @@ dependencies:
firebase_core: ^4.1.0 firebase_core: ^4.1.0
firebase_crashlytics: ^5.0.1 firebase_crashlytics: ^5.0.1
path: ^1.9.1 path: ^1.9.1
synchronized: ^3.4.0
# imin_printer: ^0.6.10 # imin_printer: ^0.6.10
dev_dependencies: dev_dependencies: