forte #1

Open
nitrobon wants to merge 3 commits from forte into master
37 changed files with 1479 additions and 305 deletions

View File

@ -47,7 +47,7 @@ android {
defaultConfig {
applicationId "kz.com.aman.kassa"
minSdkVersion 21
targetSdkVersion 30
targetSdkVersion 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true

View File

@ -30,7 +30,8 @@
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:exported="true">
<!--
<meta-data

View File

@ -66,10 +66,16 @@ class MainActivity : FlutterActivity() {
val token = call.argument<String>("token").toString()
var amount: Long = 0
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)
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()))
startOperation(
OperationType.PAYMENT,
JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()),
packageName
)
}
private fun operationRefund(call: MethodCall) {
@ -78,8 +84,15 @@ class MainActivity : FlutterActivity() {
val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString()
val amount = call.argument<String>("amount").toString()
val packageName = call.argument<String>("packageName").toString()
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) {
@ -87,16 +100,27 @@ class MainActivity : FlutterActivity() {
val terminalId = call.argument<String>("terminalId").toString()
val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString()
val packageName = call.argument<String>("packageName").toString()
val operationParameters = createOperationParameters(token)
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum);
println(body)
startOperation(OperationType.REVERSAL, body)
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)
startOperation(
OperationType.REVERSAL,
body,
packageName
)
}
private fun operationCloseDay(call: MethodCall) {
val token = call.argument<String>("token").toString()
val packageName = call.argument<String>("packageName").toString()
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)
}
private fun startOperation(operationType: OperationType, inputJsonData: String?) {
private fun startOperation(
operationType: OperationType,
inputJsonData: String?,
packageName: String
) {
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_SINGLE_TOP
intent.putExtra(externalOperationTypeKey, operationType.code)
intent.putExtra(externalInputDataKey, inputJsonData)
startActivityForResult(intent, externalApplicationRequestCode)

View File

@ -37,7 +37,7 @@ object JsonForExternalCall {
"instrument": "CARD",
"amountData" : {
"currencyCode": "348",
"amount": "6000",
"amount": "$amount",
"amountExponent": "2"
},
"parentTransaction" : {

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.61'
ext.kotlin_version = '1.5.21'
repositories {
google()
jcenter()
@ -18,6 +18,7 @@ allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
configurations.all {

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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

BIN
assets/images/fortepos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -1,6 +1,7 @@
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 '../core/services/DbService.dart';
@ -35,5 +36,7 @@ class LocatorInjector {
locator.registerLazySingleton<DataService>(() => DataService());
_log.d('Initializing BankService Service');
locator.registerLazySingleton<BankService>(() => BankService());
_log.d('Initializing Forte Service');
locator.registerLazySingleton<ForteService>(() => ForteService());
}
}

View File

@ -1,7 +1,7 @@
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 {
final String title;

View File

@ -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,
};
}

View File

@ -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,
};
}

View File

@ -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,
};
}

View File

@ -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(),
};
}

View File

@ -22,6 +22,16 @@ class HalykPosSession {
? 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"

View File

@ -10,6 +10,7 @@ const String SettingsViewRoute = "SettingsViewRoute";
const String QrViewRoute = "QrViewRoute";
const String BankViewRoute = "BankViewRoute";
const String BankSettingViewRoute = "BankSettingViewRoute";
const String ForteSettingViewRoute = "ForteSettingViewRoute";
const String SettingsPrinterRoute = "SettingsPrinterRoute";

View File

@ -1,5 +1,6 @@
import 'package:aman_kassa_flutter/views/bank_setting/forte_setting_view.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_view/bank_view.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
@ -71,6 +72,11 @@ Route<dynamic> generateRoute(RouteSettings settings) {
routeName: settings.name,
viewToShow: BankSettingView(),
);
case ForteSettingViewRoute:
return _getPageRoute(
routeName: settings.name,
viewToShow: ForteSettingView(),
);
case QrViewRoute:
ImageShowModel data = settings.arguments as ImageShowModel;
return _getPageRoute(

View File

@ -3,6 +3,7 @@ import 'dart:io';
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/forte/forte_post_session.dart';
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/views/login/login_view.dart';
@ -79,6 +80,18 @@ class ApiService extends BaseService {
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 {
Map<String, String> requestBody = <String, String>{'api_token': token};
var response = await requestFormData('/money', requestBody);

View File

@ -1,7 +1,7 @@
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/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_post_session.dart' as Ps;
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 {
int sdkVersion = 27;
String packageName = 'ru.m4bank.softpos.halyk';
final ApiService _api = locator<ApiService>();
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
@ -45,7 +46,10 @@ class BankService extends BaseService {
Future<Cd.HalykCloseDayDao> closeDay({ String token}) async {
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);
Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response));
return dao;
@ -60,7 +64,11 @@ class BankService extends BaseService {
double total = amount * 100;
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);
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
return dao;
@ -73,7 +81,12 @@ class BankService extends BaseService {
Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
try {
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));
return dao;
@ -86,7 +99,11 @@ class BankService extends BaseService {
Future<HalykResponse> 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
'token': token,
'terminalId': terminalId,
'operDay': operDay,
'transNum': transNum,
'packageName': packageName
});
log.i(response);
HalykResponse dao = HalykResponse.fromMap(json.decode(response));

View File

@ -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;
}
}

View File

@ -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/redux/state/bank_state.dart';
import 'package:meta/meta.dart';
@ -12,15 +13,50 @@ class SetBankStateAction {
final BankState bankState;
SetBankStateAction(this.bankState);
}
ThunkAction<AppState> saveData(String login, String password) {
ThunkAction<AppState> saveData(String login, String password, {String sessionType}) {
return (Store<AppState> store) async {
store.dispatch(SetBankStateAction(BankState(login: login, password: password)));
};
final currentState = store.state.bankState;
dynamic session;
if (sessionType == 'Halyk') {
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,
);
}
ThunkAction<AppState> setHalykSession(HalykPosSession session) {
return (Store<AppState> store) async {
store.dispatch(SetBankStateAction(BankState(session: session)));
store.dispatch(SetBankStateAction(BankState(
login: login,
password: password,
session: session,
sessionType: sessionType,
)));
};
}

View File

@ -1,7 +1,13 @@
import 'package:aman_kassa_flutter/redux/actions/bank_actions.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;
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,
);
}

View File

@ -1,5 +1,6 @@
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:meta/meta.dart';
@ -7,42 +8,72 @@ import 'package:meta/meta.dart';
class BankState {
final String login;
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) {
return BankState(
login: payload?.login,
password: payload?.password,
session: payload?.session
session: payload?.session,
sessionType: payload?.sessionType,
);
}
//write hive
BankState copyWith({
@required login,
@required password,
@required session,
String login,
String password,
dynamic session,
String sessionType,
}) {
return BankState(
login: login ?? this.login,
password: password ?? this.password,
session: session ?? this.session
session: session ?? this.session,
sessionType: sessionType ?? this.sessionType,
);
}
static BankState fromJson(dynamic json) {
return json != null
? BankState(
password: json['password'],
login: json['login'],
)
: null;
// Создание из JSON
static BankState fromJson(Map<String, dynamic> json) {
if (json == null) return null;
// Определяем тип сессии
dynamic session;
String sessionType = json['sessionType'];
if (sessionType == "Halyk") {
session = HalykPosSession.fromJson(json['session']);
} else if (sessionType == "Forte") {
session = FortePosSession.fromJson(json['session']);
}
dynamic toJson() {
return {"password": password, "login": login};
return BankState(
login: json['login'],
password: json['password'],
session: session,
sessionType: sessionType,
);
}
// Преобразование в JSON
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)';
}
}

View File

@ -5,6 +5,7 @@ const Color fillColor = Color.fromRGBO(248, 248, 248, 1);
const Color primaryColor = Color.fromRGBO(51, 122, 183, 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);

View File

@ -2,6 +2,8 @@ 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';
@ -24,6 +26,7 @@ class _BankSettingViewState extends State<BankSettingView> {
TextEditingController _passwordController;
final BankService _bankService = locator<BankService>();
final DialogService _dialogService = locator<DialogService>();
String _sessionType;
@override
void initState() {
@ -32,6 +35,7 @@ class _BankSettingViewState extends State<BankSettingView> {
_emailController = new TextEditingController(text: state.login);
_passwordController = new TextEditingController(text: state.password);
//permissions();
_sessionType = 'Halyk';
}
// Future<void> permissions() async {
@ -52,7 +56,11 @@ class _BankSettingViewState extends State<BankSettingView> {
void _saveData(BuildContext _context) async {
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: 'Данные сохранены');
}
@ -60,6 +68,26 @@ class _BankSettingViewState extends State<BankSettingView> {
@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 != '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(
appBar: AppBar(
centerTitle: true,

View File

@ -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),
),
],
),
),
),
);
}
}

