189 lines
5.8 KiB
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('«', '«');
|
|
text = text.replaceAll('»', '»');
|
|
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;
|
|
}
|