Merge branch 'master' into pin_locker
# Conflicts: # lib/core/router.dart # lib/redux/actions/setting_actions.dart # lib/redux/reducers/setting_reducer.dart # lib/redux/state/setting_state.dart # lib/views/home/components/popup_menu.dart # lib/views/home/home_view.dart # pubspec.lock # pubspec.yamlfix_ssl_master
commit
0cfbd11ade
|
|
@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 30
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
|
@ -46,8 +46,8 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "kz.com.aman.kassa"
|
applicationId "kz.com.aman.kassa"
|
||||||
minSdkVersion 18
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 30
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
class SettingModel {
|
||||||
|
const SettingModel({this.name, this.type, this.address});
|
||||||
|
final String type;
|
||||||
|
final String name;
|
||||||
|
final String address;
|
||||||
|
}
|
||||||
|
|
@ -6,4 +6,10 @@ const String HistoryViewRoute = "HistoryView";
|
||||||
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
||||||
const String SettingsViewRoute = "SettingsViewRoute";
|
const String SettingsViewRoute = "SettingsViewRoute";
|
||||||
const String QrViewRoute = "QrViewRoute";
|
const String QrViewRoute = "QrViewRoute";
|
||||||
|
|
||||||
|
|
||||||
|
const String SettingsPrinterRoute = "SettingsPrinterRoute";
|
||||||
|
const String SettingsPrinterBTRoute = "SettingsPrinterBTRoute";
|
||||||
|
const String SettingsPrinterEncodingRoute = "SettingsPrinterEncodingRoute";
|
||||||
|
const String SettingsPrinterPaperRoute = "SettingsPrinterPaperRoute";
|
||||||
// Generate the views here
|
// Generate the views here
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,16 @@ 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/views/PrinterSelect.dart';
|
||||||
import 'package:aman_kassa_flutter/views/settings/settings_view.dart';
|
import 'package:aman_kassa_flutter/views/settings/settings_view.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterEncoding.dart';
|
||||||
import './route_names.dart';
|
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterPaperSize.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
import 'package:aman_kassa_flutter/views/settings/setting_printer_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import './route_names.dart';
|
||||||
|
|
||||||
|
|
||||||
Route<dynamic> generateRoute(RouteSettings settings) {
|
Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
|
|
@ -57,6 +61,26 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: ImageShowContainer(data),
|
viewToShow: ImageShowContainer(data),
|
||||||
);
|
);
|
||||||
|
case SettingsPrinterRoute:
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
viewToShow: SettingPrinterView(),
|
||||||
|
);
|
||||||
|
case SettingsPrinterBTRoute:
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ class MainApplication extends StatelessWidget {
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
accentColor: yellowColor,
|
accentColor: yellowColor,
|
||||||
scaffoldBackgroundColor: Colors.white,
|
scaffoldBackgroundColor: Colors.white,
|
||||||
textTheme: GoogleFonts.latoTextTheme(
|
// textTheme: GoogleFonts.latoTextTheme(
|
||||||
Theme.of(context).textTheme,
|
// Theme.of(context).textTheme,
|
||||||
)
|
// )
|
||||||
),
|
),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
builder: (context, child) => Navigator(
|
builder: (context, child) => Navigator(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
import 'package:redux_thunk/redux_thunk.dart';
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
|
||||||
import '../store.dart';
|
import '../store.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
|
|
@ -41,4 +41,22 @@ ThunkAction<AppState> changePinSkipFromSetting(bool skip) {
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetSettingStateAction(SettingState(pinSkip: skip)));
|
store.dispatch(SetSettingStateAction(SettingState(pinSkip: skip)));
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> selectPrinterFromSetting(BluetoothDevice device) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
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 )));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -3,4 +3,17 @@ 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';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,8 @@ settingReducer(SettingState prevState, SetSettingStateAction action) {
|
||||||
pinCode: payload.pinCode,
|
pinCode: payload.pinCode,
|
||||||
pinLocked: payload.pinLocked,
|
pinLocked: payload.pinLocked,
|
||||||
pinSkip: payload.pinSkip,
|
pinSkip: payload.pinSkip,
|
||||||
|
printerBT: payload.printerBT,
|
||||||
|
printerEncoding: payload.printerEncoding,
|
||||||
|
printerPaperSize: payload.printerPaperSize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
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';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class SettingState {
|
class SettingState {
|
||||||
|
|
@ -8,9 +9,14 @@ class SettingState {
|
||||||
final String pinCode;
|
final String pinCode;
|
||||||
final bool pinLocked;
|
final bool pinLocked;
|
||||||
final bool pinSkip;
|
final bool pinSkip;
|
||||||
|
final BluetoothDevice printerBT;
|
||||||
|
final String printerEncoding;
|
||||||
|
final String printerPaperSize;
|
||||||
|
|
||||||
|
|
||||||
SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip});
|
SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip, this.printerBT,
|
||||||
|
this.printerEncoding,
|
||||||
|
this.printerPaperSize});
|
||||||
|
|
||||||
//read hive
|
//read hive
|
||||||
factory SettingState.initial(SettingState payload) {
|
factory SettingState.initial(SettingState payload) {
|
||||||
|
|
@ -20,6 +26,10 @@ class SettingState {
|
||||||
pinCode: payload?.pinCode ?? null,
|
pinCode: payload?.pinCode ?? null,
|
||||||
pinLocked: true,
|
pinLocked: true,
|
||||||
pinSkip: false,
|
pinSkip: false,
|
||||||
|
printerBT: payload?.printerBT ?? null,
|
||||||
|
printerEncoding:
|
||||||
|
payload?.printerEncoding ?? SettingPrinterEncodingCp866,
|
||||||
|
printerPaperSize: payload?.printerPaperSize ?? SettingPrinterPaperM58
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,13 +40,19 @@ class SettingState {
|
||||||
@required pinCode,
|
@required pinCode,
|
||||||
@required pinLocked,
|
@required pinLocked,
|
||||||
@required pinSkip,
|
@required pinSkip,
|
||||||
|
@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,
|
||||||
pinCode: pinCode ?? this.pinCode,
|
pinCode: pinCode ?? this.pinCode,
|
||||||
pinLocked: pinLocked ?? this.pinLocked,
|
pinLocked: pinLocked ?? this.pinLocked,
|
||||||
pinSkip: pinSkip ?? this.pinSkip
|
pinSkip: pinSkip ?? this.pinSkip,
|
||||||
|
printerBT: printerBT ?? this.printerBT,
|
||||||
|
printerEncoding: printerEncoding ?? this.printerEncoding,
|
||||||
|
printerPaperSize: printerPaperSize ?? this.printerPaperSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,6 +64,11 @@ class SettingState {
|
||||||
pinCode: json['pinCode'],
|
pinCode: json['pinCode'],
|
||||||
pinLocked: json['pinLocked'],
|
pinLocked: json['pinLocked'],
|
||||||
pinSkip: json['pinSkip'],
|
pinSkip: json['pinSkip'],
|
||||||
|
printerEncoding: json['printerEncoding'],
|
||||||
|
printerPaperSize: json['printerPaperSize'],
|
||||||
|
printerBT: json['printerBT'] != null
|
||||||
|
? BluetoothDevice.fromJson(json['printerBT'])
|
||||||
|
: null,
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +80,9 @@ class SettingState {
|
||||||
"pinCode": pinCode,
|
"pinCode": pinCode,
|
||||||
"pinLocked" : pinLocked,
|
"pinLocked" : pinLocked,
|
||||||
"pinSkip" : pinSkip,
|
"pinSkip" : pinSkip,
|
||||||
|
"printerBT": printerBT != null ? printerBT.toJson() : null,
|
||||||
|
"printerEncoding": printerEncoding,
|
||||||
|
"printerPaperSize": printerPaperSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,113 @@
|
||||||
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/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';
|
||||||
|
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_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: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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,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;
|
||||||
|
|
||||||
|
|
@ -60,8 +139,13 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
DialogService _dialog = locator<DialogService>();
|
DialogService _dialog = locator<DialogService>();
|
||||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
|
||||||
|
|
||||||
|
double sheetHeight = 260;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
|
||||||
return showFab
|
return showFab
|
||||||
? FloatingActionButton(
|
? FloatingActionButton(
|
||||||
child: Icon(Icons.share),
|
child: Icon(Icons.share),
|
||||||
|
|
@ -79,7 +163,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
color: Colors.grey[300],
|
color: Colors.grey[300],
|
||||||
spreadRadius: 5)
|
spreadRadius: 5)
|
||||||
]),
|
]),
|
||||||
height: 260,
|
height: sheetHeight,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
verticalSpaceSmall,
|
verticalSpaceSmall,
|
||||||
|
|
@ -102,7 +186,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
BusyButtonIcon(
|
BusyButtonIcon(
|
||||||
title: 'Поделиться',
|
title: 'Поделиться',
|
||||||
onPressed: shareFile,
|
onPressed: shareFile,
|
||||||
mainColor: yellowColor,
|
mainColor: redColor,
|
||||||
icon: Icons.share,
|
icon: Icons.share,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -119,7 +203,7 @@ 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');
|
||||||
}
|
}
|
||||||
|
|
@ -128,7 +212,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
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 {
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ const List<Choice> choices = const <Choice>[
|
||||||
const Choice(
|
const Choice(
|
||||||
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
||||||
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
||||||
|
const Choice(title: 'Принтер', icon: Icons.print, command: 'print'),
|
||||||
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
||||||
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
|
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
|
@ -87,7 +86,7 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: PassCodeScreen( title: 'Безопасность',)
|
child: PassCodeScreen( title: 'Áåçîïàñíîñòü',)
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -153,6 +152,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
||||||
_navigatorService.push(InfoKkmViewRoute);
|
_navigatorService.push(InfoKkmViewRoute);
|
||||||
} else if (choice.command == 'settings') {
|
} else if (choice.command == 'settings') {
|
||||||
_navigatorService.push(SettingsViewRoute);
|
_navigatorService.push(SettingsViewRoute);
|
||||||
|
} else if (choice.command == 'print') {
|
||||||
|
_navigatorService.push(SettingsPrinterRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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']);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingItem extends StatefulWidget {
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final String value;
|
||||||
|
final String title;
|
||||||
|
final Function onTap;
|
||||||
|
|
||||||
|
SettingItem({Key key, this.name, this.value, this.onTap, this.title }) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SettingItemState createState() => _SettingItemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingItemState extends State<SettingItem> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(widget.title),
|
||||||
|
subtitle: Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text: widget.name,
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
children: <TextSpan>[
|
||||||
|
if(widget.value !=null)
|
||||||
|
TextSpan(text: ' ${widget.value}', style: TextStyle(fontStyle: FontStyle.italic)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
trailing: Icon(Icons.chevron_right),
|
||||||
|
onTap: widget.onTap,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
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:flutter/services.dart';
|
||||||
|
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 {
|
||||||
|
final Ticket ticket = Ticket(paper);
|
||||||
|
|
||||||
|
//Uint8List encTxt11 = await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||||
|
//ticket.textEncoded(encTxt11, styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||||
|
//ticket.textEncoded(encTxt11);
|
||||||
|
|
||||||
|
// ticket.text('Special 1: àÀ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //А
|
||||||
|
// ticket.text('Special 1: á'.toUpperCase(), styles: PosStyles(codeTable: PosCodeTable.westEur));// Б
|
||||||
|
// ticket.text('Special 1: â', styles: PosStyles(codeTable: PosCodeTable.westEur)); //В
|
||||||
|
// ticket.text('Special 1: ã', styles: PosStyles(codeTable: PosCodeTable.westEur));// Г
|
||||||
|
// ticket.text('Special 1: äÄ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Д
|
||||||
|
// ticket.text('Special 1: å', styles: PosStyles(codeTable: PosCodeTable.westEur));// Е
|
||||||
|
// ticket.text('Special 1: æÆ', styles: PosStyles(codeTable: PosCodeTable.westEur));// Ж
|
||||||
|
// ticket.text('Special 1: ç', styles: PosStyles(codeTable: PosCodeTable.westEur));//З
|
||||||
|
// ticket.text('Special 1: èÈ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // И
|
||||||
|
// ticket.text('Special 1: éÉ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Й
|
||||||
|
// ticket.text('Special 1: ê', styles: PosStyles(codeTable: PosCodeTable.westEur));//К
|
||||||
|
// ticket.text('Special 1: ëË', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Л
|
||||||
|
// ticket.text('Special 1: ìÌ', styles: PosStyles(codeTable: PosCodeTable.westEur));// M
|
||||||
|
// ticket.text('Special 1: íÍ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Н
|
||||||
|
// ticket.text('Special 1: î', styles: PosStyles(codeTable: PosCodeTable.westEur));// О
|
||||||
|
// ticket.text('Special 1: ï', styles: PosStyles(codeTable: PosCodeTable.westEur)); // П
|
||||||
|
// ticket.text('Special 1: ð', styles: PosStyles(codeTable: PosCodeTable.westEur));// Р
|
||||||
|
// ticket.text('Special 1: ñ', styles: PosStyles(codeTable: PosCodeTable.westEur));// С
|
||||||
|
// ticket.text('Special 1: ò', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Т
|
||||||
|
// ticket.text('Special 1: óÓ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //У
|
||||||
|
// ticket.text('Special 1: ô', styles: PosStyles(codeTable: PosCodeTable.westEur));// Ф
|
||||||
|
// ticket.text('Special 1: õÕ', styles: PosStyles(codeTable: PosCodeTable.westEur));// Х
|
||||||
|
// ticket.text('Special 1: ö', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ц
|
||||||
|
// ticket.text('Special 1: ÷', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ч
|
||||||
|
// ticket.text('Special 1: ø', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ш
|
||||||
|
// ticket.text('Special 1: ù', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Щ
|
||||||
|
// ticket.text('Special 1: ú', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ъ
|
||||||
|
// ticket.text('Special 1: û', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ы
|
||||||
|
// ticket.text('Special 1: üÜ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ь
|
||||||
|
// ticket.text('Special 1: ý', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Э
|
||||||
|
// ticket.text('Special 1: þ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // ю
|
||||||
|
// ticket.text('Special 1: ÿß', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Я
|
||||||
|
|
||||||
|
// Uint8List encTxt11 = await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||||
|
// //ticket.textEncoded(encTxt11, styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||||
|
// ticket.textEncoded(encTxt11);
|
||||||
|
|
||||||
|
ticket.text(
|
||||||
|
'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
|
||||||
|
//ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||||
|
//ticket.text('Special 2: blåbærgrød', styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||||
|
|
||||||
|
ticket.text('Bold text', styles: PosStyles(bold: true));
|
||||||
|
ticket.text('Reverse text', styles: PosStyles(reverse: true));
|
||||||
|
ticket.text('Underlined text',
|
||||||
|
styles: PosStyles(underline: true), linesAfter: 1);
|
||||||
|
ticket.text('Align left', styles: PosStyles(align: PosAlign.left));
|
||||||
|
ticket.text('Align center', styles: PosStyles(align: PosAlign.center));
|
||||||
|
ticket.text('Align right',
|
||||||
|
styles: PosStyles(align: PosAlign.right), linesAfter: 1);
|
||||||
|
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(
|
||||||
|
text: 'col3',
|
||||||
|
width: 3,
|
||||||
|
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||||
|
),
|
||||||
|
PosColumn(
|
||||||
|
text: 'col6',
|
||||||
|
width: 6,
|
||||||
|
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||||
|
),
|
||||||
|
PosColumn(
|
||||||
|
text: 'col3',
|
||||||
|
width: 3,
|
||||||
|
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
ticket.text('Text size 200%',
|
||||||
|
styles: PosStyles(
|
||||||
|
height: PosTextSize.size2,
|
||||||
|
width: PosTextSize.size2,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Print image
|
||||||
|
//final ByteData data = await rootBundle.load('assets/images/logo.png');
|
||||||
|
//final Uint8List bytes = data.buffer.asUint8List();
|
||||||
|
// Print image using alternative commands
|
||||||
|
// ticket.imageRaster(image);
|
||||||
|
// ticket.imageRaster(image, imageFn: PosImageFn.graphics);
|
||||||
|
|
||||||
|
// Print barcode
|
||||||
|
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
|
||||||
|
ticket.barcode(Barcode.upcA(barData));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ticket.feed(2);
|
||||||
|
|
||||||
|
ticket.cut();
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Ticket> testTicketImage(PaperSize paper) async {
|
||||||
|
final Ticket ticket = Ticket(paper);
|
||||||
|
|
||||||
|
// Print image
|
||||||
|
final ByteData byteData = await rootBundle.load('assets/images/check.png');
|
||||||
|
final Uint8List bytes = byteData.buffer.asUint8List();
|
||||||
|
final Im.Image imagea = Im.decodeImage(bytes);
|
||||||
|
// Using `ESC *`
|
||||||
|
//ticket.image(imagea);
|
||||||
|
// Using `GS v 0` (obsolete)
|
||||||
|
//ticket.imageRaster(imagea);
|
||||||
|
// Using `GS ( L`
|
||||||
|
ticket.imageRaster(imagea, imageFn: PosImageFn.bitImageRaster);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ticket.feed(2);
|
||||||
|
|
||||||
|
ticket.cut();
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Ticket> printImageCheck(PaperSize paper, String base64Src) async {
|
||||||
|
final Ticket ticket = Ticket(paper);
|
||||||
|
final Uint8List bytes = base64Decode(base64Src);
|
||||||
|
final Im.Image image = Im.decodeImage(bytes);
|
||||||
|
//ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
|
||||||
|
ticket.image(image);
|
||||||
|
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();
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
@ -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 мм"
|
||||||
|
};
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
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 '../PrinterTest.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PrinterSelectView extends StatefulWidget {
|
||||||
|
PrinterSelectView({Key key, this.title}) : super(key: key);
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PrinterSelectViewState createState() => _PrinterSelectViewState();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PrinterSelectViewState extends State<PrinterSelectView> {
|
||||||
|
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||||
|
List<PrinterBluetooth> _devices = [];
|
||||||
|
Logger _logger = getLogger('PrinterSelectView');
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
printerManager.scanResults.listen((devices) async {
|
||||||
|
// print('UI: Devices found ${devices.length}');
|
||||||
|
setState(() {
|
||||||
|
_devices = devices;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_startScanDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startScanDevices() {
|
||||||
|
setState(() {
|
||||||
|
_devices = [];
|
||||||
|
});
|
||||||
|
printerManager.startScan(Duration(seconds: 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopScanDevices() {
|
||||||
|
printerManager.stopScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Ticket> demoReceipt(PaperSize paper) async {
|
||||||
|
final Ticket ticket = Ticket(paper, );
|
||||||
|
|
||||||
|
// Print image
|
||||||
|
// final ByteData data = await rootBundle.load('assets/images/aman_kassa_check.png');
|
||||||
|
// final Uint8List bytes = data.buffer.asUint8List();
|
||||||
|
// final Im.Image image = Im.decodeImage(bytes);
|
||||||
|
// Im.Image thumbnail = Im.copyResize(image, width: 270);
|
||||||
|
// ticket.image(thumbnail, align: PosAlign.center);
|
||||||
|
|
||||||
|
//ticket.imageRaster(image, align: PosAlign.center);
|
||||||
|
|
||||||
|
ticket.text('AMAN-SATU',
|
||||||
|
styles: PosStyles(
|
||||||
|
align: PosAlign.center,
|
||||||
|
height: PosTextSize.size2,
|
||||||
|
width: PosTextSize.size2,
|
||||||
|
),
|
||||||
|
linesAfter: 1);
|
||||||
|
|
||||||
|
ticket.text('889 Watson Lane', styles: PosStyles(align: PosAlign.center));
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, codeTable: PosCodeTable.westEur), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontA), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontB), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, height: PosTextSize.size1), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size2), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size3), containsChinese: true);
|
||||||
|
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size4), containsChinese: true);
|
||||||
|
ticket.text('Tel: 830-221-1234', styles: PosStyles(align: PosAlign.center));
|
||||||
|
ticket.text('Web: www.example.com',
|
||||||
|
styles: PosStyles(align: PosAlign.center), linesAfter: 1);
|
||||||
|
|
||||||
|
ticket.hr();
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(text: 'Qty', width: 1),
|
||||||
|
PosColumn(text: 'Item', width: 7),
|
||||||
|
PosColumn(
|
||||||
|
text: 'Price', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
PosColumn(
|
||||||
|
text: 'Total', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(text: '2', width: 1),
|
||||||
|
PosColumn(text: 'ONION RINGS', width: 7),
|
||||||
|
PosColumn(
|
||||||
|
text: '0.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
PosColumn(
|
||||||
|
text: '1.98', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
]);
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(text: '1', width: 1),
|
||||||
|
PosColumn(text: 'PIZZA', width: 7),
|
||||||
|
PosColumn(
|
||||||
|
text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
PosColumn(
|
||||||
|
text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
]);
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(text: '1', width: 1),
|
||||||
|
PosColumn(text: 'SPRING ROLLS', width: 7),
|
||||||
|
PosColumn(
|
||||||
|
text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
PosColumn(
|
||||||
|
text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
]);
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(text: '3', width: 1),
|
||||||
|
PosColumn(text: 'CRUNCHY STICKS', width: 7),
|
||||||
|
PosColumn(
|
||||||
|
text: '0.85', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
PosColumn(
|
||||||
|
text: '2.55', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||||
|
]);
|
||||||
|
ticket.hr();
|
||||||
|
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(
|
||||||
|
text: 'TOTAL',
|
||||||
|
width: 6,
|
||||||
|
styles: PosStyles(
|
||||||
|
height: PosTextSize.size2,
|
||||||
|
width: PosTextSize.size2,
|
||||||
|
)),
|
||||||
|
PosColumn(
|
||||||
|
text: '\$10.97',
|
||||||
|
width: 6,
|
||||||
|
styles: PosStyles(
|
||||||
|
align: PosAlign.right,
|
||||||
|
height: PosTextSize.size2,
|
||||||
|
width: PosTextSize.size2,
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
ticket.hr(ch: '=', linesAfter: 1);
|
||||||
|
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(
|
||||||
|
text: 'Cash',
|
||||||
|
width: 7,
|
||||||
|
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||||
|
PosColumn(
|
||||||
|
text: '\$15.00',
|
||||||
|
width: 5,
|
||||||
|
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||||
|
]);
|
||||||
|
ticket.row([
|
||||||
|
PosColumn(
|
||||||
|
text: 'Change',
|
||||||
|
width: 7,
|
||||||
|
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||||
|
PosColumn(
|
||||||
|
text: '\$4.03',
|
||||||
|
width: 5,
|
||||||
|
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
ticket.feed(2);
|
||||||
|
ticket.text('Thank you!',
|
||||||
|
styles: PosStyles(align: PosAlign.center, bold: true));
|
||||||
|
|
||||||
|
final now = DateTime.now();
|
||||||
|
final formatter = DateFormat('MM/dd/yyyy H:m');
|
||||||
|
final String timestamp = formatter.format(now);
|
||||||
|
ticket.text(timestamp,
|
||||||
|
styles: PosStyles(align: PosAlign.center), linesAfter: 2);
|
||||||
|
|
||||||
|
// Print QR Code from image
|
||||||
|
// try {
|
||||||
|
// const String qrData = 'example.com';
|
||||||
|
// const double qrSize = 200;
|
||||||
|
// final uiImg = await QrPainter(
|
||||||
|
// data: qrData,
|
||||||
|
// 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 = decodeImage(imgFile.readAsBytesSync());
|
||||||
|
|
||||||
|
// ticket.image(img);
|
||||||
|
// } catch (e) {
|
||||||
|
// print(e);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Print QR Code using native function
|
||||||
|
// ticket.qrcode('example.com');
|
||||||
|
|
||||||
|
ticket.feed(2);
|
||||||
|
ticket.cut();
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _selectPrinter(PrinterBluetooth printer, BuildContext context, ) async {
|
||||||
|
printerManager.selectPrinter(printer);
|
||||||
|
_logger.i(printer.name);
|
||||||
|
_logger.i(printer.address);
|
||||||
|
|
||||||
|
BluetoothDevice device = new BluetoothDevice()
|
||||||
|
..address = printer.address
|
||||||
|
..name=printer.name
|
||||||
|
..type=printer.type;
|
||||||
|
|
||||||
|
await Redux.store.dispatch(selectPrinterFromSetting(device));
|
||||||
|
Navigator.of(context).pop(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _testPrint(PrinterBluetooth printer) async {
|
||||||
|
printerManager.selectPrinter(printer);
|
||||||
|
|
||||||
|
// TODO Don't forget to choose printer's paper
|
||||||
|
const PaperSize paper = PaperSize.mm58;
|
||||||
|
|
||||||
|
// TEST PRINT
|
||||||
|
// final PosPrintResult res =
|
||||||
|
// await printerManager.printTicket(await testTicket(paper), queueSleepTimeMs: 50);
|
||||||
|
|
||||||
|
final PosPrintResult res =
|
||||||
|
await printerManager.printTicket(
|
||||||
|
await testTicketImage(paper),
|
||||||
|
chunkSizeBytes: 1024,
|
||||||
|
queueSleepTimeMs: 50
|
||||||
|
);
|
||||||
|
|
||||||
|
// DEMO RECEIPT
|
||||||
|
// final PosPrintResult res =
|
||||||
|
// await printerManager.printTicket(await demoReceipt(paper) , queueSleepTimeMs: 50);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
final key = GlobalKey();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RepaintBoundary(
|
||||||
|
key: key,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Выберите принтер'),
|
||||||
|
),
|
||||||
|
body: ListView.builder(
|
||||||
|
itemCount: _devices.length,
|
||||||
|
itemBuilder: (BuildContext _, int index) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => _selectPrinter(_devices[index], context),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
height: 60,
|
||||||
|
padding: EdgeInsets.only(left: 10),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(Icons.print),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(_devices[index].name ?? ''),
|
||||||
|
Text(_devices[index].address),
|
||||||
|
Text(
|
||||||
|
'Click to print a test receipt',
|
||||||
|
style: TextStyle(color: Colors.grey[700]),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
floatingActionButton: StreamBuilder<bool>(
|
||||||
|
stream: printerManager.isScanningStream,
|
||||||
|
initialData: false,
|
||||||
|
builder: (c, snapshot) {
|
||||||
|
if (snapshot.data) {
|
||||||
|
return FloatingActionButton(
|
||||||
|
child: Icon(Icons.stop),
|
||||||
|
onPressed: _stopScanDevices,
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return FloatingActionButton(
|
||||||
|
child: Icon(Icons.search),
|
||||||
|
onPressed: _startScanDevices,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.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/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/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart';
|
||||||
|
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
|
||||||
|
import 'package:esc_pos_utils/esc_pos_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
|
import 'component/setting_item.dart';
|
||||||
|
import './printer/data/settings_envi.dart';
|
||||||
|
import './printer/example/check_test.dart';
|
||||||
|
|
||||||
|
class SettingPrinterView extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_SettingPrinterViewState createState() => _SettingPrinterViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingPrinterViewState extends State<SettingPrinterView> {
|
||||||
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _testPrint() async {
|
||||||
|
final SettingState state = Redux.store.state.settingState;
|
||||||
|
printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
|
||||||
|
// TODO Don't forget to choose printer's paper
|
||||||
|
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58;
|
||||||
|
if(SettingPrinterEncodingImage == state.printerEncoding) {
|
||||||
|
final PosPrintResult res = await printerManager.printTicket(
|
||||||
|
await testTicketImage(paper),
|
||||||
|
chunkSizeBytes: 3096,
|
||||||
|
queueSleepTimeMs: 50
|
||||||
|
);
|
||||||
|
_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Настройка принтера'),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: StoreConnector<AppState, SettingState>(
|
||||||
|
converter: (store) => store.state.settingState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
SettingItem(
|
||||||
|
title: 'Принтер',
|
||||||
|
name: vm.printerBT?.name,
|
||||||
|
value: vm.printerBT != null
|
||||||
|
? 'BT: ${vm.printerBT.address} '
|
||||||
|
: 'не выбран',
|
||||||
|
onTap: () {
|
||||||
|
_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(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 24.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
AmanIconButtonHorizontal(
|
||||||
|
icon: Icons.local_printshop_outlined,
|
||||||
|
title: 'Напечатать тестовую страницу',
|
||||||
|
activeColor: primaryColor,
|
||||||
|
selected: vm.printerBT != null,
|
||||||
|
onPressed: () {
|
||||||
|
_testPrint();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
152
pubspec.lock
152
pubspec.lock
|
|
@ -1,13 +1,27 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.13"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
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:
|
||||||
|
|
@ -28,35 +42,42 @@ 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:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: charset_converter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
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:
|
||||||
|
|
@ -71,6 +92,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.5"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -99,6 +127,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.5"
|
version: "1.2.5"
|
||||||
|
esc_pos_bluetooth:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: esc_pos_bluetooth
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.8"
|
||||||
|
esc_pos_utils:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: esc_pos_utils
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.6"
|
||||||
esys_flutter_share:
|
esys_flutter_share:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -112,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:
|
||||||
|
|
@ -139,6 +181,13 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_bluetooth_basic:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_bluetooth_basic
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.5"
|
||||||
flutter_lock_screen:
|
flutter_lock_screen:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -177,6 +226,13 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
gbk_codec:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: gbk_codec
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.2"
|
||||||
get_it:
|
get_it:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -191,6 +247,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
hex:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: hex
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
|
html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: html
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.14.0+4"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -205,6 +275,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.4"
|
version: "3.1.4"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.19"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -212,6 +289,20 @@ 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:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.1"
|
||||||
local_auth:
|
local_auth:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -239,7 +330,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:
|
||||||
|
|
@ -253,7 +344,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:
|
||||||
|
|
@ -267,7 +358,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:
|
||||||
|
|
@ -310,6 +401,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.2"
|
version: "1.9.2"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -394,6 +492,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.0"
|
||||||
|
rxdart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: rxdart
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.23.1"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -447,7 +552,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:
|
||||||
|
|
@ -468,21 +573,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:
|
||||||
|
|
@ -496,21 +601,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:
|
||||||
|
|
@ -559,7 +664,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:
|
||||||
|
|
@ -574,6 +679,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2"
|
version: "0.1.2"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
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"
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ dependencies:
|
||||||
shared_preferences: ^0.5.12+4
|
shared_preferences: ^0.5.12+4
|
||||||
flutter_lock_screen: ^1.0.8
|
flutter_lock_screen: ^1.0.8
|
||||||
local_auth: ^0.6.3+4
|
local_auth: ^0.6.3+4
|
||||||
|
esc_pos_bluetooth: ^0.2.8
|
||||||
|
flutter_bluetooth_basic: ^0.1.5
|
||||||
|
esc_pos_utils: ^0.3.6 # no edit for esc_pos_bluetooth: ^0.2.8
|
||||||
|
charset_converter: ^1.0.3
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue