kkm-info
login fix
4.4
Serik.Uvaissov 2020-07-08 12:31:12 +06:00
parent a80eb5874f
commit 0b4424a0e4
16 changed files with 329 additions and 74 deletions

View File

@ -12,6 +12,7 @@ const String Voucher_columnUrl = 'url';
const String VoucherTypePayment = 'payment';
const String VoucherTypeReturnPay = 'returnPay';
const String VoucherTypeReport = 'report';
class Voucher {

View File

@ -3,4 +3,6 @@ const String HomeViewRoute = "HomeView";
const String ImageShowRoute = "ImageShowRoute";
const String PaymentViewRoute = "PaymentView";
const String HistoryViewRoute = "HistoryView";
const String InfoKkmViewRoute = "InfoKkmViewRoute";
const String QrViewRoute = "QrViewRoute";
// Generate the views here

View File

@ -1,6 +1,8 @@
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:aman_kassa_flutter/views/history/history_view.dart';
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart';
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
import './route_names.dart';
import 'package:aman_kassa_flutter/views/home/home_view.dart';
@ -30,9 +32,24 @@ Route<dynamic> generateRoute(RouteSettings settings) {
routeName: settings.name,
viewToShow: HistoryView(),
);
case InfoKkmViewRoute:
return _getPageRoute(
routeName: settings.name,
viewToShow: InfoKkmView(),
);
case QrViewRoute:
ImageShowModel data = settings.arguments as ImageShowModel;
return _getPageRoute(
routeName: settings.name,
viewToShow: QrView(data),
);
case ImageShowRoute:
ImageShowModel data = settings.arguments as ImageShowModel;
return SlideRightRoute(widget: ImageShowContainer(data));
//return SlideRightRoute(widget: ImageShowContainer(data));
return _getPageRoute(
routeName: settings.name,
viewToShow: ImageShowContainer(data),
);
default:
return MaterialPageRoute(
builder: (_) => Scaffold(

View File

@ -16,8 +16,10 @@ import 'package:http/http.dart' as http;
/// The service responsible for networking requests
class ApiService extends BaseService {
static const test_endpoint = 'https://kassa-test.aman.com.kz/ru/api/v2';
static const endpoint = 'https://kassa.aman.com.kz/ru/api/v2';
static const test_host = 'https://kassa-test.aman.com.kz';
static const test_endpoint = '$test_host/ru/api/v2';
static const host = 'https://kassa.aman.com.kz';
static const endpoint = '$host/ru/api/v2';
final NavigatorService _navigatorService = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>();
@ -64,6 +66,12 @@ class ApiService extends BaseService {
return Response.fromJsonDynamic(json.decode(response));
}
Future<Response<dynamic>> infoKkm(String token) async {
Map<String, String> requestBody = <String, String>{'api_token': token};
var response = await requestFormData('/info', requestBody);
return Response.fromJsonDynamic(json.decode(response));
}
Future<Response<dynamic>> deposit(String token, String sum) async {
Map<String, String> requestBody = <String, String>{'api_token': token, 'summ': sum};
var response = await requestFormData('/deposit', requestBody);
@ -172,4 +180,5 @@ class ApiService extends BaseService {
var response = await requestFormData('/services', requestBody);
return Response.fromJsonDynamic(json.decode(response));
}
}

View File

@ -151,11 +151,18 @@ class DataService extends BaseService {
User user = Redux.store.state.userState.user;
String check = response?.body['check'];
dynamic journal = response?.body['journal'];
print(journal);
String url = response?.body['link'];
int checkNum = journal['check_num'];
var summ = journal['summ'];
double total = summ!= null ? double.parse(summ.toString()) : 0.0;
this.insertVoucher(user: user, name: 'Чек №$checkNum', data: data , base64Data: check, total: total );
this.insertVoucher(
user: user,
name: 'Чек №$checkNum',
data: data ,
base64Data: check,
total: total,
url: url,
type: operationType == OperationTypeReturn ? VoucherTypeReturnPay : VoucherTypePayment );
}
return response;
} catch (e) {

View File

@ -2,7 +2,9 @@ import 'dart:convert';
import 'dart:io';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
import 'package:aman_kassa_flutter/core/route_names.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/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
@ -41,8 +43,9 @@ Padding imageFromBase64String(String base64String) {
class ImageShowModel {
final String data;
final String title;
final String url;
ImageShowModel(this.data, this.title);
ImageShowModel({ this.data, this.title, this.url});
}
class MyFloatingActionButton extends StatefulWidget {
@ -55,6 +58,7 @@ class MyFloatingActionButton extends StatefulWidget {
class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
bool showFab = true;
DialogService _dialog = locator<DialogService>();
NavigatorService _navigatorService = locator<NavigatorService>();
// String _batteryLevel = 'Unknown battery level.';
// static const platform = const MethodChannel('samples.flutter.dev/battery');
//
@ -93,21 +97,22 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
spreadRadius: 5)
]),
//color: Colors.grey[900],
height: 200,
height: 260,
child: Column(
children: <Widget>[
//verticalSpaceSmall,
//BusyButton(title: 'Электронная почта', onPressed: shareFile , mainColor: primaryColor, icon: Icons.mail, enabled: false, ),
verticalSpaceSmall,
BusyButton(
title: 'WhatsApp',
onPressed: callWhatsApp,
mainColor: greenColor,
icon: MdiIcons.whatsapp,
enabled: widget.data.url != null,
),
verticalSpaceSmall,
BusyButton(title: 'QR-код чека', onPressed: qrGenerate , mainColor: primaryColor, icon: MdiIcons.qrcode, enabled: widget.data.url != null, ),
verticalSpaceSmall,
BusyButton(
title: '',
title: 'Поделиться',
onPressed: shareFile,
mainColor: yellowColor,
icon: Icons.share,
@ -132,6 +137,10 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
}
}
void qrGenerate() async {
_navigatorService.push(QrViewRoute, arguments: ImageShowModel(data: widget.data.url, title: 'Спасибо за покупку'));
}
void callWhatsApp() async {
DialogResponse response = await _dialog.showConfirmationDialogInput(
description: 'Номер телефона',
@ -140,7 +149,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
);
if (response.confirmed) {
String phoneNumber = response.responseText;
String msg = "Спасибо за покупку! \r\n https://picsum.photos/200/300 ";
String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
launchWhatsApp(phone: phoneNumber, message: msg);
//FlutterOpenWhatsapp.sendSingleMessage(phoneNumber, "Спасибо что выбераете нас \r\n https://picsum.photos/200/300 ");

View File

@ -28,8 +28,8 @@ class _HistoryViewState extends State<HistoryView> {
}
load() async {
List<Map> list = await _dbService.queryAllRowsOrderBy(Voucher_tableName, '$Voucher_columnDateTime desc');
print(list);
List<Map> list = await _dbService.queryAllRowsOrderBy(
Voucher_tableName, '$Voucher_columnDateTime desc');
setState(() {
data = list.map((e) => Voucher.fromMap(e)).toList();
});
@ -42,7 +42,13 @@ class _HistoryViewState extends State<HistoryView> {
title: Text('История чеков'),
actions: <Widget>[
FlatButton(
child: Text('Очистить', style: TextStyle(color: whiteColor, fontSize: 15, fontWeight: FontWeight.bold),),
child: Text(
'Очистить',
style: TextStyle(
color: whiteColor,
fontSize: 15,
fontWeight: FontWeight.bold),
),
onPressed: () async {
await _dbService.deleteAll(Voucher_tableName);
await this.load();
@ -57,14 +63,30 @@ class _HistoryViewState extends State<HistoryView> {
itemBuilder: (BuildContext context, int index) {
Voucher voucher = data[index];
return ListTile(
onTap: (){
onTap: () {
_navigatorService.push(ImageShowRoute,
arguments: ImageShowModel(voucher.base64Data, voucher.name));
arguments: ImageShowModel(
data: voucher.base64Data,
title: voucher.name,
url: voucher.url));
},
title: buildText(voucher),
subtitle: Text(dateFormat.format(voucher.dateTime)),
trailing: Icon(Icons.arrow_right),
leading: voucher.type == VoucherTypePayment ? Icon(MdiIcons.cashRegister, size: 40,) : Icon(Icons.description, size: 40,),
leading: voucher.type == VoucherTypePayment
? Icon(
MdiIcons.cashRegister,
size: 40,
)
: voucher.type == VoucherTypeReturnPay ?
Icon(
MdiIcons.backupRestore,
size: 40,
)
: Icon(
Icons.description,
size: 40,
),
);
},
),
@ -72,8 +94,9 @@ class _HistoryViewState extends State<HistoryView> {
}
Text buildText(Voucher voucher) {
if( voucher.type == VoucherTypePayment ){
return Text('${voucher.name} на сумму: ${voucher.total.toStringAsFixed(2)}');
if (voucher.type == VoucherTypePayment || voucher.type == VoucherTypeReturnPay) {
return Text(
'${voucher.name} на сумму: ${voucher.total.toStringAsFixed(2)}');
}
return Text('${voucher.name}');
}

View File

@ -5,7 +5,7 @@ import 'package:flutter/material.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: 'info'),
const Choice(title: 'Информацио о ККМ', icon: Icons.info_outline, command: 'infokkm'),
//const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
];

View File

@ -2,6 +2,7 @@ import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/core/models/choice.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/ApiService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
@ -61,11 +62,8 @@ class _HomeViewState extends State<HomeView> {
Redux.store.dispatch(logoutAction);
}
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
} else if (choice.command == 'update') {
Dialogs.showLoadingDialog(context, _keyLoader);
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user);
log.i('result: $result');
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
} else if (choice.command == 'infokkm') {
_navigatorService.push(InfoKkmViewRoute);
}
}

View File

@ -86,12 +86,18 @@ class _AdditionalTabState extends State<AdditionalTab> {
xReportBusy = true;
});
User user = Redux.store.state.userState.user;
Response response =
await _api.xReport(user.token);
Response response = await _api.xReport(user.token);
if (response.operation) {
_navigator.push(ImageShowRoute,
arguments: ImageShowModel(response.body['check'], 'X Отчет'));
_dataService.insertVoucher(user: user, name: 'X Отчет', base64Data: response.body['check'], type: VoucherTypeReport);
arguments:
ImageShowModel(data: response.body['check'], title: 'X Отчет'));
String url = response?.body['link'];
_dataService.insertVoucher(
user: user,
name: 'X Отчет',
base64Data: response.body['check'],
type: VoucherTypeReport,
url: url);
} else {
_dialog.showDialog(description: response.body['message']);
}
@ -105,15 +111,14 @@ class _AdditionalTabState extends State<AdditionalTab> {
updateCatalog = true;
});
Dialogs.showLoadingDialog(context, _keyLoader);
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user);
bool result =
await _dataService.getDataFromServer(Redux.store.state.userState.user);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
setState(() {
updateCatalog = false;
});
}
void _deposit() async {
setState(() {
depositBusy = true;
@ -318,7 +323,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
),
AmanIconButton(
title: 'История чеков',
onPressed: (){
onPressed: () {
_navigator.push(HistoryViewRoute);
},
mainColor: yellowColor,
@ -331,7 +336,6 @@ class _AdditionalTabState extends State<AdditionalTab> {
mainColor: greenColor,
icon: MdiIcons.databaseRefresh,
),
],
),
verticalSpaceMedium,

View File

@ -0,0 +1,120 @@
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/models/user.dart';
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/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class InfoKkmView extends StatefulWidget {
InfoKkmView();
@override
_InfoKkmViewState createState() => _InfoKkmViewState();
}
class _InfoKkmViewState extends State<InfoKkmView> {
DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm:ss");
ApiService _apiService = locator<ApiService>();
List<dynamic> data = [];
bool loading = false;
@override
void initState() {
super.initState();
load();
}
load() async {
setState(() {
loading = true;
});
User user = Redux.store.state.userState.user;
Response<dynamic> response = await _apiService.infoKkm(user.token);
if (response.operation) {
List<dynamic> list = [];
for (var key in response.body.keys) {
switch (key) {
case 'sn':
list.add({'key': 'Серийный номер', 'value': response.body[key]});
break;
case 'name':
list.add(
{'key': 'Наименование компании', 'value': response.body[key]});
break;
case 'biniin':
list.add({'key': 'ИИН/БИН', 'value': response.body[key]});
break;
case 'address':
list.add({'key': 'Адрес', 'value': response.body[key]});
break;
case 'kkmreg':
list.add({
'key': 'Регистрационный номер в органах НК',
'value': response.body[key]
});
break;
default:
}
}
setState(() {
data = list;
});
}
setState(() {
loading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Информация о ККМ'),
),
body: loading
? Container(child: Center(child: CircularProgressIndicator()))
: SingleChildScrollView(
child: Container(
margin: const EdgeInsets.all(8.0),
child: Table(
//defaultVerticalAlignment: TableCellVerticalAlignment.top,
children: data.map((e) {
return this.buildRow(e['key'], e['value']);
}).toList(),
),
),
),
);
}
TableRow buildRow(String key, String value) {
return TableRow(
children: <Widget>[
Container(
child: Text(
'$key :',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15.0,
),
),
margin: EdgeInsets.only(bottom: 8.0),
),
Container(
child: Text(
value,
style: TextStyle(fontSize: 15.0),
),
margin: EdgeInsets.only(bottom: 8.0),
),
],
);
}
}

View File

@ -20,8 +20,8 @@ import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class LoginView extends StatelessWidget {
final emailController = TextEditingController(text: 'test@kkm-kassa.kz');
final passwordController = TextEditingController(text: 'qwe123');
final emailController = TextEditingController();
final passwordController = TextEditingController();
final FocusNode passwordNode = new FocusNode();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

View File

@ -3,6 +3,7 @@ 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/ApiService.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';
@ -188,28 +189,38 @@ class _PaymentViewState extends State<PaymentView> {
tradeType: _tradeType,
calcItems: calcItems,
mode: _mode);
Navigator.of(context, rootNavigator: true).pop();
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);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.pop();
_navigatorService.push(ImageShowRoute,
arguments: ImageShowModel(check, message));
arguments: ImageShowModel(data:check, title: message, url: url ));
} else if (!response.operation && response.status != 500) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialogService.showDialog(description: response.body['message']);
}
} else {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
}
} catch (e) {
//Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
Navigator.of(context, rootNavigator: true).pop();
print(e);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
} finally {
//Navigator.of(context, rootNavigator: true).pop();
setState(() {
isBusy = false;
});

View File

@ -0,0 +1,39 @@
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
class QrView extends StatefulWidget {
final ImageShowModel data;
QrView(this.data);
@override
_QrViewState createState() => _QrViewState();
}
class _QrViewState extends State<QrView> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text( widget.data.title),
),
body: Container(
child: Center(
child: QrImage(
data: widget.data.data,
version: QrVersions.auto,
size: 220.0,
),
),
),
);
}
}

View File

@ -310,6 +310,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
qr:
dependency: transitive
description:
name: qr
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
qr_flutter:
dependency: "direct main"
description:
name: qr_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
quiver:
dependency: transitive
description:

View File

@ -28,6 +28,7 @@ dependencies:
esys_flutter_share: ^1.0.2
auto_size_text: ^2.1.0
url_launcher: ^5.4.11
qr_flutter: ^3.2.0
dev_dependencies:
flutter_test:
sdk: flutter