View File

@ -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/user_actions.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/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/payment/forte_pos_service.dart';
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
@ -191,7 +193,6 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
@override
Widget build(BuildContext context) {
//print(widget.data.cardData.transactionType);
if (showFab) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
@ -205,18 +206,30 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
color: whiteColor,
),
onPressed: () async {
var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null
|| Redux.store.state.userState.smena == null
|| Redux.store.state.userState.smena.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
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)) {
_dialog.showDialog(
description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.',
);
return;
}
try {
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) {
pressRefund();
} else {
@ -225,17 +238,14 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
_navigatorService.replace(HomeViewRoute);
},
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox(
height: 10,
),
SizedBox(height: 0),
SizedBox(height: 10),
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
FloatingActionButton(
backgroundColor: redColor,
@ -245,19 +255,29 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
color: whiteColor,
),
onPressed: () async {
var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null
|| Redux.store.state.userState.smena == null
|| Redux.store.state.userState.smena.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
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)) {
_dialog.showDialog(
description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.',
);
return;
}
try {
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) {
pressRefund();
} else {
@ -270,12 +290,8 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox(
height: 10,
),
SizedBox(height: 0),
SizedBox(height: 10),
FloatingActionButton(
child: Icon(Icons.share),
onPressed: () {
@ -286,7 +302,10 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(15)),
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
boxShadow: [
BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)
],
),
height: 260,
child: Column(
children: <Widget>[
@ -314,7 +333,9 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
icon: Icons.share,
),
],
)));
),
),
);
showFloatingActionButton(false);
bottomSheetController.closed.then((value) {
showFloatingActionButton(true);

View File

@ -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/transaction_item.dart';
import 'package:aman_kassa_flutter/shared/shared_styles.dart';

View File

@ -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/card_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/services/DbService.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';

View File

@ -34,6 +34,7 @@ class _PopupMenuState extends State<PopupMenu> {
// const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
if (version >= _bankService.sdkVersion )
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.print, command: 'print'),
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')

View File

@ -159,6 +159,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
_navigatorService.push(BankViewRoute);
} else if (choice.command == 'tap2phone') {
_navigatorService.push(BankSettingViewRoute);
} else if (choice.command == 'fortepos') {
_navigatorService.push(ForteSettingViewRoute);
}
}

View File

@ -3,7 +3,7 @@ import 'dart:convert';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/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/money.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/BankService.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/navigator_service.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/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/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:aman_kassa_flutter/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_horizontal.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/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_redux/flutter_redux.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>();
NavigatorService _navigator = locator<NavigatorService>();
DialogService _dialog = locator<DialogService>();
final BankService _bankService = locator<BankService>();
dynamic _bankService;
DataService _dataService = locator<DataService>();
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
@ -222,11 +225,20 @@ class _AdditionalTabState extends State<AdditionalTab> {
}
void _closeDay() async {
setState(() {
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();
if (version < _bankService.sdkVersion) {
setState(() {
@ -236,10 +248,22 @@ class _AdditionalTabState extends State<AdditionalTab> {
return;
}
final isForteSessionActive = state.sessionType == 'Forte';
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));
log.i(closeDayDao.toJson());
forte.log.i(closeDayDao.toJson());
halyk.log.i(closeDayDao.toJson());
if (closeDayDao.result.code != 0) {
if (closeDayDao.result.description != null) {
_dialog.showDialog(description: closeDayDao.result.description);
@ -250,7 +274,6 @@ class _AdditionalTabState extends State<AdditionalTab> {
return;
}
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.transactions);
User user = Redux.store.state.userState.user;
@ -259,15 +282,14 @@ class _AdditionalTabState extends State<AdditionalTab> {
name: closeDayData.title,
data: jsonEncode(closeDayData.toJson()),
total: closeDayData.totalAmount.toDouble(),
type: VoucherTypeCloseDayPosReport);
type: VoucherTypeCloseDayPosReport,
);
// _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!');
setState(() {
isClosePosBusy = false;
});
_navigator.push(CloseDayShowRoute,
arguments: closeDayData);
_navigator.push(CloseDayShowRoute, arguments: closeDayData);
}
@override

View File

@ -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/payment/payment_view.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.pbenum.dart';
import 'package:barcode_scan/model/scan_options.dart';
import 'package:barcode_scan/platform_wrapper.dart';
// import 'package:barcode_scan/gen/protos/protos.pb.dart';
// import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
// import 'package:barcode_scan/model/scan_options.dart';
// import 'package:barcode_scan/platform_wrapper.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_redux/flutter_redux.dart';
@ -185,61 +186,58 @@ class KassaTab extends StatelessWidget {
Future<void> scan() async {
try {
await Redux.store.dispatch(changePinSkipFromSetting(true));
var options = ScanOptions(strings: {
var options = ScanOptions(
strings: {
"cancel": 'Отмена',
"flash_on": 'Вкл фонарик',
"flash_off": 'Выкл фонарик',
});
},
);
var result = await BarcodeScanner.scan(options: options);
// print(result.type); // The result type (barcode, cancelled, failed)
// print(result.rawContent); // The barcode content
// 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 dataMatrix;
if (result.format == BarcodeFormat.ean13 || result.format == BarcodeFormat.ean8) {
barcode = result.rawContent;
} else if (result.format == BarcodeFormat.dataMatrix) {
dataMatrix = result.rawContent;
if (dataMatrix != null && dataMatrix.length > 15) {
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();
} catch (e) {
// Обработка ошибки, если необходимо
}
}
// 00000046208262 nZ2qnLH ODVFWktT
// 00000046208262 tjKDqfu UzVSeFE5
}
if (barcode != null) {
List<Good> goods =
await _dataService.getGoodsByBarcode(barcode: barcode);
List<Good> goods = await _dataService.getGoodsByBarcode(barcode: barcode);
if (goods != null && goods.isNotEmpty) {
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
} else {
_dialogService.showDialog(
description: 'Товар не найден: $barcode');
_dialogService.showDialog(description: 'Товар не найден: $barcode');
}
} else {
_dialogService.showDialog(description: 'Не удалось распознать штрих-код');
}
} else if (result.type == ResultType.Cancelled) {
// Пользователь отменил сканирование
} else if (result.type == ResultType.Error) {
_dialogService.showDialog(description: 'Не верный формат QR кода');
}
_dialogService.showDialog(description: 'Ошибка сканирования: ${result.rawContent}');
}
} on PlatformException catch (e) {
var result = ScanResult.create();
result.type = ResultType.Error;
result.format = BarcodeFormat.unknown;
if (e.code == BarcodeScanner.cameraAccessDenied) {
result.rawContent = 'The user did not grant the camera permission!';
_dialogService.showDialog(
description: 'Нет доступа до камеры устройства');
_dialogService.showDialog(description: 'Нет доступа к камере устройства');
} else {
result.rawContent = 'Unknown error: $e';
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
_dialogService.showDialog(description: 'Ошибка сканирования: ${e.message}');
}
} catch (e) {
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}

View File

@ -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/widgets/fields/busy_button.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.pbenum.dart';
import 'package:barcode_scan/model/scan_options.dart';
import 'package:barcode_scan/platform_wrapper.dart';
// import 'package:barcode_scan/gen/protos/protos.pb.dart';
// import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
// import 'package:barcode_scan/model/scan_options.dart';
// import 'package:barcode_scan/platform_wrapper.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:flutter/services.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter/material.dart';
@ -161,40 +162,35 @@ class _LoginViewState extends State<LoginView> {
Future<void> scan() async {
try {
var options = ScanOptions(strings: {
var options = ScanOptions(
strings: {
"cancel": 'Отмена',
"flash_on": 'Вкл фонарик',
"flash_off": 'Выкл фонарик',
});
},
);
var result = await BarcodeScanner.scan(options: options);
// print(result.type); // The result type (barcode, cancelled, failed)
// print(result.rawContent); // The barcode content
// 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.type == ResultType.Barcode && result.rawContent?.length == 60) {
if (result.rawContent.toLowerCase().trim().startsWith('test')) {
_apiService.test = true;
} else {
_apiService.test = false;
}
Redux.store.dispatch(authenticateToken(result.rawContent));
} else if (result.type == ResultType.Cancelled) {
// Пользователь отменил сканирование
} else if (result.type == ResultType.Error) {
_dialogService.showDialog(description: 'Не верный формат QR кода');
_dialogService.showDialog(description: 'Ошибка сканирования: ${result.rawContent}');
}
} on PlatformException catch (e) {
var result = ScanResult.create();
result.type = ResultType.Error;
result.format = BarcodeFormat.unknown;
if (e.code == BarcodeScanner.cameraAccessDenied) {
result.rawContent = 'The user did not grant the camera permission!';
_dialogService.showDialog(
description: 'Нет доступа до камеры устройства');
_dialogService.showDialog(description: 'Нет доступа к камере устройства');
} else {
result.rawContent = 'Unknown error: $e';
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
_dialogService.showDialog(description: 'Ошибка сканирования: ${e.message}');
}
} catch (e) {
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
}
}
}

View File

@ -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;
}

