printer release

fix_ssl_master
suvaissov 2021-03-17 11:46:30 +06:00
parent a45bbc03c3
commit 8c3451ffd2
21 changed files with 607 additions and 89 deletions

View File

@ -18,7 +18,7 @@ class SimpleLogPrinter extends LogPrinter {
if (event.stackTrace == null) { if (event.stackTrace == null) {
stack = formatStackTrace(StackTrace.current, 2); stack = formatStackTrace(StackTrace.current, 2);
} else { } else {
stack = formatStackTrace(event.stackTrace, 2); stack = formatStackTrace(event.stackTrace, 1);
} }
print(color(' $emoji $message $error -> $stack ')); print(color(' $emoji $message $error -> $stack '));
return []; return [];
@ -34,6 +34,7 @@ class SimpleLogPrinter extends LogPrinter {
} }
String formatStackTrace(StackTrace stackTrace, int methodPosition) { String formatStackTrace(StackTrace stackTrace, int methodPosition) {
var lines = stackTrace.toString()?.split('\n'); var lines = stackTrace.toString()?.split('\n');
var formatted = <String>[]; var formatted = <String>[];
var count = 0; var count = 0;

View File

@ -0,0 +1,17 @@
class CheckImageModal {
final String base64Data;
final String textData;
CheckImageModal({this.base64Data, this.textData});
static CheckImageModal fromJson(Map<String, dynamic> json) {
return CheckImageModal(
base64Data: json['base64Data'],
textData: json['textData']
);
}
Map<String, dynamic> toJson() =>
{
'base64Data': base64Data,
'textData': textData
};
}

View File

@ -9,4 +9,6 @@ const String QrViewRoute = "QrViewRoute";
const String SettingsPrinterRoute = "SettingsPrinterRoute"; const String SettingsPrinterRoute = "SettingsPrinterRoute";
const String SettingsPrinterBTRoute = "SettingsPrinterBTRoute"; const String SettingsPrinterBTRoute = "SettingsPrinterBTRoute";
const String SettingsPrinterEncodingRoute = "SettingsPrinterEncodingRoute";
const String SettingsPrinterPaperRoute = "SettingsPrinterPaperRoute";
// Generate the views here // Generate the views here

View File

@ -3,7 +3,9 @@ import 'package:aman_kassa_flutter/views/history/history_view.dart';
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart'; import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart';
import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart'; import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
import 'package:aman_kassa_flutter/views/settings/printer/PrinterSelect.dart'; import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterEncoding.dart';
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterPaperSize.dart';
import 'file:///D:/Work/serik/Flutter/aman-kassa-flutter/lib/views/settings/printer/views/PrinterSelect.dart';
import 'package:aman_kassa_flutter/views/settings/setting_printer_view.dart'; import 'package:aman_kassa_flutter/views/settings/setting_printer_view.dart';
import './route_names.dart'; import './route_names.dart';
@ -63,6 +65,16 @@ Route<dynamic> generateRoute(RouteSettings settings) {
routeName: settings.name, routeName: settings.name,
viewToShow: PrinterSelectView(), viewToShow: PrinterSelectView(),
); );
case SettingsPrinterEncodingRoute:
return _getPageRoute(
routeName: settings.name,
viewToShow: PrinterEncodingView(),
);
case SettingsPrinterPaperRoute:
return _getPageRoute(
routeName: settings.name,
viewToShow: PrinterPaperView(),
);
default: default:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => Scaffold( builder: (_) => Scaffold(

View File

@ -8,6 +8,7 @@ import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/calc_model.dart'; import 'package:aman_kassa_flutter/core/models/calc_model.dart';
import 'package:aman_kassa_flutter/core/models/check_data.dart'; import 'package:aman_kassa_flutter/core/models/check_data.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/check_item.dart'; import 'package:aman_kassa_flutter/core/models/check_item.dart';
import 'package:aman_kassa_flutter/core/models/product_dao.dart'; import 'package:aman_kassa_flutter/core/models/product_dao.dart';
import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/response.dart';
@ -166,17 +167,26 @@ class DataService extends BaseService {
// log.i('response operation: ${response.operation}'); // log.i('response operation: ${response.operation}');
if (response.status == 200 && response.operation == true) { if (response.status == 200 && response.operation == true) {
User user = Redux.store.state.userState.user; User user = Redux.store.state.userState.user;
//check compare
String check = response?.body['check']; String check = response?.body['check'];
var checkText = response?.body['check_text'];
CheckImageModal imageModal = new CheckImageModal( base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null );
// journal analyze
dynamic journal = response?.body['journal']; dynamic journal = response?.body['journal'];
String url = response?.body['link'];
int checkNum = journal['check_num']; int checkNum = journal['check_num'];
var summ = journal['summ']; var summ = journal['summ'];
// short url
String url = response?.body['link'];
// total
double total = summ != null ? double.parse(summ.toString()) : 0.0; double total = summ != null ? double.parse(summ.toString()) : 0.0;
//insert data to db
this.insertVoucher( this.insertVoucher(
user: user, user: user,
name: 'Чек №$checkNum', name: 'Чек №$checkNum',
data: data, data: data,
base64Data: check, base64Data: jsonEncode(imageModal.toJson()),
total: total, total: total,
url: url, url: url,
type: operationType == OperationTypeReturn type: operationType == OperationTypeReturn

View File

@ -29,4 +29,16 @@ ThunkAction<AppState> selectPrinterFromSetting(BluetoothDevice device) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
store.dispatch(SetSettingStateAction(SettingState(printerBT: device ))); store.dispatch(SetSettingStateAction(SettingState(printerBT: device )));
}; };
}
ThunkAction<AppState> selectPrinterEncodingFromSetting(String encoding) {
return (Store<AppState> store) async {
store.dispatch(SetSettingStateAction(SettingState(printerEncoding: encoding )));
};
}
ThunkAction<AppState> selectPrinterPaperSizeFromSetting(String paperSize) {
return (Store<AppState> store) async {
store.dispatch(SetSettingStateAction(SettingState(printerPaperSize: paperSize )));
};
} }

View File

@ -5,3 +5,15 @@ const String SettingModeCalc = 'calcMode';
const String SettingTradeTypeGood = 'g'; const String SettingTradeTypeGood = 'g';
const String SettingTradeTypeService = 's'; const String SettingTradeTypeService = 's';
const String SettingPrinterEncodingCp866 = 'cp866';
const String SettingPrinterEncodingWin1251 = 'windows-1251';
const String SettingPrinterEncodingImage = 'image';
const String SettingPrinterPaperM58 = '58mm';
const String SettingPrinterPaperM80 = '80mm';

View File

@ -6,6 +6,8 @@ settingReducer(SettingState prevState, SetSettingStateAction action) {
return prevState.copyWith( return prevState.copyWith(
mode: payload.mode, mode: payload.mode,
tradeType: payload.tradeType, tradeType: payload.tradeType,
printerBT: payload.printerBT printerBT: payload.printerBT,
printerEncoding: payload.printerEncoding,
printerPaperSize: payload.printerPaperSize,
); );
} }

View File

@ -2,22 +2,30 @@ import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart'; import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
@immutable @immutable
class SettingState { class SettingState {
final String mode; final String mode;
final String tradeType; final String tradeType;
final BluetoothDevice printerBT; final BluetoothDevice printerBT;
final String printerEncoding;
final String printerPaperSize;
SettingState({this.mode, this.tradeType, this.printerBT}); SettingState(
{this.mode,
this.tradeType,
this.printerBT,
this.printerEncoding,
this.printerPaperSize});
//read hive //read hive
factory SettingState.initial(SettingState payload) { factory SettingState.initial(SettingState payload) {
return SettingState( return SettingState(
mode: payload?.mode ?? SettingModeKassa, mode: payload?.mode ?? SettingModeKassa,
tradeType: payload?.tradeType ?? SettingTradeTypeGood, tradeType: payload?.tradeType ?? SettingTradeTypeGood,
printerBT: payload?.printerBT ?? null printerBT: payload?.printerBT ?? null,
); printerEncoding:
payload?.printerEncoding ?? SettingPrinterEncodingCp866,
printerPaperSize: payload?.printerPaperSize ?? SettingPrinterPaperM58);
} }
//write hive //write hive
@ -25,12 +33,15 @@ class SettingState {
@required mode, @required mode,
@required tradeType, @required tradeType,
@required printerBT, @required printerBT,
@required printerEncoding,
@required printerPaperSize,
}) { }) {
return SettingState( return SettingState(
mode: mode ?? this.mode, mode: mode ?? this.mode,
tradeType: tradeType ?? this.tradeType, tradeType: tradeType ?? this.tradeType,
printerBT: printerBT ?? this.printerBT printerBT: printerBT ?? this.printerBT,
); printerEncoding: printerEncoding ?? this.printerEncoding,
printerPaperSize: printerPaperSize ?? this.printerPaperSize);
} }
static SettingState fromJson(dynamic json) { static SettingState fromJson(dynamic json) {
@ -38,7 +49,11 @@ class SettingState {
? SettingState( ? SettingState(
tradeType: json['tradeType'], tradeType: json['tradeType'],
mode: json['mode'], mode: json['mode'],
printerBT: json['printerBT']!=null ? BluetoothDevice.fromJson(json['printerBT']) : null printerEncoding: json['printerEncoding'],
printerPaperSize: json['printerPaperSize'],
printerBT: json['printerBT'] != null
? BluetoothDevice.fromJson(json['printerBT'])
: null,
) )
: null; : null;
} }
@ -47,7 +62,9 @@ class SettingState {
return { return {
"tradeType": tradeType, "tradeType": tradeType,
"mode": mode, "mode": mode,
"printerBT": printerBT !=null ? printerBT.toJson() : null "printerBT": printerBT != null ? printerBT.toJson() : null,
"printerEncoding": printerEncoding,
"printerPaperSize": printerPaperSize,
}; };
} }
} }

