ui and back worked

backend_nfc
Serik.Uvaissov 2020-08-23 14:05:56 +06:00
parent 8edcc2cdb3
commit 1b9a8af2c5
16 changed files with 717 additions and 95 deletions

View File

@ -89,7 +89,7 @@ public class BankNfcPlugins implements MethodCallHandler {
showTransaction(call, result);
break;
case "version":
result.success("version: "+ Build.VERSION.SDK_INT);
result.success(String.valueOf(Build.VERSION.SDK_INT));
break;
case "get":
AmanDao<String> dao = new AmanDao<>();

View File

@ -1,5 +1,6 @@
import 'package:aman_kassa_flutter/core/services/BankService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import '../core/services/DbService.dart';
@ -32,5 +33,7 @@ class LocatorInjector {
_log.d('Initializing DataService Service');
locator.registerLazySingleton<DataService>(() => DataService());
_log.d('Initializing BankService Service');
locator.registerLazySingleton<BankService>(() => BankService());
}
}

View File

@ -7,4 +7,5 @@ const String HistoryViewRoute = "HistoryView";
const String InfoKkmViewRoute = "InfoKkmViewRoute";
const String QrViewRoute = "QrViewRoute";
const String BankViewRoute = "BankViewRoute";
const String BankSettingViewRoute = "BankSettingViewRoute";
// Generate the views here

View File

@ -1,3 +1,4 @@
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';
import 'package:aman_kassa_flutter/views/history/history_view.dart';
@ -53,6 +54,11 @@ Route<dynamic> generateRoute(RouteSettings settings) {
routeName: settings.name,
viewToShow: BankView(),
);
case BankSettingViewRoute:
return _getPageRoute(
routeName: settings.name,
viewToShow: BankSettingView(),
);
case QrViewRoute:
ImageShowModel data = settings.arguments as ImageShowModel;
return _getPageRoute(

View File

@ -0,0 +1,114 @@
import 'dart:convert';
import 'package:aman_kassa_flutter/core/base/base_service.dart';
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
import 'package:flutter/services.dart';
class BankService extends BaseService {
static const String _url = 'http://185.98.84.231:2000';
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("BankService", e, stack);
result = '0';
}
log.i(result);
return int.parse(result) ?? 0;
}
Future<String> imei() async {
String result;
try {
result = await _channel.invokeMethod('imei');
} catch (e, stack) {
log.e("BankService", e, stack);
result = '0';
}
log.i(result);
return result;
}
Future<bool> init() async {
try {
String response = await _channel.invokeMethod('init', <String, dynamic>{
'serverUrl': _url,
});
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao.success;
} catch (e, stack) {
log.e("BankService", e, stack);
return false;
}
}
Future<bool> connect() async {
try {
String response = await _channel.invokeMethod("connection");
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao.success;
} catch (e, stack) {
log.e("BankService", e, stack);
return false;
}
}
Future<AmanDao> auth({String login, String password}) async {
try {
String response = await _channel.invokeMethod("auth",
<String, dynamic>{'login': login, 'password': password});
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao;
} catch (e, stack) {
log.e("BankService", e, stack);
return new AmanDao(msg: 'Ошибка авторизации');
}
}
Future<AmanDao> pay({double amount}) async {
try {
double total = amount * 100;
log.i('total: $total, ${total.toInt()}');
String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt()});
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao;
} catch (e, stack) {
log.e("BankService", e, stack);
return new AmanDao(msg: 'Ошибка оплаты');
}
}
Future<bool> shutdown() async {
try {
String response = await _channel.invokeMethod("shutdown");
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao.success;
} catch (e, stack) {
log.e("BankService", e, stack);
return false;
}
}
Future<bool> cancel() async {
try {
String response = await _channel.invokeMethod("cancel");
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao.success;
} catch (e, stack) {
log.e("BankService", e, stack);
return false;
}
}
}

View File

@ -0,0 +1,19 @@
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
import 'package:meta/meta.dart';
import 'package:redux/redux.dart';
import 'package:redux_thunk/redux_thunk.dart';
import '../store.dart';
@immutable
class SetBankStateAction {
final BankState bankState;
SetBankStateAction(this.bankState);
}
ThunkAction<AppState> saveData(String login, String password) {
return (Store<AppState> store) async {
store.dispatch(SetBankStateAction(BankState(login: login, password: password)));
};
}