View File

@ -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/services/BankService.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/navigator_service.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/card_data.dart';
import '../../core/models/card_data.dart';
import 'forte_pos_service.dart';
class PaymentView extends StatefulWidget {
final PaymentModel model;
@ -50,7 +52,7 @@ class _PaymentViewState extends State<PaymentView> {
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
final DataService _dataService = locator<DataService>();
final DialogService _dialogService = locator<DialogService>();
BankService _bankService = locator<BankService>();
dynamic _bankService;
final NavigatorService _navigatorService = locator<NavigatorService>();
bool isBusy;
bool isBankApiAccess;
@ -64,12 +66,25 @@ class _PaymentViewState extends State<PaymentView> {
}
_bankInit() async {
int version = await _bankService.version();
if (version >= _bankService.sdkVersion) {
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>();
} else {
setState(() {
isBankApiAccess = true;
isBankApiAccess = false;
});
return;
}
int version = await _bankService.version();
setState(() {
isBankApiAccess = version >= _bankService.sdkVersion;
});
}
@override
@ -212,27 +227,41 @@ class _PaymentViewState extends State<PaymentView> {
_total = double.parse(value);
}
if (state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1) {
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 = 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 ч. Необходимо закрыть смену и открыть ее заново.');
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 paymentHalykPos(_total);
AmanDao<CardData> data = await paymentMethod(_total);
if (data.success) {
pressPayment(widget.model.operationType, data.data);
pressPayment('card', data.data);
} else {
_dialogService.showDialog(description: data.msg);
}
@ -240,14 +269,14 @@ class _PaymentViewState extends State<PaymentView> {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
},
splashColor: halykColor.withOpacity(0.4),
splashColor: sessionColor.withOpacity(0.4),
borderRadius: BorderRadius.circular(10.0),
highlightColor: halykColor.withOpacity(0.1),
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)
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
children: [
@ -259,34 +288,24 @@ class _PaymentViewState extends State<PaymentView> {
border: Border.all(color: Colors.white),
borderRadius: BorderRadius.circular(10.0),
image: DecorationImage(
image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth
image: AssetImage(imageAsset),
fit: BoxFit.fitWidth,
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
offset: Offset(0, 3), // Смещение тени
),
],
),
),
// 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 ),),
// ],
// ),
],
),
),
);
}
},
);
}

View File

@ -21,7 +21,7 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.1"
version: "2.5.0"
auto_size_text:
dependency: "direct main"
description:
@ -29,13 +29,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
barcode_scan:
barcode_scan2:
dependency: "direct main"
description:
name: barcode_scan
name: barcode_scan2
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
version: "4.2.4"
boolean_selector:
dependency: transitive
description:
@ -56,7 +56,7 @@ packages:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
version: "1.2.0"
charset_converter:
dependency: "direct main"
description:
@ -175,7 +175,7 @@ packages:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
@ -344,7 +344,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.3.0"
nested:
dependency: transitive
description:
@ -449,7 +449,7 @@ packages:
name: protobuf
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.4"
version: "2.0.1"
provider:
dependency: "direct main"
description:
@ -566,7 +566,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
version: "1.8.0"
sqflite:
dependency: "direct main"
description:
@ -622,7 +622,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
version: "0.2.19"
typed_data:
dependency: transitive
description:
@ -685,7 +685,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
version: "2.0.5"
xdg_directories:
dependency: transitive
description:
@ -701,5 +701,5 @@ packages:
source: hosted
version: "4.5.1"
sdks:
dart: ">=2.13.0 <3.0.0"
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.22.2"

View File

@ -2,7 +2,7 @@ name: aman_kassa_flutter
description: A new Flutter project.
version: 1.2.3+36
environment:
sdk: '>=2.3.0 <3.0.0'
sdk: '>=2.3.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
@ -23,7 +23,8 @@ dependencies:
google_fonts: ^1.1.1
material_design_icons_flutter: ^4.0.5855
intl: ^0.16.1
barcode_scan: ^3.0.1
# barcode_scan: ^3.0.1
barcode_scan2: ^4.0.0
device_info: ^1.0.0
esys_flutter_share: ^1.0.2
auto_size_text: ^2.1.0