aman-satu-flutter/lib/core/utils/pos_printer.dart

189 lines
5.8 KiB
Dart

import 'dart:io';
import 'dart:typed_data';
import 'package:charset_converter/charset_converter.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:image/image.dart' as Im;
import 'package:qr_flutter/qr_flutter.dart';
import 'package:satu/core/models/flow/check_bean.dart';
import 'package:satu/core/models/flow/check_row_bean.dart';
import 'package:satu/core/models/settings/printer_setting.dart';
Future<List<int>> getTestReceipt(String encoding, String paperSize) async {
final CheckBean checkBean = CheckBean();
final CheckRowBean rowBean1 = CheckRowBean();
rowBean1.text = 'Тестовый чек';
rowBean1.center = true;
final CheckRowBean rowBean2 = CheckRowBean();
rowBean2.text = ['Левая сторона', 'Правая сторона'];
rowBean2.center = true;
checkBean.rows.add(rowBean1);
checkBean.rows.add(CheckRowBean()..text='{br}'..center=true);
checkBean.rows.add(CheckRowBean()..text='{line}'..center=true);
checkBean.rows.add(CheckRowBean()..text='{br}'..center=true);
checkBean.rows.add(rowBean2);
checkBean.rows.add(CheckRowBean()..text='{br}'..center=true);
checkBean.rows.add(CheckRowBean()..text='{line}'..center=true);
checkBean.qr = 'test qr data';
return await _generateReceipt(encoding, paperSize, checkBean);
}
Future<List<int>> getReceipt(
String encoding, String paperSize, CheckBean checkBean) async {
return await _generateReceipt(encoding, paperSize, checkBean);
}
Future<List<int>> _generateReceipt(
String encoding, String paperSize, CheckBean checkBean) async {
List<int> bytes = [];
final profile = await CapabilityProfile.load();
final generator = Generator(
paperSize == PrinterConst.paperSize58mm ? PaperSize.mm58 : PaperSize.mm80,
profile,
);
String codeTable = 'CP866';
if (encoding == PrinterConst.encodingCP866) {
codeTable = 'CP866';
} else if (encoding == PrinterConst.encodingCP1251) {
codeTable = 'CP1251';
}
generator.setGlobalCodeTable(codeTable);
for (CheckRowBean row in checkBean.rows) {
String type = row.text.runtimeType.toString();
final bool isList = type == 'List<dynamic>' || type == 'List<String>';
final bool isNull = type == 'Null';
final bool isString = type == 'String';
final bool center = row.center;
if (isNull) {
continue;
}
if (isString) {
String text = row.text as String;
text = text.replaceAll('&laquo;', '«');
text = text.replaceAll('&raquo;', '»');
final bool isLine = '{line}' == text;
final bool isBr = '{br}' == text;
if (isBr) {
bytes += generator.feed(1);
} else if (isLine) {
bytes += generator.hr();
} else {
final Uint8List firstCol =
await CharsetConverter.encode(encoding.toLowerCase(), text);
bytes += generator.textEncoded(firstCol,
styles: PosStyles(align: center ? PosAlign.center : PosAlign.left));
}
}
if (isList) {
final List<dynamic> list = row.text as List<dynamic>;
if (list.length == 2) {
final Uint8List firstCol = await CharsetConverter.encode(
encoding.toLowerCase(), list[0] as String);
final Uint8List secondCol = await CharsetConverter.encode(
encoding.toLowerCase(), list[1] as String);
bytes += generator.row([
PosColumn(
textEncoded: firstCol,
width: 6,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
textEncoded: secondCol,
width: 6,
styles: const PosStyles(align: PosAlign.right, underline: true),
),
]);
}
}
print('${row.text.runtimeType}, ${row.text}');
}
if (checkBean.qr != null) {
bytes += generator.feed(2);
const double qrSize = 200;
try {
final ByteData? uiImg = await QrPainter(
data: checkBean.qr!,
version: QrVersions.auto,
gapless: true,
).toImageData(qrSize);
final img = Im.decodePng(uiImg!.buffer.asUint8List());
bytes += generator.image(img!);
} catch (e) {
print(e);
}
}
bytes += generator.feed(2);
bytes += generator.cut();
return bytes;
}
Future<List<int>> getTestReceiptImg(String paperSize) async {
final ByteData data =
await rootBundle.load('assets/images/aman_kassa_check.png');
final Uint8List imgBytes = data.buffer.asUint8List();
return _getReceiptImg(paperSize, imgBytes);
}
Future<List<int>> getReceiptImg(String paperSize, Uint8List imgBytes) async {
return _getReceiptImg(paperSize, imgBytes);
}
Future<List<int>> _getReceiptImg(String paperSize, Uint8List imgBytes) async {
final profile = await CapabilityProfile.load();
final generator = Generator(
paperSize == PrinterConst.paperSize58mm ? PaperSize.mm58 : PaperSize.mm80,
profile,
);
List<int> bytes = [];
final Im.Image? image = Im.decodeImage(imgBytes);
// Using `ESC *`
bytes += generator.image(image!);
bytes += generator.feed(2);
bytes += generator.cut();
return bytes;
}
int getChunkSize() {
final bool isIos = Platform.isIOS;
if (isIos) {
return 75;
}
return 1024;
}
int getQueueSleep() {
final bool isIos = Platform.isIOS;
if (isIos) {
return 10;
}
return 100;
}
BluetoothDevice printerDeviceToBluetoothDevice(PrinterDevice device) {
return BluetoothDevice()
..name = device.name
..address = device.address
..connected = device.connected
..type = device.type;
}
PrinterDevice bluetoothDeviceToPrinterDevice(PrinterBluetooth device) {
return PrinterDevice()
..name = device.name
..address = device.address
..type = device.type;
}