update printer
This commit is contained in:
parent
f7cafeb583
commit
5058f99fe0
@ -5,6 +5,7 @@ import 'package:firebase_crashlytics/firebase_crashlytics.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:injectable/injectable.dart' hide Order;
|
import 'package:injectable/injectable.dart' hide Order;
|
||||||
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
|
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
|
||||||
|
import 'package:synchronized/synchronized.dart';
|
||||||
|
|
||||||
import '../../../domain/order/order.dart';
|
import '../../../domain/order/order.dart';
|
||||||
import '../../../domain/outlet/outlet.dart';
|
import '../../../domain/outlet/outlet.dart';
|
||||||
@ -28,6 +29,13 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
this._authLocalDataProvider,
|
this._authLocalDataProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final Map<String, Lock> _locks = {};
|
||||||
|
String? _connectedMac;
|
||||||
|
|
||||||
|
Lock _getLock(String address) {
|
||||||
|
return _locks.putIfAbsent(address, () => Lock());
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Either<PrinterFailure, bool>> connectBluetooth(
|
Future<Either<PrinterFailure, bool>> connectBluetooth(
|
||||||
String macAddress,
|
String macAddress,
|
||||||
@ -213,33 +221,38 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
Printer printer,
|
Printer printer,
|
||||||
List<int> printData,
|
List<int> printData,
|
||||||
) async {
|
) async {
|
||||||
try {
|
|
||||||
log(printer.toString());
|
|
||||||
if (printer.type == 'Bluetooth') {
|
if (printer.type == 'Bluetooth') {
|
||||||
final connected = await connectBluetooth(printer.address);
|
return await _getLock(printer.address).synchronized(() async {
|
||||||
|
try {
|
||||||
|
bool isConnected = await PrintBluetoothThermal.connectionStatus;
|
||||||
|
|
||||||
connected.fold(
|
// Hanya reconnect jika memang perlu
|
||||||
(f) {
|
if (!isConnected || _connectedMac != printer.address) {
|
||||||
return left(
|
// Disconnect hanya jika terhubung ke printer LAIN
|
||||||
PrinterFailure.dynamicErrorMessage(
|
if (isConnected && _connectedMac != printer.address) {
|
||||||
'Printer cannot connect to bluetooth, Please connect in printer setting!',
|
await PrintBluetoothThermal.disconnect;
|
||||||
),
|
await Future.delayed(
|
||||||
|
const Duration(milliseconds: 300),
|
||||||
|
); // dari 1500ms
|
||||||
|
}
|
||||||
|
|
||||||
|
bool connected = await PrintBluetoothThermal.connect(
|
||||||
|
macPrinterAddress: printer.address,
|
||||||
);
|
);
|
||||||
},
|
|
||||||
(connect) async {
|
if (!connected) {
|
||||||
if (!connect) {
|
_connectedMac = null;
|
||||||
FirebaseCrashlytics.instance.recordError(
|
FirebaseCrashlytics.instance.recordError(
|
||||||
'Failed to connect to Bluetooth printer',
|
'Failed to connect to Bluetooth printer',
|
||||||
null,
|
null,
|
||||||
reason: 'Failed to connect to Bluetooth print',
|
reason: 'Failed to connect to Bluetooth print',
|
||||||
information: [
|
information: [
|
||||||
'function: printStruct(Printer printer, List<int> printValue,)',
|
'function: printStruct(Printer printer, List<int> printData)',
|
||||||
'Printer: ${printer.name}',
|
'Printer: ${printer.name}',
|
||||||
'macAddress: ${printer.address}',
|
'macAddress: ${printer.address}',
|
||||||
'in: $_logName ',
|
'in: $_logName',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
return left(
|
return left(
|
||||||
PrinterFailure.dynamicErrorMessage(
|
PrinterFailure.dynamicErrorMessage(
|
||||||
'Printer cannot connect to bluetooth, Please connect in printer setting!',
|
'Printer cannot connect to bluetooth, Please connect in printer setting!',
|
||||||
@ -247,18 +260,28 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_connectedMac = printer.address;
|
||||||
|
await Future.delayed(
|
||||||
|
const Duration(milliseconds: 300),
|
||||||
|
); // dari 1000ms
|
||||||
|
}
|
||||||
|
|
||||||
log(
|
log(
|
||||||
'Printer connected to bluetooth: ${printer.name}, ${printer.address}',
|
'Printer connected to bluetooth: ${printer.name}, ${printer.address}',
|
||||||
name: _logName,
|
name: _logName,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool printResult = await _printBluetooth(printData);
|
bool printResult = await _writeBytesChunked(printData);
|
||||||
|
|
||||||
|
// Hapus delay 1000ms setelah print — tidak perlu untuk hasil cetak
|
||||||
|
log("Print result ${printer.name}: $printResult");
|
||||||
|
|
||||||
if (!printResult) {
|
if (!printResult) {
|
||||||
FirebaseCrashlytics.instance.recordError(
|
FirebaseCrashlytics.instance.recordError(
|
||||||
'Failed to print to ${printer.name}',
|
'Failed to print to ${printer.name}',
|
||||||
null,
|
null,
|
||||||
information: [
|
information: [
|
||||||
'function: await printBluetooth(printData);',
|
'function: await _writeBytesChunked(printData)',
|
||||||
'print: $printData',
|
'print: $printData',
|
||||||
'in: $_logName',
|
'in: $_logName',
|
||||||
],
|
],
|
||||||
@ -271,9 +294,25 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return right(printResult);
|
return right(printResult);
|
||||||
},
|
} catch (e, stackTrace) {
|
||||||
|
_connectedMac = null;
|
||||||
|
FirebaseCrashlytics.instance.recordError(
|
||||||
|
e,
|
||||||
|
stackTrace,
|
||||||
|
reason: 'Error printing ${printer.name}',
|
||||||
|
information: [
|
||||||
|
'Printer: ${printer.name}',
|
||||||
|
'MAC: ${printer.address}',
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
return left(
|
||||||
|
PrinterFailure.dynamicErrorMessage('Error printing struct'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// Network printer tetap sama
|
||||||
|
try {
|
||||||
bool printResult = await _printNetwork(printer.address, printData);
|
bool printResult = await _printNetwork(printer.address, printData);
|
||||||
|
|
||||||
if (!printResult) {
|
if (!printResult) {
|
||||||
@ -282,7 +321,7 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
null,
|
null,
|
||||||
reason: 'Failed to connect to Network Printer',
|
reason: 'Failed to connect to Network Printer',
|
||||||
information: [
|
information: [
|
||||||
'function: await printNetwork(printer.address, printData);',
|
'function: await _printNetwork(printer.address, printData)',
|
||||||
'Printer: ${printer.name}',
|
'Printer: ${printer.name}',
|
||||||
'ipAddress: ${printer.address}',
|
'ipAddress: ${printer.address}',
|
||||||
'print: $printData',
|
'print: $printData',
|
||||||
@ -290,59 +329,64 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return right(printResult);
|
return right(printResult);
|
||||||
}
|
|
||||||
|
|
||||||
return right(false);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing struct", name: _logName, error: e);
|
|
||||||
return left(PrinterFailure.dynamicErrorMessage('Error printing struct'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> _printBluetooth(List<int> printData) async {
|
|
||||||
try {
|
|
||||||
bool isConnected = await PrintBluetoothThermal.connectionStatus;
|
|
||||||
|
|
||||||
if (!isConnected) {
|
|
||||||
log("Not connected to Bluetooth printer", name: _logName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool printResult = await PrintBluetoothThermal.writeBytes(printData);
|
|
||||||
if (printResult) {
|
|
||||||
log("Successfully printed via Bluetooth", name: _logName);
|
|
||||||
} else {
|
|
||||||
FirebaseCrashlytics.instance.recordError(
|
|
||||||
'Failed to print via Bluetooth',
|
|
||||||
null,
|
|
||||||
reason: 'Failed to print via Bluetooth',
|
|
||||||
information: [
|
|
||||||
'function: printBluetooth(List<int> printData)',
|
|
||||||
'printData: $printData',
|
|
||||||
'in: $_logName',
|
|
||||||
],
|
|
||||||
);
|
|
||||||
log("Failed to print via Bluetooth", name: _logName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return printResult;
|
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
FirebaseCrashlytics.instance.recordError(
|
FirebaseCrashlytics.instance.recordError(
|
||||||
e,
|
e,
|
||||||
stackTrace,
|
stackTrace,
|
||||||
reason: 'Error printing via Bluetooth',
|
reason: 'Error printing ${printer.name}',
|
||||||
information: [
|
information: ['Printer: ${printer.name}', 'IP: ${printer.address}'],
|
||||||
'function: printBluetooth(List<int> printData)',
|
);
|
||||||
'Printer: Bluetooth printer',
|
return left(
|
||||||
'printData: $printData',
|
PrinterFailure.dynamicErrorMessage('Error printing struct'),
|
||||||
'in: $_logName',
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
log("Error printing via Bluetooth: $e", name: _logName);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Future<bool> _printBluetooth(List<int> printData) async {
|
||||||
|
// try {
|
||||||
|
// bool isConnected = await PrintBluetoothThermal.connectionStatus;
|
||||||
|
|
||||||
|
// if (!isConnected) {
|
||||||
|
// log("Not connected to Bluetooth printer", name: _logName);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool printResult = await PrintBluetoothThermal.writeBytes(printData);
|
||||||
|
// if (printResult) {
|
||||||
|
// log("Successfully printed via Bluetooth", name: _logName);
|
||||||
|
// } else {
|
||||||
|
// FirebaseCrashlytics.instance.recordError(
|
||||||
|
// 'Failed to print via Bluetooth',
|
||||||
|
// null,
|
||||||
|
// reason: 'Failed to print via Bluetooth',
|
||||||
|
// information: [
|
||||||
|
// 'function: printBluetooth(List<int> printData)',
|
||||||
|
// 'printData: $printData',
|
||||||
|
// 'in: $_logName',
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// log("Failed to print via Bluetooth", name: _logName);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return printResult;
|
||||||
|
// } catch (e, stackTrace) {
|
||||||
|
// FirebaseCrashlytics.instance.recordError(
|
||||||
|
// e,
|
||||||
|
// stackTrace,
|
||||||
|
// reason: 'Error printing via Bluetooth',
|
||||||
|
// information: [
|
||||||
|
// 'function: printBluetooth(List<int> printData)',
|
||||||
|
// 'Printer: Bluetooth printer',
|
||||||
|
// 'printData: $printData',
|
||||||
|
// 'in: $_logName',
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// log("Error printing via Bluetooth: $e", name: _logName);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Future<bool> _printNetwork(String ipAddress, List<int> printData) async {
|
Future<bool> _printNetwork(String ipAddress, List<int> printData) async {
|
||||||
try {
|
try {
|
||||||
@ -979,4 +1023,15 @@ class PrinterRepository implements IPrinterRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> _writeBytesChunked(List<int> data, {int chunkSize = 512}) async {
|
||||||
|
for (int i = 0; i < data.length; i += chunkSize) {
|
||||||
|
final end = (i + chunkSize > data.length) ? data.length : i + chunkSize;
|
||||||
|
final chunk = data.sublist(i, end);
|
||||||
|
bool result = await PrintBluetoothThermal.writeBytes(chunk);
|
||||||
|
if (!result) return false;
|
||||||
|
await Future.delayed(const Duration(milliseconds: 30));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,11 +46,7 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
color: AppColor.primary,
|
||||||
colors: AppColor.primaryGradient,
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@ -1230,7 +1230,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
||||||
|
|||||||
@ -43,6 +43,7 @@ dependencies:
|
|||||||
flutter_esc_pos_network: ^1.0.3
|
flutter_esc_pos_network: ^1.0.3
|
||||||
esc_pos_utils_plus: ^2.0.4
|
esc_pos_utils_plus: ^2.0.4
|
||||||
table_calendar: ^3.1.2
|
table_calendar: ^3.1.2
|
||||||
|
synchronized: ^3.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user