View File

@ -0,0 +1,7 @@
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) {
final payload = action.bankState;
return prevState.copyWith(login: payload.login, password: payload.password);
}

View File

@ -0,0 +1,41 @@
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:meta/meta.dart';
@immutable
class BankState {
final String login;
final String password;
BankState({this.login, this.password});
//read hive
factory BankState.initial(BankState payload) {
return BankState(
login: payload?.login,
password: payload?.password);
}
//write hive
BankState copyWith({
@required login,
@required password,
}) {
return BankState(
login: login ?? this.login,
password: password ?? this.password,
);
}
static BankState fromJson(dynamic json) {
return json != null
? BankState(
password: json['password'],
login: json['login'],
)
: null;
}
dynamic toJson() {
return {"password": password, "login": login};
}
}

View File

@ -1,10 +1,12 @@
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
import 'package:aman_kassa_flutter/redux/reducers/bank_reducer.dart';
import 'package:aman_kassa_flutter/redux/reducers/calc_reducer.dart';
import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart';
import 'package:aman_kassa_flutter/redux/reducers/setting_reducer.dart';
import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart';
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
@ -15,6 +17,7 @@ import 'package:redux_persist_flutter/redux_persist_flutter.dart';
import 'package:redux_thunk/redux_thunk.dart';
import 'package:redux_persist/redux_persist.dart';
import 'actions/bank_actions.dart';
import 'actions/calc_actions.dart';
//reducer context
@ -35,6 +38,10 @@ AppState appReducer(AppState state, dynamic action) {
/** CalcAction **/
final nextCalcState = calcReducer(state.calcState, action);
return state.copyWith(calcState: nextCalcState);
} else if (action is SetBankStateAction) {
/** BankAction **/
final nextBankState = bankReducer(state.bankState, action);
return state.copyWith(bankState: nextBankState);
}
return state;
}
@ -46,12 +53,14 @@ class AppState {
final KassaState kassaState;
final SettingState settingState;
final CalcState calcState;
final BankState bankState;
AppState({
this.userState,
this.kassaState,
this.settingState,
this.calcState,
this.bankState,
});
//stable work
@ -60,21 +69,23 @@ class AppState {
KassaState kassaState,
SettingState settingState,
CalcState calcState,
BankState bankState,
}) {
return AppState(
userState: userState ?? this.userState,
kassaState: kassaState ?? this.kassaState,
settingState: settingState ?? this.settingState,
calcState: calcState ?? this.calcState,
bankState: bankState ?? this.bankState,
);
}
static AppState fromJson(dynamic json) {
print(json);
return json != null
? AppState(
settingState: SettingState.fromJson(json['settingState']),
userState: UserState.fromJson(json['userState']),
bankState: BankState.fromJson(json['bankState']),
)
: null;
}
@ -83,6 +94,7 @@ class AppState {
return {
"settingState": settingState.toJson(),
"userState": userState.toJson(),
"bankState": bankState.toJson(),
};
}
}
@ -103,7 +115,8 @@ class Redux {
// Create Persistor
final persist = Persistor<AppState>(
storage: FlutterStorage(), // Or use other engines
serializer: JsonSerializer<AppState>(AppState.fromJson), // Or use other serializers
serializer: JsonSerializer<AppState>(
AppState.fromJson), // Or use other serializers
);
final initialState = await persist.load();
@ -112,6 +125,7 @@ class Redux {
final kassaStateInitial = KassaState.initial();
final settingStateInitial = SettingState.initial(initialState?.settingState);
final calcStateInitial = CalcState.initial();
final bankStateInitial = BankState.initial(initialState?.bankState);
_store = Store<AppState>(
appReducer,
@ -120,7 +134,8 @@ class Redux {
userState: userStateInitial,
kassaState: kassaStateInitial,
settingState: settingStateInitial,
calcState: calcStateInitial),
calcState: calcStateInitial,
bankState: bankStateInitial),
);
}
}

View File

