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 new file mode 100644 index 0000000..7adccaa --- /dev/null +++ b/android/app/src/main/java/kz/com/aman/kassa/handler/CardPaymentHandlerImpl.java @@ -0,0 +1,486 @@ +package kz.com.aman.kassa.handler; + +import android.app.AlertDialog; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.flutter.plugin.common.MethodChannel; +import kz.com.aman.kassa.bank.gui.CustomKeyBoardDilalog; +import kz.com.aman.kassa.plugins.BankNfcPlugins; +import ru.m4bank.mpos.library.external.transactions.CardPaymentCallbackHandler; +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; +import ru.m4bank.mpos.service.data.dynamic.objects.AdditionalTransactionData; +import ru.m4bank.mpos.service.data.dynamic.objects.GoodsData; +import ru.m4bank.mpos.service.data.dynamic.objects.Reader; +import ru.m4bank.mpos.service.data.dynamic.objects.Transaction; +import ru.m4bank.mpos.service.data.dynamic.objects.VendorData; +import ru.m4bank.mpos.service.data.dynamic.objects.printer.enums.AccountingSubject; +import ru.m4bank.mpos.service.data.dynamic.objects.printer.enums.TaxRate; +import ru.m4bank.mpos.service.data.dynamic.objects.result.ResultCode; +import ru.m4bank.mpos.service.hardware.error.AllError; +import ru.m4bank.mpos.service.hardware.error.ErrorHandler; +import ru.m4bank.mpos.service.hardware.external.cardreaderlib.data.ApplicationIdConv; +import ru.m4bank.mpos.service.hardware.external.cardreaderlib.data.enums.TransactionTypeConv; +import ru.m4bank.mpos.service.hardware.external.cardreaderlib.data.enums.VirtualKeyboardStyleTypeConv; +import ru.m4bank.mpos.service.result.PrinterResult; +import ru.m4bank.mpos.service.result.Result; +import ru.m4bank.mpos.service.transactions.data.ButtonKeyboardDto; +import ru.m4bank.mpos.service.transactions.data.MessageButtonData; +import ru.m4bank.mpos.service.transactions.data.TransactionData; +import ru.m4bank.mpos.service.transactions.data.TransactionExecutionStatus; +import ru.m4bank.mpos.service.transactions.data.VirtualPinKeyboardData; +import ru.m4bank.mpos.service.transactions.data.error.TransactionErrorData; +import ru.m4bank.mpos.service.transactions.dto.OnlineCardDataDto; +import timber.log.Timber; + +public class CardPaymentHandlerImpl implements CardPaymentCallbackHandler { + private final BankNfcPlugins plugin; + private final MethodChannel.Result callbackResult; + private final Long amount; + private CustomKeyBoardDilalog customKeyBoardDilalog; + private TransactionTypeConv transactionTypeConv; + + public CardPaymentHandlerImpl(BankNfcPlugins plugin, MethodChannel.Result result, long amount) { + this.callbackResult = result; + this.plugin = plugin; + this.amount = amount; + customKeyBoardDilalog = new CustomKeyBoardDilalog(); + transactionTypeConv = TransactionTypeConv.UNKNOWN; + } + + public CardPaymentHandlerImpl setTransactionTypeConv(TransactionTypeConv transactionTypeConv) { + this.transactionTypeConv = transactionTypeConv; + return this; + } + + @Override + public void onDeviceToConnectSelectionRequested(List deviceList) { + System.out.println("----->---->---->onDeviceToConnectSelectionRequested"); + plugin.getActivity().runOnUiThread(() -> { + 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, deviceList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + deviceListSpinner.setAdapter(adapter); + + builder.setPositiveButton("OK", (dialog, which) -> { + plugin.getClientInterface() + .getTransactionManager() + .selectCardReader(deviceListSpinner.getSelectedItem().toString()); + dialog.dismiss(); + }); + + builder.setView(deviceListSpinner); + builder.create().show(); + }); + } + + @Override + public void onCardReaderForTransactionGettingCompleted() { + System.out.println("----->---->---->Reader has been received"); + } + + @Override + public void onNoBoundedDevicesFound() { + System.out.println("----->---->---->No bounded readers"); + } + + @Override + public void onDeviceToUseSelectionRequested(List deviceList) { + System.out.println("----->---->---->onDeviceToUseSelectionRequested"); + plugin.getActivity().runOnUiThread(() -> { + 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); + builder.create().show(); + }); + } + + @Override + public void onTransactionAmountRequested() { + System.out.println("----->---->---->onTransactionAmountRequested"); + plugin.getClientInterface().getTransactionManager().setTransactionAmount(this.amount); + } + + @Override + public void onTransactionDataRequested() { + System.out.println("----->---->---->onTransactionDataRequested"); + List goodsDataList = new ArrayList<>(); + goodsDataList.add(new GoodsData.Builder() + .setOriginalPrice(100000L) + .setRealPrice(100000L) + .setName("Принтер") + .setQuantity(1) + .setCode("000001") + .setUnits("00") + .setDiscount(0L) + .setTaxRate(TaxRate.Tax_18) + .setExponent(2) + .setAccountingSubject(AccountingSubject.PRODUCT) + .build()); + goodsDataList.add(new GoodsData.Builder() + .setOriginalPrice(30065L) + .setRealPrice(30065L) + .setName("Услуга") + .setQuantity(3) + .setCode("000002") + .setUnits("00") + .setDiscount(0L) + .setTaxRate(TaxRate.Tax_18) + .setExponent(2) + .setAccountingSubject(AccountingSubject.PRODUCT) + .build()); + + HashMap vendorDescription = new HashMap<>(); + vendorDescription.put("vendor", "description"); + vendorDescription.put("vendor1", "description1"); + vendorDescription.put("vendor2", "description2"); + vendorDescription.put("vendor3", "description3"); + VendorData vendorData = new VendorData(vendorDescription); + + AdditionalTransactionData additionalTransactionData = new AdditionalTransactionData.Builder(goodsDataList).vendorData(vendorData).build(); + plugin.getClientInterface().getTransactionManager().setAdditionalTransactionData(additionalTransactionData); + } + + @Override + public void onWorkFlowDataRequested() { + System.out.println("----->---->---->WorkFlow requested"); + } + + @Override + public void onCompleted(Result result) { + System.out.println("----->---->---->onCompleted"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), result.getResultType() + " " + (result.getDescription() == null ? "" : result.getDescription()), Toast.LENGTH_SHORT) + .show()); + } + + @Override + public void onWrongApiCalled() { + System.out.println("----->---->---->onWrongApiCalled"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Wrong method has been called", Toast.LENGTH_SHORT).show()); + } + + @Override + public void onReceiveCardData(OnlineCardDataDto data, boolean shouldConfirmBeManuallyCalled) { + System.out.println("----->---->---->onReceiveCardData"); + if (shouldConfirmBeManuallyCalled) { + plugin.getClientInterface().getTransactionManager().processOnlineTransaction(false); + } + } + + @Override + public void onTransactionInit() { + //Impossible + plugin.getClientInterface().getTransactionManager().processOnlineTransaction(false); + } + + @Override + public void onTransactionExecutionStatusChanged(TransactionExecutionStatus newStatus) { + System.out.println("----->---->---->onTransactionExecutionStatusChanged: " + newStatus.name()); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), newStatus.name(), Toast.LENGTH_SHORT).show()); + } + + @Override + public void onError(ErrorHandler errorHandler, TransactionErrorData transactionErrorData) { + if (transactionErrorData.getError() != null) { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), transactionErrorData.getError().getDescription(), Toast.LENGTH_LONG).show()); + } else { + //this.result1.error("3", ((AllError) errorHandler).name(), errorHandler.getDescription()); + System.out.println(String.format("+++++++++++ onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getFinalDescription())); + + System.out.printf("----->---->---->onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getDescription()); + plugin.getActivity().runOnUiThread(() -> { + this.callbackResult.success(String.format("+++++++++++ onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getFinalDescription())); + Toast.makeText(plugin.getActivity(), String.format("onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getFinalDescription()), Toast.LENGTH_LONG).show(); + }); + } + } + + @Override + public void onErrorWithPossibilityToRetry(ErrorHandler errorHandler) { + System.out.printf("----->---->---->onErrorWithPossibilityToRetry: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getDescription()); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), String.format("onError: %s, description: %s", ((AllError) errorHandler).name(), errorHandler.getFinalDescription()), Toast.LENGTH_LONG).show()); + plugin.getClientInterface().getTransactionManager().tryToRepeatExecuteLastRequestInTransaction(); + } + + @Override + public void onTransactionDataReceivedError(TransactionData data) { + System.out.println("----->---->---->onTransactionDataReceivedError"); + } + + @Override + public void onUserInformationRequested(boolean signNeeded) { + System.out.println("----->---->---->onUserInformationRequested"); + if (transactionTypeConv != TransactionTypeConv.CANCEL) { + plugin.getClientInterface() + .getTransactionManager() + .sendTransactionUserData("signature", "phone", "vsa@centercorptech.net"); + } else { + onTransactionCompleted(); + } + } + + @Override + public void onTransactionDataReceived(TransactionData data) { + System.out.println("----->---->---->onTransactionDataReceived"); + + plugin.getActivity().runOnUiThread(() -> { + this.callbackResult.success("success"); + Toast.makeText(plugin.getActivity(), "Transaction data has been received", Toast.LENGTH_LONG) + .show(); + }); + } + + @Override + public void onTransactionCompleted() { + System.out.println("----->---->---->onTransactionCompleted"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Operation has been successfully completed", Toast.LENGTH_LONG) + .show()); + } + + @Override + public void onRequiredHostAddress() { + System.out.println("----->---->---->onRequiredHostAddress"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Set Host Address", Toast.LENGTH_LONG) + .show()); + plugin.getClientInterface().getTransactionManager().setHostAddress("213.79.122.128", "8011"); + } + + @Override + public void onDisconnectedEventReceivedOrCanNotEstablishConnection(boolean reconnectAvailable, String description) { + System.out.println("----->---->---->onDisconnectedEventReceivedOrCanNotEstablishConnection"); + if (reconnectAvailable) { + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setMessage("Connection to cardreader has been lost, try to reconnect and repeat last operation?"); + builder.setCancelable(false); + builder.setPositiveButton("Yes", (dialog, which) -> plugin.getClientInterface().tryToReconnectAndRepeatLast()); + builder.setNegativeButton("No", (dialog, which) -> plugin.getClientInterface().cancel()); + builder.create().show(); + }); + } + } + + @Override + public void onConnectingProcessStarted(String deviceName) { + System.out.printf("----->---->---->Connecting process started: %s\n", deviceName); + } + + @Override + public void onReconnectNeededToProcess() { + System.out.println("----->---->---->onReconnectNeededToProcess"); + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setMessage("Connection to cardreader has been lost, try to reconnect and continue?"); + builder.setCancelable(false); + builder.setPositiveButton("Yes", (dialog, which) -> plugin.getClientInterface().getTransactionManager().tryToReconnectToCardReader()); + builder.setNegativeButton("No", (dialog, which) -> plugin.getClientInterface().cancel()); + builder.create().show(); + }); + } + + @Override + public void onReconciliationRequiredToProcess() { + System.out.println("----->---->---->onReconciliationRequiredToProcess"); + System.out.println("----->---->---->Reconciliation required!!!"); + plugin.getClientInterface().getTransactionManager().makeReconciliationDuringTransaction(); + } + + @Override + public void onReconciliationCompleted(Result result) { + System.out.println("----->---->---->onReconciliationCompleted"); + System.out.println("----->---->---->Reconciliation completed!!!"); + if (result.getResultType() == ResultType.SUCCESSFUL) { + plugin.getClientInterface().getTransactionManager().continueTransactionAfterReconciliation(); + } else { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Reconciliation failed " + result.getDescription(), Toast.LENGTH_LONG) + .show()); + } + } + + @Override + public void notAuthorized() { + System.out.println("----->---->---->notAuthorized"); + + plugin.getActivity().runOnUiThread(() -> { + this.callbackResult.success("notAuthorized"); + Toast.makeText(plugin.getActivity(), "notAuthorized", Toast.LENGTH_SHORT).show(); + }); + } + + @Override + public void onTransactionDetailsReceived(Transaction transaction) { + System.out.println("----->---->---->onTransactionDetailsReceived"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Transaction details received", Toast.LENGTH_LONG) + .show()); + } + + @Override + public void onSuccessStatusTransaction(Transaction transaction) { + System.out.println("----->---->---->onSuccessStatusTransaction"); + } + + @Override + public void onErrorStatusTransaction() { + System.out.println("----->---->---->onErrorStatusTransaction"); + } + + @Override + public void onRepeat(int attemptNumber) { + System.out.println("----->---->---->onRepeat"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Repeat attempt number " + attemptNumber, Toast.LENGTH_SHORT).show()); + } + + @Override + public void onRequestedReportZ() { + System.out.println("----->---->---->onRequestedReportZ"); + } + + @Override + public void onCompletedPrinting(PrinterResult printerErrorDataPrinterBaseDataPrinterResult) { + System.out.println("----->---->---->onCompletedPrinting"); + } + + @Override + public void onStatusFiscalModule(FiscalStatusData fiscalStatusData) { + System.out.println("----->---->---->onStatusFiscalModule"); + } + + @Override + public void onPrinterForRegistrationGettingCompleted() { + System.out.println("----->---->---->onPrinterForRegistrationGettingCompleted"); + } + + @Override + public void onNoBoundedPrinterFound() { + System.out.println("----->---->---->onNoBoundedPrinterFound"); + + } + + @Override + public void onPrinterToUseSelectionRequested(List printerList) { + System.out.println("----->---->---->onPrinterToUseSelectionRequested"); + } + + @Override + public void onRequiredReversal(String description, ResultCode resultCode) { + System.out.printf("----->---->---->onRequiredReversal: %s, resultCode: %s\n", description, resultCode.name()); + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setMessage("Revert last of operation?"); + builder.setCancelable(false); + builder.setPositiveButton("Yes", (dialog, which) -> plugin.getClientInterface().getTransactionManager().revertCurrentOperation(new RevertCurrentOperationHandlerImpl(plugin))); + builder.setNegativeButton("No", (dialog, which) -> plugin.getClientInterface().getTransactionManager().clearLastTransactionInformation()); + builder.create().show(); + }); + } + + @Override + public void onRequiredApplicationSelection(List list) { + System.out.println("----->---->---->onRequiredApplicationSelection"); + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setTitle("Choose application identifier"); + + Spinner deviceListSpinner = new Spinner(plugin.getActivity()); + ArrayAdapter adapter = new ArrayAdapter<>(plugin.getActivity(), android.R.layout.simple_spinner_item, list); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + deviceListSpinner.setAdapter(adapter); + + builder.setPositiveButton("OK", (dialog, which) -> { + plugin.getClientInterface() + .getTransactionManager() + .setTransactionApplicationIdentifier((ApplicationIdConv) deviceListSpinner.getSelectedItem()); + dialog.dismiss(); + }); + + builder.setView(deviceListSpinner); + builder.create().show(); + }); + } + + + @Override + public void onActivityUpdateUiThread() { + System.out.println("----->---->---->onActivityUpdateUiThread"); + plugin.getClientInterface().getTransactionManager().addPinpadClickListener(plugin.getActivity()); + } + + + + @Override + public void onCreatePinPadButtons() { + System.out.println("----->---->---->onCreatePinPadButtons"); + customKeyBoardDilalog.createDialog(plugin.getActivity()); + customKeyBoardDilalog.show(plugin.getActivity()); + ButtonKeyboardDto buttonKeyboardDto = new ButtonKeyboardDto.Build( + customKeyBoardDilalog.getBtnb1(), + customKeyBoardDilalog.getBtnb2(), + customKeyBoardDilalog.getBtnb3(), + customKeyBoardDilalog.getBtnb4(), + customKeyBoardDilalog.getBtnb5(), + customKeyBoardDilalog.getBtnb6(), + customKeyBoardDilalog.getBtnb7(), + customKeyBoardDilalog.getBtnb8(), + customKeyBoardDilalog.getBtnb9(), + customKeyBoardDilalog.getBtnb0(), + customKeyBoardDilalog.getBtncancel(), + customKeyBoardDilalog.getBtnconfirm(), + customKeyBoardDilalog.getBtnclean(), + plugin.getActivity().getWindowManager().getDefaultDisplay().getRotation() + ).build(); + plugin.getClientInterface().getTransactionManager().addPinPadButtons(buttonKeyboardDto); + } + + @Override + public void onShowPinPadKeyBoard(MessageButtonData messageButtonData) { + System.out.println("----->---->---->onShowPinPadKeyBoard"); + customKeyBoardDilalog.setText(messageButtonData); + } + + @Override + public void onUpdateElementPin(int count) { + System.out.println("----->---->---->onUpdateElementPin"); + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "count = " + count, Toast.LENGTH_SHORT).show()); + } + + @Override + public void onCloseKeyboard() { + System.out.println("----->---->---->onCloseKeyboard"); + customKeyBoardDilalog.close(plugin.getActivity()); + } + + @Override + public void onRequiredAdditionalVirtualKeyboardSettings(VirtualKeyboardStyleTypeConv virtualKeyboardStyleTypeConv) { + //TODO FIX +// plugin.getActivity().showSelectStyleDialog(additionalData -> +// plugin.getClientInterface().getTransactionManager().addVirtualPinKeyboardData(additionalData)); + } + + public interface SelectStyleListener { + void onSelectStyle(VirtualPinKeyboardData virtualPinKeyboardData); + } +} diff --git a/android/app/src/main/java/kz/com/aman/kassa/handler/RevertCurrentOperationHandlerImpl.java b/android/app/src/main/java/kz/com/aman/kassa/handler/RevertCurrentOperationHandlerImpl.java new file mode 100644 index 0000000..486aca9 --- /dev/null +++ b/android/app/src/main/java/kz/com/aman/kassa/handler/RevertCurrentOperationHandlerImpl.java @@ -0,0 +1,311 @@ +package kz.com.aman.kassa.handler; + +import android.app.AlertDialog; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import kz.com.aman.kassa.MainActivity; +import kz.com.aman.kassa.bank.M4BankActivity; +import kz.com.aman.kassa.plugins.BankNfcPlugins; +import ru.m4bank.mpos.library.external.transactions.LastReversalCardPaymentCallbackHandler; +import ru.m4bank.mpos.service.commons.data.ResultType; +import ru.m4bank.mpos.service.data.FiscalStatusData; +import ru.m4bank.mpos.service.data.dynamic.objects.Reader; +import ru.m4bank.mpos.service.data.dynamic.objects.Transaction; +import ru.m4bank.mpos.service.data.dynamic.objects.result.ResultCode; +import ru.m4bank.mpos.service.hardware.error.ErrorHandler; +import ru.m4bank.mpos.service.hardware.external.cardreaderlib.data.enums.VirtualKeyboardStyleTypeConv; +import ru.m4bank.mpos.service.result.PrinterResult; +import ru.m4bank.mpos.service.result.Result; +import ru.m4bank.mpos.service.transactions.data.MessageButtonData; +import ru.m4bank.mpos.service.transactions.data.TransactionData; +import ru.m4bank.mpos.service.transactions.data.TransactionExecutionStatus; +import ru.m4bank.mpos.service.transactions.data.error.TransactionErrorData; +import ru.m4bank.mpos.service.transactions.dto.OnlineCardDataDto; +import timber.log.Timber; + +public class RevertCurrentOperationHandlerImpl implements LastReversalCardPaymentCallbackHandler { + + private final BankNfcPlugins plugin; + + public RevertCurrentOperationHandlerImpl(BankNfcPlugins plugin) { + this.plugin = plugin; + } + + @Override + public void notAuthorized() { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Not authorized", Toast.LENGTH_SHORT).show()); + } + + @Override + public void onCompleted(Result result) { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), result.getResultType() + " " + (result.getDescription() == null ? "" : result.getDescription()), Toast.LENGTH_SHORT) + .show()); + } + + @Override + public void onWrongApiCalled() { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Wrong method has been called", Toast.LENGTH_SHORT).show()); + } + + @Override + public void onCardReaderForTransactionGettingCompleted() { + + } + + @Override + public void onNoBoundedDevicesFound() { + + } + + @Override + public void onConnectingProcessStarted(String deviceName) { + + } + + @Override + public void onDisconnectedEventReceivedOrCanNotEstablishConnection(boolean reconnectAvailable, String description) { + if (reconnectAvailable) { + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setMessage("Connection to cardreader has been lost, try to reconnect and repeat last operation?"); + builder.setCancelable(false); + builder.setPositiveButton("Yes", (dialog, which) -> plugin.getClientInterface().tryToReconnectAndRepeatLast()); + builder.setNegativeButton("No", (dialog, which) -> plugin.getClientInterface().cancel()); + builder.create().show(); + }); + } + } + + @Override + public void onDeviceToConnectSelectionRequested(List deviceList) { + plugin.getActivity().runOnUiThread(() -> { + 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, deviceList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + deviceListSpinner.setAdapter(adapter); + + builder.setPositiveButton("OK", (dialog, which) -> { + plugin.getClientInterface() + .getTransactionManager() + .selectCardReader(deviceListSpinner.getSelectedItem().toString()); + dialog.dismiss(); + }); + + builder.setView(deviceListSpinner); + builder.create().show(); + }); + } + + @Override + public void onWorkFlowDataRequested() { + + } + + @Override + public void onReceiveCardData(OnlineCardDataDto data, boolean shouldConfirmBeManuallyCalled) { + + } + + @Override + public void onRequiredReversal(String description, ResultCode resultCode) { + + } + + @Override + public void onRequiredApplicationSelection(List applicationOfList) { + + } + + @Override + public void onPrinterForRegistrationGettingCompleted() { + + } + + @Override + public void onNoBoundedPrinterFound() { + + } + + @Override + public void onTransactionDetailsReceived(Transaction transaction) { + + } + + @Override + public void onSuccessStatusTransaction(Transaction transaction) { + + } + + @Override + public void onErrorStatusTransaction() { + + } + + @Override + public void onRequestedReportZ() { + + } + + @Override + public void onCompletedPrinting(PrinterResult printerResult) { + + } + + @Override + public void onStatusFiscalModule(FiscalStatusData fiscalStatusData) { + + } + + @Override + public void onReconciliationRequiredToProcess() { + Timber.d("Reconciliation required!!!"); + plugin.getClientInterface().getTransactionManager().makeReconciliationDuringTransaction(); + } + + @Override + public void onReconciliationCompleted(Result result) { + Timber.d("Reconciliation completed!!!"); + if (result.getResultType() == ResultType.SUCCESSFUL) { + plugin.getClientInterface().getTransactionManager().continueTransactionAfterReconciliation(); + } else { + plugin.getActivity().runOnUiThread(() -> Toast.makeText(plugin.getActivity(), "Reconciliation failed " + (result.getDescription() == null ? "" : result.getDescription()), Toast.LENGTH_LONG) + .show()); + } + } + + @Override + public void onRepeat(int attemptNumber) { + + } + + @Override + public void onTransactionAmountRequested() { + + } + + @Override + public void onTransactionDataRequested() { + + } + + @Override + public void onDeviceToUseSelectionRequested(List deviceList) { + 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()); + } + + @Override + public void onPrinterToUseSelectionRequested(List printerList) { + + } + + @Override + public void onTransactionInit() { + + } + + @Override + public void onTransactionExecutionStatusChanged(TransactionExecutionStatus newStatus) { + + } + + @Override + public void onUserInformationRequested(boolean signNeeded) { + + } + + @Override + public void onError(ErrorHandler errorHandler, TransactionErrorData transactionErrorData) { + + } + + @Override + public void onErrorWithPossibilityToRetry(ErrorHandler errorHandler) { + plugin.getClientInterface().getTransactionManager().tryToRepeatExecuteLastRequestInTransaction(); + } + + @Override + public void onTransactionDataReceivedError(TransactionData data) { + + } + + @Override + public void onTransactionDataReceived(TransactionData data) { + + } + + @Override + public void onTransactionCompleted() { + + } + + @Override + public void onReconnectNeededToProcess() { + plugin.getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(plugin.getActivity()); + builder.setMessage("Connection to cardreader has been lost, try to reconnect and continue?"); + builder.setCancelable(false); + builder.setPositiveButton("Yes", (dialog, which) -> plugin.getClientInterface().getTransactionManager().tryToReconnectToCardReader()); + builder.setNegativeButton("No", (dialog, which) -> plugin.getClientInterface().cancel()); + builder.create().show(); + }); + } + + @Override + public void onWrongTerminal() { + + } + + @Override + public void onActivityUpdateUiThread() { + + } + + @Override + public void onCreatePinPadButtons() { + + } + + @Override + public void onShowPinPadKeyBoard(MessageButtonData messageButtonData) { + + } + + @Override + public void onUpdateElementPin(int i) { + + } + + @Override + public void onCloseKeyboard() { + + } + + @Override + public void onRequiredAdditionalVirtualKeyboardSettings(VirtualKeyboardStyleTypeConv virtualKeyboardStyleTypeConv) { + + } +} 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 505134b..4c1a8b5 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 @@ -2,6 +2,7 @@ package kz.com.aman.kassa.plugins; import android.widget.Toast; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -15,6 +16,7 @@ import kz.com.aman.kassa.bank.builders.SslConfigurationBuilder; 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.ConnectionCheckHandlerImpl; import ru.m4bank.mpos.library.M4BankMposClient; import ru.m4bank.mpos.library.M4BankMposClientInterfaceFacade; @@ -24,6 +26,7 @@ import ru.m4bank.mpos.service.authorization.network.AuthorizationResponse; 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.hardware.external.cardreaderlib.data.enums.TransactionTypeConv; import ru.m4bank.mpos.service.network.Format; import ru.m4bank.mpos.service.network.ServerChoose; @@ -32,8 +35,6 @@ public class BankNfcPlugins implements MethodCallHandler { //main activity private MainActivity activity; - private String timer; - //main client all work with him private M4BankMposClientInterfaceFacade clientInterface; //permissions @@ -63,6 +64,15 @@ public class BankNfcPlugins implements MethodCallHandler { case "auth": authentication(call, result); break; + case "pay": + pay(call, result); + break; + case "cancel": + cancel(call, result); + break; + case "shutdown": + shutdown(call, result); + break; case "get": final List json = new ArrayList<>(); for (int i = 0; i < 2; i++) { @@ -137,6 +147,40 @@ public class BankNfcPlugins implements MethodCallHandler { clientInterface.getAuthorizationManager().authorize(new AuthorizationHandlerImpl(this, result, login, password) ); } + private void pay(MethodCall call, Result result) { + try { + 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); + } catch (Exception e) { + System.out.println("=============>ERROR:"+e.getMessage()); + result.error("2", e.getMessage(), e.getLocalizedMessage()); + } + } + + private void cancel(MethodCall call, Result result) { + try { + clientInterface.cancel(); + result.success("canceled"); + } catch (Exception e) { + System.out.println("=============>ERROR:"+e.getMessage()); + result.error("2", e.getMessage(), e.getLocalizedMessage()); + } + } + + private void shutdown(MethodCall call, Result result) { + try { + clientInterface.shutdown(); + result.success("canceled"); + } catch (Exception e) { + System.out.println("=============>ERROR:"+e.getMessage()); + result.error("2", e.getMessage(), e.getLocalizedMessage()); + } + } + //terminal config private TerminalConfiguration createTerminalConfiguration() { return new TerminalConfiguration.Builder() diff --git a/lib/views/bank_view/bank_view.dart b/lib/views/bank_view/bank_view.dart index 954d970..198065f 100644 --- a/lib/views/bank_view/bank_view.dart +++ b/lib/views/bank_view/bank_view.dart @@ -16,6 +16,9 @@ class _BankViewState extends State { String initValue; String connectionValue; String authValue; + String payValue; + String cancelValue; + String shutdownValue; bool loading = false; @override @@ -48,6 +51,45 @@ class _BankViewState extends State { }); } + pay() async { + String result; + try { + result = + await _channel.invokeMethod("pay", {'amount': 100}); + } catch (e) { + result = (e.toString()); + } + setState(() { + payValue = result; + }); + } + + cancel() async { + String result; + try { + result = + await _channel.invokeMethod("cancel"); + } catch (e) { + result = (e.toString()); + } + setState(() { + cancelValue = result; + }); + } + + shutdown() async { + String result; + try { + result = + await _channel.invokeMethod("shutdown"); + } catch (e) { + result = (e.toString()); + } + setState(() { + shutdownValue = result; + }); + } + activity() async { String result = await _activity.invokeMethod("start"); } @@ -62,15 +104,45 @@ class _BankViewState extends State { body: loading ? Container(child: Center(child: CircularProgressIndicator())) : SingleChildScrollView( - child: Center( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 14.0), child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ + RaisedButton( + child: Text('Activity m4Bank'), onPressed: activity), Text('init: $initValue'), - Text('connection: $connectionValue'), - Text('auth: $authValue'), - RaisedButton(child: Text('Connect'), onPressed: connect), - RaisedButton(child: Text('Auth'), onPressed: auth), - RaisedButton(child: Text('Press'), onPressed: activity), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('connection: $connectionValue'), + RaisedButton( + child: Text('Connect'), onPressed: connect), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('auth: $authValue'), + RaisedButton(child: Text('Auth'), onPressed: auth), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('cancel: $cancelValue'), + RaisedButton(child: Text('Cancel'), onPressed: cancel), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('shutdown: $shutdownValue'), + RaisedButton(child: Text('Shutdown'), onPressed: shutdown), + ], + ), + Text('pay: $payValue'), + RaisedButton(child: Text('Payment'), onPressed: pay), ], ), ),