ui and back worked
parent
8edcc2cdb3
commit
1b9a8af2c5
|
|
@ -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<>();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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)));
|
||||
};
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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};
|
||||
}
|
||||
}
|
||||
|
|
@ -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,29 +69,32 @@ 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
|
||||
static AppState fromJson(dynamic json) {
|
||||
return json != null
|
||||
? AppState(
|
||||
settingState: SettingState.fromJson(json['settingState']),
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
)
|
||||
settingState: SettingState.fromJson(json['settingState']),
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
bankState: BankState.fromJson(json['bankState']),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"settingState": settingState.toJson(),
|
||||
"userState" : userState.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,15 +125,17 @@ 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,
|
||||
middleware: [thunkMiddleware, persist.createMiddleware() ],
|
||||
middleware: [thunkMiddleware, persist.createMiddleware()],
|
||||
initialState: AppState(
|
||||
userState: userStateInitial,
|
||||
kassaState: kassaStateInitial,
|
||||
settingState: settingStateInitial,
|
||||
calcState: calcStateInitial),
|
||||
calcState: calcStateInitial,
|
||||
bankState: bankStateInitial),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class _HomeViewState extends State<HomeView> {
|
|||
if (choice.command == 'exit') {
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
Response<dynamic> result =
|
||||
await _api.logout(Redux.store.state.userState.user.token);
|
||||
await _api.logout(Redux.store.state.userState.user.token);
|
||||
if (result.operation && result.status == 200) {
|
||||
Redux.store.dispatch(logoutAction);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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),),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
79
pubspec.lock
79
pubspec.lock
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue