forte #1
|
|
@ -47,7 +47,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "kz.com.aman.kassa"
|
applicationId "kz.com.aman.kassa"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 30
|
targetSdkVersion 35
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<meta-data
|
<meta-data
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,16 @@ class MainActivity : FlutterActivity() {
|
||||||
val token = call.argument<String>("token").toString()
|
val token = call.argument<String>("token").toString()
|
||||||
var amount: Long = 0
|
var amount: Long = 0
|
||||||
if (call.argument<Long>("amount") != null) {
|
if (call.argument<Long>("amount") != null) {
|
||||||
amount = call.argument<Long>("amount")!!.toLong()
|
amount = call.argument<Long>("amount")!!
|
||||||
}
|
}
|
||||||
|
val packageName = call.argument<String>("packageName").toString()
|
||||||
val operationParameters = createOperationParameters(token)
|
val operationParameters = createOperationParameters(token)
|
||||||
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()))
|
|
||||||
|
startOperation(
|
||||||
|
OperationType.PAYMENT,
|
||||||
|
JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()),
|
||||||
|
packageName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun operationRefund(call: MethodCall) {
|
private fun operationRefund(call: MethodCall) {
|
||||||
|
|
@ -78,8 +84,15 @@ class MainActivity : FlutterActivity() {
|
||||||
val operDay = call.argument<String>("operDay").toString()
|
val operDay = call.argument<String>("operDay").toString()
|
||||||
val transNum = call.argument<String>("transNum").toString()
|
val transNum = call.argument<String>("transNum").toString()
|
||||||
val amount = call.argument<String>("amount").toString()
|
val amount = call.argument<String>("amount").toString()
|
||||||
|
val packageName = call.argument<String>("packageName").toString()
|
||||||
val operationParameters = createOperationParameters(token)
|
val operationParameters = createOperationParameters(token)
|
||||||
startOperation(OperationType.REFUND, JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount))
|
val body = JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount)
|
||||||
|
|
||||||
|
startOperation(
|
||||||
|
OperationType.REFUND,
|
||||||
|
body,
|
||||||
|
packageName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun operationReversal(call: MethodCall) {
|
private fun operationReversal(call: MethodCall) {
|
||||||
|
|
@ -87,16 +100,27 @@ class MainActivity : FlutterActivity() {
|
||||||
val terminalId = call.argument<String>("terminalId").toString()
|
val terminalId = call.argument<String>("terminalId").toString()
|
||||||
val operDay = call.argument<String>("operDay").toString()
|
val operDay = call.argument<String>("operDay").toString()
|
||||||
val transNum = call.argument<String>("transNum").toString()
|
val transNum = call.argument<String>("transNum").toString()
|
||||||
|
val packageName = call.argument<String>("packageName").toString()
|
||||||
val operationParameters = createOperationParameters(token)
|
val operationParameters = createOperationParameters(token)
|
||||||
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum);
|
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)
|
||||||
println(body)
|
|
||||||
startOperation(OperationType.REVERSAL, body)
|
startOperation(
|
||||||
|
OperationType.REVERSAL,
|
||||||
|
body,
|
||||||
|
packageName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun operationCloseDay(call: MethodCall) {
|
private fun operationCloseDay(call: MethodCall) {
|
||||||
val token = call.argument<String>("token").toString()
|
val token = call.argument<String>("token").toString()
|
||||||
|
val packageName = call.argument<String>("packageName").toString()
|
||||||
val operationParameters = createOperationParameters(token)
|
val operationParameters = createOperationParameters(token)
|
||||||
startOperation(OperationType.CLOSE_DAY, JsonForExternalCall.getCloseDayJson(operationParameters.authToken))
|
|
||||||
|
startOperation(
|
||||||
|
OperationType.CLOSE_DAY,
|
||||||
|
JsonForExternalCall.getCloseDayJson(operationParameters.authToken),
|
||||||
|
packageName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -104,11 +128,14 @@ class MainActivity : FlutterActivity() {
|
||||||
return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
|
return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startOperation(operationType: OperationType, inputJsonData: String?) {
|
private fun startOperation(
|
||||||
|
operationType: OperationType,
|
||||||
|
inputJsonData: String?,
|
||||||
|
packageName: String
|
||||||
|
) {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
|
intent.component = ComponentName(packageName, "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
// intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
|
||||||
intent.putExtra(externalOperationTypeKey, operationType.code)
|
intent.putExtra(externalOperationTypeKey, operationType.code)
|
||||||
intent.putExtra(externalInputDataKey, inputJsonData)
|
intent.putExtra(externalInputDataKey, inputJsonData)
|
||||||
startActivityForResult(intent, externalApplicationRequestCode)
|
startActivityForResult(intent, externalApplicationRequestCode)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ object JsonForExternalCall {
|
||||||
"instrument": "CARD",
|
"instrument": "CARD",
|
||||||
"amountData" : {
|
"amountData" : {
|
||||||
"currencyCode": "348",
|
"currencyCode": "348",
|
||||||
"amount": "6000",
|
"amount": "$amount",
|
||||||
"amountExponent": "2"
|
"amountExponent": "2"
|
||||||
},
|
},
|
||||||
"parentTransaction" : {
|
"parentTransaction" : {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.61'
|
ext.kotlin_version = '1.5.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
|
@ -18,6 +18,7 @@ allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ForteService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
|
||||||
import '../core/services/DbService.dart';
|
import '../core/services/DbService.dart';
|
||||||
|
|
@ -35,5 +36,7 @@ class LocatorInjector {
|
||||||
locator.registerLazySingleton<DataService>(() => DataService());
|
locator.registerLazySingleton<DataService>(() => DataService());
|
||||||
_log.d('Initializing BankService Service');
|
_log.d('Initializing BankService Service');
|
||||||
locator.registerLazySingleton<BankService>(() => BankService());
|
locator.registerLazySingleton<BankService>(() => BankService());
|
||||||
|
_log.d('Initializing Forte Service');
|
||||||
|
locator.registerLazySingleton<ForteService>(() => ForteService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||||
|
|
||||||
import 'halyk/halyk_close_day_dao.dart';
|
import 'forte_close_day_dao.dart';
|
||||||
|
|
||||||
class CloseDayData {
|
class CloseDayData {
|
||||||
final String title;
|
final String title;
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
/// result : {"code":"0","description":"Successfully completed"}
|
||||||
|
/// transactions : {"transaction":[{"type":"PAYMENT","instrument":"CARD","amount":"6000","terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}},{"type":"REFUND","instrument":"CARD","amount":"4500","terminalId":"123321","operationDay":"4","transactionNumber":"70","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"},"parentTransaction":{"terminalId":"123321","operationDay":"4","transactionNumber":"69"}}]}
|
||||||
|
/// closeDayResults : {"reconciliationResult":[{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]}
|
||||||
|
|
||||||
|
class ForteCloseDayDao {
|
||||||
|
ResultBean result;
|
||||||
|
TransactionsBean transactions;
|
||||||
|
CloseDayResultsBean closeDayResults;
|
||||||
|
|
||||||
|
ForteCloseDayDao({ this.result, this.closeDayResults, this.transactions});
|
||||||
|
|
||||||
|
static ForteCloseDayDao fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ForteCloseDayDao forteCloseDayDaoBean = ForteCloseDayDao();
|
||||||
|
forteCloseDayDaoBean.result = ResultBean.fromMap(map['result']);
|
||||||
|
forteCloseDayDaoBean.transactions = TransactionsBean.fromMap(map['transactions']);
|
||||||
|
forteCloseDayDaoBean.closeDayResults = CloseDayResultsBean.fromMap(map['closeDayResults']);
|
||||||
|
return forteCloseDayDaoBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"result": result,
|
||||||
|
"transactions": transactions,
|
||||||
|
"closeDayResults": closeDayResults,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reconciliationResult : [{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]
|
||||||
|
|
||||||
|
class CloseDayResultsBean {
|
||||||
|
List<ReconciliationResultBean> reconciliationResult;
|
||||||
|
|
||||||
|
static CloseDayResultsBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
CloseDayResultsBean closeDayResultsBean = CloseDayResultsBean();
|
||||||
|
closeDayResultsBean.reconciliationResult = List()..addAll(
|
||||||
|
(map['reconciliationResult'] as List ?? []).map((o) => ReconciliationResultBean.fromMap(o))
|
||||||
|
);
|
||||||
|
return closeDayResultsBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"reconciliationResult": reconciliationResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// hostResultCode : "000"
|
||||||
|
/// hostResultDescription : "Success"
|
||||||
|
/// terminalExternalId : "example_terminal_id"
|
||||||
|
|
||||||
|
class ReconciliationResultBean {
|
||||||
|
String hostResultCode;
|
||||||
|
String hostResultDescription;
|
||||||
|
String terminalExternalId;
|
||||||
|
|
||||||
|
static ReconciliationResultBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ReconciliationResultBean reconciliationResultBean = ReconciliationResultBean();
|
||||||
|
reconciliationResultBean.hostResultCode = map['hostResultCode'];
|
||||||
|
reconciliationResultBean.hostResultDescription = map['hostResultDescription'];
|
||||||
|
reconciliationResultBean.terminalExternalId = map['terminalExternalId'];
|
||||||
|
return reconciliationResultBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"hostResultCode": hostResultCode,
|
||||||
|
"hostResultDescription": hostResultDescription,
|
||||||
|
"terminalExternalId": terminalExternalId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// transaction : [{"type":"PAYMENT","instrument":"CARD","amount":"6000","terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}},{"type":"REFUND","instrument":"CARD","amount":"4500","terminalId":"123321","operationDay":"4","transactionNumber":"70","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"},"parentTransaction":{"terminalId":"123321","operationDay":"4","transactionNumber":"69"}}]
|
||||||
|
|
||||||
|
class TransactionsBean {
|
||||||
|
List<TransactionBean> transaction;
|
||||||
|
|
||||||
|
static TransactionsBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
TransactionsBean transactionsBean = TransactionsBean();
|
||||||
|
transactionsBean.transaction = List()..addAll(
|
||||||
|
(map['transaction'] as List ?? []).map((o) => TransactionBean.fromMap(o))
|
||||||
|
);
|
||||||
|
return transactionsBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"transaction": transaction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// type : "PAYMENT"
|
||||||
|
/// instrument : "CARD"
|
||||||
|
/// amount : "6000"
|
||||||
|
/// terminalId : "123321"
|
||||||
|
/// operationDay : "4"
|
||||||
|
/// transactionNumber : "69"
|
||||||
|
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
|
||||||
|
|
||||||
|
class TransactionBean {
|
||||||
|
String type;
|
||||||
|
String instrument;
|
||||||
|
num amount;
|
||||||
|
int terminalId;
|
||||||
|
int operationDay;
|
||||||
|
int transactionNumber;
|
||||||
|
InstrumentSpecificDataBean instrumentSpecificData;
|
||||||
|
|
||||||
|
static TransactionBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
TransactionBean transactionBean = TransactionBean();
|
||||||
|
transactionBean.type = map['type'];
|
||||||
|
transactionBean.instrument = map['instrument'];
|
||||||
|
transactionBean.amount = map['amount'];
|
||||||
|
transactionBean.terminalId = map['terminalId'];
|
||||||
|
transactionBean.operationDay = map['operationDay'];
|
||||||
|
transactionBean.transactionNumber = map['transactionNumber'];
|
||||||
|
transactionBean.instrumentSpecificData = InstrumentSpecificDataBean.fromMap(map['instrumentSpecificData']);
|
||||||
|
return transactionBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"type": type,
|
||||||
|
"instrument": instrument,
|
||||||
|
"amount": amount,
|
||||||
|
"terminalId": terminalId,
|
||||||
|
"operationDay": operationDay,
|
||||||
|
"transactionNumber": transactionNumber,
|
||||||
|
"instrumentSpecificData": instrumentSpecificData,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// authorizationCode : "000000"
|
||||||
|
/// rrn : "1234567890"
|
||||||
|
/// cardholderName : "IVAN IVANOV"
|
||||||
|
/// maskedPan : "123456******7890"
|
||||||
|
|
||||||
|
class InstrumentSpecificDataBean {
|
||||||
|
String authorizationCode;
|
||||||
|
String rrn;
|
||||||
|
String cardholderName;
|
||||||
|
String maskedPan;
|
||||||
|
|
||||||
|
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
|
||||||
|
instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
|
||||||
|
instrumentSpecificDataBean.rrn = map['rrn'];
|
||||||
|
instrumentSpecificDataBean.cardholderName = map['cardholderName'];
|
||||||
|
instrumentSpecificDataBean.maskedPan = map['maskedPan'];
|
||||||
|
return instrumentSpecificDataBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"authorizationCode": authorizationCode,
|
||||||
|
"rrn": rrn,
|
||||||
|
"cardholderName": cardholderName,
|
||||||
|
"maskedPan": maskedPan,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// code : "0"
|
||||||
|
/// description : "Successfully completed"
|
||||||
|
|
||||||
|
class ResultBean {
|
||||||
|
int code;
|
||||||
|
String description;
|
||||||
|
|
||||||
|
ResultBean({this.code, this.description});
|
||||||
|
|
||||||
|
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ResultBean resultBean = ResultBean();
|
||||||
|
resultBean.code = map['code'];
|
||||||
|
resultBean.description = map['description'];
|
||||||
|
return resultBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"code": code,
|
||||||
|
"description": description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
class FortePosSession {
|
||||||
|
const FortePosSession(
|
||||||
|
{this.login,
|
||||||
|
this.token,
|
||||||
|
this.serverTime,
|
||||||
|
this.tokenTimeout,
|
||||||
|
this.result});
|
||||||
|
|
||||||
|
final String login;
|
||||||
|
final String token;
|
||||||
|
final DateTime serverTime;
|
||||||
|
final int tokenTimeout;
|
||||||
|
final ResultBean result;
|
||||||
|
|
||||||
|
static FortePosSession fromJson(Map<String, dynamic> data) => FortePosSession(
|
||||||
|
login: data['login'],
|
||||||
|
token: data['token'],
|
||||||
|
result: ResultBean.fromMap(data['result']),
|
||||||
|
serverTime: data['ServerTime'] != null
|
||||||
|
? new DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").parse(data['ServerTime'])
|
||||||
|
: null,
|
||||||
|
tokenTimeout: data['TokenTimeout']);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"login": login,
|
||||||
|
"token": token,
|
||||||
|
"ServerTime": serverTime != null
|
||||||
|
? DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").format(serverTime)
|
||||||
|
: null,
|
||||||
|
"TokenTimeout": tokenTimeout,
|
||||||
|
"result": result?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ServerTime : "25.06.2021 13:18:00 GMT+06:00"
|
||||||
|
/// ResultCode : "040"
|
||||||
|
/// ResultStr : "Unknown operator login. Check the correctness of the data or contact support."
|
||||||
|
/// Response : {"Code":"040","Description":"Unknown operator login. Check the correctness of the data or contact support."}
|
||||||
|
|
||||||
|
class ResultBean {
|
||||||
|
String ServerTime;
|
||||||
|
String ResultCode;
|
||||||
|
String ResultStr;
|
||||||
|
ResponseBean Response;
|
||||||
|
|
||||||
|
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ResultBean resultBean = ResultBean();
|
||||||
|
resultBean.ServerTime = map['ServerTime'];
|
||||||
|
resultBean.ResultCode = map['ResultCode'];
|
||||||
|
resultBean.ResultStr = map['ResultStr'];
|
||||||
|
resultBean.Response = ResponseBean.fromMap(map['Response']);
|
||||||
|
return resultBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"ServerTime": ServerTime,
|
||||||
|
"ResultCode": ResultCode,
|
||||||
|
"ResultStr": ResultStr,
|
||||||
|
"Response": Response,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Code : "040"
|
||||||
|
/// Description : "Unknown operator login. Check the correctness of the data or contact support."
|
||||||
|
|
||||||
|
class ResponseBean {
|
||||||
|
String Code;
|
||||||
|
String Description;
|
||||||
|
|
||||||
|
static ResponseBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ResponseBean responseBean = ResponseBean();
|
||||||
|
responseBean.Code = map['Code'];
|
||||||
|
responseBean.Description = map['Description'];
|
||||||
|
return responseBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() => {
|
||||||
|
"Code": Code,
|
||||||
|
"Description": Description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
/// result : {"code":"0","description":"Successfully completed","hostResponse":{"code":"0","description":"Successfully completed"}}
|
||||||
|
/// transaction : {"terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}}
|
||||||
|
|
||||||
|
class ForteResponse {
|
||||||
|
ResultBean result;
|
||||||
|
TransactionBean transaction;
|
||||||
|
|
||||||
|
ForteResponse({this.result, this.transaction});
|
||||||
|
|
||||||
|
static ForteResponse fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ForteResponse forteResponseBean = ForteResponse();
|
||||||
|
forteResponseBean.result = ResultBean.fromMap(map['result']);
|
||||||
|
forteResponseBean.transaction = TransactionBean.fromMap(map['transaction']);
|
||||||
|
return forteResponseBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"result": result,
|
||||||
|
"transaction": transaction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// terminalId : "123321"
|
||||||
|
/// operationDay : "4"
|
||||||
|
/// transactionNumber : "69"
|
||||||
|
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
|
||||||
|
|
||||||
|
class TransactionBean {
|
||||||
|
int terminalId;
|
||||||
|
int operationDay;
|
||||||
|
int transactionNumber;
|
||||||
|
InstrumentSpecificDataBean instrumentSpecificData;
|
||||||
|
|
||||||
|
static TransactionBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
TransactionBean transactionBean = TransactionBean();
|
||||||
|
transactionBean.terminalId = map['terminalId'];
|
||||||
|
transactionBean.operationDay = map['operationDay'];
|
||||||
|
transactionBean.transactionNumber = map['transactionNumber'];
|
||||||
|
transactionBean.instrumentSpecificData = InstrumentSpecificDataBean.fromMap(map['instrumentSpecificData']);
|
||||||
|
return transactionBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"terminalId": terminalId,
|
||||||
|
"operationDay": operationDay,
|
||||||
|
"transactionNumber": transactionNumber,
|
||||||
|
"instrumentSpecificData": instrumentSpecificData,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// authorizationCode : "000000"
|
||||||
|
/// rrn : "1234567890"
|
||||||
|
/// cardholderName : "IVAN IVANOV"
|
||||||
|
/// maskedPan : "123456******7890"
|
||||||
|
|
||||||
|
class InstrumentSpecificDataBean {
|
||||||
|
String authorizationCode;
|
||||||
|
String rrn;
|
||||||
|
String cardholderName;
|
||||||
|
String maskedPan;
|
||||||
|
|
||||||
|
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
|
||||||
|
instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
|
||||||
|
instrumentSpecificDataBean.rrn = map['rrn'];
|
||||||
|
instrumentSpecificDataBean.cardholderName = map['cardholderName'];
|
||||||
|
instrumentSpecificDataBean.maskedPan = map['maskedPan'];
|
||||||
|
return instrumentSpecificDataBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"authorizationCode": authorizationCode,
|
||||||
|
"rrn": rrn,
|
||||||
|
"cardholderName": cardholderName,
|
||||||
|
"maskedPan": maskedPan,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// code : "0"
|
||||||
|
/// description : "Successfully completed"
|
||||||
|
/// hostResponse : {"code":"0","description":"Successfully completed"}
|
||||||
|
|
||||||
|
class ResultBean {
|
||||||
|
dynamic code;
|
||||||
|
String description;
|
||||||
|
HostResponseBean hostResponse;
|
||||||
|
ErrorResponseBean errorData;
|
||||||
|
|
||||||
|
ResultBean({this.code, this.description});
|
||||||
|
|
||||||
|
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ResultBean resultBean = ResultBean();
|
||||||
|
resultBean.code = map['code'];
|
||||||
|
resultBean.description = map['description'];
|
||||||
|
resultBean.hostResponse = HostResponseBean.fromMap(map['hostResponse']);
|
||||||
|
resultBean.errorData = ErrorResponseBean.fromMap(map['errorData']);
|
||||||
|
return resultBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"code": code,
|
||||||
|
"description": description,
|
||||||
|
"hostResponse": hostResponse,
|
||||||
|
"errorData": errorData,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// code : "0"
|
||||||
|
/// description : "Successfully completed"
|
||||||
|
|
||||||
|
class HostResponseBean {
|
||||||
|
dynamic code;
|
||||||
|
String description;
|
||||||
|
|
||||||
|
static HostResponseBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
HostResponseBean hostResponseBean = HostResponseBean();
|
||||||
|
hostResponseBean.code = map['code'];
|
||||||
|
hostResponseBean.description = map['description'];
|
||||||
|
return hostResponseBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"code": code,
|
||||||
|
"description": description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorResponseBean {
|
||||||
|
dynamic code;
|
||||||
|
String description;
|
||||||
|
|
||||||
|
static ErrorResponseBean fromMap(Map<String, dynamic> map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
ErrorResponseBean errorResponseBean = ErrorResponseBean();
|
||||||
|
errorResponseBean.code = map['code'];
|
||||||
|
errorResponseBean.description = map['description'];
|
||||||
|
return errorResponseBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map toJson() =>
|
||||||
|
{
|
||||||
|
"code": code,
|
||||||
|
"description": description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||||
|
|
||||||
|
import 'halyk_close_day_dao.dart';
|
||||||
|
|
||||||
|
class CloseDayData {
|
||||||
|
final String title;
|
||||||
|
final num totalAmount;
|
||||||
|
final int totalCount;
|
||||||
|
final num paymentAmount;
|
||||||
|
final int paymentCount;
|
||||||
|
final num refundAmount;
|
||||||
|
final int refundCount;
|
||||||
|
final num cancelAmount;
|
||||||
|
final int cancelCount;
|
||||||
|
|
||||||
|
final List<TransactionBean> items;
|
||||||
|
CloseDayData({
|
||||||
|
this.title,
|
||||||
|
this.items,
|
||||||
|
this.totalAmount, this.totalCount,
|
||||||
|
this.paymentAmount, this.paymentCount,
|
||||||
|
this.refundAmount, this.refundCount,
|
||||||
|
this.cancelAmount, this.cancelCount
|
||||||
|
});
|
||||||
|
|
||||||
|
static CloseDayData fromJson(Map<String, dynamic> json) {
|
||||||
|
return CloseDayData(
|
||||||
|
title: json['title'],
|
||||||
|
totalAmount: json['totalAmount'],
|
||||||
|
totalCount: json['totalCount'],
|
||||||
|
paymentAmount: json['paymentAmount'],
|
||||||
|
paymentCount: json['paymentCount'],
|
||||||
|
refundAmount: json['refundAmount'],
|
||||||
|
refundCount: json['refundCount'],
|
||||||
|
cancelAmount: json['cancelAmount'],
|
||||||
|
cancelCount: json['cancelCount'],
|
||||||
|
items: (json['items'] as List).map((e) => TransactionBean.fromMap(e)).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
{
|
||||||
|
'title': title,
|
||||||
|
'totalAmount': totalAmount,
|
||||||
|
'totalCount': totalCount,
|
||||||
|
'paymentAmount': paymentAmount,
|
||||||
|
'paymentCount': paymentCount,
|
||||||
|
'refundAmount': refundAmount,
|
||||||
|
'refundCount': refundCount,
|
||||||
|
'cancelAmount': cancelAmount,
|
||||||
|
'cancelCount': cancelCount,
|
||||||
|
'items': items.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,16 @@ class HalykPosSession {
|
||||||
? new DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").parse(data['ServerTime'])
|
? new DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").parse(data['ServerTime'])
|
||||||
: null,
|
: null,
|
||||||
tokenTimeout: data['TokenTimeout']);
|
tokenTimeout: data['TokenTimeout']);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"login": login,
|
||||||
|
"token": token,
|
||||||
|
"ServerTime": serverTime != null
|
||||||
|
? DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").format(serverTime)
|
||||||
|
: null,
|
||||||
|
"TokenTimeout": tokenTimeout,
|
||||||
|
"result": result?.toJson(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ServerTime : "25.06.2021 13:18:00 GMT+06:00"
|
/// ServerTime : "25.06.2021 13:18:00 GMT+06:00"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const String SettingsViewRoute = "SettingsViewRoute";
|
||||||
const String QrViewRoute = "QrViewRoute";
|
const String QrViewRoute = "QrViewRoute";
|
||||||
const String BankViewRoute = "BankViewRoute";
|
const String BankViewRoute = "BankViewRoute";
|
||||||
const String BankSettingViewRoute = "BankSettingViewRoute";
|
const String BankSettingViewRoute = "BankSettingViewRoute";
|
||||||
|
const String ForteSettingViewRoute = "ForteSettingViewRoute";
|
||||||
|
|
||||||
|
|
||||||
const String SettingsPrinterRoute = "SettingsPrinterRoute";
|
const String SettingsPrinterRoute = "SettingsPrinterRoute";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
import 'package:aman_kassa_flutter/views/bank_setting/forte_setting_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart';
|
||||||
import 'package:aman_kassa_flutter/views/bank_setting/bank_setting_view.dart';
|
import 'package:aman_kassa_flutter/views/bank_setting/bank_setting_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/bank_view/bank_view.dart';
|
import 'package:aman_kassa_flutter/views/bank_view/bank_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||||
|
|
@ -71,6 +72,11 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: BankSettingView(),
|
viewToShow: BankSettingView(),
|
||||||
);
|
);
|
||||||
|
case ForteSettingViewRoute:
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
viewToShow: ForteSettingView(),
|
||||||
|
);
|
||||||
case QrViewRoute:
|
case QrViewRoute:
|
||||||
ImageShowModel data = settings.arguments as ImageShowModel;
|
ImageShowModel data = settings.arguments as ImageShowModel;
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||||
|
|
@ -79,6 +80,18 @@ class ApiService extends BaseService {
|
||||||
return HalykPosSession.fromJson(jsonDecode(response));
|
return HalykPosSession.fromJson(jsonDecode(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<FortePosSession> fortePosToken(String token, login, password) async {
|
||||||
|
String salt = '!=uF:w1N_Salh?1gVSJ#eGfJYHA(wS4D';
|
||||||
|
String hash = md5.convert(utf8.encode('$login$salt')).toString();
|
||||||
|
print(hash);
|
||||||
|
|
||||||
|
Map<String, String> requestBody = <String, String>{'login': login, 'hash': hash};
|
||||||
|
//var response = await requestFormData('/fortepos/test/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
|
||||||
|
var response = await requestFormData('/fortepos/prod/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
|
||||||
|
print(response);
|
||||||
|
return FortePosSession.fromJson(jsonDecode(response));
|
||||||
|
}
|
||||||
|
|
||||||
Future<Response<dynamic>> money(String token) async {
|
Future<Response<dynamic>> money(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/money', requestBody);
|
var response = await requestFormData('/money', requestBody);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart' as Cd;
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart' as Cd;
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart' as Ps;
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart' as Ps;
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart';
|
||||||
|
|
@ -15,6 +15,7 @@ import '../models/aman_dao.dart';
|
||||||
|
|
||||||
class BankService extends BaseService {
|
class BankService extends BaseService {
|
||||||
int sdkVersion = 27;
|
int sdkVersion = 27;
|
||||||
|
String packageName = 'ru.m4bank.softpos.halyk';
|
||||||
final ApiService _api = locator<ApiService>();
|
final ApiService _api = locator<ApiService>();
|
||||||
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
|
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
|
||||||
|
|
||||||
|
|
@ -45,7 +46,10 @@ class BankService extends BaseService {
|
||||||
|
|
||||||
Future<Cd.HalykCloseDayDao> closeDay({ String token}) async {
|
Future<Cd.HalykCloseDayDao> closeDay({ String token}) async {
|
||||||
try {
|
try {
|
||||||
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{'token': token });
|
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{
|
||||||
|
'token': token,
|
||||||
|
'packageName': packageName
|
||||||
|
});
|
||||||
log.i(response);
|
log.i(response);
|
||||||
Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response));
|
Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response));
|
||||||
return dao;
|
return dao;
|
||||||
|
|
@ -60,7 +64,11 @@ class BankService extends BaseService {
|
||||||
|
|
||||||
double total = amount * 100;
|
double total = amount * 100;
|
||||||
log.i('total: $total, ${total.toInt()}');
|
log.i('total: $total, ${total.toInt()}');
|
||||||
String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt(), 'token': token });
|
String response = await _channel.invokeMethod("pay", <String, dynamic>{
|
||||||
|
'amount': total.toInt(),
|
||||||
|
'token': token,
|
||||||
|
'packageName': packageName
|
||||||
|
});
|
||||||
log.i(response);
|
log.i(response);
|
||||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||||
return dao;
|
return dao;
|
||||||
|
|
@ -73,7 +81,12 @@ class BankService extends BaseService {
|
||||||
Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
|
Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
|
||||||
try {
|
try {
|
||||||
String response = await _channel.invokeMethod("refund", <String, dynamic>{
|
String response = await _channel.invokeMethod("refund", <String, dynamic>{
|
||||||
'amount': amount.toInt(), 'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
|
'amount': amount.toInt(),
|
||||||
|
'token': token,
|
||||||
|
'terminalId': terminalId,
|
||||||
|
'operDay': operDay,
|
||||||
|
'transNum': transNum,
|
||||||
|
'packageName': packageName
|
||||||
});
|
});
|
||||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||||
return dao;
|
return dao;
|
||||||
|
|
@ -86,7 +99,11 @@ class BankService extends BaseService {
|
||||||
Future<HalykResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async {
|
Future<HalykResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async {
|
||||||
try {
|
try {
|
||||||
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
|
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
|
||||||
'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
|
'token': token,
|
||||||
|
'terminalId': terminalId,
|
||||||
|
'operDay': operDay,
|
||||||
|
'transNum': transNum,
|
||||||
|
'packageName': packageName
|
||||||
});
|
});
|
||||||
log.i(response);
|
log.i(response);
|
||||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/close_day_data.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_close_day_dao.dart' as Cd;
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart' as Ps;
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_response_dao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import '../models/aman_dao.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class ForteService extends BaseService {
|
||||||
|
int sdkVersion = 27;
|
||||||
|
String packageName = 'kz.forte.pos';
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
|
||||||
|
|
||||||
|
|
||||||
|
Future<int> version() async {
|
||||||
|
String result;
|
||||||
|
try {
|
||||||
|
result = await _channel.invokeMethod('version');
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
result = '0';
|
||||||
|
}
|
||||||
|
log.i(result);
|
||||||
|
return int.parse(result) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Ps.FortePosSession> renewToken({String token, String login, String password}) async {
|
||||||
|
Ps.FortePosSession result;
|
||||||
|
try {
|
||||||
|
result = await _api.fortePosToken(token, login, password);
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Future<Cd.ForteCloseDayDao> closeDay({ String token}) async {
|
||||||
|
try {
|
||||||
|
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{
|
||||||
|
'token': token,
|
||||||
|
'packageName': packageName
|
||||||
|
});
|
||||||
|
log.i(response);
|
||||||
|
Cd.ForteCloseDayDao dao = Cd.ForteCloseDayDao.fromMap(json.decode(response));
|
||||||
|
return dao;
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
return new Cd.ForteCloseDayDao(result: Cd.ResultBean(description: 'Ошибка при закрытии дня', code: -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ForteResponse> pay({double amount, String token}) async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
double total = amount * 100;
|
||||||
|
log.i('total: $total, ${total.toInt()}');
|
||||||
|
String response = await _channel.invokeMethod("pay", <String, dynamic>{
|
||||||
|
'amount': total.toInt(),
|
||||||
|
'token': token,
|
||||||
|
'packageName': packageName,
|
||||||
|
});
|
||||||
|
log.i(response);
|
||||||
|
ForteResponse dao = ForteResponse.fromMap(json.decode(response));
|
||||||
|
return dao;
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
return new ForteResponse(result: ResultBean(description: 'Ошибка оплаты', code: -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ForteResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
|
||||||
|
try {
|
||||||
|
double total = amount * 100;
|
||||||
|
String response = await _channel.invokeMethod("refund", <String, dynamic>{
|
||||||
|
'amount': total,
|
||||||
|
'token': token ,
|
||||||
|
'terminalId': terminalId,
|
||||||
|
'operDay': operDay,
|
||||||
|
'transNum': transNum,
|
||||||
|
'packageName': packageName
|
||||||
|
});
|
||||||
|
ForteResponse dao = ForteResponse.fromMap(json.decode(response));
|
||||||
|
return dao;
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
return new ForteResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ForteResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async {
|
||||||
|
try {
|
||||||
|
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
|
||||||
|
'token': token,
|
||||||
|
'terminalId': terminalId,
|
||||||
|
'operDay': operDay,
|
||||||
|
'transNum': transNum,
|
||||||
|
'packageName': packageName
|
||||||
|
});
|
||||||
|
log.i(response);
|
||||||
|
ForteResponse dao = ForteResponse.fromMap(json.decode(response));
|
||||||
|
return dao;
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e("ForteService", e, stack);
|
||||||
|
return new ForteResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CloseDayData closeDayDataConvert(Cd.TransactionsBean transactions) {
|
||||||
|
final DateFormat formatter = DateFormat('dd.MM.yyyy');
|
||||||
|
final DateTime now = DateTime.now();
|
||||||
|
final String formatted = formatter.format(now);
|
||||||
|
List<Cd.TransactionBean> items = transactions.transaction;
|
||||||
|
num totalAmount = 0;
|
||||||
|
int totalCount = 0;
|
||||||
|
num paymentAmount = 0;
|
||||||
|
int paymentCount = 0;
|
||||||
|
num refundAmount = 0;
|
||||||
|
int refundCount = 0;
|
||||||
|
num cancelAmount = 0;
|
||||||
|
int cancelCount = 0;
|
||||||
|
|
||||||
|
for(Cd.TransactionBean item in items) {
|
||||||
|
if(item.type == 'PAYMENT') {
|
||||||
|
paymentCount++;
|
||||||
|
paymentAmount += ( item.amount / 100 );
|
||||||
|
totalAmount += ( item.amount / 100 );
|
||||||
|
} else if(item.type == 'REFUND') {
|
||||||
|
refundCount++;
|
||||||
|
refundAmount += ( item.amount / 100 );
|
||||||
|
totalAmount -= ( item.amount / 100 );
|
||||||
|
} else if(item.type == 'REVERSAL') {
|
||||||
|
cancelCount++;
|
||||||
|
cancelAmount += ( item.amount / 100 );
|
||||||
|
totalAmount -= ( item.amount / 100 );
|
||||||
|
}
|
||||||
|
totalCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseDayData closeDayData = new CloseDayData(
|
||||||
|
items: items,
|
||||||
|
title: 'Отчет POS от $formatted',
|
||||||
|
totalAmount: totalAmount, totalCount: totalCount,
|
||||||
|
paymentAmount: paymentAmount, paymentCount: paymentCount,
|
||||||
|
refundAmount: refundAmount, refundCount: refundCount,
|
||||||
|
cancelAmount: cancelAmount, cancelCount: cancelCount,
|
||||||
|
);
|
||||||
|
return closeDayData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
@ -12,15 +13,50 @@ class SetBankStateAction {
|
||||||
final BankState bankState;
|
final BankState bankState;
|
||||||
SetBankStateAction(this.bankState);
|
SetBankStateAction(this.bankState);
|
||||||
}
|
}
|
||||||
|
ThunkAction<AppState> saveData(String login, String password, {String sessionType}) {
|
||||||
ThunkAction<AppState> saveData(String login, String password) {
|
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetBankStateAction(BankState(login: login, password: password)));
|
final currentState = store.state.bankState;
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ThunkAction<AppState> setHalykSession(HalykPosSession session) {
|
dynamic session;
|
||||||
return (Store<AppState> store) async {
|
if (sessionType == 'Halyk') {
|
||||||
store.dispatch(SetBankStateAction(BankState(session: session)));
|
session = HalykPosSession(
|
||||||
|
login: login,
|
||||||
|
token: currentState.session != null && currentState.session is HalykPosSession
|
||||||
|
? (currentState.session as HalykPosSession).token
|
||||||
|
: null,
|
||||||
|
serverTime: currentState.session != null && currentState.session is HalykPosSession
|
||||||
|
? (currentState.session as HalykPosSession).serverTime
|
||||||
|
: null,
|
||||||
|
tokenTimeout: currentState.session != null && currentState.session is HalykPosSession
|
||||||
|
? (currentState.session as HalykPosSession).tokenTimeout
|
||||||
|
: null,
|
||||||
|
result: currentState.session != null && currentState.session is HalykPosSession
|
||||||
|
? (currentState.session as HalykPosSession).result
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
} else if (sessionType == 'Forte') {
|
||||||
|
session = FortePosSession(
|
||||||
|
login: login,
|
||||||
|
token: currentState.session != null && currentState.session is FortePosSession
|
||||||
|
? (currentState.session as FortePosSession).token
|
||||||
|
: null,
|
||||||
|
serverTime: currentState.session != null && currentState.session is FortePosSession
|
||||||
|
? (currentState.session as FortePosSession).serverTime
|
||||||
|
: null,
|
||||||
|
tokenTimeout: currentState.session != null && currentState.session is FortePosSession
|
||||||
|
? (currentState.session as FortePosSession).tokenTimeout
|
||||||
|
: null,
|
||||||
|
result: currentState.session != null && currentState.session is FortePosSession
|
||||||
|
? (currentState.session as FortePosSession).result
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(SetBankStateAction(BankState(
|
||||||
|
login: login,
|
||||||
|
password: password,
|
||||||
|
session: session,
|
||||||
|
sessionType: sessionType,
|
||||||
|
)));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||||
|
|
||||||
bankReducer(BankState prevState, SetBankStateAction action) {
|
BankState bankReducer(BankState prevState, SetBankStateAction action) {
|
||||||
final payload = action.bankState;
|
final payload = action.bankState;
|
||||||
return prevState.copyWith(login: payload.login, password: payload.password, session: payload.session);
|
|
||||||
|
return prevState.copyWith(
|
||||||
|
login: payload.login ?? prevState.login,
|
||||||
|
password: payload.password ?? prevState.password,
|
||||||
|
session: payload.session ?? prevState.session,
|
||||||
|
sessionType: payload.sessionType ?? prevState.sessionType,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
|
@ -7,42 +8,72 @@ import 'package:meta/meta.dart';
|
||||||
class BankState {
|
class BankState {
|
||||||
final String login;
|
final String login;
|
||||||
final String password;
|
final String password;
|
||||||
final HalykPosSession session;
|
final dynamic session;
|
||||||
|
final String sessionType;
|
||||||
|
|
||||||
BankState({this.login, this.password, this.session,});
|
BankState({
|
||||||
|
this.login,
|
||||||
|
this.password,
|
||||||
|
this.session,
|
||||||
|
this.sessionType,
|
||||||
|
});
|
||||||
|
|
||||||
//read hive
|
|
||||||
factory BankState.initial(BankState payload) {
|
factory BankState.initial(BankState payload) {
|
||||||
return BankState(
|
return BankState(
|
||||||
login: payload?.login,
|
login: payload?.login,
|
||||||
password: payload?.password,
|
password: payload?.password,
|
||||||
session: payload?.session
|
session: payload?.session,
|
||||||
|
sessionType: payload?.sessionType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//write hive
|
|
||||||
BankState copyWith({
|
BankState copyWith({
|
||||||
@required login,
|
String login,
|
||||||
@required password,
|
String password,
|
||||||
@required session,
|
dynamic session,
|
||||||
|
String sessionType,
|
||||||
}) {
|
}) {
|
||||||
return BankState(
|
return BankState(
|
||||||
login: login ?? this.login,
|
login: login ?? this.login,
|
||||||
password: password ?? this.password,
|
password: password ?? this.password,
|
||||||
session: session ?? this.session
|
session: session ?? this.session,
|
||||||
|
sessionType: sessionType ?? this.sessionType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BankState fromJson(dynamic json) {
|
// Создание из JSON
|
||||||
return json != null
|
static BankState fromJson(Map<String, dynamic> json) {
|
||||||
? BankState(
|
if (json == null) return null;
|
||||||
password: json['password'],
|
|
||||||
|
// Определяем тип сессии
|
||||||
|
dynamic session;
|
||||||
|
String sessionType = json['sessionType'];
|
||||||
|
if (sessionType == "Halyk") {
|
||||||
|
session = HalykPosSession.fromJson(json['session']);
|
||||||
|
} else if (sessionType == "Forte") {
|
||||||
|
session = FortePosSession.fromJson(json['session']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BankState(
|
||||||
login: json['login'],
|
login: json['login'],
|
||||||
)
|
password: json['password'],
|
||||||
: null;
|
session: session,
|
||||||
|
sessionType: sessionType,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic toJson() {
|
// Преобразование в JSON
|
||||||
return {"password": password, "login": login};
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
"login": login,
|
||||||
|
"password": password,
|
||||||
|
"sessionType": sessionType,
|
||||||
|
"session": session?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BankState(login: $login, password: $password, sessionType: $sessionType, session: $session)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const Color fillColor = Color.fromRGBO(248, 248, 248, 1);
|
||||||
const Color primaryColor = Color.fromRGBO(51, 122, 183, 1);
|
const Color primaryColor = Color.fromRGBO(51, 122, 183, 1);
|
||||||
|
|
||||||
const Color halykColor = Color.fromRGBO(0, 118, 59, 1);
|
const Color halykColor = Color.fromRGBO(0, 118, 59, 1);
|
||||||
|
const Color forteColor = Color.fromRGBO(175, 32, 92, 1.0);
|
||||||
|
|
||||||
|
|
||||||
const Color menuColor = Color.fromRGBO(0, 75, 120, 1);
|
const Color menuColor = Color.fromRGBO(0, 75, 120, 1);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/BankService.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/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
||||||
|
|
@ -24,6 +26,7 @@ class _BankSettingViewState extends State<BankSettingView> {
|
||||||
TextEditingController _passwordController;
|
TextEditingController _passwordController;
|
||||||
final BankService _bankService = locator<BankService>();
|
final BankService _bankService = locator<BankService>();
|
||||||
final DialogService _dialogService = locator<DialogService>();
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
String _sessionType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -32,6 +35,7 @@ class _BankSettingViewState extends State<BankSettingView> {
|
||||||
_emailController = new TextEditingController(text: state.login);
|
_emailController = new TextEditingController(text: state.login);
|
||||||
_passwordController = new TextEditingController(text: state.password);
|
_passwordController = new TextEditingController(text: state.password);
|
||||||
//permissions();
|
//permissions();
|
||||||
|
_sessionType = 'Halyk';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<void> permissions() async {
|
// Future<void> permissions() async {
|
||||||
|
|
@ -52,7 +56,11 @@ class _BankSettingViewState extends State<BankSettingView> {
|
||||||
|
|
||||||
void _saveData(BuildContext _context) async {
|
void _saveData(BuildContext _context) async {
|
||||||
FocusScope.of(_context).unfocus();
|
FocusScope.of(_context).unfocus();
|
||||||
await Redux.store.dispatch(saveData(_emailController.text, _passwordController.text));
|
await Redux.store.dispatch(saveData(
|
||||||
|
_emailController.text,
|
||||||
|
_passwordController.text,
|
||||||
|
sessionType: _sessionType,
|
||||||
|
));
|
||||||
_dialogService.showDialog(description: 'Данные сохранены');
|
_dialogService.showDialog(description: 'Данные сохранены');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,6 +68,26 @@ class _BankSettingViewState extends State<BankSettingView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final BankState state = Redux.store.state.bankState;
|
||||||
|
|
||||||
|
// Проверяем, активна ли Forte-сессия
|
||||||
|
if (!(state.login == null || state.login.isEmpty) ||
|
||||||
|
!(state.password == null || state.password.isEmpty)) {
|
||||||
|
if (state.sessionType != 'Halyk') {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text('Настройка HalykPos'),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Text(
|
||||||
|
'У вас подключен терминал Forte',
|
||||||
|
style: TextStyle(fontSize: 16.0, color: Colors.grey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
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/forte/forte_post_session.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.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/redux/actions/bank_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/bank_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:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class ForteSettingView extends StatefulWidget {
|
||||||
|
ForteSettingView();
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ForteSettingViewState createState() => _ForteSettingViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ForteSettingViewState extends State<ForteSettingView> {
|
||||||
|
TextEditingController _emailController;
|
||||||
|
TextEditingController _passwordController;
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
String _sessionType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
BankState state = Redux.store.state.bankState;
|
||||||
|
_emailController = new TextEditingController(text: state.login);
|
||||||
|
_passwordController = new TextEditingController(text: state.password);
|
||||||
|
//permissions();
|
||||||
|
_sessionType = 'Forte';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<void> permissions() async {
|
||||||
|
// try {
|
||||||
|
// await _bankService.permissions();
|
||||||
|
// } on PlatformException {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_emailController.dispose();
|
||||||
|
_passwordController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveData(BuildContext _context) async {
|
||||||
|
FocusScope.of(_context).unfocus();
|
||||||
|
await Redux.store.dispatch(saveData(
|
||||||
|
_emailController.text,
|
||||||
|
_passwordController.text,
|
||||||
|
sessionType: _sessionType,
|
||||||
|
));
|
||||||
|
_dialogService.showDialog(description: 'Данные сохранены');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Получаем состояние
|
||||||
|
final BankState state = Redux.store.state.bankState;
|
||||||
|
|
||||||
|
// Проверяем, активна ли Forte-сессия
|
||||||
|
if (!(state.login == null || state.login.isEmpty) ||
|
||||||
|
!(state.password == null || state.password.isEmpty)) {
|
||||||
|
if (state.sessionType != 'Forte') {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text('Настройка FortePos'),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Text(
|
||||||
|
'У вас подключен терминал Halyk',
|
||||||
|
style: TextStyle(fontSize: 16.0, color: Colors.grey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если сессия Forte, отображаем данные
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text('Настройка FortePos'),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 14.0),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
verticalSpaceTiny,
|
||||||
|
Text(
|
||||||
|
'Необходимо указать почту и пароль для подключения к системе проведения платежей',
|
||||||
|
style: TextStyle(fontSize: 15.0),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
verticalSpaceTiny,
|
||||||
|
TextField(
|
||||||
|
controller: _emailController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'E-Mail', hintText: "Введите адрес почты"),
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
controller: _passwordController,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Пароль', hintText: "Введите пароль"),
|
||||||
|
),
|
||||||
|
verticalSpaceMedium,
|
||||||
|
RaisedButton(
|
||||||
|
onPressed: () => this._saveData(context),
|
||||||
|
child: Text(
|
||||||
|
'Cохранить',
|
||||||
|
style: TextStyle(color: whiteColor, fontSize: 25.0),
|
||||||
|
),
|
||||||
|
color: primaryColor,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,10 +16,12 @@ 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/setting_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/user_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/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/forte_pos_service.dart';
|
||||||
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.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/views/payment/halyk_pos_service.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
|
||||||
|
|
@ -191,7 +193,6 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//print(widget.data.cardData.transactionType);
|
|
||||||
if (showFab) {
|
if (showFab) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
|
@ -205,18 +206,30 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
color: whiteColor,
|
color: whiteColor,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var today = new DateTime.now();
|
var today = DateTime.now();
|
||||||
var yesterday = today.subtract(new Duration(days: 1));
|
var yesterday = today.subtract(Duration(days: 1));
|
||||||
if( Redux.store.state.userState == null
|
|
||||||
|| Redux.store.state.userState.smena == null
|
if (Redux.store.state.userState == null ||
|
||||||
|| Redux.store.state.userState.smena.startedAt == null
|
Redux.store.state.userState.smena == null ||
|
||||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
Redux.store.state.userState.smena.startedAt == null ||
|
||||||
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||||
|
_dialog.showDialog(
|
||||||
|
description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.',
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
AmanDao<CardData> response = await reversalHalykPos(widget.data.cardData, widget.data.voucher.total);
|
|
||||||
|
// Определяем метод отмены в зависимости от типа сессии
|
||||||
|
final BankState state = Redux.store.state.bankState;
|
||||||
|
final isForteSessionActive = state.sessionType == 'Forte';
|
||||||
|
|
||||||
|
final AmanDao<CardData> response = isForteSessionActive
|
||||||
|
? await reversalFortePos(widget.data.cardData, widget.data.voucher.total)
|
||||||
|
: await reversalHalykPos(widget.data.cardData, widget.data.voucher.total);
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
pressRefund();
|
pressRefund();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -225,17 +238,14 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
} finally {
|
} finally {
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
_navigatorService.replace(HomeViewRoute);
|
_navigatorService.replace(HomeViewRoute);
|
||||||
},
|
},
|
||||||
heroTag: null,
|
heroTag: null,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
SizedBox(
|
SizedBox(height: 0),
|
||||||
height: 0,
|
SizedBox(height: 10),
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
|
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
backgroundColor: redColor,
|
backgroundColor: redColor,
|
||||||
|
|
@ -245,19 +255,29 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
color: whiteColor,
|
color: whiteColor,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var today = new DateTime.now();
|
var today = DateTime.now();
|
||||||
var yesterday = today.subtract(new Duration(days: 1));
|
var yesterday = today.subtract(Duration(days: 1));
|
||||||
if( Redux.store.state.userState == null
|
|
||||||
|| Redux.store.state.userState.smena == null
|
if (Redux.store.state.userState == null ||
|
||||||
|| Redux.store.state.userState.smena.startedAt == null
|
Redux.store.state.userState.smena == null ||
|
||||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
Redux.store.state.userState.smena.startedAt == null ||
|
||||||
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||||
|
_dialog.showDialog(
|
||||||
|
description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.',
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
|
|
||||||
|
final BankState state = Redux.store.state.bankState;
|
||||||
|
final isForteSessionActive = state.sessionType == 'Forte';
|
||||||
|
|
||||||
|
final AmanDao<CardData> response = isForteSessionActive
|
||||||
|
? await refundFortePos(widget.data.cardData, widget.data.voucher.total)
|
||||||
|
: await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
pressRefund();
|
pressRefund();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -270,51 +290,52 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
heroTag: null,
|
heroTag: null,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
SizedBox(
|
SizedBox(height: 0),
|
||||||
height: 0,
|
SizedBox(height: 10),
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
child: Icon(Icons.share),
|
child: Icon(Icons.share),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
var bottomSheetController = showBottomSheet(
|
var bottomSheetController = showBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (bottomSheetContext) => Container(
|
builder: (bottomSheetContext) => Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||||
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
|
boxShadow: [
|
||||||
height: 260,
|
BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)
|
||||||
child: Column(
|
],
|
||||||
children: <Widget>[
|
),
|
||||||
verticalSpaceSmall,
|
height: 260,
|
||||||
BusyButtonIcon(
|
child: Column(
|
||||||
title: 'WhatsApp',
|
children: <Widget>[
|
||||||
onPressed: callWhatsApp,
|
verticalSpaceSmall,
|
||||||
mainColor: greenColor,
|
BusyButtonIcon(
|
||||||
icon: MdiIcons.whatsapp,
|
title: 'WhatsApp',
|
||||||
enabled: widget.data.url != null,
|
onPressed: callWhatsApp,
|
||||||
),
|
mainColor: greenColor,
|
||||||
verticalSpaceSmall,
|
icon: MdiIcons.whatsapp,
|
||||||
BusyButtonIcon(
|
enabled: widget.data.url != null,
|
||||||
title: 'QR-код чека',
|
),
|
||||||
onPressed: qrGenerate,
|
verticalSpaceSmall,
|
||||||
mainColor: primaryColor,
|
BusyButtonIcon(
|
||||||
icon: MdiIcons.qrcode,
|
title: 'QR-код чека',
|
||||||
enabled: widget.data.url != null,
|
onPressed: qrGenerate,
|
||||||
),
|
mainColor: primaryColor,
|
||||||
verticalSpaceSmall,
|
icon: MdiIcons.qrcode,
|
||||||
BusyButtonIcon(
|
enabled: widget.data.url != null,
|
||||||
title: 'Поделиться',
|
),
|
||||||
onPressed: shareFile,
|
verticalSpaceSmall,
|
||||||
mainColor: yellowColor,
|
BusyButtonIcon(
|
||||||
icon: Icons.share,
|
title: 'Поделиться',
|
||||||
),
|
onPressed: shareFile,
|
||||||
],
|
mainColor: yellowColor,
|
||||||
)));
|
icon: Icons.share,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
showFloatingActionButton(false);
|
showFloatingActionButton(false);
|
||||||
bottomSheetController.closed.then((value) {
|
bottomSheetController.closed.then((value) {
|
||||||
showFloatingActionButton(true);
|
showFloatingActionButton(true);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/card_data.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/check_data.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart';
|
||||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ class _PopupMenuState extends State<PopupMenu> {
|
||||||
// const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
|
// const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
|
||||||
if (version >= _bankService.sdkVersion )
|
if (version >= _bankService.sdkVersion )
|
||||||
const Choice(title: 'Настройка HalykPos', icon: Icons.phonelink_lock_outlined, command: 'tap2phone'),
|
const Choice(title: 'Настройка HalykPos', icon: Icons.phonelink_lock_outlined, command: 'tap2phone'),
|
||||||
|
const Choice(title: 'Настройка FortePos', icon: Icons.phonelink_lock_outlined, command: 'fortepos'),
|
||||||
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
||||||
const Choice(title: 'Принтер', icon: Icons.print, command: 'print'),
|
const Choice(title: 'Принтер', icon: Icons.print, command: 'print'),
|
||||||
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
||||||
_navigatorService.push(BankViewRoute);
|
_navigatorService.push(BankViewRoute);
|
||||||
} else if (choice.command == 'tap2phone') {
|
} else if (choice.command == 'tap2phone') {
|
||||||
_navigatorService.push(BankSettingViewRoute);
|
_navigatorService.push(BankSettingViewRoute);
|
||||||
|
} else if (choice.command == 'fortepos') {
|
||||||
|
_navigatorService.push(ForteSettingViewRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'dart:convert';
|
||||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/money.dart';
|
import 'package:aman_kassa_flutter/core/models/money.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||||
|
|
@ -13,21 +13,24 @@ import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/BankService.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/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ForteService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_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/setting_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/forte_pos_service.dart' as forte;
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart' as halyk;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
@ -45,7 +48,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
ApiService _api = locator<ApiService>();
|
ApiService _api = locator<ApiService>();
|
||||||
NavigatorService _navigator = locator<NavigatorService>();
|
NavigatorService _navigator = locator<NavigatorService>();
|
||||||
DialogService _dialog = locator<DialogService>();
|
DialogService _dialog = locator<DialogService>();
|
||||||
final BankService _bankService = locator<BankService>();
|
dynamic _bankService;
|
||||||
DataService _dataService = locator<DataService>();
|
DataService _dataService = locator<DataService>();
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
|
|
||||||
|
|
@ -222,13 +225,22 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _closeDay() async {
|
void _closeDay() async {
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
isClosePosBusy = true;
|
isClosePosBusy = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BankState state = Redux.store.state.bankState;
|
||||||
|
|
||||||
|
print(state.toJson());
|
||||||
|
|
||||||
|
if (state.sessionType == 'Halyk' && state.session != null) {
|
||||||
|
_bankService = locator<BankService>();
|
||||||
|
} else if (state.sessionType == 'Forte' && state.session != null) {
|
||||||
|
_bankService = locator<ForteService>();
|
||||||
|
}
|
||||||
|
|
||||||
int version = await _bankService.version();
|
int version = await _bankService.version();
|
||||||
if (version < _bankService.sdkVersion ) {
|
if (version < _bankService.sdkVersion) {
|
||||||
setState(() {
|
setState(() {
|
||||||
isClosePosBusy = false;
|
isClosePosBusy = false;
|
||||||
});
|
});
|
||||||
|
|
@ -236,10 +248,22 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final isForteSessionActive = state.sessionType == 'Forte';
|
||||||
|
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
HalykCloseDayDao closeDayDao = await closeDayHalykPos();
|
|
||||||
|
dynamic closeDayDao;
|
||||||
|
if (isForteSessionActive) {
|
||||||
|
closeDayDao = await forte.closeDayFortePos();
|
||||||
|
} else {
|
||||||
|
closeDayDao = await halyk.closeDayHalykPos();
|
||||||
|
}
|
||||||
|
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
log.i(closeDayDao.toJson());
|
|
||||||
|
forte.log.i(closeDayDao.toJson());
|
||||||
|
halyk.log.i(closeDayDao.toJson());
|
||||||
|
|
||||||
if (closeDayDao.result.code != 0) {
|
if (closeDayDao.result.code != 0) {
|
||||||
if (closeDayDao.result.description != null) {
|
if (closeDayDao.result.description != null) {
|
||||||
_dialog.showDialog(description: closeDayDao.result.description);
|
_dialog.showDialog(description: closeDayDao.result.description);
|
||||||
|
|
@ -250,24 +274,22 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.transactions);
|
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.transactions);
|
||||||
|
|
||||||
User user = Redux.store.state.userState.user;
|
User user = Redux.store.state.userState.user;
|
||||||
_dataService.insertVoucher(
|
_dataService.insertVoucher(
|
||||||
user: user,
|
user: user,
|
||||||
name: closeDayData.title,
|
name: closeDayData.title,
|
||||||
data: jsonEncode(closeDayData.toJson()),
|
data: jsonEncode(closeDayData.toJson()),
|
||||||
total: closeDayData.totalAmount.toDouble(),
|
total: closeDayData.totalAmount.toDouble(),
|
||||||
type: VoucherTypeCloseDayPosReport);
|
type: VoucherTypeCloseDayPosReport,
|
||||||
|
);
|
||||||
|
|
||||||
// _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!');
|
|
||||||
setState(() {
|
setState(() {
|
||||||
isClosePosBusy = false;
|
isClosePosBusy = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
_navigator.push(CloseDayShowRoute,
|
_navigator.push(CloseDayShowRoute, arguments: closeDayData);
|
||||||
arguments: closeDayData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.
|
||||||
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart';
|
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart';
|
||||||
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
||||||
import 'package:barcode_scan/gen/protos/protos.pb.dart';
|
// import 'package:barcode_scan/gen/protos/protos.pb.dart';
|
||||||
import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
|
// import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
|
||||||
import 'package:barcode_scan/model/scan_options.dart';
|
// import 'package:barcode_scan/model/scan_options.dart';
|
||||||
import 'package:barcode_scan/platform_wrapper.dart';
|
// import 'package:barcode_scan/platform_wrapper.dart';
|
||||||
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
@ -185,61 +186,58 @@ class KassaTab extends StatelessWidget {
|
||||||
Future<void> scan() async {
|
Future<void> scan() async {
|
||||||
try {
|
try {
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
var options = ScanOptions(strings: {
|
var options = ScanOptions(
|
||||||
"cancel": 'Отмена',
|
strings: {
|
||||||
"flash_on": 'Вкл фонарик',
|
"cancel": 'Отмена',
|
||||||
"flash_off": 'Выкл фонарик',
|
"flash_on": 'Вкл фонарик',
|
||||||
});
|
"flash_off": 'Выкл фонарик',
|
||||||
|
},
|
||||||
|
);
|
||||||
var result = await BarcodeScanner.scan(options: options);
|
var result = await BarcodeScanner.scan(options: options);
|
||||||
// print(result.type); // The result type (barcode, cancelled, failed)
|
|
||||||
// print(result.rawContent); // The barcode content
|
if (result.type == ResultType.Barcode) {
|
||||||
// print(result.format); // The barcode format (as enum)
|
|
||||||
// print(result.formatNote); // If a unknown format was scanned this field contains a note
|
|
||||||
// print(result.rawContent); // content
|
|
||||||
if (result.type == ResultType.Barcode ) {
|
|
||||||
String barcode;
|
String barcode;
|
||||||
String dataMatrix;
|
String dataMatrix;
|
||||||
if(result.format == BarcodeFormat.ean13 || result.format == BarcodeFormat.ean8) {
|
|
||||||
|
if (result.format == BarcodeFormat.ean13 || result.format == BarcodeFormat.ean8) {
|
||||||
barcode = result.rawContent;
|
barcode = result.rawContent;
|
||||||
} else if( result.format == BarcodeFormat.dataMatrix ) {
|
} else if (result.format == BarcodeFormat.dataMatrix) {
|
||||||
dataMatrix = result.rawContent;
|
dataMatrix = result.rawContent;
|
||||||
if(dataMatrix!= null && dataMatrix.length >15) {
|
if (dataMatrix != null && dataMatrix.length > 15) {
|
||||||
try {
|
try {
|
||||||
String numberText = dataMatrix.substring(0, dataMatrix.length - 15 ).replaceAll(RegExp("[a-zA-Z]"), '');
|
String numberText = dataMatrix
|
||||||
|
.substring(0, dataMatrix.length - 15)
|
||||||
|
.replaceAll(RegExp("[a-zA-Z]"), '');
|
||||||
barcode = int.parse(numberText).toString();
|
barcode = int.parse(numberText).toString();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// Обработка ошибки, если необходимо
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 00000046208262 nZ2qnLH ODVFWktT
|
|
||||||
// 00000046208262 tjKDqfu UzVSeFE5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(barcode != null) {
|
if (barcode != null) {
|
||||||
List<Good> goods =
|
List<Good> goods = await _dataService.getGoodsByBarcode(barcode: barcode);
|
||||||
await _dataService.getGoodsByBarcode(barcode: barcode);
|
|
||||||
if (goods != null && goods.isNotEmpty) {
|
if (goods != null && goods.isNotEmpty) {
|
||||||
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
||||||
} else {
|
} else {
|
||||||
_dialogService.showDialog(
|
_dialogService.showDialog(description: 'Товар не найден: $barcode');
|
||||||
description: 'Товар не найден: $barcode');
|
|
||||||
}
|
}
|
||||||
} else if (result.type == ResultType.Error) {
|
} else {
|
||||||
_dialogService.showDialog(description: 'Не верный формат QR кода');
|
_dialogService.showDialog(description: 'Не удалось распознать штрих-код');
|
||||||
}
|
}
|
||||||
}
|
} else if (result.type == ResultType.Cancelled) {
|
||||||
} on PlatformException catch (e) {
|
// Пользователь отменил сканирование
|
||||||
var result = ScanResult.create();
|
} else if (result.type == ResultType.Error) {
|
||||||
result.type = ResultType.Error;
|
_dialogService.showDialog(description: 'Ошибка сканирования: ${result.rawContent}');
|
||||||
result.format = BarcodeFormat.unknown;
|
|
||||||
if (e.code == BarcodeScanner.cameraAccessDenied) {
|
|
||||||
result.rawContent = 'The user did not grant the camera permission!';
|
|
||||||
_dialogService.showDialog(
|
|
||||||
description: 'Нет доступа до камеры устройства');
|
|
||||||
} else {
|
|
||||||
result.rawContent = 'Unknown error: $e';
|
|
||||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
|
||||||
}
|
}
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
if (e.code == BarcodeScanner.cameraAccessDenied) {
|
||||||
|
_dialogService.showDialog(description: 'Нет доступа к камере устройства');
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(description: 'Ошибка сканирования: ${e.message}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||||
} finally {
|
} finally {
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
|
||||||
import 'package:barcode_scan/gen/protos/protos.pb.dart';
|
// import 'package:barcode_scan/gen/protos/protos.pb.dart';
|
||||||
import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
|
// import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
|
||||||
import 'package:barcode_scan/model/scan_options.dart';
|
// import 'package:barcode_scan/model/scan_options.dart';
|
||||||
import 'package:barcode_scan/platform_wrapper.dart';
|
// import 'package:barcode_scan/platform_wrapper.dart';
|
||||||
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -161,40 +162,35 @@ class _LoginViewState extends State<LoginView> {
|
||||||
|
|
||||||
Future<void> scan() async {
|
Future<void> scan() async {
|
||||||
try {
|
try {
|
||||||
var options = ScanOptions(strings: {
|
var options = ScanOptions(
|
||||||
"cancel": 'Отмена',
|
strings: {
|
||||||
"flash_on": 'Вкл фонарик',
|
"cancel": 'Отмена',
|
||||||
"flash_off": 'Выкл фонарик',
|
"flash_on": 'Вкл фонарик',
|
||||||
});
|
"flash_off": 'Выкл фонарик',
|
||||||
|
},
|
||||||
|
);
|
||||||
var result = await BarcodeScanner.scan(options: options);
|
var result = await BarcodeScanner.scan(options: options);
|
||||||
// print(result.type); // The result type (barcode, cancelled, failed)
|
|
||||||
// print(result.rawContent); // The barcode content
|
if (result.type == ResultType.Barcode && result.rawContent?.length == 60) {
|
||||||
// print(result.format); // The barcode format (as enum)
|
|
||||||
// print(result
|
|
||||||
// .formatNote); // If a unknown format was scanned this field contains a note
|
|
||||||
if (result.type == ResultType.Barcode &&
|
|
||||||
result.rawContent?.length == 60) {
|
|
||||||
if (result.rawContent.toLowerCase().trim().startsWith('test')) {
|
if (result.rawContent.toLowerCase().trim().startsWith('test')) {
|
||||||
_apiService.test = true;
|
_apiService.test = true;
|
||||||
} else {
|
} else {
|
||||||
_apiService.test = false;
|
_apiService.test = false;
|
||||||
}
|
}
|
||||||
Redux.store.dispatch(authenticateToken(result.rawContent));
|
Redux.store.dispatch(authenticateToken(result.rawContent));
|
||||||
|
} else if (result.type == ResultType.Cancelled) {
|
||||||
|
// Пользователь отменил сканирование
|
||||||
} else if (result.type == ResultType.Error) {
|
} else if (result.type == ResultType.Error) {
|
||||||
_dialogService.showDialog(description: 'Не верный формат QR кода');
|
_dialogService.showDialog(description: 'Ошибка сканирования: ${result.rawContent}');
|
||||||
}
|
}
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
var result = ScanResult.create();
|
|
||||||
result.type = ResultType.Error;
|
|
||||||
result.format = BarcodeFormat.unknown;
|
|
||||||
if (e.code == BarcodeScanner.cameraAccessDenied) {
|
if (e.code == BarcodeScanner.cameraAccessDenied) {
|
||||||
result.rawContent = 'The user did not grant the camera permission!';
|
_dialogService.showDialog(description: 'Нет доступа к камере устройства');
|
||||||
_dialogService.showDialog(
|
|
||||||
description: 'Нет доступа до камеры устройства');
|
|
||||||
} else {
|
} else {
|
||||||
result.rawContent = 'Unknown error: $e';
|
_dialogService.showDialog(description: 'Ошибка сканирования: ${e.message}');
|
||||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_close_day_dao.dart'
|
||||||
|
as Cd;
|
||||||
|
import 'package:aman_kassa_flutter/core/models/forte/forte_response_dao.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/store.dart';
|
||||||
|
import 'package:logger/logger.dart';
|
||||||
|
import '../../core/models/aman_dao.dart';
|
||||||
|
import '../../core/models/card_data.dart';
|
||||||
|
import '../../core/models/forte/forte_post_session.dart';
|
||||||
|
import '../../core/services/ForteService.dart';
|
||||||
|
import '../../redux/state/bank_state.dart';
|
||||||
|
|
||||||
|
ForteService _bankService = locator<ForteService>();
|
||||||
|
DialogService _dialogService = locator<DialogService>();
|
||||||
|
final DataService _dataService = locator<DataService>();
|
||||||
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
Logger log = getLogger('PaymentNfcView');
|
||||||
|
|
||||||
|
Future<AmanDao<CardData>> paymentFortePos(double total) async {
|
||||||
|
//Авторизация
|
||||||
|
String token = Redux.store.state.userState.user.token;
|
||||||
|
BankState bankState = Redux.store.state.bankState;
|
||||||
|
//права доступа
|
||||||
|
FortePosSession session = await _bankService.renewToken(
|
||||||
|
token: token, login: bankState.login, password: bankState.password);
|
||||||
|
if (session.token == null) {
|
||||||
|
return sessionDeclineDao(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Инициализация
|
||||||
|
ForteResponse response =
|
||||||
|
await _bankService.pay(token: session.token, amount: total);
|
||||||
|
if (response.result.code == 0) {
|
||||||
|
CardData cardData = new CardData(
|
||||||
|
authorizationCode:
|
||||||
|
response.transaction.instrumentSpecificData.authorizationCode,
|
||||||
|
cardholderName:
|
||||||
|
response.transaction.instrumentSpecificData.cardholderName,
|
||||||
|
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||||
|
operationDay: response.transaction.operationDay,
|
||||||
|
transactionNumber: response.transaction.transactionNumber,
|
||||||
|
terminalId: response.transaction.terminalId,
|
||||||
|
transactionType: 'payment');
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.description, success: true, data: cardData);
|
||||||
|
}
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.errorData != null
|
||||||
|
? response.result.errorData.description
|
||||||
|
: response.result.description,
|
||||||
|
success: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
AmanDao<CardData> sessionDeclineDao(FortePosSession session) {
|
||||||
|
String msg = 'Отказано в доступе к API банка';
|
||||||
|
if(session.result?.Response?.Description != null) {
|
||||||
|
msg = '${session.result.Response.Description} (${session.result.Response.Code}) ';
|
||||||
|
}
|
||||||
|
return AmanDao<CardData>(success: false, msg: msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<AmanDao<CardData>> refundFortePos(
|
||||||
|
CardData refundData, double total) async {
|
||||||
|
//Авторизация
|
||||||
|
String token = Redux.store.state.userState.user.token;
|
||||||
|
BankState bankState = Redux.store.state.bankState;
|
||||||
|
//права доступа
|
||||||
|
FortePosSession session = await _bankService.renewToken(
|
||||||
|
token: token, login: bankState.login, password: bankState.password);
|
||||||
|
if (session.token == null) {
|
||||||
|
return sessionDeclineDao(session);
|
||||||
|
}
|
||||||
|
ForteResponse response = await _bankService.refund(
|
||||||
|
token: session.token,
|
||||||
|
amount: total,
|
||||||
|
operDay: refundData.operationDay,
|
||||||
|
terminalId: refundData.terminalId,
|
||||||
|
transNum: refundData.transactionNumber);
|
||||||
|
if (response.result.code == 0) {
|
||||||
|
CardData cardData = new CardData(
|
||||||
|
authorizationCode:
|
||||||
|
response.transaction.instrumentSpecificData.authorizationCode,
|
||||||
|
cardholderName:
|
||||||
|
response.transaction.instrumentSpecificData.cardholderName,
|
||||||
|
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||||
|
operationDay: response.transaction.operationDay,
|
||||||
|
transactionNumber: response.transaction.transactionNumber,
|
||||||
|
terminalId: response.transaction.terminalId,
|
||||||
|
transactionType: 'refund');
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.description, success: true, data: cardData);
|
||||||
|
}
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.errorData != null
|
||||||
|
? response.result.errorData.description
|
||||||
|
: response.result.description,
|
||||||
|
success: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<AmanDao<CardData>> reversalFortePos(
|
||||||
|
CardData refundData, double total) async {
|
||||||
|
//Авторизация
|
||||||
|
String token = Redux.store.state.userState.user.token;
|
||||||
|
BankState bankState = Redux.store.state.bankState;
|
||||||
|
//права доступа
|
||||||
|
FortePosSession session = await _bankService.renewToken(
|
||||||
|
token: token, login: bankState.login, password: bankState.password);
|
||||||
|
if (session.token == null) {
|
||||||
|
return sessionDeclineDao(session);
|
||||||
|
}
|
||||||
|
log.i(refundData.toJson());
|
||||||
|
ForteResponse response = await _bankService.reversal(
|
||||||
|
token: session.token,
|
||||||
|
operDay: refundData.operationDay,
|
||||||
|
terminalId: refundData.terminalId,
|
||||||
|
transNum: refundData.transactionNumber);
|
||||||
|
if (response.result.code == 0) {
|
||||||
|
CardData cardData = new CardData(
|
||||||
|
authorizationCode:
|
||||||
|
response.transaction.instrumentSpecificData.authorizationCode,
|
||||||
|
cardholderName:
|
||||||
|
response.transaction.instrumentSpecificData.cardholderName,
|
||||||
|
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||||
|
operationDay: response.transaction.operationDay,
|
||||||
|
transactionNumber: response.transaction.transactionNumber,
|
||||||
|
terminalId: response.transaction.terminalId,
|
||||||
|
transactionType: 'reversal');
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.description, success: true, data: cardData);
|
||||||
|
}
|
||||||
|
return AmanDao<CardData>(
|
||||||
|
msg: response.result.errorData != null
|
||||||
|
? response.result.errorData.description
|
||||||
|
: response.result.description,
|
||||||
|
success: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Cd.ForteCloseDayDao> closeDayFortePos() async {
|
||||||
|
//Авторизация
|
||||||
|
String token = Redux.store.state.userState.user.token;
|
||||||
|
BankState bankState = Redux.store.state.bankState;
|
||||||
|
//права доступа
|
||||||
|
FortePosSession session = await _bankService.renewToken(
|
||||||
|
token: token, login: bankState.login, password: bankState.password);
|
||||||
|
if (session.token == null) {
|
||||||
|
return new Cd.ForteCloseDayDao(
|
||||||
|
result: Cd.ResultBean(
|
||||||
|
description: 'Отказано в доступе к API банка', code: -1));
|
||||||
|
}
|
||||||
|
//Инициализация
|
||||||
|
Cd.ForteCloseDayDao response =
|
||||||
|
await _bankService.closeDay(token: session.token);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/BankService.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/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ForteService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
||||||
|
|
@ -36,6 +37,7 @@ import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
||||||
import '../../core/models/aman_dao.dart';
|
import '../../core/models/aman_dao.dart';
|
||||||
import '../../core/models/card_data.dart';
|
import '../../core/models/card_data.dart';
|
||||||
import '../../core/models/card_data.dart';
|
import '../../core/models/card_data.dart';
|
||||||
|
import 'forte_pos_service.dart';
|
||||||
|
|
||||||
class PaymentView extends StatefulWidget {
|
class PaymentView extends StatefulWidget {
|
||||||
final PaymentModel model;
|
final PaymentModel model;
|
||||||
|
|
@ -50,7 +52,7 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
final DataService _dataService = locator<DataService>();
|
final DataService _dataService = locator<DataService>();
|
||||||
final DialogService _dialogService = locator<DialogService>();
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
BankService _bankService = locator<BankService>();
|
dynamic _bankService;
|
||||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
bool isBusy;
|
bool isBusy;
|
||||||
bool isBankApiAccess;
|
bool isBankApiAccess;
|
||||||
|
|
@ -64,12 +66,25 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_bankInit() async {
|
_bankInit() async {
|
||||||
int version = await _bankService.version();
|
BankState state = Redux.store.state.bankState;
|
||||||
if (version >= _bankService.sdkVersion) {
|
|
||||||
|
print(state.toJson());
|
||||||
|
|
||||||
|
if (state.sessionType == 'Halyk' && state.session != null) {
|
||||||
|
_bankService = locator<BankService>();
|
||||||
|
} else if (state.sessionType == 'Forte' && state.session != null) {
|
||||||
|
_bankService = locator<ForteService>();
|
||||||
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
isBankApiAccess = true;
|
isBankApiAccess = false;
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int version = await _bankService.version();
|
||||||
|
setState(() {
|
||||||
|
isBankApiAccess = version >= _bankService.sdkVersion;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -200,93 +215,97 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return StoreConnector<AppState, AppState>(
|
return StoreConnector<AppState, AppState>(
|
||||||
converter: (store) => store.state,
|
converter: (store) => store.state,
|
||||||
builder: (_, _state) {
|
builder: (_, _state) {
|
||||||
BankState state = _state.bankState;
|
BankState state = _state.bankState;
|
||||||
double _total;
|
double _total;
|
||||||
if (widget.model.mode == SettingModeCalc) {
|
if (widget.model.mode == SettingModeCalc) {
|
||||||
String value = totalCalc(_state.calcState.calcItems);
|
String value = totalCalc(_state.calcState.calcItems);
|
||||||
_total = double.parse(value);
|
_total = double.parse(value);
|
||||||
} else {
|
} else {
|
||||||
String value = totalKassa(_state.kassaState.kassaItems);
|
String value = totalKassa(_state.kassaState.kassaItems);
|
||||||
_total = double.parse(value);
|
_total = double.parse(value);
|
||||||
}
|
|
||||||
|
|
||||||
if (state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1) {
|
|
||||||
return Container();
|
|
||||||
}
|
|
||||||
return InkWell(
|
|
||||||
onTap: () 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
|
||||||
AmanDao<CardData> data = await paymentHalykPos(_total);
|
|
||||||
if (data.success) {
|
|
||||||
pressPayment(widget.model.operationType, data.data);
|
|
||||||
} else {
|
|
||||||
_dialogService.showDialog(description: data.msg);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
await Redux.store.dispatch(changePinSkipFromSetting(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 ),),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((state.password == null || state.password.isEmpty) ||
|
||||||
|
(state.login == null || state.login.isEmpty)) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
final bool isForteSessionActive = state.sessionType == 'Forte';
|
||||||
|
|
||||||
|
final String imageAsset = isForteSessionActive
|
||||||
|
? 'assets/images/fortepos.png'
|
||||||
|
: 'assets/images/halykpos.png';
|
||||||
|
final Color sessionColor = isForteSessionActive ? forteColor : halykColor;
|
||||||
|
final Future<AmanDao<CardData>> Function(double) paymentMethod =
|
||||||
|
isForteSessionActive ? paymentFortePos : paymentHalykPos;
|
||||||
|
|
||||||
|
return InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
var today = DateTime.now();
|
||||||
|
var yesterday = today.subtract(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
|
AmanDao<CardData> data = await paymentMethod(_total);
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
pressPayment('card', data.data);
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(description: data.msg);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splashColor: sessionColor.withOpacity(0.4),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
highlightColor: sessionColor.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(imageAsset),
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.5),
|
||||||
|
spreadRadius: 5,
|
||||||
|
blurRadius: 7,
|
||||||
|
offset: Offset(0, 3), // Смещение тени
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
pubspec.lock
24
pubspec.lock
|
|
@ -21,7 +21,7 @@ packages:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.1"
|
version: "2.5.0"
|
||||||
auto_size_text:
|
auto_size_text:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -29,13 +29,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
barcode_scan:
|
barcode_scan2:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: barcode_scan
|
name: barcode_scan2
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "4.2.4"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -56,7 +56,7 @@ packages:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.2.0"
|
||||||
charset_converter:
|
charset_converter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -175,7 +175,7 @@ packages:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.11"
|
version: "1.0.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -344,7 +344,7 @@ packages:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.3.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -449,7 +449,7 @@ packages:
|
||||||
name: protobuf
|
name: protobuf
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.4"
|
version: "2.0.1"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -566,7 +566,7 @@ packages:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.0"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -622,7 +622,7 @@ packages:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.2"
|
version: "0.2.19"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -685,7 +685,7 @@ packages:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.0.5"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -701,5 +701,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.1"
|
version: "4.5.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.13.0 <3.0.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.22.2"
|
flutter: ">=1.22.2"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ name: aman_kassa_flutter
|
||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
version: 1.2.3+36
|
version: 1.2.3+36
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.3.0 <3.0.0'
|
sdk: '>=2.3.0 <4.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
@ -23,7 +23,8 @@ dependencies:
|
||||||
google_fonts: ^1.1.1
|
google_fonts: ^1.1.1
|
||||||
material_design_icons_flutter: ^4.0.5855
|
material_design_icons_flutter: ^4.0.5855
|
||||||
intl: ^0.16.1
|
intl: ^0.16.1
|
||||||
barcode_scan: ^3.0.1
|
# barcode_scan: ^3.0.1
|
||||||
|
barcode_scan2: ^4.0.0
|
||||||
device_info: ^1.0.0
|
device_info: ^1.0.0
|
||||||
esys_flutter_share: ^1.0.2
|
esys_flutter_share: ^1.0.2
|
||||||
auto_size_text: ^2.1.0
|
auto_size_text: ^2.1.0
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue