389 lines
12 KiB
Dart
Raw Normal View History

2025-11-04 14:58:51 +07:00
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
2025-11-06 18:15:54 +07:00
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
2025-11-04 14:58:51 +07:00
import 'package:injectable/injectable.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import '../../../domain/printer/printer.dart';
2025-11-04 22:13:15 +07:00
import '../datasource/local_data_provider.dart';
import '../printer_dtos.dart';
2025-11-04 14:58:51 +07:00
@Injectable(as: IPrinterRepository)
class PrinterRepository implements IPrinterRepository {
2025-11-04 22:13:15 +07:00
final PrinterLocalDataProvider _localDataProvider;
2025-11-04 14:58:51 +07:00
final _logName = 'PrinterRepository';
2025-11-04 22:13:15 +07:00
PrinterRepository(this._localDataProvider);
2025-11-04 14:58:51 +07:00
@override
Future<Either<PrinterFailure, bool>> connectBluetooth(
String macAddress,
) async {
try {
bool isConnected = await PrintBluetoothThermal.connectionStatus;
if (isConnected) {
log("Already connected to Bluetooth printer", name: _logName);
return right(true);
}
bool connected = await PrintBluetoothThermal.connect(
macPrinterAddress: macAddress,
);
if (connected) {
log(
"Successfully connected to Bluetooth printer: $macAddress",
name: _logName,
);
} else {
FirebaseCrashlytics.instance.recordError(
'Failed to connect to Bluetooth printer',
null,
reason: 'Failed to connect to Bluetooth printe',
information: [
'function: connectBluetoothPrinter(String macAddress)',
'macAddress: $macAddress',
],
);
log(
"Failed to connect to Bluetooth printer: $macAddress",
name: _logName,
);
}
return right(connected);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
e,
stackTrace,
reason: 'Error connecting to Bluetooth printer',
information: [
'function: connectBluetoothPrinter(String macAddress)',
'Printer: Bluetooth printer',
'macAddress: $macAddress',
],
);
log("Error connecting to Bluetooth printer", name: _logName, error: e);
return left(
PrinterFailure.dynamicErrorMessage(
'Error connecting to Bluetooth printer',
),
);
}
}
@override
Future<Either<PrinterFailure, bool>> disconectBluetooth() async {
try {
bool result = await PrintBluetoothThermal.disconnect;
log("Bluetooth printer disconnected: $result", name: _logName);
return right(result);
} catch (e) {
log("Error disconnecting Bluetooth printer", error: e, name: _logName);
return left(
PrinterFailure.dynamicErrorMessage(
'Error disconnecting Bluetooth printer',
),
);
}
}
@override
Future<Either<PrinterFailure, List<BluetoothInfo>>>
getPairedBluetoothDevices() async {
try {
final result = await PrintBluetoothThermal.pairedBluetooths;
log("Paired Bluetooth devices: $result", name: _logName);
return right(result);
} catch (e) {
log("Error getting paired Bluetooth devices", name: _logName, error: e);
return left(
PrinterFailure.dynamicErrorMessage(
'Error getting paired Bluetooth devices',
),
);
}
}
@override
Future<Either<PrinterFailure, bool>> isBluetoothEnabled() async {
try {
final result = await PrintBluetoothThermal.bluetoothEnabled;
return right(result);
} catch (e) {
log("Error checking Bluetooth status", name: _logName, error: e);
return left(
PrinterFailure.dynamicErrorMessage('Error checking Bluetooth status'),
);
}
}
2025-11-04 22:13:15 +07:00
@override
Future<Either<PrinterFailure, Unit>> createPrinter(Printer printer) async {
try {
final result = await _localDataProvider.createPrinter(
PrinterDto.fromDomain(printer),
);
if (result.hasError) {
return left(result.error!);
}
return right(unit);
} catch (e) {
log('createPrinterError', name: _logName, error: e);
return left(const PrinterFailure.unexpectedError());
}
}
@override
Future<Either<PrinterFailure, Unit>> deletePrinter(int id) async {
try {
final result = await _localDataProvider.deletePrinter(id);
if (result.hasError) {
return left(result.error!);
}
return right(unit);
} catch (e) {
log('deletePrinterError', name: _logName, error: e);
return left(const PrinterFailure.unexpectedError());
}
}
@override
Future<Either<PrinterFailure, Printer>> getPrinterByCode(String code) async {
try {
final result = await _localDataProvider.findPrinterByCode(code);
if (result.hasError) {
return left(result.error!);
}
final printer = result.data!.toDomain();
return right(printer);
} catch (e) {
log('getPrinterByCodeError', name: _logName, error: e);
return left(const PrinterFailure.unexpectedError());
}
}
@override
Future<Either<PrinterFailure, Unit>> updatePrinter(
Printer printer,
int id,
) async {
try {
final result = await _localDataProvider.updatePrinter(
PrinterDto.fromDomain(printer),
id,
);
if (result.hasError) {
return left(result.error!);
}
return right(unit);
} catch (e) {
log('updatePrinterError', name: _logName, error: e);
return left(const PrinterFailure.unexpectedError());
}
}
2025-11-06 18:15:54 +07:00
@override
Future<Either<PrinterFailure, bool>> printStruct(
Printer printer,
List<int> printData,
) async {
try {
log(printer.toString());
if (printer.type == 'Bluetooth') {
final connected = await connectBluetooth(printer.address);
connected.fold(
(f) {
return left(
PrinterFailure.dynamicErrorMessage(
'Printer cannot connect to bluetooth, Please connect in printer setting!',
),
);
},
(connect) async {
if (!connect) {
FirebaseCrashlytics.instance.recordError(
'Failed to connect to Bluetooth printer',
null,
reason: 'Failed to connect to Bluetooth print',
information: [
'function: printStruct(Printer printer, List<int> printValue,)',
'Printer: ${printer.name}',
'macAddress: ${printer.address}',
'in: $_logName ',
],
);
return left(
PrinterFailure.dynamicErrorMessage(
'Printer cannot connect to bluetooth, Please connect in printer setting!',
),
);
}
bool printResult = await _printBluetooth(printData);
if (!printResult) {
FirebaseCrashlytics.instance.recordError(
'Failed to print to ${printer.name}',
null,
information: [
'function: await printBluetooth(printData);',
'print: $printData',
'in: $_logName',
],
);
return left(
PrinterFailure.dynamicErrorMessage(
'Failed to print to ${printer.name}',
),
);
}
return right(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',
'in: $_logName',
],
);
}
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) {
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 {
try {
final printer = PrinterNetworkManager(ipAddress);
PosPrintResult connect = await printer.connect();
if (connect == PosPrintResult.success) {
PosPrintResult printing = await printer.printTicket(printData);
printer.disconnect();
if (printing == PosPrintResult.success) {
log("Successfully printed via Network printer: $ipAddress");
return true;
} else {
FirebaseCrashlytics.instance.recordError(
'Failed to print via Network printer: ${printing.msg}',
null,
reason: 'Failed to print via Network printer',
information: [
'function: printNetwork(String ipAddress, List<int> printData)',
'Printer: Network printer',
'ipAddress: $ipAddress',
'printData: $printData',
],
);
log("Failed to print via Network printer: ${printing.msg}");
return false;
}
} else {
FirebaseCrashlytics.instance.recordError(
'Failed to connect to Network printer: ${connect.msg}',
null,
reason: 'Failed to connectNetwork printer',
information: [
'function: printNetwork(String ipAddress, List<int> printData)',
'Printer: Network printer',
'ipAddress: $ipAddress',
'printData: $printData',
],
);
log("Failed to connect to Network printer: ${connect.msg}");
return false;
}
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
e,
stackTrace,
reason: 'Error printing via Network',
information: [
'function: printNetwork(String ipAddress, List<int> printData)',
'Printer: Network printer',
'ipAddress: $ipAddress',
'printData: $printData',
],
);
log("Error printing via Network: $e");
return false;
}
}
2025-11-04 14:58:51 +07:00
}