print order

This commit is contained in:
efrilm
2025-11-07 16:29:26 +07:00
parent 4eece81eb1
commit 93560b85cb
12 changed files with 1154 additions and 49 deletions
@@ -1,20 +1,32 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:dartz/dartz.dart' hide Order;
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:injectable/injectable.dart';
import 'package:injectable/injectable.dart' hide Order;
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import '../../../domain/order/order.dart';
import '../../../domain/outlet/outlet.dart';
import '../../../domain/printer/printer.dart';
import '../../../presentation/components/print/print_ui.dart';
import '../../auth/datasources/local_data_provider.dart';
import '../../outlet/datasources/local_data_provider.dart';
import '../datasource/local_data_provider.dart';
import '../printer_dtos.dart';
@Injectable(as: IPrinterRepository)
class PrinterRepository implements IPrinterRepository {
final PrinterLocalDataProvider _localDataProvider;
final OutletLocalDatasource _outletLocalDatasource;
final AuthLocalDataProvider _authLocalDataProvider;
final _logName = 'PrinterRepository';
PrinterRepository(this._localDataProvider);
PrinterRepository(
this._localDataProvider,
this._outletLocalDatasource,
this._authLocalDataProvider,
);
@override
Future<Either<PrinterFailure, bool>> connectBluetooth(
@@ -385,4 +397,355 @@ class PrinterRepository implements IPrinterRepository {
return false;
}
}
@override
Future<Either<PrinterFailure, Unit>> printStruckOrder({
required Order order,
}) async {
try {
final outlet = await _outletLocalDatasource.currentOutlet();
final user = await _authLocalDataProvider.currentUser();
// Struck for customer
if (order.totalPaid > 0) {
_printReceipt(order: order, outlet: outlet, cashieName: user.name);
}
// Struck for cashier
_printCashier(order: order, outlet: outlet, cashieName: user.name);
// Struck for kitchen
_printKitchen(order: order, outlet: outlet, cashieName: user.name);
// Struck for checker
_printChecker(order: order, outlet: outlet, cashieName: user.name);
// Struck for bar if exist product bar
final itemsBar = order.orderItems.where(
(item) => item.printerType == 'bar',
);
if (itemsBar.isNotEmpty) {
_printBar(order: order, outlet: outlet, cashieName: user.name);
}
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Order Error: $e',
stackTrace,
reason:
'Print struck order error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing struck order", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage('Error printing order'),
);
}
}
@override
Future<Either<PrinterFailure, Unit>> printStruckSaveOrder({
required Order order,
}) async {
try {
final outlet = await _outletLocalDatasource.currentOutlet();
final user = await _authLocalDataProvider.currentUser();
// Struck for cashier
_printCashier(order: order, outlet: outlet, cashieName: user.name);
// Struck for kitchen
_printKitchen(order: order, outlet: outlet, cashieName: user.name);
// Struck for checker
_printChecker(order: order, outlet: outlet, cashieName: user.name);
// Struck for bar if exist product bar
final itemsBar = order.orderItems.where(
(item) => item.printerType == 'bar',
);
if (itemsBar.isNotEmpty) {
_printBar(order: order, outlet: outlet, cashieName: user.name);
}
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Save Order Error: $e',
stackTrace,
reason:
'Print struck save order error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing struck save order", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage('Error printing save order'),
);
}
}
Future<Either<PrinterFailure, Unit>> _printReceipt({
required Order order,
required Outlet outlet,
required String cashieName,
}) async {
log('Starting to print receipt', name: _logName);
final receiptPrinter = await _localDataProvider.findPrinterByCode(
'receipt',
);
if (receiptPrinter.hasData) {
try {
final printer = receiptPrinter.data!.toDomain();
final printValue = await PrintUi().printOrder(
order: order,
outlet: outlet,
cashierName: cashieName,
);
await printStruct(printer, printValue);
log('Finished printed receipt', name: _logName);
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Receipt Error: $e',
stackTrace,
reason:
'Print struck receipt error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing receipt", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage(
'Error printing receipt order',
),
);
}
} 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}'],
);
return left(
const PrinterFailure.dynamicErrorMessage('Receipt printer not found'),
);
}
}
Future<Either<PrinterFailure, Unit>> _printCashier({
required Order order,
required Outlet outlet,
required String cashieName,
}) async {
log('Starting to print cashier', name: _logName);
final receiptPrinter = await _localDataProvider.findPrinterByCode(
'receipt',
);
if (receiptPrinter.hasData) {
try {
final printer = receiptPrinter.data!.toDomain();
final printValue = await PrintUi().printCashier(
order: order,
outlet: outlet,
cashierName: cashieName,
);
await printStruct(printer, printValue);
log('Finished printing cashier', name: _logName);
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Cashier Error: $e',
stackTrace,
reason:
'Print struck cashier error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing cashier", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage(
'Error printing cashier order',
),
);
}
} else {
FirebaseCrashlytics.instance.recordError(
'Cashier printer not found',
null,
reason:
'Cashier printer not found / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
return left(
const PrinterFailure.dynamicErrorMessage('Cashier printer not found'),
);
}
}
Future<Either<PrinterFailure, Unit>> _printKitchen({
required Order order,
required Outlet outlet,
required String cashieName,
}) async {
log('Starting to print kitchen', name: _logName);
final kitchenPrinter = await _localDataProvider.findPrinterByCode(
'kitchen',
);
if (kitchenPrinter.hasData) {
try {
final printer = kitchenPrinter.data!.toDomain();
final printValue = await PrintUi().printKitchen(
order: order,
outlet: outlet,
cashierName: cashieName,
);
await printStruct(printer, printValue);
log('Finished printed kitchen', name: _logName);
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Kitchen Error: $e',
stackTrace,
reason:
'Print struck kitchen error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing kitchen", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage(
'Error printing kitchen order',
),
);
}
} 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}'],
);
return left(
const PrinterFailure.dynamicErrorMessage('Kitchen printer not found'),
);
}
}
Future<Either<PrinterFailure, Unit>> _printChecker({
required Order order,
required Outlet outlet,
required String cashieName,
}) async {
log('Starting to print checker', name: _logName);
final checkerPrinter = await _localDataProvider.findPrinterByCode(
'checker',
);
if (checkerPrinter.hasData) {
try {
final printer = checkerPrinter.data!.toDomain();
final printValue = await PrintUi().printChecker(
order: order,
outlet: outlet,
cashierName: cashieName,
);
await printStruct(printer, printValue);
log('Finished printed checker', name: _logName);
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Checker Error: $e',
stackTrace,
reason:
'Print struck checker error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing checker", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage(
'Error printing checker order',
),
);
}
} 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}'],
);
return left(
const PrinterFailure.dynamicErrorMessage('Checker printer not found'),
);
}
}
Future<Either<PrinterFailure, Unit>> _printBar({
required Order order,
required Outlet outlet,
required String cashieName,
}) async {
final barPrinter = await _localDataProvider.findPrinterByCode('bar');
if (barPrinter.hasData) {
log('Starting to print bar', name: _logName);
try {
final productBar = order.orderItems
.where((item) => item.printerType == 'bar')
.toList();
if (productBar.isNotEmpty) {
final printer = barPrinter.data!.toDomain();
final printValue = await PrintUi().printBar(
order: order,
outlet: outlet,
cashierName: cashieName,
);
await printStruct(printer, printValue);
log('Finished printed bar', name: _logName);
} else {
log('Product with printer type bar not found', name: _logName);
return right(unit);
}
return right(unit);
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Print Struck Bar Error: $e',
stackTrace,
reason:
'Print struck bar error / Printer not setting in printer page',
information: ['Order ID: ${order.id}'],
);
log("Error printing bar", name: _logName, error: e);
return left(
const PrinterFailure.dynamicErrorMessage('Error printing bar order'),
);
}
} 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}'],
);
return left(
const PrinterFailure.dynamicErrorMessage('Bar printer not found'),
);
}
}
}