@ -0,0 +1,114 @@
import 'dart:convert';
import 'package:aman_kassa_flutter/core/locator.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 BankSettingView extends StatefulWidget {
BankSettingView();
@override
_BankSettingViewState createState() => _BankSettingViewState();
}
class _BankSettingViewState extends State<BankSettingView> {
TextEditingController _emailController;
TextEditingController _passwordController;
final BankService _bankService = locator<BankService>();
final DialogService _dialogService = locator<DialogService>();
String _platformImei = 'Unknown';
String _bankImei = 'Unknown';
@override
void initState() {
super.initState();
BankState state = Redux.store.state.bankState;
_emailController = new TextEditingController(text: state.login);
_passwordController = new TextEditingController(text: state.password);
initBankImeiState();
}
Future<void> initBankImeiState() async {
String imei;
try {
imei = await _bankService.imei();
} on PlatformException {
imei = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_bankImei = imei;
});
}
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
void _saveData() async {
await Redux.store.dispatch(saveData(_emailController.text, _passwordController.text));
_dialogService.showDialog(description: 'Данные сохранены');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Настройка Tap2Phone'),
),
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,
),
Text('Ваш IMEI-код:$_platformImei'),
Text('Ваш IMEI-код:$_bankImei'),
verticalSpaceTiny,
TextField(
controller: _emailController,
decoration: InputDecoration(
labelText: 'E-Mail', hintText: "Введите адрес почты"),
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: _passwordController,
decoration: InputDecoration(
labelText: 'Пароль', hintText: "Введите пароль"),
),
verticalSpaceMedium,
RaisedButton(
onPressed: this._saveData,
child: Text(
'Cохранить',
style: TextStyle(color: whiteColor, fontSize: 25.0),
),
color: primaryColor,
padding:
const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
)
],
),
),
),
);
}
}

View File

