На экране проведения покупки правильно обрабатывается сумма покупки, передается на экран подтверждения
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
<application android:name="io.flutter.app.FlutterApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher_app">
|
<application android:name="io.flutter.app.FlutterApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher_app">
|
||||||
<activity android:name="com.dinect.checker.activity.MainActivity"
|
<activity android:name="com.dinect.checker.activity.MainActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:theme="@android:style/Theme.Black.NoTitleBar"
|
android:theme="@android:style/Theme.Black.NoTitleBar"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="com.dinect.checker.activity.CameraActivity"
|
<activity android:name="com.dinect.checker.activity.CameraActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/AppTheme"/>
|
android:theme="@style/AppTheme"/>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ public class MainActivity extends FlutterActivity {
|
|||||||
Intent cameraIntent = new Intent(MainActivity.this, CameraActivity.class);
|
Intent cameraIntent = new Intent(MainActivity.this, CameraActivity.class);
|
||||||
startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
|
startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
|
||||||
break;
|
break;
|
||||||
|
case "removeKeys":
|
||||||
|
mPreferences.edit().remove(PREF_POS_TOKEN).apply();
|
||||||
|
mPreferences.edit().remove(PREF_POS_MERCHANT_ID).apply();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
break;
|
break;
|
||||||
@@ -80,11 +84,11 @@ public class MainActivity extends FlutterActivity {
|
|||||||
finish();
|
finish();
|
||||||
} else if (requestCode == START_SCANNER_REQUEST_CODE && resultCode == RESULT_OK) {
|
} else if (requestCode == START_SCANNER_REQUEST_CODE && resultCode == RESULT_OK) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
logout();
|
mChannel.invokeMethod("foo", null);
|
||||||
} else {
|
} else {
|
||||||
String code = data.getExtras().getString("code", null);
|
String code = data.getExtras().getString("code", null);
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
logout();
|
mChannel.invokeMethod("foo", null);
|
||||||
} else {
|
} else {
|
||||||
mChannel.invokeMethod("purchase", code);
|
mChannel.invokeMethod("purchase", code);
|
||||||
}
|
}
|
||||||
@@ -92,10 +96,8 @@ public class MainActivity extends FlutterActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logout() {
|
private void removeKeys() {
|
||||||
mChannel.invokeMethod("foo", null);
|
|
||||||
mPreferences.edit().remove(PREF_POS_TOKEN).apply();
|
|
||||||
mPreferences.edit().remove(PREF_POS_MERCHANT_ID).apply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startScanner() {
|
public void startScanner() {
|
||||||
@@ -122,4 +124,4 @@ public class MainActivity extends FlutterActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,41 +11,47 @@ class FinishRegistrationScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
||||||
|
|
||||||
|
bool _tokenActive = true;
|
||||||
|
String _merchantID = '';
|
||||||
|
|
||||||
|
_RegistrationScreenState() {
|
||||||
|
if (textFieldValue == "") {
|
||||||
|
_getSavedMerchantID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override String getTitle() {
|
@override String getTitle() {
|
||||||
return "Регистрация";
|
return "Регистрация";
|
||||||
}
|
}
|
||||||
|
|
||||||
@override getHint() {
|
@override getHint() {
|
||||||
return 'ID merchant';
|
return 'ID магазина';
|
||||||
}
|
}
|
||||||
|
|
||||||
@overide getMenuButtons(BuildContext context) {
|
@overide getMenuButtons(BuildContext context) {
|
||||||
return <Widget>[new IconButton(icon: new Icon(Icons.help_outline), onPressed: () {})];
|
return <Widget>[new IconButton(icon: new Icon(Icons.help_outline), onPressed: () {})];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override Widget _getScreenContent(BuildContext context) {
|
@override Widget getScreenContent() {
|
||||||
if (textFieldValue == "") {
|
|
||||||
_getSavedValue();
|
|
||||||
}
|
|
||||||
return new Column(children: <Widget>[
|
return new Column(children: <Widget>[
|
||||||
getLogo(),
|
getLogo(),
|
||||||
getHintLabel(),
|
getHintLabel(),
|
||||||
getDecoratedTextWidget(),
|
getDecoratedTextWidget(),
|
||||||
_getMessage(),
|
_getMessage(),
|
||||||
_getButton(context)
|
buildButton(new EdgeInsets.only(top: 36.0, left: buttonVerticalMargin, right: buttonVerticalMargin),
|
||||||
|
buildRaisedButton(context, _tokenActive ? 'ЗАВЕРШИТЬ РЕГИСТРАЦИЮ' : 'ОБНОВИТЬ СТАТУС АКТИВАЦИИ',() => startScanner(context)))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getMerchantID() {
|
@override Widget getTextWidget() {
|
||||||
return new Text(_merchantID != null ? _merchantID : '', style: new TextStyle(color: Colors.black, fontSize: 16.0));
|
return new Row(children: <Widget>[new Text(_merchantID != null ? _merchantID : '', style: new TextStyle(color: Colors.black, fontSize: 16.0))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getSavedMerchantID() {
|
_getSavedMerchantID() {
|
||||||
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
|
||||||
platform.invokeMethod('getMerchantID').then((result) {
|
platform.invokeMethod('getMerchantID').then((result) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_merchantID = result;
|
_merchantID = result;
|
||||||
print(_merchantID);
|
print('merchanID: ${_merchantID}');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -53,7 +59,7 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
|||||||
_getMessage() {
|
_getMessage() {
|
||||||
return new Container(height: _tokenActive ? 72.0 : 108.0, decoration: _getDecoraionForMessageField(),
|
return new Container(height: _tokenActive ? 72.0 : 108.0, decoration: _getDecoraionForMessageField(),
|
||||||
margin: new EdgeInsets.only(top: 20.0, left: 12.0, right: 12.0),
|
margin: new EdgeInsets.only(top: 20.0, left: 12.0, right: 12.0),
|
||||||
padding: new EdgeInsets.only(bottom: 16.0, left: 14.0, right: 14.0),
|
padding: new EdgeInsets.only(bottom: 22.0, left: 14.0, right: 14.0),
|
||||||
child: new Center(child: new Text(_getMessageText(),
|
child: new Center(child: new Text(_getMessageText(),
|
||||||
textAlign: TextAlign.center, style: new TextStyle(height: 1.5, fontWeight: FontWeight.bold, fontSize: 14.0, color: _tokenActive ? tokenActiveTextColor : tokenActivateTextColor))));
|
textAlign: TextAlign.center, style: new TextStyle(height: 1.5, fontWeight: FontWeight.bold, fontSize: 14.0, color: _tokenActive ? tokenActiveTextColor : tokenActivateTextColor))));
|
||||||
}
|
}
|
||||||
@@ -72,28 +78,32 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
|||||||
double buttonHeight = 42.0;
|
double buttonHeight = 42.0;
|
||||||
double topMargin = 8.0;
|
double topMargin = 8.0;
|
||||||
return new Container(margin: new EdgeInsets.only(top: topMargin), height: buttonHeight,
|
return new Container(margin: new EdgeInsets.only(top: topMargin), height: buttonHeight,
|
||||||
child: new RaisedButton(child: new Text(_tokenActive ? 'ЗАВЕРШИТЬ РЕГИСТРАЦИЮ' : 'ОБНОВИТЬ СТАТУС АКТИВАЦИИ',
|
child: new RaisedButton(child: new Text(,
|
||||||
style: new TextStyle(fontSize: 14.0, color: Colors.white)),
|
style: new TextStyle(fontSize: 14.0, color: Colors.white)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_tokenActive) {
|
|
||||||
startScanner(context);
|
startScanner(context);
|
||||||
} else {
|
|
||||||
checkToken(context).then((response) {
|
|
||||||
|
|
||||||
print(response.body);
|
|
||||||
Map parsedMap = JSON.decode(response.body);
|
|
||||||
|
|
||||||
// Обновить экран, заменить сообщение о необходимости активации токена, на сообщние о том, что токен активен.
|
// if (_tokenActive) {
|
||||||
setState(() {
|
// startScanner(context);
|
||||||
_tokenActive = parsedMap['active'];
|
// } else {
|
||||||
});
|
// checkToken(context).then((response) {
|
||||||
|
|
||||||
}).catchError((error) {
|
// print(response.body);
|
||||||
print(error.toString());
|
// Map parsedMap = JSON.decode(response.body);
|
||||||
return false;
|
|
||||||
});
|
// // Обновить экран, заменить сообщение о необходимости активации токена, на сообщние о том, что токен активен.
|
||||||
}
|
// setState(() {
|
||||||
|
// _tokenActive = parsedMap['active'];
|
||||||
|
// });
|
||||||
|
|
||||||
|
// }).catchError((error) {
|
||||||
|
// print(error.toString());
|
||||||
|
// return false;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
color: primaryColor));
|
color: primaryColor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,8 @@ abstract class BaseState<T> extends State<T> {
|
|||||||
String error = null;
|
String error = null;
|
||||||
String textFieldValue = "";
|
String textFieldValue = "";
|
||||||
|
|
||||||
|
TextEditingController controller = new TextEditingController();
|
||||||
|
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
return new Scaffold(appBar: getAppBar(context), body: getBody(context));
|
return new Scaffold(appBar: getAppBar(context), body: getBody(context));
|
||||||
}
|
}
|
||||||
@@ -57,6 +59,13 @@ abstract class BaseState<T> extends State<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Смена состояния экрана при изменении текста в поле ввода.
|
||||||
|
handleUserInput(String text) {
|
||||||
|
setState(() {
|
||||||
|
textFieldValue = text;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Метод возвращает контейнер с установленными отступами, в котором размещен TextField обернутый в BoxDecoration.
|
/// Метод возвращает контейнер с установленными отступами, в котором размещен TextField обернутый в BoxDecoration.
|
||||||
getDecoratedTextWidget() {
|
getDecoratedTextWidget() {
|
||||||
return new Container(margin: new EdgeInsets.only(left: verticalMargin, right: verticalMargin),
|
return new Container(margin: new EdgeInsets.only(left: verticalMargin, right: verticalMargin),
|
||||||
@@ -76,16 +85,21 @@ abstract class BaseState<T> extends State<T> {
|
|||||||
|
|
||||||
/// Метод возвращает BoxDecoration для _getDecoratedInputField
|
/// Метод возвращает BoxDecoration для _getDecoratedInputField
|
||||||
getDecoraionForTextWidget() {
|
getDecoraionForTextWidget() {
|
||||||
return new BoxDecoration(color: textFieldBackground,
|
return new BoxDecoration(color: getTextFilledBackground(),
|
||||||
border: new Border.all(color: textBorderColor, width: 1.0,),
|
border: new Border.all(color: textBorderColor, width: 1.0,),
|
||||||
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color getTextFilledBackground() {
|
||||||
|
return const Color(0xffefefef);
|
||||||
|
}
|
||||||
|
|
||||||
Widget getTextWidget() {
|
Widget getTextWidget() {
|
||||||
return new TextField(keyboardType: TextInputType.number,
|
return new TextField(keyboardType: TextInputType.number,
|
||||||
decoration: new InputDecoration.collapsed(hintText: getHint(),
|
decoration: new InputDecoration.collapsed(hintText: getHint(),
|
||||||
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
||||||
onChanged: (text) => _handleUserInput(text));
|
controller: controller,
|
||||||
|
onChanged: (text) => handleUserInput(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Индикация ...
|
/// Индикация ...
|
||||||
@@ -93,5 +107,35 @@ abstract class BaseState<T> extends State<T> {
|
|||||||
return new Center(child: loading ? new CircularProgressIndicator() : null);
|
return new Center(child: loading ? new CircularProgressIndicator() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget getValueWithTitle(String title, String value) {
|
||||||
|
return new Container(padding: new EdgeInsets.only(left: verticalMargin, right: verticalMargin, top: 18.0),
|
||||||
|
child: new Column(children: <Widget>[
|
||||||
|
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))]),
|
||||||
|
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(value, textAlign: TextAlign.left, style: new TextStyle(color: Colors.black, fontSize: 20.0))])
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildButton(EdgeInsets margin, Widget widget) {
|
||||||
|
return new Container(margin: margin, height: buttonHeight, child: new Row(children: <Widget>[new Expanded(child: widget)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildRaisedButton(BuildContext context, String text, VoidCallback onPressed) {
|
||||||
|
return new RaisedButton(child: new Text(text,
|
||||||
|
style: new TextStyle(color: Colors.white)),
|
||||||
|
onPressed: onPressed,
|
||||||
|
color: primaryColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildFlatButton(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)),
|
||||||
|
decoration: _getDecoraionForScanButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
_getDecoraionForScanButton() {
|
||||||
|
return new BoxDecoration(
|
||||||
|
border: new Border.all(color: primaryColor, width: 1.0),
|
||||||
|
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -33,8 +33,13 @@ const Color tokenActiveTextColor = const Color(0xff1f5a1f);
|
|||||||
const Color tokenActivateTextColor = const Color(0xff4e3a19);
|
const Color tokenActivateTextColor = const Color(0xff4e3a19);
|
||||||
const Color greenBackground = const Color(0xff8ae28a);
|
const Color greenBackground = const Color(0xff8ae28a);
|
||||||
|
|
||||||
// Margins
|
// Dimens
|
||||||
const double verticalMargin = 28.0;
|
const double verticalMargin = 28.0;
|
||||||
|
const double buttonVerticalMargin = 64.0;
|
||||||
|
const double buttonHeight = 48.0;
|
||||||
|
const double iconHeight = 20.0;
|
||||||
|
|
||||||
|
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
||||||
|
|
||||||
// HttpClient
|
// HttpClient
|
||||||
final httpClient = createHttpClient();
|
final httpClient = createHttpClient();
|
||||||
@@ -56,14 +61,12 @@ checkToken(BuildContext context) async {
|
|||||||
/// Может производиться с нескольких экранов (splash, finish_registration).
|
/// Может производиться с нескольких экранов (splash, finish_registration).
|
||||||
startScanner(BuildContext context) async {
|
startScanner(BuildContext context) async {
|
||||||
|
|
||||||
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
|
||||||
|
|
||||||
// Канал слушает ловит вызовы методов из "нативной" части приложения.
|
// Канал слушает ловит вызовы методов из "нативной" части приложения.
|
||||||
// Могут быть вызваны либо logaut либо faq, либо purchase.
|
// Могут быть вызваны либо logaut либо faq, либо purchase.
|
||||||
platform.setMethodCallHandler((MethodCall call) async {
|
platform.setMethodCallHandler((MethodCall call) async {
|
||||||
|
|
||||||
if (call.method == 'foo') {
|
if (call.method == 'foo') {
|
||||||
logout();
|
logout(context);
|
||||||
} else {
|
} else {
|
||||||
pushRoute(context, new PurchaseScreen());
|
pushRoute(context, new PurchaseScreen());
|
||||||
}
|
}
|
||||||
@@ -71,22 +74,24 @@ startScanner(BuildContext context) async {
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
await platform.invokeMethod('startScanner');
|
await platform.invokeMethod('startScanner');
|
||||||
}
|
}
|
||||||
|
|
||||||
logout(BuildContext context) {
|
logout(BuildContext context) {
|
||||||
|
|
||||||
// String url = intUrl + 'tokens/' + token + '?_dmapptoken=' + intToken;
|
String url = intUrl + 'tokens/' + 'khooi' + '?_dmapptoken=' + intToken;
|
||||||
|
print(url);
|
||||||
|
httpClient.delete(url).then((response) {
|
||||||
|
print(response.body);
|
||||||
|
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
||||||
|
platform.invokeMethod('removeKeys');
|
||||||
|
pushRoute(context, new RegistrationScreen());
|
||||||
|
}).catchError((error) {
|
||||||
|
print(error.toString());
|
||||||
|
});
|
||||||
|
|
||||||
// httpClient.delete(url).then((response) {
|
|
||||||
// print(response.body);
|
|
||||||
// }).catchError((error) {
|
|
||||||
// print(error.toString());
|
|
||||||
// });
|
|
||||||
|
|
||||||
pushRoute(context, new RegistrationScreen());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Навигация по приложению.
|
/// Навигация по приложению.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class PurchaseScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class PurchaseScreenState<T> extends BaseState<T> {
|
class PurchaseScreenState<T> extends BaseState<T> {
|
||||||
|
|
||||||
String _sum = "1234.00";
|
String integerPart = '', fractionalPart = '';
|
||||||
|
|
||||||
@override String getTitle() {
|
@override String getTitle() {
|
||||||
return "Проведение покупки";
|
return "Проведение покупки";
|
||||||
@@ -27,7 +27,7 @@ class PurchaseScreenState<T> extends BaseState<T> {
|
|||||||
@overide getMenuButtons(BuildContext context) {
|
@overide getMenuButtons(BuildContext context) {
|
||||||
return <Widget>[
|
return <Widget>[
|
||||||
new IconButton(icon: new Icon(Icons.help_outline), onPressed: () {}),
|
new IconButton(icon: new Icon(Icons.help_outline), onPressed: () {}),
|
||||||
new IconButton(icon: new Image.asset(logout_png, height: 20.0, width: 20.0), onPressed: () => logout(context))
|
new IconButton(icon: new Image.asset(logout_png, height: iconHeight, width: iconHeight), onPressed: () => logout(context))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,47 +40,53 @@ class PurchaseScreenState<T> extends BaseState<T> {
|
|||||||
getValueWithTitle('Вознаграждение', '100%'),
|
getValueWithTitle('Вознаграждение', '100%'),
|
||||||
getHintLabel(),
|
getHintLabel(),
|
||||||
getDecoratedTextWidget(),
|
getDecoratedTextWidget(),
|
||||||
buildButton(new EdgeInsets.only(top: 36.0, left: 70.0, right: 70.0), buildRaisedButton(context, 'ЗАВЕРШИТЬ ПОКУПКУ', () => _purchase(context))),
|
buildButton(new EdgeInsets.only(top: 36.0, left: buttonVerticalMargin, right: buttonVerticalMargin), buildRaisedButton(context, 'ЗАВЕРШИТЬ ПОКУПКУ', () => _purchase(context))),
|
||||||
buildButton(new EdgeInsets.only(top: 24.0, left: 70.0, right: 70.0), buildFlatButton(context, 'СКАНИРОВАТЬ', primaryColor))])
|
buildButton(new EdgeInsets.only(top: 24.0, left: buttonVerticalMargin, right: buttonVerticalMargin), buildFlatButton(context, 'СКАНИРОВАТЬ', primaryColor))])
|
||||||
].reversed.toList()));
|
].reversed.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getValueWithTitle(String title, String value) {
|
@override Color getTextFilledBackground() {
|
||||||
return new Container(padding: new EdgeInsets.only(left: verticalMargin, right: verticalMargin, top: 18.0),
|
return Colors.white;
|
||||||
child: new Column(children: <Widget>[
|
|
||||||
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))]),
|
|
||||||
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(value, textAlign: TextAlign.left, style: new TextStyle(color: Colors.black, fontSize: 20.0))])
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildButton(EdgeInsets margin, Widget widget) {
|
/// Смена состояния экрана при изменении текста в поле ввода.
|
||||||
return new Container(margin: margin, height: 48.0, child: new Row(children: <Widget>[new Expanded(child: widget)]));
|
@override handleUserInput(String tmpString) {
|
||||||
}
|
setState(() {
|
||||||
|
tmpString = tmpString.replaceAll('-', '');
|
||||||
Widget buildRaisedButton(BuildContext context, String text, VoidCallback onPressed) {
|
tmpString = tmpString.replaceAll(', ', '');
|
||||||
return new RaisedButton(child: new Text(text,
|
print(tmpString);
|
||||||
style: new TextStyle(color: Colors.white)),
|
if (tmpString.contains('.')) {
|
||||||
onPressed: onPressed,
|
int dotIndex = tmpString.indexOf('.');
|
||||||
color: primaryColor);
|
integerPart = tmpString.substring(0, dotIndex);
|
||||||
|
fractionalPart = tmpString.substring(dotIndex + 1, tmpString.length);
|
||||||
|
if (fractionalPart.length > 2) {
|
||||||
|
fractionalPart = fractionalPart.substring(0, 2);
|
||||||
|
}
|
||||||
|
controller.text = '${integerPart}.${fractionalPart}';
|
||||||
|
} else {
|
||||||
|
integerPart = tmpString;
|
||||||
|
controller.text = tmpString;
|
||||||
|
}
|
||||||
|
textFieldValue = controller.text;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFlatButton(BuildContext context, String title, Color textColor) {
|
_buildSum() {
|
||||||
return new Container(height: 48.0, child: new FlatButton(child: new Text(title,
|
String temporaryInteger = integerPart;
|
||||||
style: new TextStyle(color: textColor)),
|
String temporaryFractional = fractionalPart;
|
||||||
onPressed: () => startScanner(context)),
|
|
||||||
decoration: _getDecoraionForScanButton());
|
|
||||||
}
|
|
||||||
|
|
||||||
_getDecoraionForScanButton() {
|
while (temporaryFractional.length < 2) {
|
||||||
return new BoxDecoration(
|
temporaryFractional = temporaryFractional + '0';
|
||||||
border: new Border.all(color: primaryColor, width: 1.0),
|
}
|
||||||
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
|
||||||
|
return temporaryInteger + '.' + temporaryFractional;
|
||||||
}
|
}
|
||||||
|
|
||||||
_purchase(BuildContext context) {
|
_purchase(BuildContext context) {
|
||||||
|
String val = _buildSum();
|
||||||
showDialog(context: context, child: new AlertDialog(
|
showDialog(context: context, child: new AlertDialog(
|
||||||
title: new Text('Подтверждение'),
|
title: new Text('Подтверждение'),
|
||||||
content: new Text('Вы подтверждаете покупку на ${_sum} руб?'),
|
content: new Text('Вы подтверждаете покупку на ${val} руб?'),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
new FlatButton(
|
new FlatButton(
|
||||||
child: new Text('Нет'),
|
child: new Text('Нет'),
|
||||||
@@ -89,16 +95,11 @@ class PurchaseScreenState<T> extends BaseState<T> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
new FlatButton(
|
new FlatButton(
|
||||||
child: new Text('Дат'),
|
child: new Text('Да'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
pushRoute(context, new PurchaseSuccessScreen());
|
pushRoute(context, new PurchaseSuccessScreen(val));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
]));
|
]));
|
||||||
print('purchase');
|
|
||||||
}
|
|
||||||
|
|
||||||
_register(BuildContext context) async {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,23 @@ import 'purchase.dart';
|
|||||||
|
|
||||||
/// Экран проведения покупки.
|
/// Экран проведения покупки.
|
||||||
class PurchaseSuccessScreen extends StatefulWidget {
|
class PurchaseSuccessScreen extends StatefulWidget {
|
||||||
@override State createState() => new _PurchaseSuccessScreenState();
|
|
||||||
|
String val = '';
|
||||||
|
|
||||||
|
PurchaseSuccessScreen(String val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override State createState() => new PurchaseSuccessScreenState(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PurchaseSuccessScreenState<T> extends PurchaseScreenState<T> {
|
class PurchaseSuccessScreenState<T> extends PurchaseScreenState<T> {
|
||||||
|
|
||||||
|
String val = '';
|
||||||
|
|
||||||
|
PurchaseSuccessScreenState(String val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
@override String getTitle() {
|
@override String getTitle() {
|
||||||
return "Проведение покупки";
|
return "Проведение покупки";
|
||||||
@@ -25,17 +38,17 @@ class _PurchaseSuccessScreenState<T> extends PurchaseScreenState<T> {
|
|||||||
|
|
||||||
@override Widget getScreenContent() {
|
@override Widget getScreenContent() {
|
||||||
return new Column(children: <Widget>[
|
return new Column(children: <Widget>[
|
||||||
getValueWithTitle('Покупатель', 'Знаменитый Рокер Паук'),
|
getValueWithTitle('Покупатель', 'Знаменитый Рокер Паук'),
|
||||||
_getSuccessMessage(),
|
getSuccessMessage(),
|
||||||
new Expanded(child: new Center()),
|
new Expanded(child: new Center()),
|
||||||
buildButton(new EdgeInsets.only(bottom: 74.0, left: 70.0, right: 70.0), buildRaisedButton(context, 'СКАНИРОВАТЬ', () => startScanner(context)))
|
buildButton(new EdgeInsets.only(bottom: 74.0, left: buttonVerticalMargin, right: buttonVerticalMargin), buildRaisedButton(context, 'СКАНИРОВАТЬ', () => startScanner(context)))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getSuccessMessage() {
|
getSuccessMessage() {
|
||||||
return new Row(children: <Widget>[new Expanded(child: new Container(margin: new EdgeInsets.only(top: 20.0), height: 64.0,
|
return new Row(children: <Widget>[new Expanded(child: new Container(margin: new EdgeInsets.only(top: 20.0), height: 64.0,
|
||||||
decoration: new BoxDecoration(color: greenBackground),
|
decoration: new BoxDecoration(color: greenBackground),
|
||||||
child: new Center(child: new Text('Покупка на сумму 1234.00 руб. проведена', textAlign: TextAlign.center,
|
child: new Center(child: new Text('Покупка на сумму ${val} руб. проведена', textAlign: TextAlign.center,
|
||||||
style: new TextStyle(fontWeight: FontWeight.bold, color: tokenActiveTextColor)))))]);
|
style: new TextStyle(fontWeight: FontWeight.bold, color: tokenActiveTextColor)))))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override getHint() {
|
@override getHint() {
|
||||||
return 'ID merchant';
|
return 'ID магазина';
|
||||||
}
|
}
|
||||||
|
|
||||||
@overide getMenuButtons(BuildContext context) {
|
@overide getMenuButtons(BuildContext context) {
|
||||||
@@ -37,35 +37,17 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
getLogo(),
|
getLogo(),
|
||||||
getHintLabel(),
|
getHintLabel(),
|
||||||
getDecoratedTextWidget(),
|
getDecoratedTextWidget(),
|
||||||
_getButton(context)]))
|
buildButton(new EdgeInsets.only(top: 36.0, left: buttonVerticalMargin, right: buttonVerticalMargin),
|
||||||
|
buildRaisedButton(context, 'ЗАРЕГИСТРИРОВАТЬ', _isValidMerchantID() && !loading ? () => _registerShop(context) : null))]))
|
||||||
].reversed.toList()));
|
].reversed.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Метод возвращает кнопку, которая запускает отправку токена кассы на сервер.
|
|
||||||
_getButton(BuildContext context) {
|
|
||||||
double buttonHeight = 42.0;
|
|
||||||
double topMargin = 36.0;
|
|
||||||
double horizontalPadding = 40.0; // Отступы по краям от кнопки.
|
|
||||||
return new Container(margin: new EdgeInsets.only(top: topMargin), height: buttonHeight,
|
|
||||||
padding: new EdgeInsets.only(left: horizontalPadding, right: horizontalPadding),
|
|
||||||
child: new RaisedButton(child: new Text('ЗАРЕГИСТРИРОВАТЬ',
|
|
||||||
style: new TextStyle(color: Colors.white)),
|
|
||||||
onPressed: _isValidMerchantID() && !loading ? () => _registerShop(context) : null,
|
|
||||||
color: primaryColor));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Токен кассы - это DIN код. DIN код - это специальный код динекта, максимальная его длина - 25 символов.
|
/// Токен кассы - это DIN код. DIN код - это специальный код динекта, максимальная его длина - 25 символов.
|
||||||
_isValidMerchantID() {
|
_isValidMerchantID() {
|
||||||
|
print("${textFieldValue.length}");
|
||||||
return textFieldValue.length > 0 && textFieldValue.length < 25;
|
return textFieldValue.length > 0 && textFieldValue.length < 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Смена состояния экрана при изменении текста в поле ввода.
|
|
||||||
_handleUserInput(String text) {
|
|
||||||
setState(() {
|
|
||||||
textFieldValue = text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Показать индикатор, запросить токен.
|
/// Показать индикатор, запросить токен.
|
||||||
_registerShop(BuildContext context) {
|
_registerShop(BuildContext context) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -84,7 +66,6 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
|
|
||||||
/// Получение от платформы id установки, формирование запроса на получение токена, сохранение токена.
|
/// Получение от платформы id установки, формирование запроса на получение токена, сохранение токена.
|
||||||
_register(BuildContext context) async {
|
_register(BuildContext context) async {
|
||||||
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
|
||||||
|
|
||||||
String url = intUrl + 'tokens/?_dmapptoken=' + intToken;
|
String url = intUrl + 'tokens/?_dmapptoken=' + intToken;
|
||||||
String pos = (new DateTime.now().millisecondsSinceEpoch / 1000).toString();
|
String pos = (new DateTime.now().millisecondsSinceEpoch / 1000).toString();
|
||||||
@@ -95,31 +76,33 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
'pos': pos,
|
'pos': pos,
|
||||||
};
|
};
|
||||||
|
|
||||||
httpClient.post(url, body: body).then((response) {
|
pushRoute(context, new FinishRegistrationScreen());
|
||||||
|
|
||||||
|
// httpClient.post(url, body: body).then((response) {
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
error = null;
|
error = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
print(response.body);
|
// print(response.body);
|
||||||
Map parsedMap = JSON.decode(response.body);
|
// Map parsedMap = JSON.decode(response.body);
|
||||||
setState(() {
|
// setState(() {
|
||||||
loading = false;
|
// loading = false;
|
||||||
});
|
// });
|
||||||
if (response.statusCode == 201) {
|
// if (response.statusCode == 201) {
|
||||||
token = parsedMap['token'];
|
// token = parsedMap['token'];
|
||||||
platform.invokeMethod('saveToken', {'token' : token});
|
// platform.invokeMethod('saveToken', {'token' : token});
|
||||||
platform.invokeMethod('saveMerchantID', {'merchantID' : merchantID});
|
// platform.invokeMethod('saveMerchantID', {'merchantID' : merchantID});
|
||||||
pushRoute(context, new FinishRegistrationScreen());
|
// pushRoute(context, new FinishRegistrationScreen());
|
||||||
} else {
|
// } else {
|
||||||
setState(() {
|
// setState(() {
|
||||||
error = parsedMap['errors'][0];
|
// error = parsedMap['errors'][0];
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}).catchError((error) {
|
// }).catchError((error) {
|
||||||
setState(() {
|
// setState(() {
|
||||||
error = 'Отсутствует интернет соединение';
|
// error = 'Отсутствует интернет соединение';
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ class SplashScreen extends StatelessWidget {
|
|||||||
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
const platform = const MethodChannel('com.dinect.checker/instance_id');
|
||||||
token = await platform.invokeMethod('getToken');
|
token = await platform.invokeMethod('getToken');
|
||||||
print('token: $token');
|
print('token: $token');
|
||||||
|
|
||||||
// В случае, если в приложении отсутствует токен,
|
// В случае, если в приложении отсутствует токен,
|
||||||
// необходимо запустить регистрацию кассы.
|
// необходимо запустить регистрацию кассы.
|
||||||
|
|
||||||
@@ -44,7 +45,6 @@ class SplashScreen extends StatelessWidget {
|
|||||||
bool active = parsedMap['active'];
|
bool active = parsedMap['active'];
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
Navigator.of(context).pop();
|
|
||||||
// Запускается экран сканера, токен кассы активирован, с его помощью можно делать запросы к pos-api.
|
// Запускается экран сканера, токен кассы активирован, с его помощью можно делать запросы к pos-api.
|
||||||
startScanner(context);
|
startScanner(context);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user