244 lines
7.4 KiB
Dart
244 lines
7.4 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'dart:convert';
|
||
import 'dart:core';
|
||
|
||
import 'package:checker/resources.dart';
|
||
import 'package:checker/strings.dart';
|
||
import 'package:checker/common.dart';
|
||
import 'package:checker/consts.dart';
|
||
import 'package:checker/network.dart';
|
||
import 'package:checker/base/base_state.dart';
|
||
import 'package:checker/screens/purchase_success.dart';
|
||
|
||
/// Экран проведения покупки.
|
||
class PurchaseScreen extends StatefulWidget {
|
||
|
||
PurchaseScreen(this.user, this.card);
|
||
|
||
final String user;
|
||
final String card;
|
||
|
||
@override State createState() => new PurchaseScreenState<PurchaseScreen>(user, card);
|
||
}
|
||
|
||
class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
||
|
||
/// Объект, помогающий вручную изменять введенный пользователем текст.
|
||
/// Используется для форматирования введенных пользователем данных
|
||
/// (удаляет запрещенные символы до их отображаения).
|
||
TextEditingController controller = new TextEditingController();
|
||
|
||
PurchaseScreenState(String userString, String card) {
|
||
this.user = JSON.decode(userString);
|
||
this.card = card;
|
||
}
|
||
|
||
@override void onStart() {
|
||
getLoyalty(user['loyalty_url']);
|
||
}
|
||
|
||
bool purchaseInProgress = false;
|
||
Map user;
|
||
String card = '';
|
||
String loyalty = '';
|
||
|
||
@override Widget getScreenContent() {
|
||
return new Column(
|
||
children: <Widget>[new Expanded(child: new ListView(children: <Widget>[
|
||
getValueWithDescription(StringsLocalization.userName(), user['first_name'] == null ? '' : user['first_name']),
|
||
getValueWithDescription(StringsLocalization.card(), card),
|
||
getValueWithDescription(StringsLocalization.reward(), loyalty),
|
||
getHintLabel(),
|
||
getInputField(),
|
||
wrapButton(getScreenMargins(36.0), getCompleteButton()),
|
||
wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), Resources.getPrimaryColor(app)))
|
||
]))]);
|
||
}
|
||
|
||
getScreenMargins(double top) {
|
||
double side = 42.0;
|
||
return new EdgeInsets.only(top: top, left: side, right: side);
|
||
}
|
||
|
||
getCompleteButton() {
|
||
return buildRaisedButton(StringsLocalization.completePurchase(), () => onPurchaseClick());
|
||
}
|
||
|
||
Widget getScanButton(BuildContext context, String title, Color textColor) {
|
||
return new Container(
|
||
height: buttonHeight,
|
||
child: new FlatButton(
|
||
child: new Text(
|
||
title,
|
||
style: new TextStyle(color: textColor)),
|
||
onPressed: () => startScanner(context, app, helper)),
|
||
decoration: new BoxDecoration(
|
||
border: new Border.all(color: Resources.getButtonColor(app), width: 1.0),
|
||
borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
|
||
}
|
||
|
||
@override String getTitle() {
|
||
return StringsLocalization.carryingPurchase();
|
||
}
|
||
|
||
@override getHint() {
|
||
return StringsLocalization.sum();
|
||
}
|
||
|
||
@override getTextWidget() {
|
||
return new TextField(
|
||
keyboardType: TextInputType.number,
|
||
decoration: new InputDecoration.collapsed(
|
||
hintText: getHint(),
|
||
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)
|
||
),
|
||
controller: controller,
|
||
onSubmitted: (String text) {
|
||
setState(() {
|
||
controller.text = _parseSum(text);
|
||
});
|
||
},
|
||
textAlign: TextAlign.center,
|
||
autofocus: true,
|
||
);
|
||
}
|
||
|
||
getLoyalty(String url) async {
|
||
|
||
if (await platform.invokeMethod('isOnline')) {
|
||
|
||
String token = await helper.getToken();
|
||
|
||
var headers = {
|
||
'DM-Authorization': 'dmapptoken $appToken',
|
||
'Authorization': 'dmtoken ${token}'
|
||
};
|
||
|
||
httpClient.get(url, headers: headers).then((response) {
|
||
|
||
print(response.body);
|
||
|
||
Map bonuses = JSON.decode(response.body);
|
||
String type = bonuses['type'];
|
||
setState(() {
|
||
if (type == 'amount') {
|
||
this.loyalty = '${user['discount']}%';
|
||
} else {
|
||
List amountToBonus = bonuses['amount_to_bonus'];
|
||
double loyalityVal = (double.parse(amountToBonus[1]) / amountToBonus[0]) * 100;
|
||
this.loyalty = '${loyalityVal.toStringAsFixed(0)}%';
|
||
}
|
||
});
|
||
}).catchError((error) {
|
||
print(error.toString());
|
||
});
|
||
}
|
||
}
|
||
|
||
String _cleanupNumber(String text){
|
||
String tmp = text
|
||
.replaceAll(' ', '')
|
||
.replaceAll('-', '')
|
||
.replaceAll(',', '.')
|
||
.replaceAll('..', '.');
|
||
|
||
while(tmp.indexOf('..') != -1){
|
||
tmp = tmp.replaceAll('..', '.');
|
||
}
|
||
return tmp;
|
||
}
|
||
|
||
_parseSum(String input) {
|
||
num sumTotal = 0.0;
|
||
String text = _cleanupNumber(input);
|
||
|
||
try {
|
||
sumTotal = num.parse(text);
|
||
} catch(exception) {
|
||
print(exception);
|
||
try {
|
||
int idx = text.indexOf('.');
|
||
String integerPart = text.substring(0, idx);
|
||
String fractionalPart = text.substring(idx + 1, text.length);
|
||
if(fractionalPart.length > 2) {
|
||
fractionalPart = fractionalPart.substring(0, 2);
|
||
}
|
||
return '${integerPart}.${fractionalPart}';
|
||
} catch(exception){
|
||
print(exception);
|
||
}
|
||
}
|
||
return sumTotal.toStringAsFixed(2);
|
||
}
|
||
|
||
onPurchaseClick() {
|
||
String val = _parseSum(controller.text);
|
||
showDialog(context: context, child: new AlertDialog(
|
||
title: new Text(StringsLocalization.confirmation()),
|
||
content: new Text(StringsLocalization.confirmPurchase(val)),
|
||
actions: <Widget>[
|
||
new FlatButton(
|
||
child: new Text(StringsLocalization.no()),
|
||
onPressed: () {
|
||
Navigator.of(context).pop();
|
||
},
|
||
),
|
||
new FlatButton(
|
||
child: new Text(StringsLocalization.yes()),
|
||
onPressed: () {
|
||
purchase(val);
|
||
},
|
||
)
|
||
]));
|
||
}
|
||
|
||
purchase(String sumTotal) async {
|
||
if (await platform.invokeMethod('isOnline')) {
|
||
if (!purchaseInProgress) {
|
||
purchaseInProgress = true;
|
||
|
||
String token = await helper.getToken();
|
||
helper.getMerchantID().then((result) {
|
||
|
||
String url = user['purchases_url'];
|
||
|
||
helper.getCurrency().then((currency) {
|
||
var body = {
|
||
'doc_id': result,
|
||
'curr_iso_code': currency.toString(),
|
||
'commit': 'true',
|
||
'sum_total': sumTotal
|
||
};
|
||
|
||
var headers = {
|
||
'DM-Authorization': 'dmapptoken $appToken',
|
||
'Authorization': 'dmtoken ${token}'
|
||
};
|
||
|
||
httpClient.post(url, body: body, headers: headers).then((response) {
|
||
|
||
print(response.body);
|
||
Map parsedMap = JSON.decode(response.body);
|
||
|
||
if (parsedMap.containsKey('errors')) {
|
||
List<String> errors = parsedMap['errors'];
|
||
// TODO: ПОказывать сообщение с ошибкой!
|
||
} else {
|
||
helper.close().then((_) {
|
||
Navigator.of(context).pop();
|
||
pushRouteReplacement(context, new PurchaseSuccessScreen(sumTotal, user['first_name'] == null ? '' : user['first_name']));
|
||
});
|
||
}
|
||
|
||
}).catchError((error) {
|
||
purchaseInProgress = false;
|
||
print(error.toString());
|
||
});
|
||
});
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|