@ -1,23 +1,46 @@
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/choice.dart';
import 'package:aman_kassa_flutter/core/services/BankService.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
const List<Choice> choices = const <Choice>[
//const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
//const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
const Choice(
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
//const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
];
class PopupMenu extends StatelessWidget {
class PopupMenu extends StatefulWidget {
final void Function(Choice value) onSelectChoice;
PopupMenu({this.onSelectChoice});
@override
_PopupMenuState createState() => _PopupMenuState();
}
class _PopupMenuState extends State<PopupMenu> {
BankService _bankService = locator<BankService>();
List<Choice> choices;
@override
void initState() {
// TODO: implement initState
super.initState();
load();
}
load () async {
int version = await _bankService.version();
List<Choice> _choices = <Choice>[
const Choice(title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
if (version >= 24 )
const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
if (version >= 24 )
const Choice(title: 'Настройка Tap2Phone', icon: MdiIcons.nfc, command: 'tap2phone'),
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
];
setState(() {
choices= _choices;
});
}
@override
Widget build(BuildContext context) {
return PopupMenuButton<Choice>(
@ -25,7 +48,7 @@ class PopupMenu extends StatelessWidget {
Icons.more_vert,
color: menuColor,
),
onSelected: onSelectChoice,
onSelected: widget.onSelectChoice,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(

View File

@ -67,6 +67,8 @@ class _HomeViewState extends State<HomeView> {
_navigatorService.push(InfoKkmViewRoute);
} else if (choice.command == 'bank') {
_navigatorService.push(BankViewRoute);
} else if (choice.command == 'tap2phone') {
_navigatorService.push(BankSettingViewRoute);
}
}

View File

@ -1,8 +1,11 @@
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/BankService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
@ -11,24 +14,25 @@ import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/action_view.dart';
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/background_view.dart';
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/card_view.dart';
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/phone_view.dart';
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/text_state.dart';
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter_screenutil/screenutil.dart';
import 'package:logger/logger.dart';
class PaymentNfcView extends StatefulWidget {
final PaymentModel model;
@ -40,14 +44,184 @@ class PaymentNfcView extends StatefulWidget {
}
class _PaymentNfcViewState extends State<PaymentNfcView> {
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
BankService _bankService = locator<BankService>();
DialogService _dialogService = locator<DialogService>();
final DataService _dataService = locator<DataService>();
final NavigatorService _navigatorService = locator<NavigatorService>();
Logger log = getLogger('PaymentNfcView');
bool isBusy;
bool isPhoneScaled = false;
int status = 0;
bool isPhoneScaled;
int status;
@override
void initState() {
super.initState();
isBusy = false;
isPhoneScaled = false;
status = 0;
start();
}
void start() async {
//Инициализация
bool initialized = await _bankService.init();
log.i(initialized);
if (!initialized) {
setState(() {
status = 4;
});
return;
}
//Проверка связи
bool connected = await _bankService.connect();
log.i(connected);
if (!connected) {
setState(() {
status = 5;
});
return;
}
//Авторизация
BankState bankState = Redux.store.state.bankState;
AmanDao authDao = await _bankService.auth(
login: bankState.login, password: bankState.password);
if (!authDao.success) {
setState(() {
status = 6;
});
if (authDao.msg != null) {
log.i(authDao.msg);
_dialogService.showDialog(description: authDao.msg);
}
return;
}
pay();
}
pay() async {
//Платеж
num total = 0.0;
if (widget.model.mode == SettingModeCalc) {
total = totalCalc(Redux.store.state.calcState.calcItems);
} else {
total = totalKassa(Redux.store.state.kassaState.kassaItems);
}
setState(() {
status = 1;
isPhoneScaled = true;
});
log.i('total: $total');
AmanDao payDao = await _bankService.pay(amount: total);
if (!payDao.success) {
int _status = 7;
if (payDao.data != null ) {
if("onWrongApiCalled" == payDao.data.toString()) {
cancel();
} else if("notAuthorized" == payDao.data.toString() ) {
cancel();
_status = 6;
}
}
setState(() {
status = _status;
isPhoneScaled = false;
});
if (payDao.msg != null) {
log.i(payDao.msg);
_dialogService.showDialog(description: payDao.msg);
}
return;
}
setState(() {
status = 3;
isPhoneScaled = false;
});
//check
pressPayment('card');
}
cancel() async {
bool isCanceled = await _bankService.cancel();
_navigatorService.pop();
}
pressPayment(String type) async {
setState(() {
isBusy = true;
});
Dialogs.showLoadingDialog(context, _keyLoader);
try {
AppState _state = Redux.store.state;
String _token = _state.userState.user.token;
String _tradeType = _state.settingState.tradeType;
String _mode = _state.settingState.mode;
if (_mode == SettingModeCalc) {
_tradeType = SettingTradeTypeGood;
}
List<ProductDao> kassaItems = _state.kassaState.kassaItems;
List<CalcModel> calcItems = _state.calcState.calcItems;
Response<dynamic> response = await _dataService.sellOrReturn(
token: _token,
kassaItems: kassaItems,
paymentType: type,
operationType: widget.model.operationType,
tradeType: _tradeType,
calcItems: calcItems,
mode: _mode);
setState(() {
isBusy = false;
});
if (response != null) {
if (response.operation) {
String message = response.body['message'];
String check = response.body['check'];
String url = response?.body['link'];
print('url : $url');
if (_mode == SettingModeCalc) {
Redux.store.dispatch(cleanCalcItems);
} else if (_mode == SettingModeKassa) {
Redux.store.dispatch(cleanKassaItems);
}
Redux.store.dispatch(checkMoney);
Redux.store.dispatch(openSmenaPseudo);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.replace(HomeViewRoute);
_navigatorService.push(ImageShowRoute,
arguments: ImageShowModel(data: check, title: message, url: url));
} else if (!response.operation &&
![401, 402, 403, 412, 500].contains(response.status)) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialogService.showDialog(description: response.body['message']);
} else {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
} else {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
} catch (e) {
print(e);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
} finally {
//Navigator.of(context, rootNavigator: true).pop();
setState(() {
isBusy = false;
});
}
}
@override
void dispose() {
_bankService.shutdown();
super.dispose();
}
@override
@ -71,16 +245,6 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
dataTitle(),
style: TextStyle(color: whiteColor),
),
actions: <Widget>[
FlatButton(
onPressed: () {
setState(() {
isPhoneScaled = !isPhoneScaled;
status += 1;
});
},
child: Icon(Icons.add)),
],
),
body: Container(
decoration: BoxDecoration(color: purpleColor),
@ -108,7 +272,11 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
CardView(
show: isPhoneScaled,
),
PhoneView(scaled: isPhoneScaled, status: status,),
PhoneView(
scaled: isPhoneScaled,
status: status,
),
buildActionView()
],
),
)
@ -119,6 +287,55 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
);
}
ActionView buildActionView() {
switch (status) {
case 5:
return ActionView(
show: true,
acceptText: 'Повторить',
acceptCallback: () async {
await _bankService.shutdown();
start();
},
declineText: 'Отмена',
declineCallback: () {
cancel();
},
);
break;
case 6:
return ActionView(
show: true,
acceptText: 'Повторить',
acceptCallback: () async {
await _bankService.shutdown();
start();
},
declineText: 'Отмена',
declineCallback: () {
cancel();
},
);
break;
case 7:
return ActionView(
show: true,
acceptText: 'Повторить',
acceptCallback: () {
pay();
},
declineText: 'Отмена',
declineCallback: () {
cancel();
},
);
break;
default:
}
return ActionView();
}
String dataTitle() =>
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
@ -149,15 +366,15 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
});
}
String totalKassa(List<ProductDao> kassaItems) {
num totalKassa(List<ProductDao> kassaItems) {
num total = 0.0;
kassaItems.forEach((element) {
total += element.total == null ? 0.0 : element.total.toDouble();
});
return total.toString();
return total;
}
String totalCalc(List<CalcModel> items) {
num totalCalc(List<CalcModel> items) {
num total = 0.0;
items.forEach((element) {
if (element.operation == Calculations.MULTIPLY) {
@ -168,6 +385,6 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
total += element.num1 == null ? 0.0 : double.parse(element.num1);
}
});
return total.toString();
return total;
}
}

View File

@ -0,0 +1,49 @@
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ActionView extends StatelessWidget {
final String acceptText;
final String declineText;
final void Function() acceptCallback;
final void Function() declineCallback;
final bool show;
const ActionView(
{Key key,
this.acceptText,
this.declineText,
this.acceptCallback,
this.declineCallback,
this.show = false})
: super(key: key);
@override
Widget build(BuildContext context) {
return Positioned(
bottom: ScreenUtil().setSp(100),
left: ScreenUtil().setSp(25),
right: ScreenUtil().setSp(25),
child: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: show ? 1.0 : 0.0,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
child: buildContainer()),
));
}
Row buildContainer() {
return Row(
children: <Widget>[
if (acceptCallback !=null && acceptText !=null)
Expanded(child: BusyButton(title: acceptText, onPressed: acceptCallback)),
SizedBox(width: 5.0,),
if (declineCallback !=null && declineText !=null)
BusyButton(title: declineText, onPressed: declineCallback, mainColor: redColor,)
],
);
}
}

View File

@ -101,7 +101,39 @@ class _PhoneViewState extends State<PhoneView> {
children: <Widget>[
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
verticalSpaceSmall,
AutoSizeText('Ошибка', style: TextStyle(fontWeight: FontWeight.bold),)
AutoSizeText('Ошибка инициализации', style: TextStyle(fontWeight: FontWeight.bold),)
],
);
}
if(widget.status == 5){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
verticalSpaceSmall,
AutoSizeText('Ошибка соединения', style: TextStyle(fontWeight: FontWeight.bold),),
AutoSizeText('попробуйте еще раз', style: TextStyle(fontWeight: FontWeight.bold),)
],
);
}
if(widget.status == 6){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
verticalSpaceSmall,
AutoSizeText('Ошибка авторизации', style: TextStyle(fontWeight: FontWeight.bold),),
],
);
}
if(widget.status == 7){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
verticalSpaceSmall,
AutoSizeText('Ошибка чтения карты', style: TextStyle(fontWeight: FontWeight.bold),),
],
);
}

View File

@ -1,27 +1,13 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
version: "2.4.2"
auto_size_text:
dependency: "direct main"
description:
@ -43,6 +29,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
charcode:
dependency: transitive
description:
@ -50,13 +43,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.12"
version: "1.14.13"
convert:
dependency: transitive
description:
@ -99,6 +99,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
file:
dependency: transitive
description:
@ -170,13 +177,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
intl:
dependency: "direct main"
description:
@ -204,7 +204,7 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.6"
version: "0.12.8"
material_design_icons_flutter:
dependency: "direct main"
description:
@ -232,7 +232,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
version: "1.7.0"
path_provider:
dependency: "direct main"
description:
@ -268,13 +268,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
platform:
dependency: transitive
description:
@ -338,13 +331,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
redux:
dependency: "direct main"
description:
@ -440,7 +426,7 @@ packages:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
version: "1.9.5"
stream_channel:
dependency: transitive
description:
@ -475,14 +461,14 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.15"
version: "0.2.17"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
version: "1.2.0"
url_launcher:
dependency: "direct main"
description:
@ -532,13 +518,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
sdks:
dart: ">=2.8.0 <3.0.0"
dart: ">=2.9.0-14.0.dev <3.0.0"
flutter: ">=1.17.0 <2.0.0"