From ff25363a196789acc4417f30a1e4655fa6023a92 Mon Sep 17 00:00:00 2001 From: renolation Date: Tue, 4 Nov 2025 08:12:13 +0700 Subject: [PATCH] sunmi --- lib/core/services/sunmi_service.dart | 163 ++++++++++++++++++ .../pages/product_detail_page.dart | 9 +- lib/main.dart | 2 +- pubspec.lock | 8 + pubspec.yaml | 1 + 5 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 lib/core/services/sunmi_service.dart diff --git a/lib/core/services/sunmi_service.dart b/lib/core/services/sunmi_service.dart new file mode 100644 index 0000000..4f2e64f --- /dev/null +++ b/lib/core/services/sunmi_service.dart @@ -0,0 +1,163 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:sunmi_printer_plus/sunmi_printer_plus.dart'; + +/// Service for printing to Sunmi thermal printers +class SunmiService { + /// Print warehouse export form to Sunmi printer + static Future printWarehouseExport({ + required BuildContext context, + required String warehouseName, + required int productId, + required String productCode, + required String productName, + String? stageName, + required double passedKg, + required int passedPcs, + required double issuedKg, + required int issuedPcs, + String? responsibleName, + String? receiverName, + String? barcodeData, + }) async { + try { + // Check if printer is bound + final bool? isBound = await SunmiPrinter.bindingPrinter(); + if (isBound != true) { + throw Exception('Sunmi printer not available'); + } + + // Format current date + final dt = DateFormat('dd/MM/yyyy HH:mm').format(DateTime.now()); + + // Reset printer + await SunmiPrinter.initPrinter(); + await SunmiPrinter.resetFontSize(); + + // Title - PHIẾU XUẤT KHO + await SunmiPrinter.setAlignment(SunmiPrintAlign.CENTER); + await SunmiPrinter.bold(); + await SunmiPrinter.setCustomFontSize(30); + await SunmiPrinter.printText('PHIEU XUAT KHO'); + await SunmiPrinter.resetBold(); + await SunmiPrinter.setCustomFontSize(24); + await SunmiPrinter.lineWrap(1); + + // Company name + await SunmiPrinter.printText('Cong ty TNHH Co Khi Chinh Xac Minh Thu'); + await SunmiPrinter.resetFontSize(); + await SunmiPrinter.lineWrap(1); + + // Warehouse name + await SunmiPrinter.printText(warehouseName); + await SunmiPrinter.lineWrap(1); + + // Date + await SunmiPrinter.printText('Ngay: $dt'); + await SunmiPrinter.lineWrap(2); + + // Separator line + await SunmiPrinter.line(); + await SunmiPrinter.lineWrap(1); + + // Product information + await SunmiPrinter.setAlignment(SunmiPrintAlign.LEFT); + await SunmiPrinter.bold(); + await SunmiPrinter.printText('THONG TIN SAN PHAM'); + await SunmiPrinter.resetBold(); + await SunmiPrinter.lineWrap(1); + + // ProductId + await SunmiPrinter.printText('ProductId: $productId'); + await SunmiPrinter.lineWrap(1); + + // Product Code + await SunmiPrinter.printText('Ma san pham: $productCode'); + await SunmiPrinter.lineWrap(1); + + // Product Name + await SunmiPrinter.printText('Ten san pham: $productName'); + await SunmiPrinter.lineWrap(1); + + // Stage Name + await SunmiPrinter.printText('Cong doan: ${stageName ?? '-'}'); + await SunmiPrinter.lineWrap(2); + + // Separator line + await SunmiPrinter.line(); + await SunmiPrinter.lineWrap(1); + + // Quantities + await SunmiPrinter.bold(); + await SunmiPrinter.printText('SO LUONG'); + await SunmiPrinter.resetBold(); + await SunmiPrinter.lineWrap(1); + + // Table header + await SunmiPrinter.setAlignment(SunmiPrintAlign.LEFT); + await SunmiPrinter.printText('Loai KG PCS'); + await SunmiPrinter.line(); + + // Passed quantity (Hàng đạt) + final passedLine = 'Hang dat ${passedKg.toStringAsFixed(2).padLeft(7)} ${passedPcs.toString().padLeft(5)}'; + await SunmiPrinter.printText(passedLine); + + // Issued quantity (Hàng lỗi) + final issuedLine = 'Hang loi ${issuedKg.toStringAsFixed(2).padLeft(7)} ${issuedPcs.toString().padLeft(5)}'; + await SunmiPrinter.printText(issuedLine); + await SunmiPrinter.lineWrap(2); + + // Separator line + await SunmiPrinter.line(); + await SunmiPrinter.lineWrap(1); + + // Responsible person + await SunmiPrinter.printText('Nhan vien kho: ${responsibleName ?? '-'}'); + await SunmiPrinter.lineWrap(1); + + // Receiver + await SunmiPrinter.printText('Nhan vien tiep nhan: ${receiverName ?? '-'}'); + await SunmiPrinter.lineWrap(2); + + // Barcode + if (barcodeData != null && barcodeData.isNotEmpty) { + await SunmiPrinter.line(); + await SunmiPrinter.setAlignment(SunmiPrintAlign.CENTER); + await SunmiPrinter.printBarCode(barcodeData); + await SunmiPrinter.lineWrap(2); + } + + // Footer + await SunmiPrinter.line(); + await SunmiPrinter.setAlignment(SunmiPrintAlign.CENTER); + await SunmiPrinter.printText('Nguoi nhan'); + await SunmiPrinter.lineWrap(4); + + // Cut paper + await SunmiPrinter.cut(); + + // Show success message + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Đã in thành công!'), + backgroundColor: Colors.green, + duration: Duration(seconds: 2), + ), + ); + } + } catch (e) { + // Show error message + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Lỗi khi in: ${e.toString()}'), + backgroundColor: Colors.red, + duration: const Duration(seconds: 3), + ), + ); + } + rethrow; + } + } +} diff --git a/lib/features/products/presentation/pages/product_detail_page.dart b/lib/features/products/presentation/pages/product_detail_page.dart index a926f57..5665db7 100644 --- a/lib/features/products/presentation/pages/product_detail_page.dart +++ b/lib/features/products/presentation/pages/product_detail_page.dart @@ -4,8 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import '../../../../core/di/providers.dart'; -import '../../../../core/router/app_router.dart'; -import '../../../../core/services/print_service.dart'; +import '../../../../core/services/sunmi_service.dart'; import '../../../../core/storage/secure_storage.dart'; import '../../../../core/utils/text_utils.dart'; import '../../../users/domain/entities/user_entity.dart'; @@ -94,7 +93,7 @@ class _ProductDetailPageState extends ConsumerState { // Get stored current user ID from secure storage final secureStorage = SecureStorage(); final currentUserId = await secureStorage.getCurrentUserId(); - print('user $currentUserId'); + if (currentUserId == null) { return; } @@ -730,7 +729,7 @@ class _ProductDetailPageState extends ConsumerState { : 'P${stage.productId}'; try { - await PrintService.printWarehouseExport( + await SunmiService.printWarehouseExport( context: context, warehouseName: widget.warehouseName, productId: stage.productId, @@ -749,7 +748,7 @@ class _ProductDetailPageState extends ConsumerState { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('Error printing: ${e.toString()}'), + content: Text('Lỗi khi in: ${e.toString()}'), backgroundColor: Colors.red, duration: const Duration(seconds: 3), ), diff --git a/lib/main.dart b/lib/main.dart index c0331b3..a2d131c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -33,7 +33,7 @@ class MyApp extends ConsumerWidget { final router = ref.watch(appRouterProvider); return MaterialApp.router( - title: 'Warehouse Manager', + title: 'MinhThu', theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, themeMode: ThemeMode.system, diff --git a/pubspec.lock b/pubspec.lock index bf07448..818a62a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1029,6 +1029,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + sunmi_printer_plus: + dependency: "direct main" + description: + name: sunmi_printer_plus + sha256: "77293b7da16bdf3805c5a24ea41731978e8a31da99c3fca38a658a0778450b78" + url: "https://pub.dev" + source: hosted + version: "4.1.1" synchronized: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 641f1ce..e9aafe1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,7 @@ dependencies: pdf: ^3.11.3 barcode_widget: ^2.0.4 google_fonts: ^6.2.1 + sunmi_printer_plus: ^4.1.1 dev_dependencies: flutter_test: