aman-kassa-flutter/lib/views/check/image_show_container.dart

419 lines
16 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:convert';
import 'dart:io';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.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/aman_dao.dart';
import 'package:aman_kassa_flutter/core/models/card_data.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.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/services/BankService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.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/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.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/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.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_bluetooth_basic/flutter_bluetooth_basic.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../core/models/aman_dao.dart';
class ImageShowContainer extends StatefulWidget {
final ImageShowModel showModel;
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;
final BluetoothManager bluetoothManager = BluetoothManager.instance;
bool _printing = false;
void _preparePrint() async {
if (Platform.isIOS) {
await _print();
} else {
bluetoothManager.state.listen((val) {
print("state = $val");
if (!mounted) return;
if (val == 12) {
print('on');
_print();
} else if (val == 10) {
print('off');
_dialogService.showDialog(description: 'Отсутвует соеденение Bluetooth или он отключен', title: 'Bluetooth');
}
print('state is $val');
});
}
}
void _print() async {
final SettingState state = Redux.store.state.settingState;
if (state.printerBT == null) {
_dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков');
return;
}
bool isIos = Platform.isIOS;
int chunkSizeBytes = 3096;
int queueSleepTimeMs = 100;
if (isIos) {
chunkSizeBytes = 75;
queueSleepTimeMs = 10;
}
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: chunkSizeBytes,
queueSleepTimeMs: queueSleepTimeMs);
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: chunkSizeBytes,
queueSleepTimeMs: queueSleepTimeMs);
if (res.value != 1) {
_dialogService.showDialog(description: res.msg);
}
}
} catch (e) {
print(e);
}
await Future.delayed(Duration(seconds: 7));
setState(() {
_printing = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//backgroundColor: fillColor,
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: _preparePrint)
],
),
body: ListView(
children: <Widget>[imageFromBase64String(widget.showModel.data.base64Data)],
),
floatingActionButton: MyFloatingActionButton(widget.showModel),
);
}
}
Padding imageFromBase64String(String base64String) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
child: Image.memory(base64Decode(base64String)),
);
}
class ImageShowModel {
final CheckImageModal data;
final String title;
final String url;
final CardData cardData;
final Voucher voucher;
ImageShowModel({this.data, this.title, this.url, this.cardData, this.voucher});
}
class MyFloatingActionButton extends StatefulWidget {
final ImageShowModel data;
MyFloatingActionButton(this.data);
@override
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
}
class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
bool showFab = true;
DialogService _dialog = locator<DialogService>();
NavigatorService _navigatorService = locator<NavigatorService>();
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
final DataService _dataService = locator<DataService>();
double sheetHeight = 260;
@override
Widget build(BuildContext context) {
//print(widget.data.cardData.transactionType);
if (showFab) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
FloatingActionButton(
backgroundColor: redColor,
tooltip: 'Отмена',
child: Icon(
Icons.cancel,
color: whiteColor,
),
onPressed: () async {
var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null
|| Redux.store.state.userState.smena == null
|| Redux.store.state.userState.smena.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
return;
}
try {
await Redux.store.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await reversalHalykPos(widget.data.cardData, widget.data.voucher.total);
if (response.success) {
pressRefund();
} else {
_dialog.showDialog(description: response.msg);
}
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
_navigatorService.replace(HomeViewRoute);
},
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox(
height: 10,
),
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
FloatingActionButton(
backgroundColor: redColor,
tooltip: 'Возврат',
child: Icon(
Icons.settings_backup_restore,
color: whiteColor,
),
onPressed: () async {
var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null
|| Redux.store.state.userState.smena == null
|| Redux.store.state.userState.smena.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
return;
}
try {
await Redux.store.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
if (response.success) {
pressRefund();
} else {
_dialog.showDialog(description: response.msg);
}
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
},
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox(
height: 10,
),
FloatingActionButton(
child: Icon(Icons.share),
onPressed: () {
var bottomSheetController = showBottomSheet(
context: context,
builder: (bottomSheetContext) => Container(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(15)),
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
height: 260,
child: Column(
children: <Widget>[
verticalSpaceSmall,
BusyButtonIcon(
title: 'WhatsApp',
onPressed: callWhatsApp,
mainColor: greenColor,
icon: MdiIcons.whatsapp,
enabled: widget.data.url != null,
),
verticalSpaceSmall,
BusyButtonIcon(
title: 'QR-код чека',
onPressed: qrGenerate,
mainColor: primaryColor,
icon: MdiIcons.qrcode,
enabled: widget.data.url != null,
),
verticalSpaceSmall,
BusyButtonIcon(
title: 'Поделиться',
onPressed: shareFile,
mainColor: yellowColor,
icon: Icons.share,
),
],
)));
showFloatingActionButton(false);
bottomSheetController.closed.then((value) {
showFloatingActionButton(true);
});
},
),
],
);
} else {
return Container();
}
}
pressRefund() async {
Dialogs.showLoadingDialog(context, _keyLoader);
try {
AppState _state = Redux.store.state;
String _token = _state.userState.user.token;
CardData _cardData = widget.data.cardData;
CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data));
Response<dynamic> response =
await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData);
if (response != null) {
if (response.operation) {
String message = response.body['message'];
String check = response.body['check'];
var checkText = response.body['check_text'];
String url = response?.body['link'];
print('url : $url');
Redux.store.dispatch(checkMoney);
Redux.store.dispatch(openSmenaPseudo);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.replace(HomeViewRoute);
_navigatorService.push(ImageShowRoute,
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)) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialog.showDialog(description: response.body['message']);
} else {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
} else {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
} catch (e) {
print(e);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
}
void shareFile() async {
try {
await Share.file('Aman Kassa', 'aman_kassa_check.png', base64Decode(widget.data.data.base64Data), 'image/png');
} catch (e) {
print('error: $e');
}
}
void qrGenerate() async {
_navigatorService.push(QrViewRoute, arguments: ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
}
void callWhatsApp() async {
DialogResponse response = await _dialog.showConfirmationDialogInput(
description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone');
if (response.confirmed) {
String phoneNumber = response.responseText;
String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
launchWhatsApp(phone: phoneNumber, message: msg);
}
}
void launchWhatsApp({
@required String phone,
@required String message,
}) async {
String url() {
if (Platform.isIOS) {
return "whatsapp://wa.me/$phone/?text=${Uri.encodeFull(message)}";
} else {
return "whatsapp://send?phone=$phone&text=${Uri.encodeFull(message)}";
}
}
if (await canLaunch(url())) {
await launch(url());
} else {
_dialog.showDialog(description: 'Отсутсвует приложение WhatsApp');
}
}
void showFloatingActionButton(bool value) {
setState(() {
showFab = value;
});
}
}