Упрощена работа с локалью, базовый url и токен приложения вынесены в build.gradle, добавлен конфиг для разработки и тестирования, исправлена проблема с переходом на экран сканера если локаль не выбиралась в настройках
This commit is contained in:
12
README.md
12
README.md
@@ -3,7 +3,6 @@
|
|||||||
Для запуска необходимо установить [Dart](https://www.dartlang.org/install) - язык программирования и
|
Для запуска необходимо установить [Dart](https://www.dartlang.org/install) - язык программирования и
|
||||||
[flutter](https://flutter.io/setup/) - фреймворк для создания кроссплатформенных мобильных приложений на этом языке.
|
[flutter](https://flutter.io/setup/) - фреймворк для создания кроссплатформенных мобильных приложений на этом языке.
|
||||||
|
|
||||||
|
|
||||||
Для сборки и запуска приложения используются команды flutter run (собирает debug apk, устанавливает его на устройство) и
|
Для сборки и запуска приложения используются команды flutter run (собирает debug apk, устанавливает его на устройство) и
|
||||||
flutter build (собирает release apk, не устанавливает на устройство).
|
flutter build (собирает release apk, не устанавливает на устройство).
|
||||||
|
|
||||||
@@ -20,11 +19,9 @@ flutter build (собирает release apk, не устанавливает н
|
|||||||
2) В файл pubscpec.yaml в раздел assets/ добавить пути этих изображений.
|
2) В файл pubscpec.yaml в раздел assets/ добавить пути этих изображений.
|
||||||
|
|
||||||
3) В файл lib/resources.dart в методы ```getPrimaryColor``` и ```getButtonsColor```
|
3) В файл lib/resources.dart в методы ```getPrimaryColor``` и ```getButtonsColor```
|
||||||
добавить цвета необходимые цвета.*
|
добавить цвета необходимые цвета.
|
||||||
|
|
||||||
4) В файле consts.dart изменить значения переменных appName, url, appToken на правильные для сборки значения.*
|
4) В файл android/app/build.gradle в раздел productFlavors добавить блок следующего вида:
|
||||||
|
|
||||||
5) В файл android/app/build.gradle в раздел productFlavors добавить блок следующего вида:
|
|
||||||
```
|
```
|
||||||
%name% {
|
%name% {
|
||||||
applicationId 'com.dinect.autobonus'
|
applicationId 'com.dinect.autobonus'
|
||||||
@@ -33,6 +30,8 @@ flutter build (собирает release apk, не устанавливает н
|
|||||||
buildConfigField "int", "currency", "643"
|
buildConfigField "int", "currency", "643"
|
||||||
buildConfigField "String", "supportPhone", "\"8-800-234-6064\""
|
buildConfigField "String", "supportPhone", "\"8-800-234-6064\""
|
||||||
buildConfigField "String", "supportUrl", "\"https://www.auto-club.biz\""
|
buildConfigField "String", "supportUrl", "\"https://www.auto-club.biz\""
|
||||||
|
buildConfigField "String", "endpoint", "\"https://pos-api-int.dinect.com/20130701/\""
|
||||||
|
buildConfigField "String", "appToken", "\"9fec83cdca38c357e6b65dbb17514cdd36bf2a08\""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -46,7 +45,6 @@ flutter build (собирает release apk, не устанавливает н
|
|||||||
</resources>
|
</resources>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Иконки проще всего нарезать тут:
|
Иконки проще всего нарезать тут:
|
||||||
https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html
|
https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html
|
||||||
|
|
||||||
@@ -55,8 +53,6 @@ https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html
|
|||||||
После выполнения всех этих пунктов появится возможность собирать приложение
|
После выполнения всех этих пунктов появится возможность собирать приложение
|
||||||
как описано выше(flutter run --flavor %name% либо flutter build apk --flavor %name%).
|
как описано выше(flutter run --flavor %name% либо flutter build apk --flavor %name%).
|
||||||
|
|
||||||
\* - параметры из этих пунктов будут при первой же возможности перенесены в пункт 5, чтобы менять их из одного места.
|
|
||||||
|
|
||||||
#Добавление локализации приложения
|
#Добавление локализации приложения
|
||||||
|
|
||||||
1) В каталог lib/i18n добавить файл messages_%locale%.dart.
|
1) В каталог lib/i18n добавить файл messages_%locale%.dart.
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ android {
|
|||||||
buildConfigField "int", "currency", "643"
|
buildConfigField "int", "currency", "643"
|
||||||
buildConfigField "String", "supportPhone", "\"8-800-234-6064\""
|
buildConfigField "String", "supportPhone", "\"8-800-234-6064\""
|
||||||
buildConfigField "String", "supportUrl", "\"https://www.auto-club.biz\""
|
buildConfigField "String", "supportUrl", "\"https://www.auto-club.biz\""
|
||||||
|
buildConfigField "String", "endpoint", "\"https://pos-api-autoclub.dinect.com/20130701/\""
|
||||||
|
buildConfigField "String", "appToken", "\"bdea0f3ba9034b688019a7cac753d1209e2b227f\""
|
||||||
}
|
}
|
||||||
|
|
||||||
pip {
|
pip {
|
||||||
@@ -58,6 +60,19 @@ android {
|
|||||||
buildConfigField "int", "currency", "980"
|
buildConfigField "int", "currency", "980"
|
||||||
buildConfigField "String", "supportPhone", "\"+38 080 030 9997\\n+38 044 390 1697\""
|
buildConfigField "String", "supportPhone", "\"+38 080 030 9997\\n+38 044 390 1697\""
|
||||||
buildConfigField "String", "supportUrl", "\"http://discount.kiev.ua/\""
|
buildConfigField "String", "supportUrl", "\"http://discount.kiev.ua/\""
|
||||||
|
buildConfigField "String", "endpoint", "\"https://pos-api.discount.kiev.ua/20130701/\""
|
||||||
|
buildConfigField "String", "appToken", "\"bdea0f3ba9034b688019a7cac753d1209e2b227f\""
|
||||||
|
}
|
||||||
|
|
||||||
|
develop {
|
||||||
|
applicationId 'com.dinect.develop'
|
||||||
|
buildConfigField "String", "locale", "\"ru\""
|
||||||
|
buildConfigField "String", "flavor", "\"autobonus\""
|
||||||
|
buildConfigField "int", "currency", "643"
|
||||||
|
buildConfigField "String", "supportPhone", "\"8 800 555 35 35\""
|
||||||
|
buildConfigField "String", "supportUrl", "\"http://yandex.ru/\""
|
||||||
|
buildConfigField "String", "endpoint", "\"https://pos-api-int.dinect.com/20130701/\""
|
||||||
|
buildConfigField "String", "appToken", "\"9fec83cdca38c357e6b65dbb17514cdd36bf2a08\""
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -79,7 +94,7 @@ flutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
compile 'com.squareup.okhttp3:okhttp:3.8.1'
|
compile 'com.squareup.okhttp3:okhttp:3.8.1'
|
||||||
compile 'com.squareup.okio:okio:1.13.0'
|
compile 'com.squareup.okio:okio:1.13.0'
|
||||||
|
|||||||
@@ -4,50 +4,37 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.dinect.checker.net.ApiClient;
|
|
||||||
import com.dinect.checker.zbar.CameraActivity;
|
import com.dinect.checker.zbar.CameraActivity;
|
||||||
import com.dinect.checker.zxing.ScannerActivity;
|
import com.dinect.checker.zxing.ScannerActivity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import io.flutter.app.FlutterActivity;
|
import io.flutter.app.FlutterActivity;
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
|
||||||
import io.flutter.plugin.common.MethodChannel.Result;
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
import io.flutter.plugins.GeneratedPluginRegistrant;
|
import io.flutter.plugins.GeneratedPluginRegistrant;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class MainActivity extends FlutterActivity {
|
public class MainActivity extends FlutterActivity {
|
||||||
|
|
||||||
static final String TAG = "Checker.MainActivity";
|
|
||||||
|
|
||||||
private static final int START_SCANNER_REQUEST_CODE = 2017;
|
private static final int START_SCANNER_REQUEST_CODE = 2017;
|
||||||
|
private static final String FLUTTER_CHANNEL_NAME = "com.dinect.checker/instance_id";
|
||||||
|
|
||||||
public static final String PREF_API_URL = "prefs_api_token";
|
static final String PREF_API_URL = "prefs_api_token";
|
||||||
public static final String PREF_APP_TOKEN = "pres_app_token";
|
static final String PREF_APP_TOKEN = "pres_app_token";
|
||||||
public static final String PREF_POS_TOKEN = "pref_pos_token";
|
static final String PREF_POS_TOKEN = "pref_pos_token";
|
||||||
static final String PREF_APP_BAR_COLOR = "pref_app_bar_color";
|
static final String PREF_APP_BAR_COLOR = "pref_app_bar_color";
|
||||||
|
static final String SCANNER_BACKEND_KEY = "scanner_backend_idx";
|
||||||
|
|
||||||
public static final int ZXING = 0;
|
static final int ZXING = 0;
|
||||||
public static final int ZBAR = 1;
|
static final int ZBAR = 1;
|
||||||
|
|
||||||
static final Class[] SCANNER_BACKEND = {
|
static final Class[] SCANNER_BACKEND = {
|
||||||
ScannerActivity.class,
|
ScannerActivity.class,
|
||||||
CameraActivity.class,
|
CameraActivity.class,
|
||||||
};
|
};
|
||||||
|
|
||||||
static final String SCANNER_BACKEND_KEY = "scanner_backend_idx";
|
|
||||||
|
|
||||||
private MethodChannel mChannel;
|
private MethodChannel mChannel;
|
||||||
private Map mScannerArgs;
|
private Map mScannerArgs;
|
||||||
|
|
||||||
@@ -55,9 +42,9 @@ public class MainActivity extends FlutterActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
GeneratedPluginRegistrant.registerWith(this);
|
GeneratedPluginRegistrant.registerWith(this);
|
||||||
mChannel = new MethodChannel(getFlutterView(), "com.dinect.checker/instance_id");
|
mChannel = new MethodChannel(getFlutterView(), FLUTTER_CHANNEL_NAME);
|
||||||
mChannel.setMethodCallHandler(
|
mChannel.setMethodCallHandler(
|
||||||
new MethodCallHandler() {
|
new MethodChannel.MethodCallHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onMethodCall(MethodCall call, Result result) {
|
public void onMethodCall(MethodCall call, Result result) {
|
||||||
callMethod(call, result);
|
callMethod(call, result);
|
||||||
@@ -89,6 +76,12 @@ public class MainActivity extends FlutterActivity {
|
|||||||
case "getSupportUrl":
|
case "getSupportUrl":
|
||||||
result.success(BuildConfig.supportUrl);
|
result.success(BuildConfig.supportUrl);
|
||||||
break;
|
break;
|
||||||
|
case "getEndpoint":
|
||||||
|
result.success(BuildConfig.endpoint);
|
||||||
|
break;
|
||||||
|
case "getAppToken":
|
||||||
|
result.success(BuildConfig.appToken);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
break;
|
break;
|
||||||
@@ -112,6 +105,7 @@ public class MainActivity extends FlutterActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setLocale(String locale) {
|
private void setLocale(String locale) {
|
||||||
|
locale = locale != null ? locale : getLanguage();
|
||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
Configuration configuration = new Configuration(res.getConfiguration());
|
Configuration configuration = new Configuration(res.getConfiguration());
|
||||||
configuration.locale = new Locale(locale);
|
configuration.locale = new Locale(locale);
|
||||||
@@ -146,7 +140,6 @@ public class MainActivity extends FlutterActivity {
|
|||||||
mChannel.invokeMethod("purchase", args);
|
mChannel.invokeMethod("purchase", args);
|
||||||
} else {
|
} else {
|
||||||
String menuItem = data.getExtras().getString("item", null);
|
String menuItem = data.getExtras().getString("item", null);
|
||||||
Log.d(TAG, menuItem);
|
|
||||||
if (menuItem != null) {
|
if (menuItem != null) {
|
||||||
mChannel.invokeMethod(menuItem, null);
|
mChannel.invokeMethod(menuItem, null);
|
||||||
}
|
}
|
||||||
@@ -190,4 +183,11 @@ public class MainActivity extends FlutterActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getEndpoint() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getAppToken() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
String error;
|
String error;
|
||||||
|
|
||||||
/// Введенное пользователем значение.
|
/// Введенное пользователем значение.
|
||||||
String dinCode = '';
|
String merchantID = '';
|
||||||
|
|
||||||
Widget getMainWidget() {
|
Widget getMainWidget() {
|
||||||
return app == null ? getBackground() : new Scaffold(appBar: getAppBar(),
|
return app == null ? getBackground() : new Scaffold(appBar: getAppBar(),
|
||||||
@@ -112,7 +112,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
|
|
||||||
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
|
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
|
||||||
String getHintOrError() {
|
String getHintOrError() {
|
||||||
if (dinCode.length == 0 && error == null) {
|
if (merchantID.length == 0 && error == null) {
|
||||||
return ' ';
|
return ' ';
|
||||||
} else if (error != null) {
|
} else if (error != null) {
|
||||||
return error;
|
return error;
|
||||||
@@ -130,7 +130,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
/// Смена состояния экрана при изменении текста в поле ввода.
|
/// Смена состояния экрана при изменении текста в поле ввода.
|
||||||
void handleUserInput(String text) {
|
void handleUserInput(String text) {
|
||||||
setState(() {
|
setState(() {
|
||||||
dinCode = text;
|
merchantID = text;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import 'package:checker/screens/settings.dart';
|
|||||||
import 'package:checker/screens/splash.dart';
|
import 'package:checker/screens/splash.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'consts.dart';
|
|
||||||
import 'db.dart';
|
import 'db.dart';
|
||||||
import 'network.dart';
|
import 'network.dart';
|
||||||
import 'resources.dart';
|
import 'resources.dart';
|
||||||
@@ -34,11 +34,11 @@ faq(BuildContext context, bool returnToScanner) {
|
|||||||
logout(BuildContext context, SqliteHelper helper) async {
|
logout(BuildContext context, SqliteHelper helper) async {
|
||||||
|
|
||||||
String token = await helper.getToken();
|
String token = await helper.getToken();
|
||||||
String locale = await helper.getLocale();
|
// String locale = await helper.getLocale();
|
||||||
|
|
||||||
VoidCallback positiveCallback = () {
|
VoidCallback positiveCallback = () {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
deleteToken(token, locale).then((response) {
|
getDeleteTokenRequest(token).then((response) {
|
||||||
helper.clear().then((result) {
|
helper.clear().then((result) {
|
||||||
helper.close().then((_) {
|
helper.close().then((_) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@@ -59,8 +59,7 @@ logout(BuildContext context, SqliteHelper helper) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceLogout(String token , BuildContext context) async {
|
forceLogout(String token , BuildContext context) async {
|
||||||
|
getDeleteTokenRequest(token).then((response) {
|
||||||
deleteToken(token, 'ru').then((response) {
|
|
||||||
SqliteHelper helper = new SqliteHelper();
|
SqliteHelper helper = new SqliteHelper();
|
||||||
helper.open().then((_) {
|
helper.open().then((_) {
|
||||||
helper.clear().then((_) {
|
helper.clear().then((_) {
|
||||||
@@ -87,7 +86,6 @@ startScanner(BuildContext context, String app, SqliteHelper helper) async {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
String token = await helper.getToken();
|
String token = await helper.getToken();
|
||||||
String locale = await helper.getLocale();
|
|
||||||
helper.close();
|
helper.close();
|
||||||
// Канал ловит вызовы методов из "нативной" части приложения.
|
// Канал ловит вызовы методов из "нативной" части приложения.
|
||||||
// Могут быть вызваны либо logout либо faq, либо purchase.
|
// Могут быть вызваны либо logout либо faq, либо purchase.
|
||||||
@@ -116,15 +114,20 @@ startScanner(BuildContext context, String app, SqliteHelper helper) async {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await platform.invokeMethod('startScanner', {
|
platform.invokeMethod('getEndpoint').then((endpoint) {
|
||||||
'token': token,
|
platform.invokeMethod('getAppToken').then((appToken) async {
|
||||||
'url': url,
|
platform.invokeMethod('startScanner', {
|
||||||
'appToken': appToken,
|
'token': token,
|
||||||
'locale': locale,
|
'url': endpoint,
|
||||||
'color': Resources
|
'appToken': appToken,
|
||||||
.getPrimaryColor(app)
|
'locale': Intl.defaultLocale,
|
||||||
.value
|
'color': Resources
|
||||||
|
.getPrimaryColor(app)
|
||||||
|
.value
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// Serious constants
|
|
||||||
const String appName = "Autobonus";
|
|
||||||
|
|
||||||
const String url = 'https://pos-api-autoclub.dinect.com/20130701/';
|
|
||||||
const String appToken = 'bdea0f3ba9034b688019a7cac753d1209e2b227f';
|
|
||||||
|
|
||||||
//const String url = 'https://pos-api-int.dinect.com/20130701/';
|
|
||||||
//const String appToken = '9fec83cdca38c357e6b65dbb17514cdd36bf2a08';
|
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
const String logout_png = 'assets/logout.png';
|
const String logout_png = 'assets/logout.png';
|
||||||
const String help_png = 'assets/help.png';
|
const String help_png = 'assets/help.png';
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class SqliteHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Создается запись в таблице, содержащая данные, которые не зависят от сессии.
|
/// Создается запись в таблице, содержащая данные, которые не зависят от сессии.
|
||||||
Future createAppInfo(String locale, int currency) async {
|
Future createAppInfo(int currency) async {
|
||||||
List<Map> appInfo = await db.query(tableSettings);
|
List<Map> appInfo = await db.query(tableSettings);
|
||||||
if (appInfo.length > 0) {
|
if (appInfo.length > 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:checker/screens/splash.dart';
|
import 'package:checker/screens/splash.dart';
|
||||||
import 'consts.dart';
|
|
||||||
|
|
||||||
/// Точка входа в приложение.
|
/// Точка входа в приложение.
|
||||||
void main() {
|
void main() {
|
||||||
runApp(new Checker());
|
runApp(new Checker());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Запрашивать appName у платформы
|
|
||||||
class Checker extends StatelessWidget {
|
class Checker extends StatelessWidget {
|
||||||
|
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
return new MaterialApp(
|
return new MaterialApp(home: new SplashScreen());
|
||||||
title: appName,
|
|
||||||
home: new SplashScreen());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:checker/db.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'consts.dart';
|
import 'common.dart';
|
||||||
|
|
||||||
// Клиент http приложения
|
// Клиент http приложения
|
||||||
final httpClient = createHttpClient();
|
final httpClient = createHttpClient();
|
||||||
@@ -8,23 +10,58 @@ final httpClient = createHttpClient();
|
|||||||
// Попытка создать токен для кассы.
|
// Попытка создать токен для кассы.
|
||||||
// В случае если токен для кассы уже существует, вернется ошибка 409.
|
// В случае если токен для кассы уже существует, вернется ошибка 409.
|
||||||
// На сервере есть ограничение в 40 токенов.
|
// На сервере есть ограничение в 40 токенов.
|
||||||
createToken(String merchantId, String posID, String locale) async {
|
getCreateTokenRequest(Map httpBody) async {
|
||||||
|
return httpClient.post(
|
||||||
// Поле description - необязательное.
|
await getEndpoint() + 'tokens/?_dmapptoken=' + await getToken(),
|
||||||
var body = {
|
body: httpBody,
|
||||||
'merchant_shop': merchantId,
|
headers: {'Accept-Language': Intl.defaultLocale});
|
||||||
'pos': posID,
|
|
||||||
};
|
|
||||||
|
|
||||||
return httpClient.post(url + 'tokens/?_dmapptoken=' + appToken, body: body, headers: {'Accept-Language': locale});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверка статуса токена. В ответе приходит параметр active, который может быть либо true, либо false,.
|
// Проверка статуса токена. В ответе приходит параметр active, который может быть либо true, либо false,.
|
||||||
checkTokenStatus(String token, String locale) async {
|
getCheckTokenStatusRequest(String token) async {
|
||||||
return httpClient.get(url + 'tokens/' + token + '?_dmapptoken=' + appToken, headers: {'Accept-Language': locale});
|
return httpClient.get(
|
||||||
|
await getEndpoint() +
|
||||||
|
'tokens/' +
|
||||||
|
token +
|
||||||
|
'?_dmapptoken=' +
|
||||||
|
await getToken(),
|
||||||
|
headers: {'Accept-Language': Intl.defaultLocale});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удаление токена на сервере.
|
// Удаление токена на сервере.
|
||||||
deleteToken(String token, String locale) async {
|
getDeleteTokenRequest(String token) async {
|
||||||
return httpClient.delete(url + 'tokens/' + token + '?_dmapptoken=' + appToken, headers: {'Accept-Language': locale});
|
return httpClient.delete(
|
||||||
|
await getEndpoint() + 'tokens/' + token + '?_dmapptoken=' +
|
||||||
|
await getToken(), headers: {'Accept-Language': Intl.defaultLocale});
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoyaltyRequest(String endpoint, SqliteHelper helper) async {
|
||||||
|
String token = await helper.getToken();
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'DM-Authorization': 'dmapptoken ${await getToken()}',
|
||||||
|
'Authorization': 'dmtoken ${token}',
|
||||||
|
'Accept-Language': Intl.defaultLocale
|
||||||
|
};
|
||||||
|
|
||||||
|
return httpClient.get(endpoint, headers: headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPurchaseRequest(String endpoint, Map body, String token) async {
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'DM-Authorization': 'dmapptoken ${await getToken()}',
|
||||||
|
'Authorization': 'dmtoken ${token}',
|
||||||
|
'Accept-Language': Intl.defaultLocale
|
||||||
|
};
|
||||||
|
|
||||||
|
return httpClient.post(endpoint, body: body, headers: headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
getEndpoint() async {
|
||||||
|
return await platform.invokeMethod('getEndpoint');
|
||||||
|
}
|
||||||
|
|
||||||
|
getToken() async {
|
||||||
|
return await platform.invokeMethod('getAppToken');
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ import 'package:checker/network.dart';
|
|||||||
import 'package:checker/strings.dart';
|
import 'package:checker/strings.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class FinishRegistrationScreen extends BaseScreen {
|
class FinishRegistrationScreen extends BaseScreen {
|
||||||
|
|
||||||
@@ -66,8 +67,7 @@ class RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
|||||||
} else {
|
} else {
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
String token = await helper.getToken();
|
String token = await helper.getToken();
|
||||||
String locale = await helper.getLocale();
|
getCheckTokenStatusRequest(token).then((response) {
|
||||||
checkTokenStatus(token, locale).then((response) {
|
|
||||||
Map parsedMap = JSON.decode(response.body);
|
Map parsedMap = JSON.decode(response.body);
|
||||||
|
|
||||||
// Обновить экран, заменить сообщение о необходимости активации токена, на сообщние о том, что токен активен.
|
// Обновить экран, заменить сообщение о необходимости активации токена, на сообщние о том, что токен активен.
|
||||||
|
|||||||
@@ -45,18 +45,8 @@ class LanguagesState extends SettingsBaseState<LanguagesScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void getSelectedValue() {
|
void getSelectedValue() {
|
||||||
helper.getLocale().then((locale) {
|
setState(() {
|
||||||
if (locale == null) {
|
selectedItem = getOptions().indexOf(getLocaleTitle(Intl.defaultLocale));
|
||||||
platform.invokeMethod('getLocale').then((locale) {
|
|
||||||
setState(() {
|
|
||||||
selectedItem == locale;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
selectedItem = getOptions().indexOf(getLocaleTitle(locale));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,17 +14,16 @@ import 'package:checker/screens/purchase_success.dart';
|
|||||||
|
|
||||||
/// Экран проведения покупки.
|
/// Экран проведения покупки.
|
||||||
class PurchaseScreen extends StatefulWidget {
|
class PurchaseScreen extends StatefulWidget {
|
||||||
|
|
||||||
PurchaseScreen(this.user, this.card);
|
PurchaseScreen(this.user, this.card);
|
||||||
|
|
||||||
final String user;
|
final String user;
|
||||||
final String card;
|
final String card;
|
||||||
|
|
||||||
@override State createState() => new PurchaseScreenState<PurchaseScreen>(user, card);
|
@override
|
||||||
|
State createState() => new PurchaseScreenState<PurchaseScreen>(user, card);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
||||||
|
|
||||||
/// Объект, помогающий вручную изменять введенный пользователем текст.
|
/// Объект, помогающий вручную изменять введенный пользователем текст.
|
||||||
/// Используется для форматирования введенных пользователем данных
|
/// Используется для форматирования введенных пользователем данных
|
||||||
/// (удаляет запрещенные символы до их отображаения).
|
/// (удаляет запрещенные символы до их отображаения).
|
||||||
@@ -35,7 +34,8 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
this.card = card;
|
this.card = card;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override Widget build(BuildContext ctx) {
|
@override
|
||||||
|
Widget build(BuildContext ctx) {
|
||||||
if (helper == null) {
|
if (helper == null) {
|
||||||
helper = new SqliteHelper();
|
helper = new SqliteHelper();
|
||||||
helper.open().then((_) {
|
helper.open().then((_) {
|
||||||
@@ -43,7 +43,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
platform.invokeMethod('getFlavor').then((flavor) {
|
platform.invokeMethod('getFlavor').then((flavor) {
|
||||||
app = flavor;
|
app = flavor;
|
||||||
setState(() {
|
setState(() {
|
||||||
getLoyalty(user['loyalty_url']);
|
requestLoyalty(user['loyalty_url']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -57,17 +57,24 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
String card = '';
|
String card = '';
|
||||||
String loyalty = '';
|
String loyalty = '';
|
||||||
|
|
||||||
@override Widget getScreenContent() {
|
@override
|
||||||
return new Column(
|
Widget getScreenContent() {
|
||||||
children: <Widget>[new Expanded(child: new ListView(children: <Widget>[
|
return new Column(children: <Widget>[
|
||||||
getValueWithDescription(StringsLocalization.buyer(), user['first_name'] == null ? '' : user['first_name']),
|
new Expanded(
|
||||||
getValueWithDescription(StringsLocalization.card(), card),
|
child: new ListView(children: <Widget>[
|
||||||
getValueWithDescription(StringsLocalization.reward(), loyalty),
|
getValueWithDescription(StringsLocalization.buyer(),
|
||||||
getHintLabel(),
|
user['first_name'] == null ? '' : user['first_name']),
|
||||||
getInputField(),
|
getValueWithDescription(StringsLocalization.card(), card),
|
||||||
wrapButton(getScreenMargins(36.0), getCompleteButton()),
|
getValueWithDescription(StringsLocalization.reward(), loyalty),
|
||||||
wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), Resources.getPrimaryColor(app)))
|
getHintLabel(),
|
||||||
]))]);
|
getInputField(),
|
||||||
|
wrapButton(getScreenMargins(36.0), getCompleteButton()),
|
||||||
|
wrapButton(
|
||||||
|
getScreenMargins(24.0),
|
||||||
|
getScanButton(context, StringsLocalization.scan(),
|
||||||
|
Resources.getPrimaryColor(app)))
|
||||||
|
]))
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getScreenMargins(double top) {
|
getScreenMargins(double top) {
|
||||||
@@ -76,37 +83,39 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCompleteButton() {
|
getCompleteButton() {
|
||||||
return buildRaisedButton(StringsLocalization.completePurchase(), () => onPurchaseClick());
|
return buildRaisedButton(
|
||||||
|
StringsLocalization.completePurchase(), () => onPurchaseClick());
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getScanButton(BuildContext context, String title, Color textColor) {
|
Widget getScanButton(BuildContext context, String title, Color textColor) {
|
||||||
return new Container(
|
return new Container(
|
||||||
height: buttonHeight,
|
height: buttonHeight,
|
||||||
child: new FlatButton(
|
child: new FlatButton(
|
||||||
child: new Text(
|
child: new Text(title, style: new TextStyle(color: textColor)),
|
||||||
title,
|
|
||||||
style: new TextStyle(color: textColor)),
|
|
||||||
onPressed: () => startScanner(context, app, helper)),
|
onPressed: () => startScanner(context, app, helper)),
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
border: new Border.all(color: Resources.getButtonColor(app), width: 1.0),
|
border: new Border.all(
|
||||||
|
color: Resources.getButtonColor(app), width: 1.0),
|
||||||
borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
|
borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override String getTitle() {
|
@override
|
||||||
|
String getTitle() {
|
||||||
return StringsLocalization.carryingPurchase();
|
return StringsLocalization.carryingPurchase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override getHintString() {
|
@override
|
||||||
|
getHintString() {
|
||||||
return StringsLocalization.sum();
|
return StringsLocalization.sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override getTextWidget() {
|
@override
|
||||||
|
getTextWidget() {
|
||||||
return new TextField(
|
return new TextField(
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
decoration: new InputDecoration.collapsed(
|
decoration: new InputDecoration.collapsed(
|
||||||
hintText: getHintString(),
|
hintText: getHintString(),
|
||||||
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)
|
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
||||||
),
|
|
||||||
controller: controller,
|
controller: controller,
|
||||||
onSubmitted: (String text) {
|
onSubmitted: (String text) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -118,33 +127,11 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoyalty(String url) async {
|
requestLoyalty(String url) async {
|
||||||
|
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
|
getLoyaltyRequest(url, helper).then((response) {
|
||||||
String token = await helper.getToken();
|
|
||||||
String locale = await helper.getLocale();
|
|
||||||
|
|
||||||
var headers = {
|
|
||||||
'DM-Authorization': 'dmapptoken $appToken',
|
|
||||||
'Authorization': 'dmtoken ${token}',
|
|
||||||
'Accept-Language': locale
|
|
||||||
};
|
|
||||||
|
|
||||||
httpClient.get(url, headers: headers).then((response) {
|
|
||||||
|
|
||||||
print(response.body);
|
|
||||||
|
|
||||||
Map bonuses = JSON.decode(response.body);
|
|
||||||
String type = bonuses['type'];
|
|
||||||
setState(() {
|
setState(() {
|
||||||
if (type == 'amount') {
|
setBonuses(JSON.decode(response.body));
|
||||||
this.loyalty = '${user['discount']}%';
|
|
||||||
} else {
|
|
||||||
List amountToBonus = bonuses['amount_to_bonus'];
|
|
||||||
double loyaltyVal = (double.parse(amountToBonus[1]) / amountToBonus[0]) * 100;
|
|
||||||
this.loyalty = '${loyaltyVal.toStringAsFixed(0)}%';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
print(error.toString());
|
print(error.toString());
|
||||||
@@ -152,15 +139,15 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Переделать? чтобы работало хорошо
|
// TODO: Переделать, если потребуется
|
||||||
String _cleanupNumber(String text){
|
String _cleanupNumber(String text) {
|
||||||
String tmp = text
|
String tmp = text
|
||||||
.replaceAll(' ', '')
|
.replaceAll(' ', '')
|
||||||
.replaceAll('-', '')
|
.replaceAll('-', '')
|
||||||
.replaceAll(',', '.')
|
.replaceAll(',', '.')
|
||||||
.replaceAll('..', '.');
|
.replaceAll('..', '.');
|
||||||
|
|
||||||
while(tmp.indexOf('..') != -1){
|
while (tmp.indexOf('..') != -1) {
|
||||||
tmp = tmp.replaceAll('..', '.');
|
tmp = tmp.replaceAll('..', '.');
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
@@ -172,17 +159,17 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
sumTotal = num.parse(text);
|
sumTotal = num.parse(text);
|
||||||
} catch(exception) {
|
} catch (exception) {
|
||||||
print(exception);
|
print(exception);
|
||||||
try {
|
try {
|
||||||
int idx = text.indexOf('.');
|
int idx = text.indexOf('.');
|
||||||
String integerPart = text.substring(0, idx);
|
String integerPart = text.substring(0, idx);
|
||||||
String fractionalPart = text.substring(idx + 1, text.length);
|
String fractionalPart = text.substring(idx + 1, text.length);
|
||||||
if(fractionalPart.length > 2) {
|
if (fractionalPart.length > 2) {
|
||||||
fractionalPart = fractionalPart.substring(0, 2);
|
fractionalPart = fractionalPart.substring(0, 2);
|
||||||
}
|
}
|
||||||
return '${integerPart}.${fractionalPart}';
|
return '${integerPart}.${fractionalPart}';
|
||||||
} catch(exception){
|
} catch (exception) {
|
||||||
print(exception);
|
print(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,23 +180,26 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
String val = _parseSum(controller.text);
|
String val = _parseSum(controller.text);
|
||||||
helper.getCurrency().then((currency) {
|
helper.getCurrency().then((currency) {
|
||||||
print(currency.toString());
|
print(currency.toString());
|
||||||
showDialog(context: context, child: new AlertDialog(
|
showDialog(
|
||||||
title: new Text(StringsLocalization.confirmation()),
|
context: context,
|
||||||
content: new Text(StringsLocalization.confirmPurchase(val, currency)),
|
child: new AlertDialog(
|
||||||
actions: <Widget>[
|
title: new Text(StringsLocalization.confirmation()),
|
||||||
new FlatButton(
|
content:
|
||||||
child: new Text(StringsLocalization.no()),
|
new Text(StringsLocalization.confirmPurchase(val, currency)),
|
||||||
onPressed: () {
|
actions: <Widget>[
|
||||||
Navigator.of(context).pop();
|
new FlatButton(
|
||||||
},
|
child: new Text(StringsLocalization.no()),
|
||||||
),
|
onPressed: () {
|
||||||
new FlatButton(
|
Navigator.of(context).pop();
|
||||||
child: new Text(StringsLocalization.yes()),
|
},
|
||||||
onPressed: () {
|
),
|
||||||
purchase(val);
|
new FlatButton(
|
||||||
},
|
child: new Text(StringsLocalization.yes()),
|
||||||
)
|
onPressed: () {
|
||||||
]));
|
purchase(val);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
]));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,11 +209,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
purchaseInProgress = true;
|
purchaseInProgress = true;
|
||||||
|
|
||||||
String token = await helper.getToken();
|
String token = await helper.getToken();
|
||||||
String locale = await helper.getLocale();
|
|
||||||
helper.getMerchantID().then((result) {
|
helper.getMerchantID().then((result) {
|
||||||
|
|
||||||
String url = user['purchases_url'];
|
|
||||||
|
|
||||||
helper.getCurrency().then((currency) {
|
helper.getCurrency().then((currency) {
|
||||||
var body = {
|
var body = {
|
||||||
'doc_id': result,
|
'doc_id': result,
|
||||||
@@ -232,14 +218,8 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
'sum_total': sumTotal
|
'sum_total': sumTotal
|
||||||
};
|
};
|
||||||
|
|
||||||
var headers = {
|
getPurchaseRequest(user['purchases_url'], body, token)
|
||||||
'DM-Authorization': 'dmapptoken $appToken',
|
.then((response) {
|
||||||
'Authorization': 'dmtoken ${token}',
|
|
||||||
'Accept-Language': locale
|
|
||||||
};
|
|
||||||
|
|
||||||
httpClient.post(url, body: body, headers: headers).then((response) {
|
|
||||||
|
|
||||||
print(response.body);
|
print(response.body);
|
||||||
Map parsedMap = JSON.decode(response.body);
|
Map parsedMap = JSON.decode(response.body);
|
||||||
|
|
||||||
@@ -247,11 +227,18 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
|
|
||||||
if (parsedMap.containsKey('errors')) {
|
if (parsedMap.containsKey('errors')) {
|
||||||
List<String> errors = parsedMap['errors'];
|
List<String> errors = parsedMap['errors'];
|
||||||
Scaffold.of(context).showSnackBar(new SnackBar(content: new Text(errors[0])));
|
Scaffold
|
||||||
|
.of(context)
|
||||||
|
.showSnackBar(new SnackBar(content: new Text(errors[0])));
|
||||||
} else {
|
} else {
|
||||||
pushRouteReplacement(context, new PurchaseSuccessScreen(sumTotal, user['first_name'] == null ? '' : user['first_name'], helper, app));
|
pushRouteReplacement(
|
||||||
|
context,
|
||||||
|
new PurchaseSuccessScreen(
|
||||||
|
sumTotal,
|
||||||
|
user['first_name'] == null ? '' : user['first_name'],
|
||||||
|
helper,
|
||||||
|
app));
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
purchaseInProgress = false;
|
purchaseInProgress = false;
|
||||||
print(error.toString());
|
print(error.toString());
|
||||||
@@ -261,4 +248,14 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBonuses(Map bonuses) {
|
||||||
|
if (bonuses['type'] == 'amount') {
|
||||||
|
this.loyalty = '${user['discount']}%';
|
||||||
|
} else {
|
||||||
|
double loyaltyVal = (double.parse(bonuses['amount_to_bonus'][1]) /
|
||||||
|
bonuses['amount_to_bonus'][0]) * 100;
|
||||||
|
this.loyalty = '${loyaltyVal.toStringAsFixed(0)}%';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,58 +11,64 @@ import 'package:checker/strings.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
// Пакет для обработки json с ответом от сервера.
|
// Пакет для обработки json с ответом от сервера.
|
||||||
|
|
||||||
|
|
||||||
/// Экран регистрации магазина и кассы.
|
/// Экран регистрации магазина и кассы.
|
||||||
class RegistrationScreen extends BaseScreen {
|
class RegistrationScreen extends BaseScreen {
|
||||||
|
|
||||||
RegistrationScreen(helper, app) : super(helper, app);
|
RegistrationScreen(helper, app) : super(helper, app);
|
||||||
|
|
||||||
@override State createState() => new RegistrationScreenState(helper, app);
|
@override
|
||||||
|
State createState() => new RegistrationScreenState(helper, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegistrationScreenState extends BaseState<RegistrationScreen> {
|
class RegistrationScreenState extends BaseState<RegistrationScreen> {
|
||||||
|
|
||||||
RegistrationScreenState(SqliteHelper helper, String app) {
|
RegistrationScreenState(SqliteHelper helper, String app) {
|
||||||
this.helper = helper;
|
this.helper = helper;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override Widget build(BuildContext ctx) {
|
@override
|
||||||
|
Widget build(BuildContext ctx) {
|
||||||
return getMainWidget();
|
return getMainWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override String getTitle() {
|
@override
|
||||||
|
String getTitle() {
|
||||||
return StringsLocalization.registration();
|
return StringsLocalization.registration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override getHintString() {
|
@override
|
||||||
|
getHintString() {
|
||||||
return StringsLocalization.idStore();
|
return StringsLocalization.idStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Список виджетов, автоматически прокручиваемый вверх при открытии клавиатуры.
|
/// Список виджетов, автоматически прокручиваемый вверх при открытии клавиатуры.
|
||||||
@override Widget getScreenContent() {
|
@override
|
||||||
|
Widget getScreenContent() {
|
||||||
return new Container(
|
return new Container(
|
||||||
child: new ListView(children: <Widget>[
|
child: new ListView(children: <Widget>[
|
||||||
new Column(children: <Widget>[
|
new Column(children: <Widget>[
|
||||||
getLogo(),
|
getLogo(),
|
||||||
getHintLabel(),
|
getHintLabel(),
|
||||||
getInputField(),
|
getInputField(),
|
||||||
getButton()
|
getButton()
|
||||||
])
|
])
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override getTextWidget() {
|
@override
|
||||||
return new TextField(keyboardType: TextInputType.number,
|
getTextWidget() {
|
||||||
decoration: new InputDecoration.collapsed(hintText: getHintString(),
|
return new TextField(
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
decoration: new InputDecoration.collapsed(
|
||||||
|
hintText: getHintString(),
|
||||||
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
||||||
onChanged: (text) => handleUserInput(text));
|
onChanged: (text) => handleUserInput(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Возвращает кнопку регистрации.
|
/// Возвращает кнопку регистрации.
|
||||||
getButton() {
|
getButton() {
|
||||||
return new Container(margin: new EdgeInsets.only(top: 36.0), child:
|
return new Container(
|
||||||
buildRaisedButton(StringsLocalization.signUp(), getOnPressed()));
|
margin: new EdgeInsets.only(top: 36.0),
|
||||||
|
child: buildRaisedButton(StringsLocalization.signUp(), getOnPressed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Возвращает обработчик нажатий на кнопку регистрации.
|
// Возвращает обработчик нажатий на кнопку регистрации.
|
||||||
@@ -72,8 +78,8 @@ class RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
|
|
||||||
/// Токен кассы - это DIN код. DIN код - это специальный код динекта, максимальная его длина - 25 символов.
|
/// Токен кассы - это DIN код. DIN код - это специальный код динекта, максимальная его длина - 25 символов.
|
||||||
_isValidMerchantID() {
|
_isValidMerchantID() {
|
||||||
print("${dinCode.length}");
|
print("${merchantID.length}");
|
||||||
return dinCode.length > 0 && dinCode.length < 25;
|
return merchantID.length > 0 && merchantID.length < 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Показать progressBar, запросить токен.
|
/// Показать progressBar, запросить токен.
|
||||||
@@ -88,8 +94,9 @@ class RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
_register() async {
|
_register() async {
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
String posID = await helper.getPosID();
|
String posID = await helper.getPosID();
|
||||||
String locale = await helper.getLocale();
|
|
||||||
createToken(dinCode, posID, locale).then((response) {
|
getCreateTokenRequest({'merchant_shop': merchantID, 'pos': posID})
|
||||||
|
.then((response) {
|
||||||
setState(() {
|
setState(() {
|
||||||
error = null;
|
error = null;
|
||||||
loading = false;
|
loading = false;
|
||||||
@@ -100,8 +107,9 @@ class RegistrationScreenState extends BaseState<RegistrationScreen> {
|
|||||||
Map parsedMap = JSON.decode(response.body);
|
Map parsedMap = JSON.decode(response.body);
|
||||||
|
|
||||||
if (response.statusCode == 201) {
|
if (response.statusCode == 201) {
|
||||||
helper.createSession(dinCode, posID, parsedMap['token']).then((_) {
|
helper.createSession(merchantID, posID, parsedMap['token']).then((_) {
|
||||||
pushRouteReplacement(context, new FinishRegistrationScreen(helper, app));
|
pushRouteReplacement(
|
||||||
|
context, new FinishRegistrationScreen(helper, app));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ import 'package:http/http.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class SplashScreen extends StatefulWidget {
|
class SplashScreen extends StatefulWidget {
|
||||||
@override State createState() => new _SplashScreenState();
|
@override
|
||||||
|
State createState() => new _SplashScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SplashScreenState extends BaseState<SplashScreen> {
|
class _SplashScreenState extends BaseState<SplashScreen> {
|
||||||
|
@override
|
||||||
@override Widget build(BuildContext ctx) {
|
Widget build(BuildContext ctx) {
|
||||||
if (helper == null) {
|
if (helper == null) {
|
||||||
helper = new SqliteHelper();
|
helper = new SqliteHelper();
|
||||||
helper.open().then((_) {
|
helper.open().then((_) {
|
||||||
@@ -42,7 +43,7 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
if (locale == null) {
|
if (locale == null) {
|
||||||
initWithSystemValue();
|
initWithSystemValue();
|
||||||
} else {
|
} else {
|
||||||
initWithSavedValue();
|
initWithSavedValue(locale);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -61,17 +62,15 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void initWithSavedValue() {
|
void initWithSavedValue(String locale) {
|
||||||
helper.getLocale().then((locale) {
|
initLocale(locale, () {
|
||||||
initLocale(locale, () {
|
showNext();
|
||||||
showNext();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSettingsTable(String locale) {
|
void createSettingsTable(String locale) {
|
||||||
platform.invokeMethod('getCurrency').then((currency) {
|
platform.invokeMethod('getCurrency').then((currency) {
|
||||||
helper.createAppInfo(locale, currency);
|
helper.createAppInfo(currency);
|
||||||
initLocale(locale, () {
|
initLocale(locale, () {
|
||||||
showNext();
|
showNext();
|
||||||
});
|
});
|
||||||
@@ -95,44 +94,31 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
Widget getScreenContent() {
|
Widget getScreenContent() {
|
||||||
return app == null
|
return app == null
|
||||||
? getBackground()
|
? getBackground()
|
||||||
: new Stack(
|
: new Stack(children: <Widget>[
|
||||||
children: <Widget>[
|
getBackground(),
|
||||||
getBackground(),
|
getLogo(),
|
||||||
getLogo(),
|
new Align(
|
||||||
new Align(
|
alignment: FractionalOffset.bottomRight,
|
||||||
alignment: FractionalOffset.bottomRight,
|
child: new Container(
|
||||||
child: new Container(
|
margin: new EdgeInsets.only(right: 11.0, bottom: 5.0),
|
||||||
margin: new EdgeInsets.only(
|
child: new Image.asset(powered_by_dinect_splash_png,
|
||||||
right: 11.0,
|
height: 16.0, width: 122.0)))
|
||||||
bottom: 5.0),
|
]);
|
||||||
child: new Image.asset(powered_by_dinect_splash_png,
|
|
||||||
height: 16.0,
|
|
||||||
width: 122.0)))
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Возвращает столбец с логотипом приложения и текстом под ним.
|
/// Возвращает столбец с логотипом приложения и текстом под ним.
|
||||||
/// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана.
|
/// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана.
|
||||||
getLogo() {
|
getLogo() {
|
||||||
return new Center(
|
return new Center(
|
||||||
child: new Column(
|
child: new Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
|
||||||
mainAxisSize: MainAxisSize.min,
|
new Image.asset(Resources.getLogo(app), height: 112.0, width: 252.0),
|
||||||
children: <Widget>[
|
new Image.asset(splash_text_png, height: 40.0, width: 240.0)
|
||||||
new Image.asset(
|
]));
|
||||||
Resources.getLogo(app),
|
|
||||||
height: 112.0,
|
|
||||||
width: 252.0),
|
|
||||||
new Image.asset(
|
|
||||||
splash_text_png,
|
|
||||||
height: 40.0,
|
|
||||||
width: 240.0)
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Запуск следующего экрана приложения.
|
/// Запуск следующего экрана приложения.
|
||||||
showNextScreen() async {
|
showNextScreen() async {
|
||||||
String token = await helper.getToken();
|
String token = await helper.getToken();
|
||||||
String locale = await helper.getLocale();
|
|
||||||
|
|
||||||
// В случае, если в приложении отсутствует токен,
|
// В случае, если в приложении отсутствует токен,
|
||||||
// необходимо запустить регистрацию кассы.
|
// необходимо запустить регистрацию кассы.
|
||||||
@@ -140,7 +126,7 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
pushRouteReplacement(context, new RegistrationScreen(helper, app));
|
pushRouteReplacement(context, new RegistrationScreen(helper, app));
|
||||||
} else {
|
} else {
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
checkTokenStatus(token, locale).then((statusResponse) {
|
getCheckTokenStatusRequest(token).then((statusResponse) {
|
||||||
handleStatusResponse(statusResponse, helper);
|
handleStatusResponse(statusResponse, helper);
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
handleError(error.toString());
|
handleError(error.toString());
|
||||||
@@ -183,11 +169,12 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
_createToken(SqliteHelper helper) async {
|
_createToken(SqliteHelper helper) async {
|
||||||
String merchantID = await helper.getMerchantID();
|
String merchantID = await helper.getMerchantID();
|
||||||
String posID = await helper.getPosID();
|
String posID = await helper.getPosID();
|
||||||
String locale = await helper.getLocale();
|
|
||||||
|
|
||||||
createToken(merchantID, posID, locale).then((response) {
|
getCreateTokenRequest({'merchant_shop': merchantID, 'pos': posID})
|
||||||
|
.then((response) {
|
||||||
if (response.statusCode == 409) {
|
if (response.statusCode == 409) {
|
||||||
pushRouteReplacement(context, new FinishRegistrationScreen(helper, app));
|
pushRouteReplacement(
|
||||||
|
context, new FinishRegistrationScreen(helper, app));
|
||||||
} else if (response.statusCode == 201) {
|
} else if (response.statusCode == 201) {
|
||||||
clearToken(response, helper);
|
clearToken(response, helper);
|
||||||
}
|
}
|
||||||
@@ -198,10 +185,9 @@ class _SplashScreenState extends BaseState<SplashScreen> {
|
|||||||
|
|
||||||
/// Очищаем бд, делаем запрос на удаление токена.
|
/// Очищаем бд, делаем запрос на удаление токена.
|
||||||
Future clearToken(Response response, SqliteHelper helper) async {
|
Future clearToken(Response response, SqliteHelper helper) async {
|
||||||
String locale = await helper.getLocale();
|
|
||||||
helper.clear().then((_) {
|
helper.clear().then((_) {
|
||||||
Map parsedMap = JSON.decode(response.body);
|
Map parsedMap = JSON.decode(response.body);
|
||||||
deleteToken(parsedMap['token'], locale).then((_) {
|
getDeleteTokenRequest(parsedMap['token']).then((_) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
pushRouteReplacement(context, new RegistrationScreen(helper, app));
|
pushRouteReplacement(context, new RegistrationScreen(helper, app));
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
|
|||||||
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
include ':app'
|
||||||
|
project(':app').projectDir = new File('android/app')
|
||||||
Reference in New Issue
Block a user