diff --git a/lib/core/base/base_view_model.dart b/lib/core/base/base_view_model.dart deleted file mode 100644 index 630c082..0000000 --- a/lib/core/base/base_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:logger/logger.dart'; -import '../logger.dart'; - -class BaseViewModel extends ChangeNotifier { - String _title; - bool _busy; - Logger log; - bool _isDisposed = false; - - BaseViewModel({ - bool busy = false, - String title, - }) : _busy = busy, - _title = title { - log = getLogger(title ?? this.runtimeType.toString()); - } - - bool get busy => this._busy; - bool get isDisposed => this._isDisposed; - String get title => _title ?? this.runtimeType.toString(); - - set busy(bool busy) { - log.i( - 'busy: ' - '$title is entering ' - '${busy ? 'busy' : 'free'} state', - ); - this._busy = busy; - notifyListeners(); - } - - @override - void notifyListeners() { - if (!isDisposed) { - super.notifyListeners(); - } else { - log.w('notifyListeners: Notify listeners called after ' - '${title ?? this.runtimeType.toString()} has been disposed'); - } - } - - @override - void dispose() { - log.i('dispose'); - _isDisposed = true; - super.dispose(); - } -} \ No newline at end of file diff --git a/lib/core/entity/Category.dart b/lib/core/entity/Category.dart index 5f08460..8d78a1b 100644 --- a/lib/core/entity/Category.dart +++ b/lib/core/entity/Category.dart @@ -4,16 +4,19 @@ const String Category_tableName = 'goods_category'; const String Category_columnId = 'id'; const String Category_columnParentIn = 'parent_id'; const String Category_columnName = 'name'; +const String Category_columnAppCompanyId = 'app_company_id'; class Category { int id; int parentIn; String name; + int appCompanyId; Map toMap() { var map = { Category_columnParentIn: parentIn, Category_columnName: name, + Category_columnAppCompanyId: appCompanyId }; if (id != null) { map[Category_columnId] = id; @@ -27,12 +30,14 @@ class Category { id = map[Category_columnId]; parentIn = map[Category_columnParentIn]; name = map[Category_columnName]; + appCompanyId = map[Category_columnAppCompanyId]; } Category.fromJson(Map map) { id = map[Category_columnId]; parentIn = map[Category_columnParentIn]; name = map[Category_columnName]; + appCompanyId = map[Category_columnAppCompanyId]; } } diff --git a/lib/core/entity/Goods.dart b/lib/core/entity/Goods.dart index 6a484a5..a5221c7 100644 --- a/lib/core/entity/Goods.dart +++ b/lib/core/entity/Goods.dart @@ -7,6 +7,12 @@ const String Goog_columnName = 'name'; const String Goog_columnPrice = 'price'; const String Goog_columnCategoryId = 'category_id'; const String Goog_columnEan = 'ean'; +const String Goog_columnAppCompanyId = 'app_company_id'; + +const String Goog_columnDescription = 'description'; +const String Goog_columnShowPrice = 'show_price'; +const String Goog_columnOkei = 'okei'; +const String Goog_columnDiscount = 'discount'; class Good { int id; @@ -15,6 +21,11 @@ class Good { double price; int categoryId; String ean; + int appCompanyId; + String description; + double showPrice; + int okei; + double discount; Map toMap() { var map = { @@ -23,6 +34,11 @@ class Good { Goog_columnPrice: price, Goog_columnCategoryId: categoryId, Goog_columnEan: ean, + Goog_columnAppCompanyId: appCompanyId, + Goog_columnDescription: description, + Goog_columnShowPrice: showPrice, + Goog_columnOkei: okei, + Goog_columnDiscount: discount }; if (id != null) { map[Goog_columnId] = id; @@ -39,6 +55,11 @@ class Good { price = map[Goog_columnPrice]?.toDouble(); categoryId = map[Goog_columnCategoryId]; ean = map[Goog_columnEan]; + appCompanyId= map[Goog_columnAppCompanyId]; + description = map[Goog_columnDescription]; + showPrice = map[Goog_columnShowPrice]?.toDouble(); + okei = map[Goog_columnOkei]; + discount = map[Goog_columnDiscount]?.toDouble(); } Good.fromJson(Map map) { @@ -48,6 +69,11 @@ class Good { price = double.parse(map[Goog_columnPrice]); categoryId = map[Goog_columnCategoryId]; ean = map[Goog_columnEan]; + appCompanyId = map[Goog_columnAppCompanyId]; + description = map[Goog_columnDescription]; + showPrice = map[Goog_columnShowPrice]?.toDouble(); + okei = map[Goog_columnOkei]; + discount = map[Goog_columnDiscount]?.toDouble(); } } diff --git a/lib/core/entity/Service.dart b/lib/core/entity/Service.dart index 45ea1b5..6195721 100644 --- a/lib/core/entity/Service.dart +++ b/lib/core/entity/Service.dart @@ -7,18 +7,36 @@ const String Service_columnName = 'name'; const String Service_columnPrice = 'price'; const String Service_columnCategoryId = 'category_id'; const String Service_columnEan = 'ean'; +const String Service_columnAppCompanyId = 'app_company_id'; + +const String Service_columnDescription = 'description'; +const String Service_columnShowPrice = 'show_price'; +const String Service_columnOkei = 'okei'; +const String Service_columnDiscount = 'discount'; + class Service { int id; int articul; String name; double price; + String ean; + int appCompanyId; + String description; + double showPrice; + String okei; + double discount; Map toMap() { var map = { Service_columnArticul: articul, Service_columnName: name, Service_columnPrice: price, + Service_columnAppCompanyId: appCompanyId, + Service_columnDescription: description, + Service_columnShowPrice: showPrice, + Service_columnOkei: okei, + Service_columnDiscount: discount }; if (id != null) { map[Service_columnId] = id; @@ -33,13 +51,24 @@ class Service { articul = map[Service_columnArticul]; name = map[Service_columnName]; price = map[Service_columnPrice]?.toDouble(); + appCompanyId = map[Service_columnAppCompanyId]; + description = map[Service_columnDescription]; + showPrice = map[Service_columnShowPrice]?.toDouble(); + okei = map[Service_columnOkei]; + discount = map[Service_columnDiscount]?.toDouble(); } Service.fromJson(Map map) { id = map[Service_columnId]; articul = map[Service_columnArticul]; name = map[Service_columnName]; - price = map[Service_columnPrice]?.toDouble(); } + price = map[Service_columnPrice]?.toDouble(); + appCompanyId = map[Service_columnAppCompanyId]; + description = map[Service_columnDescription]; + showPrice = map[Service_columnShowPrice]?.toDouble(); + okei = map[Service_columnOkei]; + discount = map[Service_columnDiscount]?.toDouble(); + } } diff --git a/lib/core/logger.dart b/lib/core/logger.dart index 1065a6d..082f050 100644 --- a/lib/core/logger.dart +++ b/lib/core/logger.dart @@ -38,15 +38,25 @@ import 'package:logger/logger.dart'; // } // } +//Logger getLogger(String className) { +// //return Logger(printer: SimpleLogPrinter(className)); +// return Logger( +// printer: PrettyPrinter( +// methodCount: 1, // number of method calls to be displayed +// errorMethodCount: 1, // number of method calls if stacktrace is provided +// lineLength: 120, // width of the output +// colors: false, // Colorful log messages +// printEmojis: false, // Print an emoji for each log message +// printTime: false // Should each log print contain a timestamp +// )); +//} + + Logger getLogger(String className) { //return Logger(printer: SimpleLogPrinter(className)); return Logger( - printer: PrettyPrinter( - methodCount: 2, // number of method calls to be displayed - errorMethodCount: 8, // number of method calls if stacktrace is provided - lineLength: 120, // width of the output - colors: true, // Colorful log messages - printEmojis: true, // Print an emoji for each log message - printTime: false // Should each log print contain a timestamp - )); + printer: SimplePrinter( + colors: true, // Colorful log messages + printTime: false // Should each log print contain a timestamp + )); } \ No newline at end of file diff --git a/lib/core/models/ProductDao.dart b/lib/core/models/ProductDao.dart deleted file mode 100644 index 21551cd..0000000 --- a/lib/core/models/ProductDao.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:aman_kassa_flutter/core/entity/Goods.dart'; - -class ProductDao { - final String name; - final num price; - num count; - final Good good; - - - ProductDao( {this.name, this.price, this.count, this.good}); - -} \ No newline at end of file diff --git a/lib/core/models/authResponse.dart b/lib/core/models/auth_response.dart similarity index 89% rename from lib/core/models/authResponse.dart rename to lib/core/models/auth_response.dart index 8b60a15..d255f4d 100644 --- a/lib/core/models/authResponse.dart +++ b/lib/core/models/auth_response.dart @@ -1,3 +1,4 @@ +import '../utilsParse.dart'; import 'user.dart'; class AuthResponse { @@ -17,11 +18,6 @@ class AuthResponse { } } -List parseListString(json){ - if(json==null) return null; - return new List.from(json); -} - class AuthBody { final List email; final List password; diff --git a/lib/core/models/calc_model.dart b/lib/core/models/calc_model.dart new file mode 100644 index 0000000..e49bb4e --- /dev/null +++ b/lib/core/models/calc_model.dart @@ -0,0 +1,14 @@ +class CalcModel { + String num1; + String num2; + bool closed; + String operation; + CalcModel({this.num1, this.num2, this.operation, this.closed = false}); + + @override + String toString() { + // TODO: implement toString + + return 'num1: $num1 num2:$num2 operation:$operation closed:$closed'; + } +} \ No newline at end of file diff --git a/lib/core/models/check_data.dart b/lib/core/models/check_data.dart new file mode 100644 index 0000000..954fd69 --- /dev/null +++ b/lib/core/models/check_data.dart @@ -0,0 +1,22 @@ +import 'package:aman_kassa_flutter/core/models/check_item.dart'; + +class CheckData { + final String type; + num card; + final List items; + CheckData({this.type, this.card, this.items}); + + static CheckData fromJson(Map json) { + return CheckData( + type: json['type'], + card: json['card'], + items: json['items'], + ); + } + Map toJson() => + { + 'type': type, + 'card': card, + 'items': items.map((e) => e.toJson()).toList() + }; +} \ No newline at end of file diff --git a/lib/core/models/check_item.dart b/lib/core/models/check_item.dart new file mode 100644 index 0000000..6e2125c --- /dev/null +++ b/lib/core/models/check_item.dart @@ -0,0 +1,23 @@ +class CheckItem { + final String name; + final num cnt; + final num price; + final int articul; + CheckItem({this.name, this.cnt, this.price, this.articul}); + + static CheckItem fromJson(Map json) { + return CheckItem( + name: json['name'], + cnt: json['cnt'], + price: json['price'], + articul: json['articul'], + ); + } + Map toJson() => + { + 'name': name, + 'cnt': cnt, + 'price': price, + 'articul': articul + }; +} \ No newline at end of file diff --git a/lib/core/models/Choice.dart b/lib/core/models/choice.dart similarity index 100% rename from lib/core/models/Choice.dart rename to lib/core/models/choice.dart diff --git a/lib/core/models/dialog_models.dart b/lib/core/models/dialog_models.dart index 3dda7e7..52a195f 100644 --- a/lib/core/models/dialog_models.dart +++ b/lib/core/models/dialog_models.dart @@ -14,13 +14,15 @@ class DialogRequest { } class DialogResponse { - final String fieldOne; - final String fieldTwo; + //final String fieldOne; + //final String fieldTwo; + final String responseText; final bool confirmed; DialogResponse({ - this.fieldOne, - this.fieldTwo, + //this.fieldOne, + //this.fieldTwo, + this.responseText, this.confirmed, }); } diff --git a/lib/core/models/DictDao.dart b/lib/core/models/dict_dao.dart similarity index 100% rename from lib/core/models/DictDao.dart rename to lib/core/models/dict_dao.dart diff --git a/lib/core/models/Message.dart b/lib/core/models/message.dart similarity index 100% rename from lib/core/models/Message.dart rename to lib/core/models/message.dart diff --git a/lib/core/models/product_dao.dart b/lib/core/models/product_dao.dart new file mode 100644 index 0000000..8885b86 --- /dev/null +++ b/lib/core/models/product_dao.dart @@ -0,0 +1,15 @@ +import 'package:aman_kassa_flutter/core/entity/Goods.dart'; +import 'package:aman_kassa_flutter/core/entity/Service.dart'; + +class ProductDao { + final String name; + final num price; + num count; + num total; + final Good good; + final Service service; + + + ProductDao( {this.name, this.price, this.count, this.total, this.good, this.service }); + +} \ No newline at end of file diff --git a/lib/core/models/Response.dart b/lib/core/models/response.dart similarity index 100% rename from lib/core/models/Response.dart rename to lib/core/models/response.dart diff --git a/lib/core/models/smena.dart b/lib/core/models/smena.dart new file mode 100644 index 0000000..519df1e --- /dev/null +++ b/lib/core/models/smena.dart @@ -0,0 +1,21 @@ +class Smena { + final int id; + final DateTime startedAt; + final DateTime endedAt; + final String message; + + Smena({this.id, this.startedAt, this.endedAt, this.message}); + + static Smena fromJson(Map data) => Smena( + id: data['id'], + message: data['message'], + startedAt: + data['started_at'] != null + ? DateTime.parse(data['started_at']) + : null, + endedAt: + data['ended_at'] != null + ? DateTime.parse(data['ended_at']) + : null, + ); +} diff --git a/lib/core/route_names.dart b/lib/core/route_names.dart index cd86836..1e43493 100644 --- a/lib/core/route_names.dart +++ b/lib/core/route_names.dart @@ -1,3 +1,5 @@ const String LoginViewRoute = "LoginView"; const String HomeViewRoute = "HomeView"; +const String ImageShowRoute = "ImageShowRoute"; +const String PaymentViewRoute = "PaymentView"; // Generate the views here diff --git a/lib/core/router.dart b/lib/core/router.dart index e6ee8c7..43f4abf 100644 --- a/lib/core/router.dart +++ b/lib/core/router.dart @@ -1,3 +1,6 @@ +import 'package:aman_kassa_flutter/views/check/image_show_container.dart'; +import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; + import './route_names.dart'; import 'package:aman_kassa_flutter/views/home/home_view.dart'; import 'package:aman_kassa_flutter/views/login/login_view.dart'; @@ -15,11 +18,15 @@ Route generateRoute(RouteSettings settings) { routeName: settings.name, viewToShow: HomeView(), ); - // case AddAndEditViewRoute: - // var documentToEdit = settings.arguments as Document; - // return SlideRightRoute(widget:AddAndEditView( - // edittingDocument: documentToEdit, - // )); + case PaymentViewRoute: + PaymentModel model = settings.arguments as PaymentModel; + return _getPageRoute( + routeName: settings.name, + viewToShow: PaymentView(model: model), + ); + case ImageShowRoute: + ImageShowModel data = settings.arguments as ImageShowModel; + return SlideRightRoute(widget:ImageShowContainer(data)); default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/core/services/ApiService.dart b/lib/core/services/ApiService.dart index ce98c9a..3ec151c 100644 --- a/lib/core/services/ApiService.dart +++ b/lib/core/services/ApiService.dart @@ -3,9 +3,10 @@ import 'dart:io'; import 'package:aman_kassa_flutter/core/base/base_service.dart'; import 'package:aman_kassa_flutter/core/entity/Goods.dart'; -import 'package:aman_kassa_flutter/core/models/Message.dart'; -import 'package:aman_kassa_flutter/core/models/Response.dart'; -import '../models/authResponse.dart'; +import 'package:aman_kassa_flutter/core/models/message.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; +import '../models/auth_response.dart'; import 'package:http/http.dart' as http; @@ -15,32 +16,92 @@ class ApiService extends BaseService { var client = new http.Client(); - Future authenticate(String email, String password) async { + Future authenticate(String email, String password, { bool statusCheck = true}) async { Map requestBody = { 'email': email, 'password': password }; - var response = await requestFormData('/authenticate', requestBody); - final respStr = await response.stream.bytesToString(); - AuthResponse aman = AuthResponse.fromJson(json.decode(respStr)); + String response = await requestFormData('/authenticate', requestBody, statusCheck: statusCheck ); + + AuthResponse aman = AuthResponse.fromJson(json.decode(response)); return aman.body; } Future> isActive(String token) async { Map requestBody = {'api_token': token}; var response = await requestFormData('/test_auth', requestBody); - final respStr = await response.stream.bytesToString(); - return Response.fromJson(json.decode(respStr), Message.fromJson); + return Response.fromJson(json.decode(response), Message.fromJson); } Future> logout(String token) async { Map requestBody = {'api_token': token}; var response = await requestFormData('/logout', requestBody); - final respStr = await response.stream.bytesToString(); - return Response.fromJson(json.decode(respStr), Message.fromJson); + return Response.fromJson(json.decode(response), Message.fromJson); } - Future requestFormData(String point, Map requestBody) async { + Future> money(String token) async { + Map requestBody = {'api_token': token}; + var response = await requestFormData('/money', requestBody); + return Response.fromJsonDynamic(json.decode(response)); + } + + Future> deposit(String token, String sum) async { + Map requestBody = {'api_token': token, 'summ': sum}; + var response = await requestFormData('/deposit', requestBody); + return Response.fromJsonDynamic(json.decode(response)); + } + + Future> withdrawal(String token, String sum) async { + Map requestBody = {'api_token': token, 'summ': sum}; + var response = await requestFormData('/withdrawal', requestBody); + return Response.fromJsonDynamic(json.decode(response)); + } + + + + Future> smena(String token) async { + Map requestBody = {'api_token': token}; + var response = await requestFormData('/smena', requestBody); + + return Response.fromJson(json.decode(response), Smena.fromJson); + } + + Future> closeSmena(String token) async { + Map requestBody = {'api_token': token}; + var response = await requestFormData('/close_smena', requestBody); + + return Response.fromJson(json.decode(response), Smena.fromJson); + } + + Future> openSmena(String token) async { + Map requestBody = {'api_token': token}; + var response = await requestFormData('/open_smena', requestBody); + return Response.fromJson(json.decode(response), Smena.fromJson); + } + + Future> xReport(String token) async { + Map requestBody = {'api_token': token}; + var response = await requestFormData('/report_x', requestBody); + + return Response.fromJsonDynamic(json.decode(response)); + } + + Future> sell(String token, String checkData) async { + Map requestBody = {'api_token': token, 'data': checkData}; + var response = await requestFormData('/sell', requestBody); + print(response); + return Response.fromJsonDynamic(json.decode(response)); + } + + Future> sellReturn(String token, String checkData) async { + Map requestBody = {'api_token': token, 'data': checkData}; + var response = await requestFormData('/sell_return', requestBody); + print(response); + return Response.fromJsonDynamic(json.decode(response)); + } + + + Future requestFormData(String point, Map requestBody, { bool statusCheck = true } ) async { Map headers = { HttpHeaders.contentTypeHeader: "multipart/form-data", HttpHeaders.cacheControlHeader: "no-cache" @@ -48,32 +109,38 @@ class ApiService extends BaseService { var uri = Uri.parse('$endpoint$point'); var request = http.MultipartRequest('POST', uri) - ..headers.addAll( - headers) //if u have headers, basic auth, token bearer... Else remove line + ..headers.addAll(headers) ..fields.addAll(requestBody); - return await request.send(); + + var response = await request.send(); + + String body = await response.stream.bytesToString(); + if(statusCheck) { //Проверка на авторизованный запрос, необязательный параметр + Response check = Response.fromJsonDynamic(json.decode(body)); + if (!check.operation && check.status == 401) { + print('object'); + } + } + return body; } Future> getGoodsFromServer(String token) async { Map requestBody = {'api_token': token}; var response = await requestFormData('/goods', requestBody); - final respStr = await response.stream.bytesToString(); - print(respStr); - return Response.fromJsonDynamic(json.decode(respStr)); + print(response); + return Response.fromJsonDynamic(json.decode(response)); } Future> getCategoryFromServer(String token) async { Map requestBody = {'api_token': token}; var response = await requestFormData('/goods_category', requestBody); - final respStr = await response.stream.bytesToString(); - print(respStr); - return Response.fromJsonDynamic(json.decode(respStr)); + print(response); + return Response.fromJsonDynamic(json.decode(response)); } Future> getServiceFromServer(String token) async { Map requestBody = {'api_token': token}; var response = await requestFormData('/services', requestBody); - final respStr = await response.stream.bytesToString(); - print(respStr); - return Response.fromJsonDynamic(json.decode(respStr)); + print(response); + return Response.fromJsonDynamic(json.decode(response)); } } diff --git a/lib/core/services/DataService.dart b/lib/core/services/DataService.dart index 95f7509..2b64e2c 100644 --- a/lib/core/services/DataService.dart +++ b/lib/core/services/DataService.dart @@ -5,8 +5,14 @@ import 'package:aman_kassa_flutter/core/entity/Category.dart'; import 'package:aman_kassa_flutter/core/entity/Goods.dart'; import 'package:aman_kassa_flutter/core/entity/Service.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/Response.dart'; +import 'package:aman_kassa_flutter/core/models/check_data.dart'; +import 'package:aman_kassa_flutter/core/models/check_item.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/user.dart'; import 'package:aman_kassa_flutter/core/services/DbService.dart'; +import 'package:aman_kassa_flutter/redux/constants/operation_const.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; import 'ApiService.dart'; @@ -14,19 +20,94 @@ class DataService extends BaseService { final ApiService _api = locator(); final DbService _db = locator(); - Future> getCategoriesByParentId ( {int parentId} ) async { - List> list = await _db.queryRowsWithWhere(Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0 ]); + Future> getCategoriesByParentId({int parentId}) async { + List> list = await _db.queryRowsWithWhere( + Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0]); return list.map((e) => Category.fromMap(e)).toList(); } - Future> getGoodsByCategoryId ( {int categoryId} ) async { - List> list = await _db.queryRowsWithWhere(Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]); + Future> getServices() async { + List> list = await _db.queryAllRows(Service_tableName); + return list.map((e) => Service.fromMap(e)).toList(); + } + + Future> getGoodsByCategoryId({int categoryId}) async { + List> list = await _db.queryRowsWithWhere( + Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]); return list.map((e) => Good.fromMap(e)).toList(); } - Future getDataFromServer(String token) async { - try { + CheckData _transformProductsToCheckData( + {String paymentType, + String tradeType, + List items}) { + List itemsList = []; + int iterator = 1; + num summ = 0.0; + items.forEach((el) { + int articul = iterator; + if (el.service != null) { + articul = el.service.articul; + } else if (el.good != null) { + articul = el.good.articul; + } + itemsList.add(CheckItem( + name: el.name ?? 'Позиция №$iterator', + cnt: el.count, + price: el.price, + articul: articul)); + summ += el.total; + iterator++; + }); + CheckData checkData = CheckData(type: tradeType, items: itemsList); + if ((paymentType ?? 'cash') == 'card') { + checkData.card = summ; + } + print(checkData); + return checkData; + } + Future> sellOrReturn( + {String paymentType, + String tradeType, + String token, + List items, + String operationType}) async { + try { + CheckData checkData = _transformProductsToCheckData( + paymentType: paymentType, tradeType: tradeType, items: items); + String data = jsonEncode(checkData.toJson()); + log.i('token: $token'); + log.i('data: $data'); + Response response = await (operationType == OperationTypePay + ? _api.sell(token, data) + : _api.sellReturn(token, data)); + log.i('response status: ${response.status}'); + log.i('response operation: ${response.operation}'); + if (response.status == 200 && response.operation == true) { + log.i( + 'save to db appCompanyId: ${Redux.store.state.userState.user.appCompanyId}, kassaId: ${Redux.store.state.userState.user.kassaId}'); + /* save data to db + * data, + * dateTime, + * check, + * appCompanyId, + * kassaId, + * total, + * name, + * type + */ + } + return response; + } catch (e) { + print(e); + } + return null; + } + + Future getDataFromServer(User user) async { + try { + String token = user.token; Response goods = await _api.getGoodsFromServer(token); Response categories = await _api.getCategoryFromServer(token); Response services = await _api.getServiceFromServer(token); @@ -37,21 +118,21 @@ class DataService extends BaseService { for (var key in goods.body.keys) { print(goods.body[key]); Good row = Good.fromJson(goods.body[key]); - _db.insert(Goog_tableName,row.toMap()); + await _db.insert(Goog_tableName, row.toMap()); } log.i('Inserted ${goods.body.length} to table $Goog_tableName'); for (var el in categories.body) { print(el); Category row = Category.fromJson(el); - _db.insert(Category_tableName,row.toMap()); + await _db.insert(Category_tableName, row.toMap()); } log.i('Inserted ${categories.body.length} to table $Category_tableName'); for (var key in services.body.keys) { print(services.body[key]); Service row = Service.fromJson(services.body[key]); - _db.insert(Service_tableName,row.toMap()); + await _db.insert(Service_tableName, row.toMap()); } log.i('Inserted ${services.body.length} to table $Service_tableName'); @@ -61,4 +142,4 @@ class DataService extends BaseService { return false; } } -} \ No newline at end of file +} diff --git a/lib/core/services/DbService.dart b/lib/core/services/DbService.dart index dde357f..4e7fd99 100644 --- a/lib/core/services/DbService.dart +++ b/lib/core/services/DbService.dart @@ -10,7 +10,7 @@ import 'package:path_provider/path_provider.dart'; class DbService extends BaseService { static final _databaseName = "AmanFlutterDb.db"; - static final _databaseVersion = 5; + static final _databaseVersion = 15; // make this a singleton class DbService._privateConstructor(); @@ -39,18 +39,17 @@ class DbService extends BaseService { ); } Future _onUpdate(Database db, int oldVersion, int newVersion) async { - print('update from $oldVersion to $newVersion'); + log.i('update from $oldVersion to $newVersion'); //Goods table - await db.execute(''' - DROP TABLE IF EXISTS $Goog_tableName; - DROP TABLE IF EXISTS $Category_tableName; - DROP TABLE IF EXISTS $Service_tableName; - '''); + await db.execute('DROP TABLE IF EXISTS $Goog_tableName;'); + await db.execute('DROP TABLE IF EXISTS $Category_tableName;'); + await db.execute('DROP TABLE IF EXISTS $Service_tableName;'); + log.i('dropped tables'); _onCreate(db, newVersion); } Future _onCreate(Database db, int version) async { - print('create tables'); + log.i('create tables'); //Goods table await db.execute(''' CREATE TABLE IF NOT EXISTS $Goog_tableName ( @@ -59,20 +58,35 @@ class DbService extends BaseService { $Goog_columnName text not null, $Goog_columnPrice real not null, $Goog_columnCategoryId integer not null, - $Goog_columnEan text); + $Goog_columnEan text, + $Goog_columnAppCompanyId integer, + $Goog_columnDescription text, + $Goog_columnShowPrice real, + $Goog_columnOkei integer, + $Goog_columnDiscount real + ); '''); await db.execute(''' CREATE TABLE IF NOT EXISTS $Category_tableName ( $Category_columnId integer primary key unique, $Category_columnName text not null, - $Category_columnParentIn integer); + $Category_columnParentIn integer, + $Category_columnAppCompanyId integer + ); '''); + //Service await db.execute(''' CREATE TABLE IF NOT EXISTS $Service_tableName ( $Service_columnId integer primary key unique, $Service_columnArticul integer not null, $Service_columnName text not null, - $Service_columnPrice real not null); + $Service_columnPrice real not null, + $Service_columnAppCompanyId integer, + $Service_columnDescription text, + $Service_columnShowPrice real, + $Service_columnOkei text, + $Service_columnDiscount real + ); '''); } diff --git a/lib/core/services/authentication_service.dart b/lib/core/services/authentication_service.dart index f59073b..6b3672b 100644 --- a/lib/core/services/authentication_service.dart +++ b/lib/core/services/authentication_service.dart @@ -1,8 +1,8 @@ import 'package:aman_kassa_flutter/core/base/base_service.dart'; -import 'package:aman_kassa_flutter/core/models/Message.dart'; -import 'package:aman_kassa_flutter/core/models/Response.dart'; +import 'package:aman_kassa_flutter/core/models/message.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/user.dart'; -import 'package:aman_kassa_flutter/core/models/authResponse.dart'; +import 'package:aman_kassa_flutter/core/models/auth_response.dart'; import 'package:flutter/foundation.dart'; import 'ApiService.dart'; diff --git a/lib/core/services/dialog_service.dart b/lib/core/services/dialog_service.dart index f7e2c56..b979113 100644 --- a/lib/core/services/dialog_service.dart +++ b/lib/core/services/dialog_service.dart @@ -6,18 +6,20 @@ import 'package:flutter/cupertino.dart'; class DialogService { GlobalKey _dialogNavigationKey = GlobalKey(); Function(DialogRequest) _showDialogListener; + Function(DialogRequest) _showDialogInputListener; Completer _dialogCompleter; GlobalKey get dialogNavigationKey => _dialogNavigationKey; /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { + void registerDialogListener(Function(DialogRequest) showDialogListener, Function(DialogRequest) showDialogInputListener) { _showDialogListener = showDialogListener; + _showDialogInputListener = showDialogInputListener; } /// Calls the dialog listener and returns a Future that will wait for dialogComplete. Future showDialog({ - String title, + String title = 'Aman Касса', String description, String buttonTitle = 'Ok', }) { @@ -45,6 +47,20 @@ class DialogService { return _dialogCompleter.future; } + Future showConfirmationDialogInput( + {String title =' Aman Касса', + String description, + String confirmationTitle = 'Ok', + String cancelTitle = 'Cancel'}) { + _dialogCompleter = Completer(); + _showDialogInputListener(DialogRequest( + title: title, + description: description, + buttonTitle: confirmationTitle, + cancelTitle: cancelTitle)); + return _dialogCompleter.future; + } + /// Completes the _dialogCompleter to resume the Future's execution call void dialogComplete(DialogResponse response) { _dialogNavigationKey.currentState.pop(); diff --git a/lib/core/utilsParse.dart b/lib/core/utilsParse.dart new file mode 100644 index 0000000..a5d21ea --- /dev/null +++ b/lib/core/utilsParse.dart @@ -0,0 +1,4 @@ +List parseListString(json){ + if(json==null) return null; + return new List.from(json); +} \ No newline at end of file diff --git a/lib/redux/actions/calc_actions.dart b/lib/redux/actions/calc_actions.dart new file mode 100644 index 0000000..5e8c351 --- /dev/null +++ b/lib/redux/actions/calc_actions.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; + +import 'package:aman_kassa_flutter/core/entity/Category.dart'; +import 'package:aman_kassa_flutter/core/entity/Goods.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/dict_dao.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; +import 'package:aman_kassa_flutter/core/services/ApiService.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; +import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart'; +import 'package:meta/meta.dart'; +import 'package:redux/redux.dart'; +import 'package:redux_thunk/redux_thunk.dart'; + +import '../store.dart'; + +@immutable +class SetCalcStateAction { + final CalcState calcState; + SetCalcStateAction(this.calcState); +} + + +Future setEqual(Store store) async { + store.dispatch(SetCalcStateAction(CalcState(isEqual: true))); +} + +ThunkAction onTapAction(String value) { + return (Store store) async { + + if(value == Calculations.EQUAL){ + return setEqual(store); + } + + //TODO create private methods by operations and values + List calcItems = Calculator.action(value: value, items: store.state.calcState.calcItems); + calcItems.asMap().forEach((index,element ) { + print('#$index: ${element.toString()}'); + }); + store.dispatch(SetCalcStateAction(CalcState(calcItems: calcItems, isEqual: false))); + }; +} \ No newline at end of file diff --git a/lib/redux/actions/kassa_actions.dart b/lib/redux/actions/kassa_actions.dart new file mode 100644 index 0000000..7f4e621 --- /dev/null +++ b/lib/redux/actions/kassa_actions.dart @@ -0,0 +1,136 @@ +import 'dart:convert'; + +import 'package:aman_kassa_flutter/core/entity/Category.dart'; +import 'package:aman_kassa_flutter/core/entity/Goods.dart'; +import 'package:aman_kassa_flutter/core/entity/Service.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/dict_dao.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; +import 'package:aman_kassa_flutter/core/services/ApiService.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:meta/meta.dart'; +import 'package:redux/redux.dart'; +import 'package:redux_thunk/redux_thunk.dart'; + +import '../store.dart'; + +@immutable +class SetKassaStateAction { + final KassaState kassaState; + SetKassaStateAction(this.kassaState); +} + +final ApiService _api = locator(); +final DataService _dataService = locator(); +final NavigatorService _navigation = locator(); + +Future backBottomElement(Store store) async { + List prevCategories = store.state.kassaState.prevCategories; + DictDao last = prevCategories.removeLast(); + if (last != null) { + store.dispatch(SetKassaStateAction(KassaState(prevCategories: prevCategories))); + store.dispatch(selectBottomElement(last.id)); + } +} + +ThunkAction addCustomProductToKassaItems(String name, int count, double price, double total) { + return (Store store) async { + List items = store.state.kassaState.kassaItems; + items.add(new ProductDao(name: name, count: count, price: price, total: total)); + store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); + }; +} + + +ThunkAction addProductToKassaItems(Good good) { + return (Store store) async { + List items = store.state.kassaState.kassaItems; + int index = items.indexWhere((element) => element.good?.id == good.id); + if (index > -1) { + store.dispatch(counterProductFromKassaItems(index, 1)); + } else { + items.add(new ProductDao( + name: good.name, good: good, count: 1, price: good.price, total: good.price)); + store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); + } + }; +} + +ThunkAction addServiceToKassaItems(Service service) { + return (Store store) async { + List items = store.state.kassaState.kassaItems; + int index = items.indexWhere((element) => element.good?.id == service.id); + if (index > -1) { + store.dispatch(counterProductFromKassaItems(index, 1)); + } else { + items.add(new ProductDao( + name: service.name, service: service, count: 1, price: service.price, total: service.price)); + store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); + } + }; +} + +ThunkAction removeProductFromKassaItems(int index) { + return (Store store) async { + List items = List.from(store.state.kassaState.kassaItems); + items.removeAt(index); + store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); + }; +} + +ThunkAction counterProductFromKassaItems(int index, int counter) { + return (Store store) async { + List items = store.state.kassaState.kassaItems; + ProductDao product = items.elementAt(index); + if (product.count == 1 && counter < 0) { + //if count to zero need delete element + store.dispatch(removeProductFromKassaItems(index)); + } else { + product.count += counter; + product.total = (((product.count * product.price) * 100).roundToDouble()) / 100; + store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); + } + }; +} + +ThunkAction selectBottomElement(int parentId) { + return (Store store) async { + store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: true))); + try { + List prevCategories = store.state.kassaState.prevCategories; + if (parentId == 0) { + prevCategories = []; + } + store.state.kassaState.bottomSheetElements.forEach((element) { + if (element is Category && element.id == parentId) { + prevCategories.add(DictDao(id: element.parentIn, name: element.name)); + } + }); + List _bottomSheetElements = []; + + + if(store.state.settingState.tradeType == SettingTradeTypeGood) { + List categories = await _dataService.getCategoriesByParentId(parentId: parentId); + _bottomSheetElements.addAll(categories); + List goods = await _dataService.getGoodsByCategoryId(categoryId: parentId); + _bottomSheetElements.addAll(goods); + } else if(store.state.settingState.tradeType == SettingTradeTypeService) { + List services = await _dataService.getServices(); + _bottomSheetElements.addAll(services); + } + + store.dispatch(SetKassaStateAction(KassaState( + bottomSheetLoading: false, + bottomSheetElements: _bottomSheetElements, + prevCategories: prevCategories))); + } catch (e) { + print(e); + store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: false))); + } + }; +} \ No newline at end of file diff --git a/lib/redux/actions/main_actions.dart b/lib/redux/actions/main_actions.dart deleted file mode 100644 index 991219d..0000000 --- a/lib/redux/actions/main_actions.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'dart:convert'; - -import 'package:aman_kassa_flutter/core/entity/Category.dart'; -import 'package:aman_kassa_flutter/core/entity/Goods.dart'; -import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/DictDao.dart'; -import 'package:aman_kassa_flutter/core/models/ProductDao.dart'; -import 'package:aman_kassa_flutter/core/services/ApiService.dart'; -import 'package:aman_kassa_flutter/core/services/DataService.dart'; -import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; -import 'package:aman_kassa_flutter/redux/state/main_state.dart'; -import 'package:meta/meta.dart'; -import 'package:redux/redux.dart'; -import 'package:redux_thunk/redux_thunk.dart'; - -import '../store.dart'; - -@immutable -class SetMainStateAction { - final MainState mainState; - - SetMainStateAction(this.mainState); -} - -final ApiService _api = locator(); -final DataService _dataService = locator(); -final NavigatorService _navigation = locator(); - -Future backBottomElement(Store store) async { - List prevCategories = store.state.mainState.prevCategories; - DictDao last = prevCategories.removeLast(); - if (last != null) { - store.dispatch( - SetMainStateAction(MainState(prevCategories: prevCategories))); - store.dispatch(selectBottomElement(last.id)); - } -} - -ThunkAction addCustomProductToKassaItems(String name, int count, double price) { - return (Store store) async { - List items = store.state.mainState.kassaItems; - items.add(new ProductDao(name: name, count: count, price: price)); - store.dispatch(SetMainStateAction(MainState(kassaItems: items))); - }; -} - - -ThunkAction addProductToKassaItems(Good good) { - return (Store store) async { - List items = store.state.mainState.kassaItems; - int index = items.indexWhere((element) => element.good?.id == good.id); - if (index > -1) { - store.dispatch(counterProductFromKassaItems(index, 1)); - } else { - items.add(new ProductDao( - name: good.name, good: good, count: 1, price: good.price)); - store.dispatch(SetMainStateAction(MainState(kassaItems: items))); - } - }; -} - -ThunkAction removeProductFromKassaItems(int index) { - return (Store store) async { - List items = List.from(store.state.mainState.kassaItems); - items.removeAt(index); - store.dispatch(SetMainStateAction(MainState(kassaItems: items))); - }; -} - -ThunkAction counterProductFromKassaItems(int index, int counter) { - return (Store store) async { - List items = store.state.mainState.kassaItems; - if (items.elementAt(index).count == 1 && counter < 0) { - //if count to zero need delete element - store.dispatch(removeProductFromKassaItems(index)); - } else { - items.elementAt(index).count += counter; - store.dispatch(SetMainStateAction(MainState(kassaItems: items))); - } - }; -} - -ThunkAction selectBottomElement(int parentId) { - return (Store store) async { - store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: true))); - try { - List prevCategories = store.state.mainState.prevCategories; - if (parentId == 0) { - prevCategories = []; - } - store.state.mainState.bottomSheetElements.forEach((element) { - if (element is Category && element.id == parentId) { - prevCategories.add(DictDao(id: element.parentIn, name: element.name)); - } - }); - List categories = - await _dataService.getCategoriesByParentId(parentId: parentId); - List goods = - await _dataService.getGoodsByCategoryId(categoryId: parentId); - List _bottomSheetElements = []; - _bottomSheetElements.addAll(categories); - _bottomSheetElements.addAll(goods); - store.dispatch(SetMainStateAction(MainState( - bottomSheetLoading: false, - bottomSheetElements: _bottomSheetElements, - prevCategories: prevCategories))); - } catch (e) { - print(e); - store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: false))); - } - }; -} diff --git a/lib/redux/actions/setting_actions.dart b/lib/redux/actions/setting_actions.dart new file mode 100644 index 0000000..e86d198 --- /dev/null +++ b/lib/redux/actions/setting_actions.dart @@ -0,0 +1,39 @@ +import 'dart:convert'; + +import 'package:aman_kassa_flutter/core/entity/Category.dart'; +import 'package:aman_kassa_flutter/core/entity/Goods.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/dict_dao.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; +import 'package:aman_kassa_flutter/core/services/ApiService.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; +import 'package:meta/meta.dart'; +import 'package:redux/redux.dart'; +import 'package:redux_thunk/redux_thunk.dart'; + +import '../store.dart'; + +@immutable +class SetSettingStateAction { + final SettingState settingState; + SetSettingStateAction(this.settingState); +} + + +ThunkAction changeModeFromSetting(bool isKassa) { + return (Store store) async { + store.dispatch(SetSettingStateAction(SettingState(mode: isKassa? SettingModeKassa: SettingModeCalc ))); + }; +} + +ThunkAction changeTradeTypeFromSetting(String tradeType) { + return (Store store) async { + store.dispatch(SetSettingStateAction(SettingState(tradeType: tradeType ))); + }; +} \ No newline at end of file diff --git a/lib/redux/actions/user_actions.dart b/lib/redux/actions/user_actions.dart index 3df788e..ef9ecdc 100644 --- a/lib/redux/actions/user_actions.dart +++ b/lib/redux/actions/user_actions.dart @@ -1,9 +1,10 @@ import 'dart:convert'; import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/Message.dart'; -import 'package:aman_kassa_flutter/core/models/authResponse.dart'; -import 'package:aman_kassa_flutter/core/models/Response.dart'; +import 'package:aman_kassa_flutter/core/models/message.dart'; +import 'package:aman_kassa_flutter/core/models/auth_response.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; import 'package:aman_kassa_flutter/core/models/user.dart'; import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/services/ApiService.dart'; @@ -53,7 +54,7 @@ ThunkAction authenticate(String email, String password) { return (Store store) async { store.dispatch(SetUserStateAction(UserState(isLoading: true))); try { - AuthBody result = await _api.authenticate(email, password); + AuthBody result = await _api.authenticate(email, password, statusCheck: false); store.dispatch(SetUserStateAction(UserState( isLoading: false, loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message), @@ -66,7 +67,29 @@ ThunkAction authenticate(String email, String password) { _navigation.replace(HomeViewRoute); } } catch(e) { + print(e); store.dispatch(SetUserStateAction(UserState(isLoading: false))); } }; } + +Future checkSmena(Store store) async { + String token = store.state.userState.user.token; + Response result = await _api.smena(token); + store.dispatch(SetUserStateAction(UserState(smena: result.body))); +} + +Future closeSmena(Store store) async { + String token = store.state.userState.user.token; + Response result = await _api.closeSmena(token); + store.dispatch(SetUserStateAction(UserState(smena: result.body))); +} + +Future openSmena(Store store) async { + String token = store.state.userState.user.token; + Response result = await _api.openSmena(token); + store.dispatch(SetUserStateAction(UserState(smena: result.body))); + if(result.operation){ + store.dispatch(checkSmena); + } +} diff --git a/lib/redux/constants/operation_const.dart b/lib/redux/constants/operation_const.dart new file mode 100644 index 0000000..8557ec6 --- /dev/null +++ b/lib/redux/constants/operation_const.dart @@ -0,0 +1,2 @@ +const String OperationTypePay = 'OperationTypePay'; +const String OperationTypeReturn = 'OperationTypeReturn'; \ No newline at end of file diff --git a/lib/redux/constants/setting_const.dart b/lib/redux/constants/setting_const.dart new file mode 100644 index 0000000..787527a --- /dev/null +++ b/lib/redux/constants/setting_const.dart @@ -0,0 +1,6 @@ +const String SettingModeKassa = 'kassaMode'; +const String SettingModeCalc = 'calcMode'; + + +const String SettingTradeTypeGood = 'g'; +const String SettingTradeTypeService = 's'; \ No newline at end of file diff --git a/lib/redux/reducers/calc_reducer.dart b/lib/redux/reducers/calc_reducer.dart new file mode 100644 index 0000000..136fd91 --- /dev/null +++ b/lib/redux/reducers/calc_reducer.dart @@ -0,0 +1,10 @@ +import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart'; +import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; + +calcReducer(CalcState prevState, SetCalcStateAction action) { + final payload = action.calcState; + return prevState.copyWith( + calcItems: payload.calcItems, + isEqual: payload.isEqual + ); +} diff --git a/lib/redux/reducers/main_reducer.dart b/lib/redux/reducers/main_reducer.dart index f782b51..9d35d6d 100644 --- a/lib/redux/reducers/main_reducer.dart +++ b/lib/redux/reducers/main_reducer.dart @@ -1,8 +1,8 @@ -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; -import 'package:aman_kassa_flutter/redux/state/main_state.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; -mainReducer(MainState prevState, SetMainStateAction action) { - final payload = action.mainState; +mainReducer(KassaState prevState, SetKassaStateAction action) { + final payload = action.kassaState; return prevState.copyWith( bottomSheetElements: payload.bottomSheetElements, bottomSheetLoading: payload.bottomSheetLoading, diff --git a/lib/redux/reducers/setting_reducer.dart b/lib/redux/reducers/setting_reducer.dart new file mode 100644 index 0000000..e5395f0 --- /dev/null +++ b/lib/redux/reducers/setting_reducer.dart @@ -0,0 +1,12 @@ +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; + +settingReducer(SettingState prevState, SetSettingStateAction action) { + final payload = action.settingState; + return prevState.copyWith( + mode: payload.mode, + tradeType: payload.tradeType + ); +} diff --git a/lib/redux/reducers/user_reducer.dart b/lib/redux/reducers/user_reducer.dart index 4ffa940..46120bf 100644 --- a/lib/redux/reducers/user_reducer.dart +++ b/lib/redux/reducers/user_reducer.dart @@ -10,5 +10,6 @@ userReducer(UserState prevState, SetUserStateAction action) { user: payload.user, isAuthenticated: payload.isAuthenticated, loginFormMessage: payload.loginFormMessage, + smena: payload.smena, ); } \ No newline at end of file diff --git a/lib/redux/state/calc_state.dart b/lib/redux/state/calc_state.dart new file mode 100644 index 0000000..c6712b5 --- /dev/null +++ b/lib/redux/state/calc_state.dart @@ -0,0 +1,26 @@ +import 'dart:collection'; + +import 'package:aman_kassa_flutter/core/models/calc_model.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:meta/meta.dart'; + +@immutable +class CalcState { + final List calcItems; + final bool isEqual; + + CalcState({this.calcItems, this.isEqual}); + + factory CalcState.initial() => CalcState(calcItems: [], isEqual: false); + + CalcState copyWith({ + @required calcItems, + @required isEqual, + }) { + return CalcState( + calcItems: calcItems ?? this.calcItems, + isEqual: isEqual ?? this.isEqual, + ); + } +} + diff --git a/lib/redux/state/main_state.dart b/lib/redux/state/kassa_state.dart similarity index 70% rename from lib/redux/state/main_state.dart rename to lib/redux/state/kassa_state.dart index b1a8e04..d68a967 100644 --- a/lib/redux/state/main_state.dart +++ b/lib/redux/state/kassa_state.dart @@ -1,35 +1,37 @@ -import 'package:aman_kassa_flutter/core/models/DictDao.dart'; -import 'package:aman_kassa_flutter/core/models/ProductDao.dart'; +import 'package:aman_kassa_flutter/core/models/dict_dao.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; import 'package:meta/meta.dart'; @immutable -class MainState { +class KassaState { final List bottomSheetElements; final bool bottomSheetLoading; final List prevCategories; - final List kassaItems; - MainState( + + KassaState( {this.bottomSheetElements, this.bottomSheetLoading, this.prevCategories, - this.kassaItems}); + this.kassaItems, + }); - factory MainState.initial() => MainState( + factory KassaState.initial() => KassaState( bottomSheetElements: [], bottomSheetLoading: false, prevCategories: [], kassaItems: [], ); - MainState copyWith({ + KassaState copyWith({ @required bottomSheetElements, @required bottomSheetLoading, @required prevCategories, @required kassaItems, }) { - return MainState( + return KassaState( bottomSheetElements: bottomSheetElements ?? this.bottomSheetElements, bottomSheetLoading: bottomSheetLoading ?? this.bottomSheetLoading, prevCategories: prevCategories ?? this.prevCategories, diff --git a/lib/redux/state/setting_state.dart b/lib/redux/state/setting_state.dart new file mode 100644 index 0000000..3443d09 --- /dev/null +++ b/lib/redux/state/setting_state.dart @@ -0,0 +1,22 @@ +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:meta/meta.dart'; + +@immutable +class SettingState { + final String mode; + final String tradeType; + + SettingState({this.mode, this.tradeType}); + + factory SettingState.initial() => SettingState(mode: SettingModeCalc, tradeType: SettingTradeTypeGood); + + SettingState copyWith({ + @required mode, + @required tradeType, + }) { + return SettingState( + mode: mode ?? this.mode, + tradeType: tradeType ?? this.tradeType, + ); + } +} diff --git a/lib/redux/state/user_state.dart b/lib/redux/state/user_state.dart index c2d6f3d..eb32786 100644 --- a/lib/redux/state/user_state.dart +++ b/lib/redux/state/user_state.dart @@ -1,3 +1,4 @@ +import 'package:aman_kassa_flutter/core/models/smena.dart'; import 'package:aman_kassa_flutter/core/models/user.dart'; import 'package:meta/meta.dart'; @@ -8,13 +9,15 @@ class UserState { final bool isAuthenticated; final LoginFormMessage loginFormMessage; final User user; + final Smena smena; UserState({ this.isError, this.isLoading, this.isAuthenticated, this.user, - this.loginFormMessage + this.loginFormMessage, + this.smena }); factory UserState.initial() => UserState( @@ -22,6 +25,7 @@ class UserState { isError: false, isAuthenticated: false, loginFormMessage: LoginFormMessage(), + smena: Smena(), ); UserState copyWith({ @@ -30,6 +34,7 @@ class UserState { @required User user, @required bool isAuthenticated, @required LoginFormMessage loginFormMessage, + @required Smena smena, }) { return UserState( isError: isError ?? this.isError, @@ -37,6 +42,7 @@ class UserState { isAuthenticated: isAuthenticated ?? this.isAuthenticated, user: user ?? this.user, loginFormMessage: loginFormMessage ?? this.loginFormMessage, + smena: smena ?? this.smena, ); } } diff --git a/lib/redux/store.dart b/lib/redux/store.dart index 29ef873..2b6b906 100644 --- a/lib/redux/store.dart +++ b/lib/redux/store.dart @@ -1,23 +1,38 @@ -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart'; import 'package:aman_kassa_flutter/redux/actions/user_actions.dart'; +import 'package:aman_kassa_flutter/redux/reducers/calc_reducer.dart'; import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart'; +import 'package:aman_kassa_flutter/redux/reducers/setting_reducer.dart'; import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart'; -import 'package:aman_kassa_flutter/redux/state/main_state.dart'; +import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/state/user_state.dart'; import 'package:meta/meta.dart'; import 'package:redux/redux.dart'; import 'package:redux_thunk/redux_thunk.dart'; +import 'actions/calc_actions.dart'; //reducer context AppState appReducer(AppState state, dynamic action) { - - if (action is SetUserStateAction) { /** UserAction **/ + if (action is SetUserStateAction) { + /** UserAction **/ final nextUserState = userReducer(state.userState, action); return state.copyWith(userState: nextUserState); - } else if(action is SetMainStateAction) { /** MainAction **/ - final nextMainState = mainReducer(state.mainState, action); - return state.copyWith(mainState: nextMainState); + } else if (action is SetKassaStateAction) { + /** KassaAction **/ + final nextMainState = mainReducer(state.kassaState, action); + return state.copyWith(kassaState: nextMainState); + } else if (action is SetSettingStateAction) { + /** SettingAction **/ + final nextSettingState = settingReducer(state.settingState, action); + return state.copyWith(settingState: nextSettingState); + } else if (action is SetCalcStateAction) { + /** CalcAction **/ + final nextCalcState = calcReducer(state.calcState, action); + return state.copyWith(calcState: nextCalcState); } return state; } @@ -26,20 +41,29 @@ AppState appReducer(AppState state, dynamic action) { @immutable class AppState { final UserState userState; - final MainState mainState; + final KassaState kassaState; + final SettingState settingState; + final CalcState calcState; + AppState({ @required this.userState, - @required this.mainState, + @required this.kassaState, + @required this.settingState, + @required this.calcState, }); //stable work AppState copyWith({ UserState userState, - MainState mainState, + KassaState kassaState, + SettingState settingState, + CalcState calcState, }) { return AppState( userState: userState ?? this.userState, - mainState: mainState ?? this.mainState, + kassaState: kassaState ?? this.kassaState, + settingState: settingState ?? this.settingState, + calcState: calcState ?? this.calcState, ); } } @@ -58,12 +82,18 @@ class Redux { //initial context static Future init() async { final userStateInitial = UserState.initial(); - final mainStateInitial = MainState.initial(); + final kassaStateInitial = KassaState.initial(); + final settingStateInitial = SettingState.initial(); + final calcStateInitial = CalcState.initial(); _store = Store( appReducer, middleware: [thunkMiddleware], - initialState: AppState(userState: userStateInitial, mainState: mainStateInitial), + initialState: AppState( + userState: userStateInitial, + kassaState: kassaStateInitial, + settingState: settingStateInitial, + calcState: calcStateInitial), ); } -} \ No newline at end of file +} diff --git a/lib/shared/shared_styles.dart b/lib/shared/shared_styles.dart index 29d87a6..227a428 100644 --- a/lib/shared/shared_styles.dart +++ b/lib/shared/shared_styles.dart @@ -24,10 +24,10 @@ const TextStyle productTextStyle = const TextStyle(fontWeight: FontWeight.w400, const TextStyle buttonTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 15); const TextStyle buttonBigTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 22, ); -const TextStyle stepTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: textColor, fontSize: 15); -const TextStyle stepSubTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: textColor, fontSize: 12); +const TextStyle dropDownTradeTypeTextStyle = TextStyle( color: Colors.black54, fontWeight: FontWeight.bold, fontSize: 24); + // Box Shadow const BoxShadow mainShadowBox = BoxShadow(blurRadius: 16, color: shadowColor, offset: Offset(0, 5)); -const BoxShadow cardShadowBox = BoxShadow(blurRadius: 23, color: cardShadowColor, offset: Offset(0, 2)); \ No newline at end of file +const BoxShadow buttonShadowBox = BoxShadow(blurRadius: 5, color: Colors.grey, offset: Offset(0, 1)); +const BoxShadow cardShadowBox = BoxShadow(blurRadius: 5, color: Colors.black26, offset: Offset(0, 5)); \ No newline at end of file diff --git a/lib/views/check/image_show_container.dart b/lib/views/check/image_show_container.dart new file mode 100644 index 0000000..c51a1eb --- /dev/null +++ b/lib/views/check/image_show_container.dart @@ -0,0 +1,36 @@ +import 'dart:convert'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:flutter/material.dart'; + +class ImageShowContainer extends StatelessWidget { + final ImageShowModel data; + ImageShowContainer(this.data); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + //backgroundColor: fillColor, + title: Text(data.title), + ), + body: ListView( + children: [ + imageFromBase64String(data.data) + ], + ), + ); + } +} + +Padding imageFromBase64String(String base64String) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0), + child: Image.memory(base64Decode(base64String)), + ); +} + + +class ImageShowModel { + final String data; + final String title; + ImageShowModel(this.data, this.title); +} \ No newline at end of file diff --git a/lib/views/home/components/bottom_bar.dart b/lib/views/home/components/bottom_bar.dart new file mode 100644 index 0000000..0fb052f --- /dev/null +++ b/lib/views/home/components/bottom_bar.dart @@ -0,0 +1,61 @@ +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; + +class BottomBar extends StatelessWidget { + final PageController pageController; + final int selectedTabIndex; + + BottomBar({ + this.pageController, + this.selectedTabIndex, + }); + + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: (store) => store.state.settingState, + builder: (context, vm) { + return BottomNavigationBar( + currentIndex: selectedTabIndex, + backgroundColor: menuColor, + type: BottomNavigationBarType.shifting, + items: [ + vm.mode == SettingModeKassa + ? BottomNavigationBarItem( + backgroundColor: menuColor, + icon: Icon(MdiIcons.cashRegister, color: Colors.white), + title: new Text( + 'Касса', + style: TextStyle(color: Colors.white), + )) + : BottomNavigationBarItem( + backgroundColor: menuColor, + icon: Icon(MdiIcons.calculator, color: Colors.white), + title: new Text( + 'Калькулятор', + style: TextStyle(color: Colors.white), + )), + BottomNavigationBarItem( + backgroundColor: menuColor, + icon: Icon(MdiIcons.tune, color: Colors.white), + title: new Text( + 'Опции', + style: TextStyle(color: Colors.white), + )), + ], + onTap: (index) { + pageController.animateToPage( + index, + duration: const Duration(milliseconds: 300), + curve: Curves.easeIn, + ); + }, + ); + }); + } +} diff --git a/lib/views/home/components/header_title.dart b/lib/views/home/components/header_title.dart new file mode 100644 index 0000000..12f79e3 --- /dev/null +++ b/lib/views/home/components/header_title.dart @@ -0,0 +1,44 @@ +import 'package:aman_kassa_flutter/redux/state/user_state.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:intl/intl.dart'; + +DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss"); + +class HeaderTitle extends StatelessWidget { + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: (store) => store.state.userState, + builder: (context, vm) { + return Row( + children: [ + Container( + width: 75, + child: Image( + image: AssetImage('assets/images/logo.png'), + fit: BoxFit.fitWidth, + ), + margin: const EdgeInsets.only(right: 15), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Пользователь: ${vm.user.email}' ,style: TextStyle(fontSize: 13, color: Colors.black),), + vm.smena.message !=null + ? Text(vm.smena.message, style: TextStyle(fontSize: 13, color: redColor) ) + : vm.smena.startedAt !=null + ? Text('Смена от: ${dateFormat.format(vm.smena.startedAt)}' , style: TextStyle(fontSize: 13, color: Colors.black),) + : Text('Смена от:', style: TextStyle(fontSize: 13, color: Colors.black),), + ], + ), + ) + ], + ); + } + ); + } +} diff --git a/lib/views/home/components/popup_menu.dart b/lib/views/home/components/popup_menu.dart new file mode 100644 index 0000000..27b0eec --- /dev/null +++ b/lib/views/home/components/popup_menu.dart @@ -0,0 +1,40 @@ +import 'package:aman_kassa_flutter/core/models/choice.dart'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:flutter/material.dart'; + +const List choices = const [ + const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'), + const Choice(title: 'Помощь', icon: Icons.help, command: 'help'), + const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'), + const Choice(title: 'Язык', icon: Icons.language, command: 'language'), + const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit') +]; + +class PopupMenu extends StatelessWidget { + + final void Function(Choice value) onSelectChoice; + + PopupMenu({this.onSelectChoice}); + + @override + Widget build(BuildContext context) { + return PopupMenuButton( + icon: Icon( + Icons.more_vert, + color: menuColor, + ), + onSelected: onSelectChoice, + itemBuilder: (BuildContext context) { + return choices.map((Choice choice) { + return PopupMenuItem( + value: choice, + child: Row(children: [ + Icon(choice.icon, color: primaryColor,), + Text(choice.title) + ], ), + ); + }).toList(); + }, + ); + } +} diff --git a/lib/views/home/home_view.dart b/lib/views/home/home_view.dart index 6d94f26..ab2804f 100644 --- a/lib/views/home/home_view.dart +++ b/lib/views/home/home_view.dart @@ -1,22 +1,29 @@ import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/Choice.dart'; +import 'package:aman_kassa_flutter/core/logger.dart'; +import 'package:aman_kassa_flutter/core/models/choice.dart'; import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/redux/actions/user_actions.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:aman_kassa_flutter/views/home/components/header_title.dart'; import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:logger/logger.dart'; import './tabs/KassaTab.dart'; import './tabs/AdditionalTab.dart'; import './tabs/CalculatorTab.dart'; - +import './components/popup_menu.dart'; +import 'components/bottom_bar.dart'; const List choices = const [ - const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'), + const Choice( + title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'), const Choice(title: 'Помощь', icon: Icons.help, command: 'help'), const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'), const Choice(title: 'Язык', icon: Icons.language, command: 'language'), @@ -29,18 +36,18 @@ class HomeView extends StatefulWidget { } class _HomeViewState extends State { + Logger log = getLogger('HomeView'); PageController pageController; int selectedTabIndex; DataService _dataService = locator(); final GlobalKey _keyLoader = new GlobalKey(); - @override void initState() { - // TODO: implement initState super.initState(); selectedTabIndex = 0; pageController = new PageController(initialPage: selectedTabIndex); + Redux.store.dispatch(checkSmena); } @override @@ -50,13 +57,13 @@ class _HomeViewState extends State { } void _onSelectChoice(Choice choice) async { - if(choice.command == 'exit') { + if (choice.command == 'exit') { } else if (choice.command == 'update') { Dialogs.showLoadingDialog(context, _keyLoader); - bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user.token); - print('result: $result'); - Navigator.of(_keyLoader.currentContext,rootNavigator: true).pop(); + bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user); + log.i('result: $result'); + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); } } @@ -64,81 +71,34 @@ class _HomeViewState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Center( - child: Container( - width: 100, - child: Image( - image: AssetImage('assets/images/logo.png'), - fit: BoxFit.fitHeight, - ), - )), + title: HeaderTitle(), actions: [ - PopupMenuButton( - icon: Icon( - Icons.more_vert, - color: menuColor, - ), - onSelected: _onSelectChoice, - itemBuilder: (BuildContext context) { - return choices.map((Choice choice) { - return PopupMenuItem( - value: choice, - child: Row(children: [ - Icon(choice.icon, color: primaryColor,), - Text(choice.title) - ], ), - ); - }).toList(); - }, + PopupMenu( + onSelectChoice: _onSelectChoice, ) ], backgroundColor: fillColor, ), - body: PageView( - onPageChanged: (index) { - setState(() { - selectedTabIndex = index; - }); - }, - controller: pageController, - children: [ - KassaTab(0), - CalculatorTab(1), - AdditionalTab(2), - ], - ), - bottomNavigationBar: BottomNavigationBar( - currentIndex: selectedTabIndex, - backgroundColor: menuColor, - type: BottomNavigationBarType.shifting, - items: [ - BottomNavigationBarItem( - backgroundColor: menuColor, - icon: Icon(MdiIcons.cashRegister, color: Colors.white), - title: new Text( - 'Касса', - style: TextStyle(color: Colors.white), - )), - BottomNavigationBarItem( - icon: Icon(MdiIcons.calculator, color: Colors.white), - title: new Text( - 'Калькулятор', - style: TextStyle(color: Colors.white), - )), - BottomNavigationBarItem( - icon: Icon(MdiIcons.tune, color: Colors.white), - title: new Text( - 'Опции', - style: TextStyle(color: Colors.white), - )), - ], - onTap: (index) { - pageController.animateToPage( - index, - duration: const Duration(milliseconds: 300), - curve: Curves.easeIn, + body:StoreConnector( + converter: (store) => store.state.settingState, + builder: (context, vm) { + return PageView( + onPageChanged: (index) { + setState(() { + selectedTabIndex = index; + }); + }, + controller: pageController, + children: [ + vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0), + AdditionalTab(1), + ], ); - }, + } + ), + bottomNavigationBar: BottomBar( + pageController: pageController, + selectedTabIndex: selectedTabIndex, ), ); } diff --git a/lib/views/home/tabs/AdditionalTab.dart b/lib/views/home/tabs/AdditionalTab.dart index 7cbd189..0863b2f 100644 --- a/lib/views/home/tabs/AdditionalTab.dart +++ b/lib/views/home/tabs/AdditionalTab.dart @@ -1,59 +1,298 @@ -import 'package:aman_kassa_flutter/redux/state/user_state.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/message.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; +import 'package:aman_kassa_flutter/core/models/smena.dart'; +import 'package:aman_kassa_flutter/core/route_names.dart'; +import 'package:aman_kassa_flutter/core/services/ApiService.dart'; +import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/actions/user_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; +import 'package:aman_kassa_flutter/views/check/image_show_container.dart'; +import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart'; +import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:google_fonts/google_fonts.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; -class AdditionalTab extends StatelessWidget { +class AdditionalTab extends StatefulWidget { final int index; + AdditionalTab(this.index); + + @override + _AdditionalTabState createState() => _AdditionalTabState(); +} + +class _AdditionalTabState extends State { + ApiService _api = locator(); + NavigatorService _navigator = locator(); + DialogService _dialog = locator(); + + bool isMoneyCheckBusy; + bool closeSmenaBusy; + bool openSmenaBusy; + bool depositBusy; + bool withdrawalBusy; + bool xReportBusy; + + @override + void initState() { + super.initState(); + isMoneyCheckBusy = false; + closeSmenaBusy = false; + openSmenaBusy = false; + depositBusy = false; + withdrawalBusy = false; + xReportBusy = false; + } + + void _closeSmena() async { + setState(() { + closeSmenaBusy = true; + }); + await Redux.store.dispatch(closeSmena); + setState(() { + closeSmenaBusy = false; + }); + } + + void _openSmena() async { + setState(() { + openSmenaBusy = true; + }); + await Redux.store.dispatch(openSmena); + setState(() { + openSmenaBusy = false; + }); + } + + void _xReport() async { + setState(() { + xReportBusy = true; + }); + Response response = + await _api.xReport(Redux.store.state.userState.user.token); + if (response.operation) { + _navigator.push(ImageShowRoute, + arguments: ImageShowModel(response.body['check'], 'X Отчет')); + } else { + _dialog.showDialog(description: response.body['message']); + } + setState(() { + xReportBusy = false; + }); + } + + void _deposit() async { + setState(() { + depositBusy = true; + }); + try { + DialogResponse response = await _dialog.showConfirmationDialogInput( + description: 'Укажите сумму', + cancelTitle: 'Отмена', + confirmationTitle: 'Взнос', + ); + if (response.confirmed) { + Response result = await _api.deposit( + Redux.store.state.userState.user.token, response.responseText); + //if(result.operation) { + _dialog.showDialog(description: result.body['message']); + //} + } + } catch (e) { + print(e); + } finally { + setState(() { + depositBusy = false; + }); + } + } + + void _withdrawal() async { + setState(() { + withdrawalBusy = true; + }); + try { + DialogResponse response = await _dialog.showConfirmationDialogInput( + description: 'Укажите сумму', + cancelTitle: 'Отмена', + confirmationTitle: 'Снятие', + ); + if (response.confirmed) { + Response result = await _api.withdrawal( + Redux.store.state.userState.user.token, response.responseText); + //if(result.operation) { + _dialog.showDialog(description: result.body['message']); + //} + } + } catch (e) { + print(e); + } finally { + setState(() { + withdrawalBusy = false; + }); + } + } + + void _checkMoney() async { + setState(() { + isMoneyCheckBusy = true; + }); + try { + Response result = + await _api.money(Redux.store.state.userState.user.token); + setState(() { + isMoneyCheckBusy = false; + }); + if (result.operation) { + _dialog.showDialog( + description: 'Денег в кассе: ${result.body['money']}'); + } else { + _dialog.showDialog(description: '${result.body['message']}'); + } + } catch (e) { + print(e); + setState(() { + isMoneyCheckBusy = false; + }); + } + } + @override Widget build(BuildContext context) { - return StoreConnector( - converter: (store) => store.state.userState, - builder: (context, vm) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 15), - child: Column( + return Container( + padding: const EdgeInsets.symmetric(vertical: 15), + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: StoreConnector( + converter: (store) => store.state.settingState, + builder: (context, vm) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 1, + child: AmanIconButtonHorizontal( + icon: MdiIcons.calculator, + title: 'Калькулятор', + selected: vm.mode == SettingModeCalc, + onPressed: () => changeMode(false), + )), + Expanded( + flex: 1, + child: Center( + child: Switch( + value: vm.mode == SettingModeKassa, + onChanged: changeMode, + inactiveThumbColor: primaryColor, + activeColor: primaryColor, + ))), + Expanded( + flex: 1, + child: AmanIconButtonHorizontal( + icon: MdiIcons.cashRegister, + title: 'Режим кассы', + selected: vm.mode == SettingModeKassa, + onPressed: () => changeMode(true))), + ], + ); + }), + ), + Divider(), + verticalSpaceMedium, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Center( + child: Column( + children: [ + Text( + 'Денег в кассе:', + style: TextStyle(color: primaryColor, fontSize: 15), + ), + Text( + '250 024.38 тенге', + style: TextStyle( + color: primaryColor, + fontSize: 25, + fontWeight: FontWeight.bold), + ), + ], + )), + ), + verticalSpaceMedium, + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - verticalSpaceLarge, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - BusyButton(title: 'Открыть смену', onPressed: null, mainColor: greenColor,), - BusyButton(title: 'Закрыть смену', onPressed: null, mainColor: redColor ,), - ], + AmanIconButton( + title: 'Открыть смену', + onPressed: _openSmena, + mainColor: greenColor, + busy: openSmenaBusy, + icon: Icons.lock_open, ), - verticalSpaceLarge, - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - BusyButton(title: 'Денег в кассе', onPressed: null,), - ], + AmanIconButton( + title: 'Закрыть смену', + onPressed: _closeSmena, + mainColor: redColor, + busy: closeSmenaBusy, + icon: Icons.lock_outline, ), - verticalSpaceLarge, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - BusyButton(title: 'Взнос наличных', onPressed: null,), - BusyButton(title: 'Снятие наличных', onPressed: null, mainColor: redColor ,), - ], + AmanIconButton( + title: 'Денег в кассе', + onPressed: _checkMoney, + busy: isMoneyCheckBusy, + icon: Icons.attach_money, + mainColor: primaryColor, ), - verticalSpaceLarge, - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - BusyButton(title: 'Х Отчет', onPressed: null,), - ], - ) ], ), - ); - }, - + verticalSpaceTiny, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AmanIconButton( + title: 'Х Отчет', + onPressed: _xReport, + busy: xReportBusy, + mainColor: primaryColor, + icon: Icons.description, + ), + ], + ), + verticalSpaceMedium, + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + BusyButton( + title: 'Взнос наличных', + onPressed: _deposit, + busy: depositBusy, + ), + BusyButton( + title: 'Снятие наличных', + onPressed: _withdrawal, + mainColor: redColor, + busy: withdrawalBusy, + ), + ], + ), + ], + ), ); } -} \ No newline at end of file + + void changeMode(el) { + Redux.store.dispatch(changeModeFromSetting(el)); + } +} diff --git a/lib/views/home/tabs/CalculatorTab.dart b/lib/views/home/tabs/CalculatorTab.dart index 0fba9c9..4e071ba 100644 --- a/lib/views/home/tabs/CalculatorTab.dart +++ b/lib/views/home/tabs/CalculatorTab.dart @@ -1,10 +1,26 @@ +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/route_names.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart'; +import 'package:aman_kassa_flutter/redux/constants/operation_const.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:aman_kassa_flutter/shared/shared_styles.dart'; +import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; +import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart'; import 'package:flutter/material.dart'; import 'package:aman_kassa_flutter/widgets/components/calculator/calculator-buttons.dart'; import 'package:aman_kassa_flutter/widgets/components/calculator/number-display.dart'; +import 'package:flutter_redux/flutter_redux.dart'; class CalculatorTab extends StatelessWidget { + + NavigatorService _navigatorService = locator(); + final int index; CalculatorTab(this.index); @@ -14,10 +30,53 @@ class CalculatorTab extends StatelessWidget { return Scaffold( body: Column( children: [ - NumberDisplay(value: 'values'), - CalculatorButtons(onTap: null), + StoreConnector( + converter: (store) => store.state.calcState, + builder: (context, vm) { + return NumberDisplay(value: Calculator.parseItems(vm.calcItems, vm.isEqual)); + } + ), + CalculatorButtons(onTap: _onPress), + Row( + children: [ + Expanded( + + child: RaisedButton( + padding: EdgeInsets.all(10.0), + color: redColor, + child: Text( + "Возврат", + style: buttonBigTitleTextStyle, + ), + onPressed: () { + _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeCalc, operationType: OperationTypeReturn) ); + } + ), + ), + Expanded( + child: RaisedButton( + padding: EdgeInsets.all(10.0), + + color: greenColor, + child: Text( + "Оплата", + style: buttonBigTitleTextStyle, + ), + onPressed: () { + _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeCalc, operationType: OperationTypePay) ); + }, + ), + ), + ], + ) ], mainAxisAlignment: MainAxisAlignment.spaceBetween, )); } + + void _onPress({ String buttonText}) { + Redux.store.dispatch(onTapAction(buttonText)); + } + + } \ No newline at end of file diff --git a/lib/views/home/tabs/KassaTab.dart b/lib/views/home/tabs/KassaTab.dart index 2093172..8f31f8f 100644 --- a/lib/views/home/tabs/KassaTab.dart +++ b/lib/views/home/tabs/KassaTab.dart @@ -1,25 +1,33 @@ -import 'package:aman_kassa_flutter/core/models/ProductDao.dart'; -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; -import 'package:aman_kassa_flutter/redux/state/main_state.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/route_names.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; +import 'package:aman_kassa_flutter/redux/constants/operation_const.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/shared_styles.dart'; import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.dart'; import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart'; +import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; class KassaTab extends StatelessWidget { + NavigatorService _navigatorService = locator(); + final int index; KassaTab(this.index); Widget buildItem(BuildContext ctxt, int index, ProductDao productDao) { return ProductListItem( - item: new ProductDao(name: productDao.name, count: productDao.count, price: productDao.price), + item: productDao, index: index, ); } @@ -64,8 +72,8 @@ class KassaTab extends StatelessWidget { ), Expanded( child: Container( - child: StoreConnector( - converter: (store) => store.state.mainState, + child: StoreConnector( + converter: (store) => store.state.kassaState, builder: (context, vm) { return ListView.builder( itemCount: vm.kassaItems.length, @@ -75,6 +83,21 @@ class KassaTab extends StatelessWidget { ), ), ), + Divider(), + Container( + margin: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + StoreConnector( + converter: (store) => store.state.kassaState, + builder: (context, vm) { + return Text(totalCalc(vm.kassaItems), style: TextStyle(fontSize: 25)); + } + ), + ], + ), + ), Row( children: [ Expanded( @@ -87,7 +110,9 @@ class KassaTab extends StatelessWidget { "Возврат", style: buttonBigTitleTextStyle, ), - onPressed: () => null, + onPressed: () { + _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypeReturn) ); + } ), ), ), @@ -101,7 +126,9 @@ class KassaTab extends StatelessWidget { "Оплата", style: buttonBigTitleTextStyle, ), - onPressed: () => null, + onPressed: () { + _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypePay) ); + }, ), ), ), @@ -112,6 +139,14 @@ class KassaTab extends StatelessWidget { ); } + String totalCalc(List kassaItems) { + num total = 0.0; + kassaItems.forEach((element) { + total+= element.total == null ? 0.0 : element.total.toDouble(); + }); + return total.toString(); + } + void showModalBottomSheetCatalog(BuildContext context, String action) { showModalBottomSheet( context: context, diff --git a/lib/views/home/tabs/kassaView/CatalogBottomSheet.dart b/lib/views/home/tabs/kassaView/CatalogBottomSheet.dart index 11432bf..3951419 100644 --- a/lib/views/home/tabs/kassaView/CatalogBottomSheet.dart +++ b/lib/views/home/tabs/kassaView/CatalogBottomSheet.dart @@ -1,7 +1,14 @@ import 'package:aman_kassa_flutter/core/entity/Category.dart'; import 'package:aman_kassa_flutter/core/entity/Goods.dart'; -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; -import 'package:aman_kassa_flutter/redux/state/main_state.dart'; +import 'package:aman_kassa_flutter/core/entity/Service.dart'; +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/Choice.dart'; +import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/shared_styles.dart'; @@ -15,8 +22,8 @@ class CatalogBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - return StoreConnector( - converter: (store) => store.state.mainState, + return StoreConnector( + converter: (store) => store.state.kassaState, onInit: (store) => Redux.store.dispatch(selectBottomElement(0)), builder: (context, vm) { return WillPopScope( @@ -28,7 +35,7 @@ class CatalogBottomSheet extends StatelessWidget { return new Future(() => false); }, child: Scaffold( - appBar: AppBar( + appBar: AppBar( title: Text( vm.prevCategories.isNotEmpty ? vm.prevCategories?.last?.name @@ -36,8 +43,8 @@ class CatalogBottomSheet extends StatelessWidget { style: TextStyle(color: Colors.black45), ), iconTheme: IconThemeData(color: Colors.black), - backgroundColor: fillColor, - elevation: 3, + backgroundColor: whiteColor, + elevation: 1, leading: IconButton( icon: Icon(vm.prevCategories.length > 0 ? Icons.arrow_back @@ -49,6 +56,7 @@ class CatalogBottomSheet extends StatelessWidget { Navigator.pop(context); }, ), + actions: [buildActionContainer()], ), body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -60,30 +68,49 @@ class CatalogBottomSheet extends StatelessWidget { itemBuilder: (context, index) { var el = vm.bottomSheetElements[index]; String name; + String price; if (el is Category) { Category category = el; name = category.name; } else if (el is Good) { Good good = el; name = good.name; + price = good.price.toString(); + } else if (el is Service) { + Service service = el; + name = service.name; + price = service.price.toString(); } return Card( child: ListTile( - leading: Icon( - el is Category ? Icons.layers : Icons.move_to_inbox, - size: 40, + leading: el is Category + ? Icon(Icons.layers, size: 25) + : null, + title: Text( + name, + style: TextStyle(fontSize: 15), ), - title: Text(name), onTap: () async { if (el is Category) { - Redux.store.dispatch(selectBottomElement(el.id)); + Redux.store + .dispatch(selectBottomElement(el.id)); } else if (el is Good) { - await Redux.store.dispatch(addProductToKassaItems(el)); + await Redux.store + .dispatch(addProductToKassaItems(el)); + Navigator.pop(context); + } else if (el is Service) { + await Redux.store + .dispatch(addServiceToKassaItems(el)); Navigator.pop(context); } }, - trailing: - el is Category ? Icon(Icons.chevron_right) : null, + trailing: el is Category + ? Icon(Icons.chevron_right) + : Text( + price, + style: TextStyle( + fontSize: 15, color: Colors.black54), + ), ), ); }, @@ -104,4 +131,68 @@ class CatalogBottomSheet extends StatelessWidget { }, ); } + + Container buildActionContainer() { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0), + child: StoreConnector( + converter: (store) => store.state.kassaState, + builder: (_, mainState) { + return StoreConnector( + converter: (store) => store.state.settingState, + builder: (_, settingState) { + if (mainState.kassaItems.isNotEmpty) { + return GestureDetector( + onTap: () { + locator().showDialog( + description: + 'Выбрать другой тип продажи, возможно только при пустом списке покупок'); + }, + child: Container( + child: Text( + settingState.tradeType == SettingTradeTypeGood + ? 'Товары' + : 'Услуги', + style: dropDownTradeTypeTextStyle, + ), + padding: const EdgeInsets.symmetric(vertical: 8.0), + )); + } + return DropdownButton( + value: settingState.tradeType, + icon: Icon( + Icons.arrow_drop_down_circle, + color: yellowColor, + ), + iconSize: 24, + elevation: 6, + style: dropDownTradeTypeTextStyle, + underline: Container( + height: 1, + ), + onChanged: (String newValue) { + onChangeTradeType(newValue, settingState.tradeType); + }, + items: [ + DropdownMenuItem( + child: Text('Товары'), + value: SettingTradeTypeGood, + ), + DropdownMenuItem( + child: Text('Услуги'), + value: SettingTradeTypeService, + ) + ], + ); + }); + }), + ); + } + + void onChangeTradeType(String newValue, String oldValue) async { + if (oldValue != newValue) { + await Redux.store.dispatch(changeTradeTypeFromSetting(newValue)); + await Redux.store.dispatch(selectBottomElement(0)); + } + } } diff --git a/lib/views/home/tabs/kassaView/ProductAddBottomSheet.dart b/lib/views/home/tabs/kassaView/ProductAddBottomSheet.dart index c751840..9493342 100644 --- a/lib/views/home/tabs/kassaView/ProductAddBottomSheet.dart +++ b/lib/views/home/tabs/kassaView/ProductAddBottomSheet.dart @@ -1,4 +1,4 @@ -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; @@ -155,7 +155,7 @@ class _ProductAddBottomSheetState extends State { _showDialog(); } else { Redux.store.dispatch(addCustomProductToKassaItems(nameController.text, - int.parse(countController.text), double.parse(priceController.text))); + int.parse(countController.text), double.parse(priceController.text), sum)); Navigator.pop(context); } } diff --git a/lib/views/login/login_view.dart b/lib/views/login/login_view.dart index 2b4b254..3bf0345 100644 --- a/lib/views/login/login_view.dart +++ b/lib/views/login/login_view.dart @@ -25,7 +25,6 @@ class LoginView extends StatelessWidget { return StoreConnector( converter: (store) => store.state.userState, builder: (context, vm) { - print('build'); return Scaffold( key: _scaffoldKey, backgroundColor: fillColor, diff --git a/lib/views/payment/payment_view.dart b/lib/views/payment/payment_view.dart new file mode 100644 index 0000000..b5dd9fb --- /dev/null +++ b/lib/views/payment/payment_view.dart @@ -0,0 +1,179 @@ +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/calc_model.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; +import 'package:aman_kassa_flutter/core/route_names.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/constants/operation_const.dart'; +import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; +import 'package:aman_kassa_flutter/redux/state/calc_state.dart'; +import 'package:aman_kassa_flutter/redux/state/kassa_state.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; +import 'package:aman_kassa_flutter/views/check/image_show_container.dart'; +import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart'; +import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart'; +import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; + +class PaymentView extends StatefulWidget { + final PaymentModel model; + + const PaymentView({Key key, this.model}) : super(key: key); + + @override + _PaymentViewState createState() => _PaymentViewState(); +} + +class _PaymentViewState extends State { + final GlobalKey _keyLoader = new GlobalKey(); + final DataService _dataService = locator(); + final DialogService _dialogService = locator(); + final NavigatorService _navigatorService = locator(); + bool isBusy; + + @override + void initState() { + // TODO: implement initState + super.initState(); + isBusy = false; + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () { + if (!isBusy) + Navigator.pop(context); + return new Future(() => false); + }, + child: Scaffold( + appBar: AppBar( + backgroundColor: whiteColor, + elevation: 0, + leading: IconButton(icon: Icon(Icons.arrow_back_ios), color: Colors.black87, onPressed: () => Navigator.pop(context),), + title: Text(dataTitle(), style: TextStyle(color: Colors.black87),), + ), + body: Container( + padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0 ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(dataText() , style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black26, fontSize: 15 ),), + buildStoreConnector(), + verticalSpaceLarge, + _buildBodyContent(), + ], + ), + ), + ), + ); + } + + String dataTitle() => widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат'; + + String dataText() => widget.model.operationType == OperationTypePay ? 'К оплате' : 'К возврату'; + + StoreConnector buildStoreConnector() { + if(widget.model.mode == SettingModeCalc) { + return StoreConnector( + converter: (store) => store.state.calcState, + builder: (context, vm) { + return Text('${totalCalc(vm.calcItems)} тнг', style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.black87, + fontSize: 35)); + } + ); + } + return StoreConnector( + converter: (store) => store.state.kassaState, + builder: (context, vm) { + return Text('${totalKassa(vm.kassaItems)} тнг', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 35 )); + } + ); + } + + Expanded _buildBodyContent() { + return Expanded( + child: Column( + children: [ + Container( + height: 150, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded(child: BusyButton(title: 'Оплатить картой', onPressed:() { pressPayment('card');}, mainColor: greenColor,)), + horizontalSpaceSmall, + Expanded(child: BusyButton(title: 'Наличными', onPressed:() { pressPayment('cash');}, mainColor: primaryColor,)), + ], + ), + ), + verticalSpaceLarge, + Expanded(child: Container(),), + Container(child: BusyButton(title: 'Отмена', onPressed:() { Navigator.pop(context);} , mainColor: redColor,)), + ], + ), + ); + } + + pressPayment(String type) async { + setState(() { isBusy = true; }); + Dialogs.showLoadingDialog(context, _keyLoader); + try { + AppState _state = Redux.store.state; + String _token = _state.userState.user.token; + String _tradeType = _state.settingState.tradeType; + List items = _state.kassaState.kassaItems; + Response response = await _dataService.sellOrReturn(token: _token, items: items, paymentType: type, operationType: widget.model.operationType, tradeType: _tradeType ); + Navigator.of(context, rootNavigator: true).pop(); + setState(() { isBusy = false; }); + if(response.operation){ + String message = response.body['message']; + String check = response.body['check']; + _navigatorService.pop(); + _navigatorService.push(ImageShowRoute, arguments: ImageShowModel(check, message)); + } else if(!response.operation && response.status !=500) { + _dialogService.showDialog(description: response.body['message']); + } + } catch(e) { + //Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + Navigator.of(context, rootNavigator: true).pop(); + setState(() { isBusy = false; }); + } + + + } + + String totalKassa(List kassaItems) { + num total = 0.0; + kassaItems.forEach((element) { + total+= element.total == null ? 0.0 : element.total.toDouble(); + }); + return total.toString(); + } + + String totalCalc(List items) { + num total = 0.0; + items.forEach((element) { + if(element.operation == Calculations.MULTIPLY) { + double num1 = element.num1 == null ? 0.0 : double.parse(element.num1); + double num2 = element.num2 == null ? 0.0 : double.parse(element.num2); + total += num1 * num2; + } else { + total+= element.num1 == null ? 0.0 : double.parse(element.num1); + } + }); + return total.toString(); + } +} + +class PaymentModel { + String operationType; + String mode; + PaymentModel({this.mode, this.operationType}); +} \ No newline at end of file diff --git a/lib/views/start_up/start_up_view.dart b/lib/views/start_up/start_up_view.dart index cc9b1f4..2bff42d 100644 --- a/lib/views/start_up/start_up_view.dart +++ b/lib/views/start_up/start_up_view.dart @@ -34,8 +34,6 @@ class _StartUpViewState extends State { height: 200, child: Image.asset('assets/images/icon_large.png'), ), - Text('${userState.isLoading}'), - Text('${userState.isAuthenticated}'), CircularProgressIndicator( strokeWidth: 3, valueColor: AlwaysStoppedAnimation( diff --git a/lib/widgets/components/ProductListItem.dart b/lib/widgets/components/ProductListItem.dart index 8f76713..4570ebe 100644 --- a/lib/widgets/components/ProductListItem.dart +++ b/lib/widgets/components/ProductListItem.dart @@ -1,9 +1,9 @@ -import 'package:aman_kassa_flutter/redux/actions/main_actions.dart'; +import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/shared_styles.dart'; import 'package:flutter/material.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; -import 'package:aman_kassa_flutter/core/models/ProductDao.dart'; +import 'package:aman_kassa_flutter/core/models/product_dao.dart'; class ProductListItem extends StatelessWidget { final ProductDao item; @@ -28,7 +28,7 @@ class ProductListItem extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), child: Text( - '${item.price?.toString()} x ${item.count?.toString()}', + '${item.price?.toString()} x ${item.count?.toString()} = ${item.total?.toString()}', textAlign: TextAlign.right, style: productTextStyle)), ) ], diff --git a/lib/widgets/components/calculator/calculator-button.dart b/lib/widgets/components/calculator/calculator-button.dart index 72e1217..96d146a 100644 --- a/lib/widgets/components/calculator/calculator-button.dart +++ b/lib/widgets/components/calculator/calculator-button.dart @@ -20,7 +20,7 @@ class CalculatorButton extends StatelessWidget { decoration: BoxDecoration( border: Border.all( color: Colors.black, - width: 1, + width: 1.2, ), ), child: FlatButton( diff --git a/lib/widgets/components/calculator/calculator.dart b/lib/widgets/components/calculator/calculator.dart index 306d043..4dd959b 100644 --- a/lib/widgets/components/calculator/calculator.dart +++ b/lib/widgets/components/calculator/calculator.dart @@ -1,3 +1,5 @@ +import 'package:aman_kassa_flutter/core/models/calc_model.dart'; + import 'number-formatter.dart'; class Calculations { @@ -5,7 +7,8 @@ class Calculations { static const MULTIPLY = '*'; static const SUBTRACT = '-'; static const ADD = '+'; - static const DIVIDE = '/'; + static const NONE = 'none'; + static const ERASE = '<<'; static const CLEAR = 'C'; static const EQUAL = '='; @@ -13,72 +16,273 @@ class Calculations { Calculations.ADD, Calculations.MULTIPLY, Calculations.SUBTRACT, - Calculations.DIVIDE, Calculations.ERASE ]; static double add(double a, double b) => a + b; + static double subtract(double a, double b) => a - b; + static double divide(double a, double b) => a / b; - static double multiply(double a, double b) => a * b; + + static double multiply(double a, double b) => a * b; } class Calculator { - static String parseString(String text) { - List numbersToAdd; - double a, b, result; - if (text.contains(Calculations.ADD)) { - numbersToAdd = text.split(Calculations.ADD); - a = double.parse(numbersToAdd[0]); - b = double.parse(numbersToAdd[1]); - - result = Calculations.add(a, b); - } else if (text.contains(Calculations.MULTIPLY)) { - numbersToAdd = text.split(Calculations.MULTIPLY); - a = double.parse(numbersToAdd[0]); - b = double.parse(numbersToAdd[1]); - - result = Calculations.multiply(a, b); - } else if (text.contains(Calculations.DIVIDE)) { - numbersToAdd = text.split(Calculations.DIVIDE); - a = double.parse(numbersToAdd[0]); - b = double.parse(numbersToAdd[1]); - - result = Calculations.divide(a, b); - } else if (text.contains(Calculations.SUBTRACT)) { - numbersToAdd = text.split(Calculations.SUBTRACT); - a = double.parse(numbersToAdd[0]); - b = double.parse(numbersToAdd[1]); - - result = Calculations.subtract(a, b); + static String parseItems(List items, bool isEqual) { + if (isEqual) { + return _viewResult(items); } else { - return text; + return _viewValues(items); } - - return NumberFormatter.format(result.toString()); } - static String addPeriod(String calculatorString) { - if (calculatorString.isEmpty) { - return calculatorString = '0${Calculations.PERIOD}'; + static String _viewResult(List items) { + String str = ''; + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + if (last.operation == Calculations.NONE && last.num1 != '0') { + last.operation = Calculations.ADD; + } else if (last.operation == Calculations.MULTIPLY) { + if (last.num2 == null) { + last.num2 = '1'; + last.operation = Calculations.ADD; + } + } + last.closed = true; + items.add(last); + double summ = 0.0; + for (var i = 0; i < items.length; i++) { + var row = items[i]; + if (row.operation == Calculations.MULTIPLY) { + str += "${row.num1} * ${row.num2}" ; + summ += double.parse(row.num1) * double.parse(row.num2); + } else { + str += row.num1; + summ += double.parse(row.num1) ; + } + + if (row.closed) { + if (i < items.length - 1) { + str += " + "; + } else { + str += " = "; + } + } + } + + str += summ.toStringAsFixed(2); + } - - RegExp exp = new RegExp(r"\d\."); - Iterable matches = exp.allMatches(calculatorString); - int maxMatches = Calculator.includesOperation(calculatorString) ? 2 : 1; - - return matches.length == maxMatches - ? calculatorString - : calculatorString += Calculations.PERIOD; + return str; } - static bool includesOperation(String calculatorString) { - for (var operation in Calculations.OPERATIONS) { - if (calculatorString.contains(operation)) { - return true; + static String _viewValues(List items) { + String str = ''; + for (var i = 0; i < items.length; i++) { + CalcModel row = items[i]; + if (row.operation == Calculations.ADD) { + str += row.num1; + } else if (row.operation == Calculations.MULTIPLY) { + if (row.num2 == null) { + str += row.num1 + " * "; + } else { + str += row.num1 + " * " + row.num2; + } + } else if (row.operation == Calculations.NONE) { + str += row.num1; + } else if (row.operation == Calculations.EQUAL) { + str += row.num1; + } + if (row.closed) { + str += " + "; } } + return str; + } - return false; + static List action({String value, List items}) { + switch (value) { + case Calculations.ADD: + { + items = _setPlus(value: value, items: items); + } + break; + case Calculations.MULTIPLY: + { + items = _setMultiply(value: value, items: items); + } + break; + case Calculations.ERASE: + { + items = _setBackward(value: value, items: items); + } + break; + case Calculations.CLEAR: + { + items = _setClean(value: value, items: items); + } + break; + case Calculations.PERIOD: + { + items = _setDot(value: value, items: items); + } + break; + case Calculations.EQUAL: + { + items = _setEqual(value: value, items: items); + } + break; + + default: + { + items = _setNumber(value: value, items: items); + } + break; + } + + return [...items]; + } + + static List _setNumber({String value, List items}) { + if (items.isEmpty) { + items.add(CalcModel(num1: value, operation: Calculations.NONE)); + } else { + CalcModel last = items.removeLast(); + if (last.closed) { + items.add(last); + items.add(CalcModel(num1: value, operation: Calculations.NONE)); + } else { + if (value == '0' && last.num1 == '0') { + last.operation = Calculations.NONE; + items.add(last); + } else if (value == '0' && last.num1 == '0.') { + last.num1 += value; + last.operation = Calculations.NONE; + items.add(last); + } else { + if (last.operation == Calculations.NONE) { + if (last.num1 == '0' && value != '0') { + last.num1 = value; + } else { + last.num1 += value; + } + items.add(last); + } else if (last.operation == Calculations.MULTIPLY) { + if(last.num2 == null) + last.num2 = value; + else + last.num2 += value; + last.operation = Calculations.MULTIPLY; + items.add(last); + } else if (last.operation == Calculations.ADD) { + last.operation = Calculations.ADD; + items.add(last); + } + } + } + } + return [...items]; + } + + static List _setPlus({String value, List items}) { + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + if (last.closed) { + items.add(last); + } else { + if (last.operation == Calculations.NONE) { + if (last.num1 != '0') { + last.num2 = '1'; + last.operation = Calculations.ADD; + last.closed = true; + } + items.add(last); + } else if (last.operation == Calculations.MULTIPLY) { + if (last.num2 == null) { + last.num2 = '1'; + last.operation = Calculations.ADD; + } + last.closed = true; + items.add(last); + } else { + last.closed = true; + items.add(last); + } + } + } + return [...items]; + } + + static List _setDot({String value, List items}) { + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + if (last.operation == Calculations.NONE) { + if (last.num1?.contains('.') == false) { + last.num1 += '.'; + } + last.operation = Calculations.NONE; + items.add(last); + } else if (last.operation == Calculations.ADD) { + items.add(last); + items.add(CalcModel(num1: '0.', operation: Calculations.NONE)); + } else if (last.operation == Calculations.MULTIPLY) { + if (last.num2 == null) { + last.num2 += '0.'; + } else { + if (last.num2?.contains('.') == false) { + last.num2 += '.'; + } + } + last.operation = Calculations.MULTIPLY; + items.add(last); + } + } else { + items.add(CalcModel(num1: '0.', operation: Calculations.NONE)); + } + return [...items]; + } + + static List _setClean({String value, List items}) { + return []; + } + + static List _setEqual({String value, List items}) { + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + last.operation = Calculations.EQUAL; + items.add(last); + } + return [...items]; + } + + static List _setMultiply({String value, List items}) { + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + if (last.closed) { + items.add(last); + } else { + if (last.operation == Calculations.NONE) { + if (last.num1 != '0') { + last.operation = Calculations.MULTIPLY; + last.num2 = null; + } + items.add(last); + } else if (last.operation == Calculations.MULTIPLY) { + if (last.num2 != '0') { + last.closed = true; + } + items.add(last); + } + } + } + return [...items]; + } + + static List _setBackward({String value, List items}) { + if (items.isNotEmpty) { + CalcModel last = items.removeLast(); + } + return [...items]; } } diff --git a/lib/widgets/components/calculator/number-display.dart b/lib/widgets/components/calculator/number-display.dart index 9c44a33..3257df4 100644 --- a/lib/widgets/components/calculator/number-display.dart +++ b/lib/widgets/components/calculator/number-display.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; class NumberDisplay extends StatelessWidget { @@ -5,18 +7,44 @@ class NumberDisplay extends StatelessWidget { final String value; + GlobalKey stickyKey = GlobalKey(); + @override Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.all(20), - child: Row( - children: [ - Text( - value, - style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold), + return Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0 ), + child: Container( + key: stickyKey, + alignment: Alignment.topLeft, + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 200), + style: TextStyle( + fontSize: fontSizeCalc(value: value), + fontWeight: FontWeight.bold, + color: Colors.black, + ), + child: Text( + value, + ), ), - ], - mainAxisAlignment: MainAxisAlignment.end, - )); + )), + ); + } + + double fontSizeCalc({ String value = " " }) { + const double result = 40.0; + try { + const double global = 100000.0; + double scale = (global / value.length); + final pixelOfLetter = sqrt(scale); + final pixelOfLetterP = pixelOfLetter - (pixelOfLetter * 5) / 100; + if(pixelOfLetterP> result){ + return result; + } + return pixelOfLetterP; + } catch(e) { + return result; + } } } diff --git a/lib/widgets/dialog_manager.dart b/lib/widgets/dialog_manager.dart index 130fba9..39157fa 100644 --- a/lib/widgets/dialog_manager.dart +++ b/lib/widgets/dialog_manager.dart @@ -2,9 +2,11 @@ import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; class DialogManager extends StatefulWidget { final Widget child; + DialogManager({Key key, this.child}) : super(key: key); _DialogManagerState createState() => _DialogManagerState(); @@ -12,11 +14,19 @@ class DialogManager extends StatefulWidget { class _DialogManagerState extends State { DialogService _dialogService = locator(); + TextEditingController controller; @override void initState() { super.initState(); - _dialogService.registerDialogListener(_showDialog); + controller = new TextEditingController(); + _dialogService.registerDialogListener(_showDialog, _showDialogInput); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); } @override @@ -50,4 +60,44 @@ class _DialogManagerState extends State { ], )); } + + void _showDialogInput(DialogRequest request) { + var isConfirmationDialog = request.cancelTitle != null; + controller.clear(); + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(request.title), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(request.description), + TextField( + controller: controller, + keyboardType: TextInputType.number, + inputFormatters: [ + WhitelistingTextInputFormatter(RegExp("^[0-9.]*")), + ], + ) + ], + ), + actions: [ + if (isConfirmationDialog) + FlatButton( + child: Text(request.cancelTitle), + onPressed: () { + _dialogService + .dialogComplete(DialogResponse(confirmed: false)); + }, + ), + FlatButton( + child: Text(request.buttonTitle), + onPressed: () { + _dialogService + .dialogComplete(DialogResponse(confirmed: true, responseText: controller.text)); + }, + ), + ], + )); + } } diff --git a/lib/widgets/fields/aman_icon_button.dart b/lib/widgets/fields/aman_icon_button.dart new file mode 100644 index 0000000..424c448 --- /dev/null +++ b/lib/widgets/fields/aman_icon_button.dart @@ -0,0 +1,64 @@ +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:aman_kassa_flutter/shared/shared_styles.dart'; +import 'package:flutter/material.dart'; + +/// A button that shows a busy indicator in place of title +class AmanIconButton extends StatefulWidget { + final bool busy; + final String title; + final Function onPressed; + final bool enabled; + final Color mainColor; + final IconData icon; + const AmanIconButton( + { + @required this.title, + this.busy = false, + @required this.onPressed, + this.enabled = true, + this.mainColor, + @required this.icon + }); + + @override + _AmanIconButtonState createState() => _AmanIconButtonState(); +} + +class _AmanIconButtonState extends State { + @override + Widget build(BuildContext context) { + return GestureDetector( + child: InkWell( + + onTap: widget.busy ? () {} : widget.onPressed, + child: Container( + //height: 75, + width: 120, + alignment: Alignment.center, + padding: EdgeInsets.symmetric( + horizontal: 25, + vertical: 15), + decoration: BoxDecoration( + //color: widget.enabled ? ( whiteColor ) : blueColorLigth, + borderRadius: BorderRadius.circular(50), + //boxShadow: [buttonShadowBox], + ), + child: Column( + children: [ + (!widget.busy + ? Icon( + widget.icon, + color: widget.mainColor, + size: 36, + ) + : CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(widget.mainColor))), + Text(widget.title, style: TextStyle(color: widget.mainColor, fontSize: 15, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center,) + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/fields/aman_icon_button_horizontal.dart b/lib/widgets/fields/aman_icon_button_horizontal.dart new file mode 100644 index 0000000..1a0b951 --- /dev/null +++ b/lib/widgets/fields/aman_icon_button_horizontal.dart @@ -0,0 +1,38 @@ +import 'package:aman_kassa_flutter/shared/app_colors.dart'; +import 'package:aman_kassa_flutter/shared/shared_styles.dart'; +import 'package:flutter/material.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; + +/// A button that shows a busy indicator in place of title +class AmanIconButtonHorizontal extends StatefulWidget { + final String title; + final Function onPressed; + final Color activeColor; + final Color inactiveColor; + final bool selected; + final IconData icon; + const AmanIconButtonHorizontal( + { + @required this.title, + this.onPressed, + this.activeColor = primaryColor, + this.inactiveColor = Colors.black26, + this.selected = false, + @required this.icon + }); + + @override + _AmanIconButtonHorizontalState createState() => _AmanIconButtonHorizontalState(); +} + +class _AmanIconButtonHorizontalState extends State { + @override + Widget build(BuildContext context) { + return GestureDetector( + child: InkWell( + onTap: widget.onPressed, + child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Icon(widget.icon , color: widget.selected ? widget.activeColor : widget.inactiveColor ), Text(widget.title, style: TextStyle( color: widget.selected ? widget.activeColor : widget.inactiveColor, fontWeight: FontWeight.w800 ) )],), + ), + ); + } +} diff --git a/lib/widgets/fields/busy_button.dart b/lib/widgets/fields/busy_button.dart index 8b9536b..c891e18 100644 --- a/lib/widgets/fields/busy_button.dart +++ b/lib/widgets/fields/busy_button.dart @@ -25,30 +25,36 @@ class BusyButton extends StatefulWidget { class _BusyButtonState extends State { @override Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 25, - vertical: widget.busy ? 10 : 15), - decoration: BoxDecoration( - color: widget.enabled ? ( widget.mainColor ?? primaryColor) : blueColorLigth, - borderRadius: BorderRadius.circular(7), - boxShadow: [mainShadowBox] + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + decoration: BoxDecoration( + color: widget.enabled ? ( widget.mainColor ?? primaryColor) : blueColorLigth, + borderRadius: BorderRadius.circular(7), + boxShadow: [ + cardShadowBox + ] + ), + child: Material( + type: MaterialType.transparency, + child: InkWell( + onTap: widget.busy ? () {} : widget.onPressed, + child: AnimatedContainer( + height: widget.busy ? 40 : 40, + //width: widget.busy ? 40 : 40, + duration: const Duration(milliseconds: 300), + alignment: Alignment.center, + margin: EdgeInsets.symmetric( + horizontal: widget.busy ? 10 : 25, + vertical: widget.busy ? 10 : 15), + child: !widget.busy + ? Text( + widget.title, + style: buttonTitleTextStyle, + ) + : CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation(Colors.white)), ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), ), ), ); diff --git a/lib/widgets/loader/Dialogs.dart b/lib/widgets/loader/Dialogs.dart index 3cbd7da..46414fa 100644 --- a/lib/widgets/loader/Dialogs.dart +++ b/lib/widgets/loader/Dialogs.dart @@ -1,3 +1,4 @@ +import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:flutter/material.dart'; class Dialogs { @@ -17,7 +18,7 @@ class Dialogs { child: Column(children: [ CircularProgressIndicator(), SizedBox(height: 10,), - Text("Please Wait....",style: TextStyle(color: Colors.blueAccent),) + Text("Подождите выполняеться операция с сервером", textAlign: TextAlign.center, style: TextStyle(color: Colors.grey.shade300, fontWeight: FontWeight.bold, fontSize: 15),) ]), ) ])); diff --git a/pubspec.lock b/pubspec.lock index 244b923..883b5ca 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -130,6 +130,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.12" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" logger: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 13bc3d3..889e10f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,7 @@ dependencies: flutter_boom_menu: ^1.0.2 sliding_up_panel: ^1.0.2 material_design_icons_flutter: ^4.0.5345 + intl: ^0.16.1 dev_dependencies: flutter_test: sdk: flutter