import 'dart:convert'; import 'package:aman_kassa_flutter/core/entity/Voucher.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/check_image_modal.dart'; import 'package:aman_kassa_flutter/core/models/card_data.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/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/calc_actions.dart'; import 'package:aman_kassa_flutter/redux/actions/kassa_actions.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/operation_const.dart'; import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; import 'package:aman_kassa_flutter/redux/state/bank_state.dart'; import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; import 'package:aman_kassa_flutter/redux/state/kassa_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/check/image_show_container.dart'; import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart'; import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart'; import '../../core/models/aman_dao.dart'; import '../../core/models/card_data.dart'; import '../../core/models/card_data.dart'; class PaymentView extends StatefulWidget { final PaymentModel model; const PaymentView({Key? key, required this.model}) : super(key: key); @override _PaymentViewState createState() => _PaymentViewState(); } class _PaymentViewState extends State { final GlobalKey _keyLoader = new GlobalKey(); final DataService _dataService = locator(); final DialogService _dialogService = locator(); BankService _bankService = locator(); final NavigatorService _navigatorService = locator(); late bool isBusy; late bool isBankApiAccess; @override void initState() { super.initState(); isBusy = false; isBankApiAccess = false; _bankInit(); } _bankInit() async { int version = await _bankService.version(); if (version >= _bankService.sdkVersion) { setState(() { isBankApiAccess = true; }); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () { if (!isBusy) Navigator.pop(context); return new Future(() => false); }, child: Scaffold( appBar: AppBar( brightness: Brightness.light, backgroundColor: whiteColor, elevation: 0, leading: IconButton( icon: Icon(Icons.arrow_back_ios), color: Colors.black87, onPressed: () => Navigator.pop(context), ), title: Text( dataTitle(), style: TextStyle(color: Colors.black87), ), ), body: Container( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( dataText(), style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black26, fontSize: 15), ), buildStoreConnector(), verticalSpaceLarge, _buildBodyContent(), ], ), ), ), ); } String dataTitle() => widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат'; String dataText() => widget.model.operationType == OperationTypePay ? 'К оплате' : 'К возврату'; StoreConnector buildStoreConnector() { if (widget.model.mode == SettingModeCalc) { return StoreConnector( converter: (store) => store.state.calcState!, builder: (_, vm) { return Text('${totalCalc(vm.calcItems!)} тнг', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 35)); }); } return StoreConnector( converter: (store) => store.state.kassaState!, builder: (_, vm) { return Text('${totalKassa(vm.kassaItems!)} тнг', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 35)); }); } Expanded _buildBodyContent() { return Expanded( child: Column( children: [ Container( height: 150, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded( child: BusyButton( title: 'Оплатить картой', onPressed: () { pressPayment('card', null); }, mainColor: primaryColor, )), horizontalSpaceSmall, Expanded( child: BusyButton( title: 'Наличными', onPressed: () { pressPayment('cash', null); }, mainColor: greenColor, )), ], ), ), verticalSpaceLarge, _nfsButtonRender(), verticalSpaceSmall, Expanded( child: Container(), ), Container( child: BusyButton( title: 'Отмена', onPressed: () { Navigator.pop(context); }, mainColor: redColor, )), ], ), ); } Widget _nfsButtonRender() { if (!isBankApiAccess || widget.model.operationType != OperationTypePay) { return Container(); } return StoreConnector( converter: (store) => store.state, builder: (_, _state) { BankState state = _state.bankState!; double _total; if (widget.model.mode == SettingModeCalc) { String value = totalCalc(_state.calcState!.calcItems!); _total = double.parse(value); } else { String value = totalKassa(_state.kassaState!.kassaItems!); _total = double.parse(value); } if (state.password == null || state.login == null || state.password!.length < 1 || state.login!.length < 1) { return Container(); } return InkWell( onTap: isBusy ? null : () 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!)) { _dialogService.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.'); return; } setState(() { isBusy = true; }); try { await Redux.store!.dispatch(changePinSkipFromSetting(true)); AmanDao data = await paymentHalykPos(_total); if (data.success == true) { pressPayment(widget.model.operationType, data.data); } else { _dialogService.showDialog(description: data.msg ?? ''); } } finally { await Redux.store!.dispatch(changePinSkipFromSetting(false)); setState(() { isBusy = false; }); } }, splashColor: halykColor.withOpacity(0.4), borderRadius: BorderRadius.circular(10.0), highlightColor: halykColor.withOpacity(0.1), child: Container( width: ScreenUtil().setSp(100.0), padding: const EdgeInsets.symmetric(vertical: 8.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0) ), child: Column( children: [ Container( width: ScreenUtil().setSp(80.0), height: ScreenUtil().setSp(80.0), margin: const EdgeInsets.only(bottom: 8.0), decoration: BoxDecoration( border: Border.all(color: Colors.white), borderRadius: BorderRadius.circular(10.0), image: DecorationImage( image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth ), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.5), spreadRadius: 5, blurRadius: 7, offset: Offset(0, 3), // changes position of shadow ), ], ), ), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Icon( // MdiIcons.nfc, // color: halykColor, // size: ScreenUtil().setSp(20.0), // ), // Text('Tap2Phone',style: TextStyle(fontSize: ScreenUtil().setSp(10.0), color: halykColor, fontWeight: FontWeight.bold ),), // ], // ), ], ), ), ); } ); } pressPayment(String type, CardData? cardData) async { setState(() { isBusy = true; }); Dialogs.showLoadingDialog(context, _keyLoader); try { AppState _state = Redux.store!.state; String _token = _state.userState!.user!.token!; String _tradeType = _state.settingState!.tradeType!; String _mode = _state.settingState!.mode!; if (_mode == SettingModeCalc) { _tradeType = SettingTradeTypeGood; } List kassaItems = _state.kassaState!.kassaItems!; List calcItems = _state.calcState!.calcItems!; Response? response = await _dataService.sellOrReturn( token: _token, kassaItems: kassaItems, paymentType: type, operationType: widget.model.operationType, tradeType: _tradeType, calcItems: calcItems, mode: _mode, cardData: cardData ); setState(() { isBusy = false; }); 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'); if (_mode == SettingModeCalc) { Redux.store!.dispatch(cleanCalcItems); } else if (_mode == SettingModeKassa) { Redux.store!.dispatch(cleanKassaItems); } Redux.store!.dispatch(checkMoney); Redux.store!.dispatch(openSmenaPseudo); Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop(); _navigatorService.pop(); _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(); _dialogService.showDialog(description: response.body['message']); } else if (!response.operation && response.body['message'] != null) { Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop(); _dialogService.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(); } finally { //Navigator.of(context, rootNavigator: true).pop(); setState(() { isBusy = false; }); } } String totalKassa(List kassaItems) { num total = 0.0; kassaItems.forEach((element) { total += element.total == null ? 0.0 : element.total.toDouble(); }); return total.toString(); } String totalCalc(List items) { num total = 0.0; items.forEach((element) { if (element.operation == Calculations.MULTIPLY) { double num1 = element.num1 == null ? 0.0 : double.parse(element.num1); double num2 = element.num2 == null ? 0.0 : double.parse(element.num2!); total += num1 * num2; } else { total += element.num1 == null ? 0.0 : double.parse(element.num1); } }); return total.toString(); } } class PaymentModel { String operationType; String mode; Voucher? voucher; CardData? cardData; PaymentModel({required this.mode, required this.operationType, this.voucher, this.cardData}); }