From 0de65ff2e9c11ab757b7a5255af7d422aac37e1b Mon Sep 17 00:00:00 2001 From: suvaissov Date: Tue, 5 Jan 2021 16:09:12 +0600 Subject: [PATCH] refund release --- .../kassa/handler/CardPaymentHandlerImpl.java | 1 + .../handler/CardRefundAmanHandlerImpl.java | 158 ++++++++++++++---- .../kz/com/aman/kassa/model/CardData.java | 9 + .../aman/kassa/plugins/BankNfcPlugins.java | 45 ++++- lib/core/models/card_data.dart | 5 +- lib/core/services/BankService.dart | 25 +++ lib/core/services/DataService.dart | 38 +++++ lib/views/check/image_show_container.dart | 144 ++++++++++------ lib/views/history/history_view.dart | 5 +- lib/views/payment/payment_view.dart | 6 +- lib/views/payment_nfc/payment_nfc_view.dart | 143 +++++++++++++++- lib/views/payment_nfc/widgets/phone_view.dart | 11 ++ 12 files changed, 490 insertions(+), 100 deletions(-) diff --git a/android/app/src/main/java/kz/com/aman/kassa/handler/CardPaymentHandlerImpl.java b/android/app/src/main/java/kz/com/aman/kassa/handler/CardPaymentHandlerImpl.java index 42b069b..b2b146c 100644 --- a/android/app/src/main/java/kz/com/aman/kassa/handler/CardPaymentHandlerImpl.java +++ b/android/app/src/main/java/kz/com/aman/kassa/handler/CardPaymentHandlerImpl.java @@ -282,6 +282,7 @@ public class CardPaymentHandlerImpl implements CardPaymentCallbackHandler dao = new AmanDao<>(); dao.setSuccess(true); dao.setData(cardData); diff --git a/android/app/src/main/java/kz/com/aman/kassa/handler/CardRefundAmanHandlerImpl.java b/android/app/src/main/java/kz/com/aman/kassa/handler/CardRefundAmanHandlerImpl.java index dd5b0a3..2150beb 100644 --- a/android/app/src/main/java/kz/com/aman/kassa/handler/CardRefundAmanHandlerImpl.java +++ b/android/app/src/main/java/kz/com/aman/kassa/handler/CardRefundAmanHandlerImpl.java @@ -14,9 +14,12 @@ import io.flutter.plugin.common.MethodChannel; import kz.com.aman.kassa.MainActivity; import kz.com.aman.kassa.bank.M4BankActivity; import kz.com.aman.kassa.bank.gui.CustomKeyBoardDilalog; +import kz.com.aman.kassa.model.AmanDao; +import kz.com.aman.kassa.model.CardData; import kz.com.aman.kassa.plugins.BankNfcPlugins; import ru.m4bank.mpos.library.external.transactions.EasyCardRefundCallbackHandler; import ru.m4bank.mpos.library.external.transactions.GetTransactionsListCallbackHandler; +import ru.m4bank.mpos.service.commons.data.ResultType; import ru.m4bank.mpos.service.data.FiscalStatusData; import ru.m4bank.mpos.service.data.PrinterBaseData; import ru.m4bank.mpos.service.data.PrinterErrorData; @@ -42,13 +45,19 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< private final BankNfcPlugins plugin; private final MethodChannel.Result result; + private final Integer transactionNumber; + private String authorizationCode; private final Gson gson = new Gson(); private Transaction transaction; + private CustomKeyBoardDilalog customKeyBoardDilalog; - public CardRefundAmanHandlerImpl(BankNfcPlugins plugin , MethodChannel.Result result) { + public CardRefundAmanHandlerImpl(BankNfcPlugins plugin , MethodChannel.Result result, Integer transactionNumber, String authorizationCode,Transaction transaction) { this.plugin = plugin; this.result = result; + this.transactionNumber = transactionNumber; + this.authorizationCode = authorizationCode; + this.transaction = transaction; customKeyBoardDilalog = new CustomKeyBoardDilalog(); } @@ -64,22 +73,38 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< @Override public void onDeviceToUseSelectionRequested(List deviceList) { - Timber.d("onDeviceToUseSelectionRequested"); - AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); - builder.setTitle("Choose device"); +// Timber.d("onDeviceToUseSelectionRequested"); +// AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); +// builder.setTitle("Choose device"); +// +// Spinner deviceListSpinner = new Spinner(plugin.getActivity()); +// ArrayAdapter adapter = new ArrayAdapter<>(plugin.getActivity(), android.R.layout.simple_spinner_item, new ArrayList<>(deviceList)); +// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +// deviceListSpinner.setAdapter(adapter); +// +// builder.setPositiveButton("OK", (dialog, which) -> { +// plugin.getClientInterface().getTransactionManager().setCardReaderToUse((Reader) deviceListSpinner.getSelectedItem()); +// dialog.dismiss(); +// }); +// +// builder.setView(deviceListSpinner); +// plugin.getActivity().runOnUiThread(() -> builder.create().show()); - Spinner deviceListSpinner = new Spinner(plugin.getActivity()); - ArrayAdapter adapter = new ArrayAdapter<>(plugin.getActivity(), android.R.layout.simple_spinner_item, new ArrayList<>(deviceList)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - deviceListSpinner.setAdapter(adapter); - - builder.setPositiveButton("OK", (dialog, which) -> { - plugin.getClientInterface().getTransactionManager().setCardReaderToUse((Reader) deviceListSpinner.getSelectedItem()); - dialog.dismiss(); + System.out.println("----->---->---->onDeviceToUseSelectionRequested"); + plugin.getActivity().runOnUiThread(() -> { + if (deviceList != null && !deviceList.isEmpty()) { + for (Reader reader : deviceList) { + String name = reader.toString(); + System.out.println("name: " + name); + if (name.contains("SOFT")) { + plugin.getClientInterface() + .getTransactionManager() + .setCardReaderToUse(reader); + break; + } + } + } }); - - builder.setView(deviceListSpinner); - plugin.getActivity().runOnUiThread(() -> builder.create().show()); } @Override @@ -111,13 +136,19 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< @Override public void onWrongApiCalled() { - Timber.d("onWrongApiCalled"); - plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Wrong method has been called", Toast.LENGTH_SHORT).show()); + System.out.println("----->---->---->onWrongApiCalled"); + plugin.getActivity().runOnUiThread(() -> { + //Toast.makeText(plugin.getActivity(), "Wrong method has been called", Toast.LENGTH_SHORT).show(); + AmanDao dao = new AmanDao<>(); + dao.setSuccess(false); + dao.setMsg("Данная транзакция уже отменена или ее невозможно отменить через данный функционал"); + this.result.success(gson.toJson(dao)); + }); } @Override public void onReceiveCardData(OnlineCardDataDto data, boolean shouldConfirmBeManuallyCalled) { - Timber.d("onReceiveCardData"); + System.out.println("----->---->---->onReceiveCardData"); if (shouldConfirmBeManuallyCalled) { plugin.getClientInterface().getTransactionManager().processOnlineTransaction(false); } @@ -146,8 +177,17 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< @Override public void onError(ErrorHandler errorHandler, TransactionErrorData transactionErrorData) { - Timber.d("onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getDescription()); - plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), errorHandler.getFinalDescription(), Toast.LENGTH_LONG).show()); + if (transactionErrorData.getError() != null) { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), transactionErrorData.getError().getDescription(), Toast.LENGTH_LONG).show()); + } else { + plugin.getActivity().runOnUiThread(() -> { + AmanDao dao = new AmanDao<>(); + dao.setSuccess(false); + dao.setMsg(String.format("%s", errorHandler.getFinalDescription())); + this.result.success(gson.toJson(dao)); + //Toast.makeText(plugin.getActivity(), String.format("onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getFinalDescription()), Toast.LENGTH_LONG).show(); + }); + } } @Override @@ -170,9 +210,21 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< @Override public void onTransactionDataReceived(TransactionData data) { - Timber.d("onTransactionDataReceived"); - plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Transaction data has been received", Toast.LENGTH_LONG) - .show()); + System.out.println("----->---->---->onTransactionDataReceived"); + plugin.getActivity().runOnUiThread(() -> { + CardData cardData = new CardData(); + cardData.setCardExpiryDate(data.getCardExpiryDate()); + cardData.setCardNumber(data.getCardNumber()); + cardData.setCardPaymentSystemType(data.getCardPaymentSystemType()); + cardData.setTransactionNumber(data.getTransactionNumber()); + cardData.setTransactionType(data.getTransactionType().getCode()); + AmanDao dao = new AmanDao<>(); + dao.setSuccess(true); + dao.setData(cardData); + this.result.success(gson.toJson(dao)); + Toast.makeText(plugin.getActivity(), "Transaction data has been received", Toast.LENGTH_LONG) + .show(); + }); } @Override @@ -260,23 +312,55 @@ public class CardRefundAmanHandlerImpl implements EasyCardRefundCallbackHandler< @Override public void onTransactionsListReceived(List transactionList) { - Timber.d("onTransactionsListReceived"); - AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); - builder.setTitle("Choose transaction"); +// Timber.d("onTransactionsListReceived"); +// AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); +// builder.setTitle("Choose transaction"); +// +// Spinner transactionListSpinner = new Spinner(plugin.getActivity()); +// ArrayAdapter adapter = new ArrayAdapter<>(plugin.getActivity(), android.R.layout.simple_spinner_item, new ArrayList<>(transactionList)); +// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +// transactionListSpinner.setAdapter(adapter); +// +// builder.setPositiveButton("OK", (dialog, which) -> { +// transaction = (Transaction) transactionListSpinner.getSelectedItem(); +// plugin.getClientInterface().getTransactionManager().makeCardRefund(this); +// dialog.dismiss(); +// }); +// +// builder.setView(transactionListSpinner); +// plugin.getActivity().runOnUiThread(() -> builder.create().show()); + this.transaction = null; + this.plugin.setTransaction(null); + for(Transaction transaction : transactionList){ + if(this.authorizationCode.equalsIgnoreCase(transaction.getAuthorizationCode()) + && transactionNumber.equals(transaction.getTransactionNumber()) + && transaction.getTransactionType().equalsIgnoreCase("PAYMENT")) { + System.out.println("getCheck:"+ transaction.getCheck()); + System.out.println("getCheckNumber:"+ transaction.getCheckNumber()); + System.out.println("getAmount:"+ transaction.getAmount()); + System.out.println("getCardHolderName:"+ transaction.getCardHolderName()); + System.out.println("getCardType:"+ transaction.getCardType()); + System.out.println("getPrinterCheckNumber:"+ transaction.getPrinterCheckNumber()); + System.out.println("getTransactionNumber:"+ transaction.getTransactionNumber()); + System.out.println("getAdditionalAuthorizationCode:"+ transaction.getAdditionalAuthorizationCode()); + System.out.println("getAuthorizationCode:"+ transaction.getAuthorizationCode()); + System.out.println("getCardExpiryDate:"+ transaction.getCardExpiryDate()); + System.out.println("getTransactionType:"+ transaction.getTransactionType()); + System.out.println("getTransactionDate:"+ transaction.getTransactionDate()); + this.transaction = transaction; + break; + } + } - Spinner transactionListSpinner = new Spinner(plugin.getActivity()); - ArrayAdapter adapter = new ArrayAdapter<>(plugin.getActivity(), android.R.layout.simple_spinner_item, new ArrayList<>(transactionList)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - transactionListSpinner.setAdapter(adapter); - - builder.setPositiveButton("OK", (dialog, which) -> { - transaction = (Transaction) transactionListSpinner.getSelectedItem(); - plugin.getClientInterface().getTransactionManager().makeCardRefund(this); - dialog.dismiss(); + plugin.getActivity().runOnUiThread(() -> { + AmanDao dao = new AmanDao<>(); + dao.setSuccess(this.transaction !=null ); + this.plugin.setTransaction(this.transaction); + dao.setMsg(this.transaction == null ? "Транзакция не может быть отозвана т.к. все операции оп ней закрыты" : null); + this.result.success(gson.toJson(dao)); }); - builder.setView(transactionListSpinner); - plugin.getActivity().runOnUiThread(() -> builder.create().show()); + } @Override diff --git a/android/app/src/main/java/kz/com/aman/kassa/model/CardData.java b/android/app/src/main/java/kz/com/aman/kassa/model/CardData.java index 9d8ab39..7961365 100644 --- a/android/app/src/main/java/kz/com/aman/kassa/model/CardData.java +++ b/android/app/src/main/java/kz/com/aman/kassa/model/CardData.java @@ -6,6 +6,15 @@ public class CardData { private String cardNumber; private String transactionType; private String cardPaymentSystemType; + private String authorizationCode; + + public String getAuthorizationCode() { + return authorizationCode; + } + + public void setAuthorizationCode(String authorizationCode) { + this.authorizationCode = authorizationCode; + } public String getCardExpiryDate() { return cardExpiryDate; diff --git a/android/app/src/main/java/kz/com/aman/kassa/plugins/BankNfcPlugins.java b/android/app/src/main/java/kz/com/aman/kassa/plugins/BankNfcPlugins.java index 4ce915d..1be52b3 100644 --- a/android/app/src/main/java/kz/com/aman/kassa/plugins/BankNfcPlugins.java +++ b/android/app/src/main/java/kz/com/aman/kassa/plugins/BankNfcPlugins.java @@ -18,6 +18,7 @@ import kz.com.aman.kassa.bank.permissions.PermissionsManager; import kz.com.aman.kassa.bank.permissions.PermissionsManagerImpl; import kz.com.aman.kassa.handler.AuthorizationHandlerImpl; import kz.com.aman.kassa.handler.CardPaymentHandlerImpl; +import kz.com.aman.kassa.handler.CardRefundAmanHandlerImpl; import kz.com.aman.kassa.handler.ConnectionCheckHandlerImpl; import kz.com.aman.kassa.handler.TransactionDetailsHandlerImpl; import kz.com.aman.kassa.handler.CloseDayHandlerImpl; @@ -25,12 +26,14 @@ import kz.com.aman.kassa.model.AmanDao; import ru.m4bank.mpos.library.M4BankMposClient; import ru.m4bank.mpos.library.M4BankMposClientInterfaceFacade; import ru.m4bank.mpos.library.M4BankMposParameters; +import ru.m4bank.mpos.library.external.transactions.GetTransactionsListCallbackHandler; import ru.m4bank.mpos.service.commons.data.ConfigurationSettings; import ru.m4bank.mpos.service.commons.data.NetworkConfiguration; import ru.m4bank.mpos.service.commons.data.TerminalConfiguration; import ru.m4bank.mpos.service.data.dynamic.CurrencyDataHolder; import ru.m4bank.mpos.service.data.dynamic.objects.Currency; import ru.m4bank.mpos.service.data.dynamic.objects.GetOperationType; +import ru.m4bank.mpos.service.data.dynamic.objects.Transaction; import ru.m4bank.mpos.service.hardware.external.cardreaderlib.data.enums.TransactionTypeConv; import ru.m4bank.mpos.service.network.Format; import ru.m4bank.mpos.service.network.ServerChoose; @@ -43,6 +46,16 @@ public class BankNfcPlugins implements MethodCallHandler { //main activity private MainActivity activity; + private Transaction transaction; + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + //main client all work with him private M4BankMposClientInterfaceFacade clientInterface; //permissions @@ -93,6 +106,12 @@ public class BankNfcPlugins implements MethodCallHandler { case "transaction": showTransaction(call, result); break; + case "findTransaction": + findTransaction(call, result); + break; + case "refund": + refund(call, result); + break; case "version": result.success(String.valueOf(Build.VERSION.SDK_INT)); break; @@ -240,9 +259,6 @@ public class BankNfcPlugins implements MethodCallHandler { Integer value = call.argument("amount"); long amount = value.longValue(); clientInterface.cancel(); -// CardPaymentHandlerImpl handler = new CardPaymentHandlerImpl(this, result, amount); -// handler.setTransactionTypeConv(TransactionTypeConv.PAYMENT); -// clientInterface.getTransactionManager().makeCardPayment(handler); clientInterface.getTransactionManager().makeCardPayment(new CardPaymentHandlerImpl(this, result, amount, TransactionTypeConv.PAYMENT)); } catch (Exception e) { System.out.println("=============>ERROR:"+e.getMessage()); @@ -250,6 +266,29 @@ public class BankNfcPlugins implements MethodCallHandler { } } + private void findTransaction(MethodCall call, Result result) { + try { + Integer transactionNumber = call.argument("transactionNumber"); + String authorizationCode = call.argument("authorizationCode"); + clientInterface.getTransactionManager() + .getTransactionsList(new CardRefundAmanHandlerImpl(this, result, transactionNumber, authorizationCode , transaction), 1000, + 0, GetOperationType.SHOW, null); + } catch (Exception e) { + System.out.println("=============>ERROR:"+e.getMessage()); + result.error("2", e.getMessage(), e.getLocalizedMessage()); + } + } + + private void refund(MethodCall call, Result result) { + try { + clientInterface.getTransactionManager() + .makeCardRefund(new CardRefundAmanHandlerImpl(this, result, null, null, transaction)); + } catch (Exception e) { + System.out.println("=============>ERROR:"+e.getMessage()); + result.error("2", e.getMessage(), e.getLocalizedMessage()); + } + } + private void closeDay(MethodCall call, Result result) { try { clientInterface.cancel(); diff --git a/lib/core/models/card_data.dart b/lib/core/models/card_data.dart index edb5869..8fe0014 100644 --- a/lib/core/models/card_data.dart +++ b/lib/core/models/card_data.dart @@ -4,8 +4,9 @@ class CardData { final String cardNumber; final String transactionType; final String cardPaymentSystemType; + final String authorizationCode; - CardData({this.transactionNumber, this.cardExpiryDate, this.cardNumber, this.transactionType, this.cardPaymentSystemType}); + CardData({this.transactionNumber, this.cardExpiryDate, this.cardNumber, this.transactionType, this.cardPaymentSystemType, this.authorizationCode}); static CardData fromJson(Map json) { return json != null ? @@ -15,6 +16,7 @@ class CardData { cardNumber: json['cardNumber'], transactionType: json['transactionType'], cardPaymentSystemType: json['cardPaymentSystemType'], + authorizationCode: json['authorizationCode'], ) : null; } @@ -25,5 +27,6 @@ class CardData { 'cardNumber': cardNumber, 'transactionType': transactionType, 'cardPaymentSystemType': cardPaymentSystemType, + 'authorizationCode': authorizationCode, }; } \ No newline at end of file diff --git a/lib/core/services/BankService.dart b/lib/core/services/BankService.dart index 41d814e..4c9982d 100644 --- a/lib/core/services/BankService.dart +++ b/lib/core/services/BankService.dart @@ -122,6 +122,31 @@ class BankService extends BaseService { } } + Future findTransaction({int transactionNumber, String authorizationCode}) async { + try { + log.i('transactionNumber: $transactionNumber'); + String response = await _channel.invokeMethod("findTransaction", {'transactionNumber': transactionNumber, 'authorizationCode': authorizationCode}); + AmanDao dao = AmanDao.fromJson(json.decode(response)); + log.i('${dao.success} - ${dao.msg}'); + return dao; + } catch (e, stack) { + log.e("BankService", e, stack); + return new AmanDao(msg: 'Ошибка при поиске транзакии банка'); + } + } + + Future refund() async { + try { + String response = await _channel.invokeMethod("refund"); + AmanDao dao = AmanDao.fromJson(json.decode(response)); + log.i('${dao.success} - ${dao.msg}'); + return dao; + } catch (e, stack) { + log.e("BankService", e, stack); + return new AmanDao(msg: 'Ошибка при возврате'); + } + } + Future shutdown() async { try { String response = await _channel.invokeMethod("shutdown"); diff --git a/lib/core/services/DataService.dart b/lib/core/services/DataService.dart index 9347463..472d931 100644 --- a/lib/core/services/DataService.dart +++ b/lib/core/services/DataService.dart @@ -129,6 +129,44 @@ class DataService extends BaseService { return null; } + Future> refundM4Bank( + { + String token, + CheckData checkData, + CardData cardData}) async { + try { + checkData.cardData = cardData; + String data = jsonEncode(checkData.toJson()); + + log.i('token: $token'); + log.i('data: $data'); + Response response = await _api.sellReturn(token, data); + log.i('response status: ${response.status}'); + log.i('response operation: ${response.operation}'); + if (response.status == 200 && response.operation == true) { + User user = Redux.store.state.userState.user; + String check = response?.body['check']; + dynamic journal = response?.body['journal']; + String url = response?.body['link']; + int checkNum = journal['check_num']; + var summ = journal['summ']; + double total = summ != null ? double.parse(summ.toString()) : 0.0; + this.insertVoucher( + user: user, + name: 'Чек №$checkNum', + data: data, + base64Data: check, + total: total, + url: url, + type: VoucherTypeReturnPay); + } + return response; + } catch (e, stack) { + log.e("sellOrReturn", e, stack); + } + return null; + } + Future> sellOrReturn( {String paymentType, String tradeType, diff --git a/lib/views/check/image_show_container.dart b/lib/views/check/image_show_container.dart index 93be746..9a58721 100644 --- a/lib/views/check/image_show_container.dart +++ b/lib/views/check/image_show_container.dart @@ -1,12 +1,17 @@ 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/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/route_names.dart'; +import 'package:aman_kassa_flutter/core/services/BankService.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/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; +import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart'; import 'package:flutter/material.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; @@ -44,8 +49,10 @@ class ImageShowModel { final String data; final String title; final String url; + final CardData cardData; + final Voucher voucher; - ImageShowModel({this.data, this.title, this.url}); + ImageShowModel({this.data, this.title, this.url, this.cardData, this.voucher}); } class MyFloatingActionButton extends StatefulWidget { @@ -60,60 +67,88 @@ class _MyFloatingActionButtonState extends State { DialogService _dialog = locator(); NavigatorService _navigatorService = locator(); + + @override Widget build(BuildContext context) { - return showFab - ? 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: [ - 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, - ), - ], - ))); - showFoatingActionButton(false); - bottomSheetController.closed.then((value) { - showFoatingActionButton(true); - }); - }, - ) - : Container(); + if (showFab) { + return Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment") FloatingActionButton( + backgroundColor: redColor, + child: Icon( + Icons.settings_backup_restore, + color: whiteColor, + ), + onPressed: () { + _navigatorService.replace(HomeViewRoute); + PaymentModel model = new PaymentModel(voucher: widget.data.voucher, cardData: widget.data.cardData); + _navigatorService.push(PaymentNfcViewRoute, + arguments: model); + }, + 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: [ + 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(); + } } void shareFile() async { @@ -156,7 +191,6 @@ class _MyFloatingActionButtonState extends State { } } - print(url()); if (await canLaunch(url())) { await launch(url()); } else { @@ -164,7 +198,7 @@ class _MyFloatingActionButtonState extends State { } } - void showFoatingActionButton(bool value) { + void showFloatingActionButton(bool value) { setState(() { showFab = value; }); diff --git a/lib/views/history/history_view.dart b/lib/views/history/history_view.dart index e49359c..ec7498f 100644 --- a/lib/views/history/history_view.dart +++ b/lib/views/history/history_view.dart @@ -74,7 +74,10 @@ class _HistoryViewState extends State { arguments: ImageShowModel( data: voucher.base64Data, title: voucher.name, - url: voucher.url)); + url: voucher.url, + cardData: cardData, + voucher: voucher, + )); }, title: buildText(voucher), subtitle: Column( diff --git a/lib/views/payment/payment_view.dart b/lib/views/payment/payment_view.dart index 893793c..4d902f7 100644 --- a/lib/views/payment/payment_view.dart +++ b/lib/views/payment/payment_view.dart @@ -1,5 +1,7 @@ +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/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'; @@ -317,6 +319,8 @@ class _PaymentViewState extends State { class PaymentModel { String operationType; String mode; + Voucher voucher; + CardData cardData; - PaymentModel({this.mode, this.operationType}); + PaymentModel({this.mode, this.operationType, this.voucher, this.cardData}); } diff --git a/lib/views/payment_nfc/payment_nfc_view.dart b/lib/views/payment_nfc/payment_nfc_view.dart index 6eb6b3e..c0d855e 100644 --- a/lib/views/payment_nfc/payment_nfc_view.dart +++ b/lib/views/payment_nfc/payment_nfc_view.dart @@ -1,8 +1,12 @@ +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/logger.dart'; import 'package:aman_kassa_flutter/core/models/aman_dao.dart'; import 'package:aman_kassa_flutter/core/models/calc_model.dart'; import 'package:aman_kassa_flutter/core/models/card_data.dart'; +import 'package:aman_kassa_flutter/core/models/check_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'; @@ -37,7 +41,6 @@ import 'package:logger/logger.dart'; class PaymentNfcView extends StatefulWidget { final PaymentModel model; - const PaymentNfcView({Key key, this.model}) : super(key: key); @override @@ -65,6 +68,8 @@ class _PaymentNfcViewState extends State { } void start() async { + + //права доступа bool success = await _bankService.permissions(); log.i(success); @@ -74,6 +79,19 @@ class _PaymentNfcViewState extends State { }); return; } + + + 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 ч. Необходимо закрыть смену и открыть ее заново.'); + _navigatorService.pop(); + return; + } + //Инициализация bool initialized = await _bankService.init(); log.i(initialized); @@ -121,7 +139,53 @@ class _PaymentNfcViewState extends State { return; } - pay(); + if(widget.model.voucher == null) { + pay(); + } else { + refund(); + } + } + + refund() async { + CardData _cardData = widget.model.cardData; + AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode); + if(!findTransaction.success){ + _dialogService.showDialog(description: findTransaction.msg); + setState(() { + status = 8; + }); + return; + } + + setState(() { + status = 1; + isPhoneScaled = true; + }); + + AmanDao refundDao = await _bankService.refund(); + if (!refundDao.success) { + int _status = 7; + + setState(() { + status = _status; + isPhoneScaled = false; + }); + + if (refundDao.msg != null) { + log.i(refundDao.msg); + _dialogService.showDialog(description: refundDao.msg); + } + return; + } + + setState(() { + status = 3; + isPhoneScaled = false; + }); + + //check + pressRefund('card' , refundDao.data); + } pay() async { @@ -245,6 +309,57 @@ class _PaymentNfcViewState extends State { } } + pressRefund(String type, dynamic cardDataDynamic) async { + setState(() { + isBusy = true; + }); + Dialogs.showLoadingDialog(context, _keyLoader); + try { + AppState _state = Redux.store.state; + String _token = _state.userState.user.token; + CardData _cardData = cardDataDynamic != null ? CardData.fromJson(cardDataDynamic) : null; + CheckData _checkData = CheckData.fromJson(json.decode(widget.model.voucher.data)); + Response response = await _dataService.refundM4Bank( + token: _token, + cardData: _cardData, + checkData: _checkData + ); + setState(() { + isBusy = false; + }); + if (response != null) { + if (response.operation) { + String message = response.body['message']; + String check = response.body['check']; + 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: check, 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 { + 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; + }); + } + } + @override void dispose() { _bankService.shutdown(); @@ -357,6 +472,19 @@ class _PaymentNfcViewState extends State { }, ); break; + case 8: + return ActionView( + show: true, + acceptText: 'Повторить', + acceptCallback: () { + refund(); + }, + declineText: 'Отмена', + declineCallback: () { + cancel(); + }, + ); + break; default: } @@ -382,6 +510,17 @@ class _PaymentNfcViewState extends State { fontSize: 35)); }); } + if(widget.model.voucher !=null) { + return StoreConnector( + converter: (store) => store.state.kassaState, + builder: (_, vm) { + return Text('${widget.model.voucher.total} тнг', + style: TextStyle( + fontWeight: FontWeight.bold, + color: whiteColor, + fontSize: 35)); + }); + } return StoreConnector( converter: (store) => store.state.kassaState, builder: (_, vm) { diff --git a/lib/views/payment_nfc/widgets/phone_view.dart b/lib/views/payment_nfc/widgets/phone_view.dart index 242dd49..ad99627 100644 --- a/lib/views/payment_nfc/widgets/phone_view.dart +++ b/lib/views/payment_nfc/widgets/phone_view.dart @@ -138,6 +138,17 @@ class _PhoneViewState extends State { ); } + if(widget.status == 8){ + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),), + verticalSpaceSmall, + AutoSizeText('Ошибка транзакции', style: TextStyle(fontWeight: FontWeight.bold),), + ], + ); + } + return Container(); } }