View File

@ -1,10 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
@ -12,28 +15,99 @@ import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart'; import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class ImageShowContainer extends StatelessWidget { class ImageShowContainer extends StatefulWidget {
final ImageShowModel data; final ImageShowModel showModel;
ImageShowContainer(this.data); ImageShowContainer(this.showModel);
@override
_ImageShowContainerState createState() => _ImageShowContainerState();
}
class _ImageShowContainerState extends State<ImageShowContainer> {
final PrinterBluetoothManager printerManager = PrinterBluetoothManager();
final DialogService _dialogService = locator<DialogService>();
final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT;
bool _printing = false;
void _print() async {
final SettingState state = Redux.store.state.settingState;
if(state.printerBT == null) {
_dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков');
return;
}
setState(() {
_printing = true;
});
try {
printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80
? PaperSize.mm80
: PaperSize.mm58;
if (SettingPrinterEncodingImage == state.printerEncoding) {
final PosPrintResult res = await printerManager.printTicket(
await printImageCheck(paper, widget.showModel.data.base64Data),
chunkSizeBytes: 3096,
queueSleepTimeMs: 50);
if (res.value != 1) {
_dialogService.showDialog(description: res.msg);
}
} else {
final PosPrintResult res = await printerManager.printTicket(
await printTextCheck(
paper, state.printerEncoding,
jsonDecode(widget.showModel.data.textData)),
chunkSizeBytes: 3096,
queueSleepTimeMs: 50);
if (res.value != 1) {
_dialogService.showDialog(description: res.msg);
}
}
} finally {
setState(() {
_printing = false;
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
//backgroundColor: fillColor, //backgroundColor: fillColor,
title: Text(data.title), title: Text(widget.showModel.title),
actions: [
if(_printing)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: SizedBox(
width: 36.0,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: new AlwaysStoppedAnimation<Color>(
whiteColor),
),
),
),
)
else
IconButton(icon: Icon(Icons.print), onPressed: _print)
],
), ),
body: ListView( body: ListView(
children: <Widget>[imageFromBase64String(data.data)], children: <Widget>[imageFromBase64String(widget.showModel.data.base64Data)],
), ),
floatingActionButton: MyFloatingActionButton(data), floatingActionButton: MyFloatingActionButton(widget.showModel),
); );
} }
} }
@ -46,7 +120,7 @@ Padding imageFromBase64String(String base64String) {
} }
class ImageShowModel { class ImageShowModel {
final String data; final CheckImageModal data;
final String title; final String title;
final String url; final String url;
@ -64,17 +138,13 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
bool showFab = true; bool showFab = true;
DialogService _dialog = locator<DialogService>(); DialogService _dialog = locator<DialogService>();
NavigatorService _navigatorService = locator<NavigatorService>(); NavigatorService _navigatorService = locator<NavigatorService>();
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
final DialogService _dialogService = locator<DialogService>();
BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT;
double sheetHeight = 260; double sheetHeight = 260;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if ( printerBtDevice != null){
sheetHeight = 340;
}
return showFab return showFab
? FloatingActionButton( ? FloatingActionButton(
@ -119,14 +189,6 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
mainColor: redColor, mainColor: redColor,
icon: Icons.share, icon: Icons.share,
), ),
verticalSpaceSmall,
BusyButtonIcon(
title: 'Печать',
onPressed: printFile,
mainColor: primaryColor,
icon: Icons.print,
),
], ],
))); )));
showFoatingActionButton(false); showFoatingActionButton(false);
@ -141,33 +203,16 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
void shareFile() async { void shareFile() async {
try { try {
await Share.file('Aman Kassa', 'aman_kassa_check.png', await Share.file('Aman Kassa', 'aman_kassa_check.png',
base64Decode(widget.data.data), 'image/png'); base64Decode(widget.data.data.base64Data), 'image/png');
} catch (e) { } catch (e) {
print('error: $e'); print('error: $e');
} }
} }
void printFile() async {
Navigator.of(context).pop(false);
printerManager.selectPrinter(PrinterBluetooth(Redux.store.state.settingState.printerBT));
// TODO Don't forget to choose printer's paper
const PaperSize paper = PaperSize.mm58;
final PosPrintResult res =
await printerManager.printTicket(
await printImageCheck(paper,widget.data.data ),
chunkSizeBytes: 3096,
queueSleepTimeMs: 50
);
if(res.value != 1) {
_dialogService.showDialog(description: res.msg);
}
}
void qrGenerate() async { void qrGenerate() async {
_navigatorService.push(QrViewRoute, _navigatorService.push(QrViewRoute,
arguments: arguments:
ImageShowModel(data: widget.data.url, title: 'Спасибо за покупку')); ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
} }
void callWhatsApp() async { void callWhatsApp() async {

View File

@ -1,5 +1,8 @@
import 'dart:convert';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart'; import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/DbService.dart'; import 'package:aman_kassa_flutter/core/services/DbService.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
@ -62,11 +65,18 @@ class _HistoryViewState extends State<HistoryView> {
}, },
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
Voucher voucher = data[index]; Voucher voucher = data[index];
String base64Data = voucher.base64Data;
CheckImageModal checkImageData;
if(base64Data !=null && base64Data.startsWith('{')){
checkImageData = CheckImageModal.fromJson(jsonDecode(base64Data));
} else {
checkImageData = new CheckImageModal(base64Data: base64Data);
}
return ListTile( return ListTile(
onTap: () { onTap: () {
_navigatorService.push(ImageShowRoute, _navigatorService.push(ImageShowRoute,
arguments: ImageShowModel( arguments: ImageShowModel(
data: voucher.base64Data, data: checkImageData,
title: voucher.name, title: voucher.name,
url: voucher.url)); url: voucher.url));
}, },

View File

@ -1,5 +1,8 @@
import 'dart:convert';
import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/calc_model.dart'; import 'package:aman_kassa_flutter/core/models/calc_model.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/product_dao.dart'; import 'package:aman_kassa_flutter/core/models/product_dao.dart';
import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/route_names.dart';
@ -195,6 +198,7 @@ class _PaymentViewState extends State<PaymentView> {
if (response.operation) { if (response.operation) {
String message = response.body['message']; String message = response.body['message'];
String check = response.body['check']; String check = response.body['check'];
var checkText = response.body['check_text'];
String url = response?.body['link']; String url = response?.body['link'];
print('url : $url'); print('url : $url');
if (_mode == SettingModeCalc) { if (_mode == SettingModeCalc) {
@ -207,7 +211,7 @@ class _PaymentViewState extends State<PaymentView> {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.pop(); _navigatorService.pop();
_navigatorService.push(ImageShowRoute, _navigatorService.push(ImageShowRoute,
arguments: ImageShowModel(data:check, title: message, url: url )); arguments: ImageShowModel(data:new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url ));
} else if (!response.operation && ![401,402,403,412,500].contains(response.status)) { } else if (!response.operation && ![401,402,403,412,500].contains(response.status)) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialogService.showDialog(description: response.body['message']); _dialogService.showDialog(description: response.body['message']);

View File

@ -27,7 +27,7 @@ class _QrViewState extends State<QrView> {
body: Container( body: Container(
child: Center( child: Center(
child: QrImage( child: QrImage(
data: widget.data.data, data: widget.data.url,
version: QrVersions.auto, version: QrVersions.auto,
size: 220.0, size: 220.0,
), ),

View File

@ -1,9 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:charset_converter/charset_converter.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:image/image.dart' as Im; import 'package:image/image.dart' as Im;
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
Future<Ticket> testTicket(PaperSize paper) async { Future<Ticket> testTicket(PaperSize paper) async {
final Ticket ticket = Ticket(paper); final Ticket ticket = Ticket(paper);
@ -132,8 +137,93 @@ Future<Ticket> printImageCheck(PaperSize paper, String base64Src) async {
final Ticket ticket = Ticket(paper); final Ticket ticket = Ticket(paper);
final Uint8List bytes = base64Decode(base64Src); final Uint8List bytes = base64Decode(base64Src);
final Im.Image image = Im.decodeImage(bytes); final Im.Image image = Im.decodeImage(bytes);
ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster); //ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
ticket.image(image);
ticket.feed(2); ticket.feed(2);
ticket.cut();
return ticket;
}
Future<Ticket> printTextCheck(PaperSize paper, String encoding, var data ) async {
final Ticket ticket = Ticket(paper);
PosCodeTable codeTable;
if(encoding == SettingPrinterEncodingCp866) {
codeTable = PosCodeTable.pc866_2;
} else if(encoding == SettingPrinterEncodingWin1251) {
codeTable = PosCodeTable.wpc1251;
}
ticket.setGlobalCodeTable(codeTable);
ticket.setGlobalFont(PosFontType.fontB);
String qr = data['qr'];
List<dynamic> rows = data['rows'] as List;
for(dynamic element in rows) {
var text = element['text'];
int size = element['size'] as int;
bool center = element['center'] !=null ? element['center'] as bool : false;
if(text is List) {
Uint8List firstCol = await CharsetConverter.encode(encoding, (text).first as String);
Uint8List lastCol = await CharsetConverter.encode(encoding, (text).last as String);
ticket.row([
PosColumn(
textEncoded: firstCol,
width: 6,
styles: PosStyles(align: PosAlign.left),
),
PosColumn(
textEncoded: lastCol,
width: 6,
styles: PosStyles(align: PosAlign.right),
),
]);
} else {
String line = text as String;
if(line == 'breakline') {
ticket.hr();
} else if(line == 'br') {
ticket.emptyLines(1);
} else {
Uint8List encTxt11 = await CharsetConverter.encode(encoding, line);
ticket.textEncoded( encTxt11, styles: PosStyles( align: center ? PosAlign.center : PosAlign.left ));
}
}
}
// Print barcode
//final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
//ticket.barcode(Barcode.upcA(barData));
//ticket.qrcode(qr, align: PosAlign.center);
ticket.emptyLines(1);
const double qrSize = 200;
try {
final uiImg = await QrPainter(
data: qr,
version: QrVersions.auto,
gapless: false,
).toImageData(qrSize);
final dir = await getTemporaryDirectory();
final pathName = '${dir.path}/qr_tmp.png';
final qrFile = File(pathName);
final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
final img = Im.decodeImage(imgFile.readAsBytesSync());
ticket.image(img);
} catch (e) {
print(e);
}
ticket.feed(2);
ticket.cut(); ticket.cut();
return ticket; return ticket;
} }

View File

@ -0,0 +1,12 @@
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
var encoding = {
SettingPrinterEncodingCp866: "CP-866",
SettingPrinterEncodingWin1251: "Windows-1251",
SettingPrinterEncodingImage: "Big-Encoding",
};
var paperSize = {
SettingPrinterPaperM58: "58 мм",
SettingPrinterPaperM80: "80 мм"
};

View File

@ -0,0 +1,53 @@
var exampleJson = {
"check_text": {
"rows": [
{"size": 14, "text": "", "center": true},
{"size": 15, "text": "breakline", "center": true},
{"size": 14, "text": "ТОО «Aman Systems»"},
{"size": 14, "text": "ИИН/БИН: 180640018960"},
{"size": 14, "text": "Сер. номер ККМ: TEST00000005"},
{"size": 14, "text": "Регистрационный номер: 123132132323"},
{"size": 14, "text": "Коргальджинское шоссе, д.19 оф.308"},
{"size": 15, "text": "breakline", "center": true},
{"size": 14, "text": "Продажа,Наличные, ", "center": true},
{"size": 15, "text": "ФИСКАЛЬНЫЙ ЧЕК №16580", "center": true},
{"size": 15, "text": "ФП 471369529060", "center": true},
{"size": 15, "text": "Дата: 03.03.2021 23:16", "center": true},
{"size": 15, "text": "breakline", "center": true},
{"size": 14, "text": "Кассир: Амантай ИХ"},
{"size": 14, "text": "Касса: Касса 1"},
{"size": 15, "text": "breakline", "center": true},
{"size": 15, "text": "br"},
{"size": 14, "text": "1. test"},
{"size": 14, "text": "200,00 x 1 = 200,00"},
{"size": 10, "text": "br"},
{"size": 15, "text": "breakline"},
{
"size": 17,
"text": ["ИТОГО:", "200,00"]
},
{
"size": 14,
"text": ["Наличные", "200,00"]
},
{"size": 15, "text": "breakline"},
{"size": 17, "text": "В том числе НДС:"},
{
"size": 14,
"text": ["12 %", "21,43"]
},
{"size": 14, "text": ""},
{"size": 15, "text": "breakline"},
{"size": 15, "text": "ОФД АО \"Транстелеком\"", "center": true},
{"size": 15, "text": "ofd1.kz", "center": true},
{"size": 14, "text": ""},
{"size": 15, "text": "breakline"},
{"size": 14, "text": "", "center": true},
{"size": 13, "text": "порядковый номер чека:19800", "center": true},
{"size": 14, "text": "Онлайн касса Aman", "center": true},
{"size": 14, "text": "kassa.aman.com.kz", "center": true}
],
"qr":
"87.255.215.94:4000/t/?i=471369529060&f=123132132323&s=200.0&t=20210303T231651"
}
};

View File

@ -0,0 +1,94 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' hide Image;
import 'package:flutter/rendering.dart';
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:intl/intl.dart';
import 'package:logger/logger.dart';
import '../data/settings_envi.dart';
class PrinterEncodingView extends StatefulWidget {
PrinterEncodingView({Key key, this.title}) : super(key: key);
final String title;
@override
_PrinterEncodingViewState createState() => _PrinterEncodingViewState();
}
class _PrinterEncodingViewState extends State<PrinterEncodingView> {
Logger _logger = getLogger('PrinterEncodingView');
@override
void initState() {
super.initState();
}
void _selectPrinter(String encoding, BuildContext context, ) async {
_logger.i(encoding);
await Redux.store.dispatch(selectPrinterEncodingFromSetting(encoding));
Navigator.of(context).pop(false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Выберите кодировку'),
),
body: ListView.builder(
itemCount: encoding.keys.length,
itemBuilder: (BuildContext _, int index) {
return InkWell(
onTap: () => _selectPrinter(encoding.keys.elementAt(index), context),
child: Column(
children: <Widget>[
Container(
height: 60,
padding: EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
Icon(Icons.sort_by_alpha_outlined),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(encoding.values.elementAt(index) ?? ''),
],
),
)
],
),
),
Divider(),
],
),
);
}),
);
}
}

View File

@ -0,0 +1,94 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' hide Image;
import 'package:flutter/rendering.dart';
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:intl/intl.dart';
import 'package:logger/logger.dart';
import '../data/settings_envi.dart';
class PrinterPaperView extends StatefulWidget {
PrinterPaperView({Key key, this.title}) : super(key: key);
final String title;
@override
_PrinterEncodingViewState createState() => _PrinterEncodingViewState();
}
class _PrinterEncodingViewState extends State<PrinterPaperView> {
Logger _logger = getLogger('PrinterEncodingView');
@override
void initState() {
super.initState();
}
void _selectPaper(String paperSize, BuildContext context, ) async {
_logger.i(encoding);
await Redux.store.dispatch(selectPrinterPaperSizeFromSetting(paperSize));
Navigator.of(context).pop(false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Выберите ширину ленты'),
),
body: ListView.builder(
itemCount: paperSize.keys.length,
itemBuilder: (BuildContext _, int index) {
return InkWell(
onTap: () => _selectPaper(paperSize.keys.elementAt(index), context),
child: Column(
children: <Widget>[
Container(
height: 60,
padding: EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
Icon(Icons.sort_by_alpha_outlined),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(paperSize.values.elementAt(index) ?? ''),
],
),
)
],
),
),
Divider(),
],
),
);
}),
);
}
}

View File

@ -17,7 +17,7 @@ import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'PrinterTest.dart'; import '../PrinterTest.dart';
class PrinterSelectView extends StatefulWidget { class PrinterSelectView extends StatefulWidget {

View File

@ -4,6 +4,7 @@ import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart';
@ -15,6 +16,8 @@ import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'component/setting_item.dart'; import 'component/setting_item.dart';
import './printer/data/settings_envi.dart';
import './printer/example/check_test.dart';
class SettingPrinterView extends StatefulWidget { class SettingPrinterView extends StatefulWidget {
@override @override
@ -34,16 +37,25 @@ class _SettingPrinterViewState extends State<SettingPrinterView> {
void _testPrint() async { void _testPrint() async {
printerManager.selectPrinter(PrinterBluetooth(Redux.store.state.settingState.printerBT)); final SettingState state = Redux.store.state.settingState;
printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
// TODO Don't forget to choose printer's paper // TODO Don't forget to choose printer's paper
const PaperSize paper = PaperSize.mm58; PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58;
final PosPrintResult res = if(SettingPrinterEncodingImage == state.printerEncoding) {
await printerManager.printTicket( final PosPrintResult res = await printerManager.printTicket(
await testTicketImage(paper), await testTicketImage(paper),
chunkSizeBytes: 3096, chunkSizeBytes: 3096,
queueSleepTimeMs: 50 queueSleepTimeMs: 50
); );
_dialogService.showDialog(description: res.msg); _dialogService.showDialog(description: res.msg);
} else {
final PosPrintResult res = await printerManager.printTicket(
await printTextCheck(paper, state.printerEncoding, exampleJson['check_text']),
chunkSizeBytes: 3096,
queueSleepTimeMs: 50
);
_dialogService.showDialog(description: res.msg);
}
} }
@ -69,6 +81,18 @@ class _SettingPrinterViewState extends State<SettingPrinterView> {
onTap: () { onTap: () {
_navigatorService.push(SettingsPrinterBTRoute); _navigatorService.push(SettingsPrinterBTRoute);
}), }),
SettingItem(
title: 'Кодировка',
name: vm.printerEncoding != null ? encoding[vm.printerEncoding] : null ,
onTap: () {
_navigatorService.push(SettingsPrinterEncodingRoute);
}),
SettingItem(
title: 'Ширина ленты',
name: vm.printerPaperSize != null ? paperSize[vm.printerPaperSize] : null ,
onTap: () {
_navigatorService.push(SettingsPrinterPaperRoute);
}),
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.only(bottom: 24.0), padding: const EdgeInsets.only(bottom: 24.0),

View File

@ -21,7 +21,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0-nullsafety.1" version: "2.5.0"
auto_size_text: auto_size_text:
dependency: "direct main" dependency: "direct main"
description: description:
@ -42,21 +42,21 @@ packages:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.1" version: "2.1.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
charset_converter: charset_converter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -70,14 +70,14 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.1" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0-nullsafety.3" version: "1.15.0"
convert: convert:
dependency: transitive dependency: transitive
description: description:
@ -154,7 +154,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -275,6 +275,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.16.1"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
json_annotation: json_annotation:
dependency: transitive dependency: transitive
description: description:
@ -302,7 +309,7 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10-nullsafety.1" version: "0.12.10"
material_design_icons_flutter: material_design_icons_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -316,7 +323,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.3" version: "1.3.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -330,7 +337,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.1" version: "1.8.0"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -524,7 +531,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.2" version: "1.8.0"
sqflite: sqflite:
dependency: "direct main" dependency: "direct main"
description: description:
@ -545,21 +552,21 @@ packages:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0-nullsafety.1" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.1" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.1" version: "1.1.0"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
@ -573,21 +580,21 @@ packages:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.19-nullsafety.2" version: "0.2.19"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.3" version: "1.3.0"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:
@ -636,7 +643,7 @@ packages:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:
@ -659,5 +666,5 @@ packages:
source: hosted source: hosted
version: "4.5.1" version: "4.5.1"
sdks: sdks:
dart: ">=2.10.2 <2.11.0" dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.22.2 <2.0.0" flutter: ">=1.22.2"