From 1d31dce7bee1a6c00c2a79544c1a8ceb8cede7bd Mon Sep 17 00:00:00 2001 From: suvaissov Date: Wed, 5 May 2021 23:06:35 +0600 Subject: [PATCH] add_product_view.dart --- lib/core/entity/Category.dart | 40 +++--- lib/core/entity/Goods.dart | 99 ++++++-------- lib/core/entity/Service.dart | 72 ---------- lib/core/entity/Transaction.dart | 49 +++++++ lib/core/entity/Voucher.dart | 64 --------- .../models/dictionary/category_response.dart | 28 ++++ lib/core/models/dictionary/good_response.dart | 52 +++++++ lib/core/models/flow/product_dao.dart | 11 ++ lib/core/models/response.dart | 32 +++++ lib/core/redux/actions/sell_actions.dart | 44 ++++++ lib/core/redux/actions/user_actions.dart | 32 ++++- lib/core/redux/constants/auth_type_const.dart | 2 - lib/core/redux/constants/operation_const.dart | 2 - lib/core/redux/constants/setting_const.dart | 6 - lib/core/redux/reducers/sell_reducer.dart | 11 ++ lib/core/redux/state/sell_state.dart | 20 +++ lib/core/redux/state/user_state.dart | 2 +- lib/core/redux/store.dart | 8 +- lib/core/services/api_service.dart | 18 ++- lib/core/services/data_service.dart | 2 + lib/core/services/db_service.dart | 81 ++++------- lib/core/services/dictionary_service.dart | 129 ++++++++++++++++++ lib/core/services/navigator_service.dart | 10 +- lib/core/utils/locator.dart | 3 + lib/core/utils/logger.dart | 2 +- lib/views/add_product/add_product_view.dart | 111 ++++++++++++--- .../component/add_category_list_item.dart | 4 +- .../component/add_product_list_item.dart | 4 +- lib/views/start_up/start_up_view.dart | 7 +- lib/views/work/tabs/sell_view.dart | 36 +++-- 30 files changed, 660 insertions(+), 321 deletions(-) delete mode 100644 lib/core/entity/Service.dart create mode 100644 lib/core/entity/Transaction.dart delete mode 100644 lib/core/entity/Voucher.dart create mode 100644 lib/core/models/dictionary/category_response.dart create mode 100644 lib/core/models/dictionary/good_response.dart create mode 100644 lib/core/models/flow/product_dao.dart create mode 100644 lib/core/models/response.dart create mode 100644 lib/core/redux/actions/sell_actions.dart delete mode 100644 lib/core/redux/constants/auth_type_const.dart delete mode 100644 lib/core/redux/constants/operation_const.dart delete mode 100644 lib/core/redux/constants/setting_const.dart create mode 100644 lib/core/redux/reducers/sell_reducer.dart create mode 100644 lib/core/redux/state/sell_state.dart create mode 100644 lib/core/services/dictionary_service.dart diff --git a/lib/core/entity/Category.dart b/lib/core/entity/Category.dart index f816f3a..e61445d 100644 --- a/lib/core/entity/Category.dart +++ b/lib/core/entity/Category.dart @@ -1,23 +1,26 @@ -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'; +const String CategoryTableName = 'goods_category'; +const String CategoryColumnId = 'id'; +const String CategoryColumnParentIn = 'parent_id'; +const String CategoryColumnName = 'name'; +const String CategoryColumnAppCompanyId = 'app_company_id'; +const String CategoryColumnUpdatedAt = 'updated_at'; class Category { int id; - int parentIn; + int parentId; String name; int appCompanyId; + String updatedAt; Map toMap() { var map = { - Category_columnParentIn: parentIn, - Category_columnName: name, - Category_columnAppCompanyId: appCompanyId + CategoryColumnParentIn: parentId, + CategoryColumnName: name, + CategoryColumnAppCompanyId: appCompanyId, + CategoryColumnUpdatedAt: updatedAt, }; if (id != null) { - map[Category_columnId] = id; + map[CategoryColumnId] = id; } return map; } @@ -25,18 +28,11 @@ class Category { Category(); Category.fromMap(Map map) { - id = map[Category_columnId]; - parentIn = map[Category_columnParentIn]; - name = map[Category_columnName]; - appCompanyId = map[Category_columnAppCompanyId]; + id = map[CategoryColumnId]; + parentId = map[CategoryColumnParentIn]; + name = map[CategoryColumnName]; + appCompanyId = map[CategoryColumnAppCompanyId]; + updatedAt = map[CategoryColumnUpdatedAt]; } - - 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 6d0f31d..3eccea1 100644 --- a/lib/core/entity/Goods.dart +++ b/lib/core/entity/Goods.dart @@ -1,45 +1,44 @@ -const String Goog_tableName = 'goods'; -const String Goog_columnId = 'id'; -const String Goog_columnArticul = 'articul'; -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'; +const String GoodTableName = 'goods'; +const String GoodColumnId = 'id'; +const String GoodColumnCategoryId = 'category_id'; +const String GoodColumnName = 'name'; +const String GoodColumnEan = 'ean'; +const String GoodColumnArticul = 'articul'; +const String GoodColumnPrice = 'price'; +const String GoodColumnOptPrice = 'opt_price'; +const String GoodColumnBasePrice = 'base_price'; +const String GoodColumnDivisible = 'divisible'; +const String GoodColumnUpdatedAt = 'updated_at'; +const String GoodColumnAppCompanyId = 'app_company_id'; class Good { int id; - int articul; - String name; - double price; int categoryId; + String name; String ean; + int articul; + num price; + num optPrice; + num basePrice; + int divisible; + String updatedAt; int appCompanyId; - String description; - double showPrice; - int okei; - double discount; Map toMap() { var map = { - Goog_columnArticul: articul, - Goog_columnName: name, - Goog_columnPrice: price, - Goog_columnCategoryId: categoryId, - Goog_columnEan: ean, - Goog_columnAppCompanyId: appCompanyId, - Goog_columnDescription: description, - Goog_columnShowPrice: showPrice, - Goog_columnOkei: okei, - Goog_columnDiscount: discount + GoodColumnArticul: articul, + GoodColumnName: name, + GoodColumnPrice: price, + GoodColumnCategoryId: categoryId, + GoodColumnEan: ean, + GoodColumnAppCompanyId: appCompanyId, + GoodColumnOptPrice: optPrice, + GoodColumnBasePrice: basePrice, + GoodColumnDivisible: divisible, + GoodColumnUpdatedAt: updatedAt, }; if (id != null) { - map[Goog_columnId] = id; + map[GoodColumnId] = id; } return map; } @@ -47,32 +46,16 @@ class Good { Good(); Good.fromMap(Map map) { - id = map[Goog_columnId]; - articul = map[Goog_columnArticul]; - name = map[Goog_columnName]; - 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(); + id = map[GoodColumnId]; + articul = map[GoodColumnArticul]; + name = map[GoodColumnName]; + price = map[GoodColumnPrice]?.toDouble(); + categoryId = map[GoodColumnCategoryId]; + ean = map[GoodColumnEan]; + appCompanyId = map[GoodColumnAppCompanyId]; + optPrice = map[GoodColumnOptPrice]; + basePrice = map[GoodColumnBasePrice]; + divisible = map[GoodColumnDivisible]; + updatedAt = map[GoodColumnUpdatedAt]; } - - Good.fromJson(Map map) { - id = map[Goog_columnId]; - articul = map[Goog_columnArticul]; - name = map[Goog_columnName]; - 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 deleted file mode 100644 index 1226a93..0000000 --- a/lib/core/entity/Service.dart +++ /dev/null @@ -1,72 +0,0 @@ -const String Service_tableName = 'services'; -const String Service_columnId = 'id'; -const String Service_columnArticul = 'articul'; -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; - } - return map; - } - - Service(); - - Service.fromMap(Map map) { - id = map[Service_columnId]; - 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(); - 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/entity/Transaction.dart b/lib/core/entity/Transaction.dart new file mode 100644 index 0000000..9ae76d4 --- /dev/null +++ b/lib/core/entity/Transaction.dart @@ -0,0 +1,49 @@ +const String TransactionTableName = 'transactions'; +const String TransactionColumnId = 'id'; +const String TransactionColumnUuid = 'uuid'; +const String TransactionColumnType = 'type'; +const String TransactionColumnStatus = 'status'; +const String TransactionColumnData = 'data'; +const String TransactionColumnCreatedAt = 'createdAt'; + +const int TransactionTypeSell = 1; +const int TransactionTypeBuy = 2; + +const int TransactionStatusPrepare = 0; + + +class Transaction { + int id; + String uuid; + int type; + int status; + String data; + String createdAt; + + Map toMap() { + var map = { + TransactionColumnUuid: uuid, + TransactionColumnType: type, + TransactionColumnStatus: status, + TransactionColumnData: data, + TransactionColumnCreatedAt: createdAt, + }; + if (id != null) { + map[TransactionColumnId] = id; + } + return map; + } + + Transaction(); + + Transaction.fromMap(Map map) { + id = map[TransactionColumnId]; + uuid = map[TransactionColumnUuid]; + type = map[TransactionColumnType]; + status = map[TransactionColumnStatus]; + data = map[TransactionColumnData]; + createdAt = map[TransactionColumnCreatedAt]; + } + +} + diff --git a/lib/core/entity/Voucher.dart b/lib/core/entity/Voucher.dart deleted file mode 100644 index 8b6740a..0000000 --- a/lib/core/entity/Voucher.dart +++ /dev/null @@ -1,64 +0,0 @@ -const String Voucher_tableName = 'vouches'; -const String Voucher_columnId = 'id'; -const String Voucher_columnName = 'name'; -const String Voucher_columnTotal = 'total'; -const String Voucher_columnBase64Data = 'base64Data'; -const String Voucher_columnData = 'data'; -const String Voucher_columnDateTime = 'dateTime'; -const String Voucher_columnAppCompanyId = 'app_company_id'; -const String Voucher_columnKassaId = 'kassaId'; -const String Voucher_columnType = 'type'; -const String Voucher_columnUrl = 'url'; - - -const String VoucherTypePayment = 'payment'; -const String VoucherTypeReturnPay = 'returnPay'; -const String VoucherTypeReport = 'report'; - -class Voucher { - int id; - String name; - double total; - String data; - String base64Data; - DateTime dateTime; - int appCompanyId; - int kassaId; - String type; - String url; - - Voucher(); - - Map toMap() { - var map = { - Voucher_columnName: name, - Voucher_columnTotal: total, - Voucher_columnData: data, - Voucher_columnBase64Data: base64Data, - Voucher_columnDateTime: dateTime.toIso8601String(), - Voucher_columnKassaId: kassaId, - Voucher_columnAppCompanyId: appCompanyId, - Voucher_columnType: type, - Voucher_columnUrl: url, - }; - if (id != null) { - map[Voucher_columnId] = id; - } - return map; - } - - Voucher.fromMap(Map map) { - id = map[Voucher_columnId]; - name = map[Voucher_columnName]; - total = map[Voucher_columnTotal]?.toDouble(); - data = map[Voucher_columnData]; - base64Data = map[Voucher_columnBase64Data]; - dateTime = DateTime.parse(map[Voucher_columnDateTime]); - appCompanyId= map[Voucher_columnAppCompanyId]; - kassaId = map[Voucher_columnKassaId]; - type = map[Voucher_columnType]; - url = map[Voucher_columnUrl]; - } - -} - diff --git a/lib/core/models/dictionary/category_response.dart b/lib/core/models/dictionary/category_response.dart new file mode 100644 index 0000000..cc04da4 --- /dev/null +++ b/lib/core/models/dictionary/category_response.dart @@ -0,0 +1,28 @@ +/// id : 4 +/// parent_id : 0 +/// name : "" +/// updated_at : "2021-01-06 14:20:47" + +class CategoryResponse { + int id; + int parentId; + String name; + String updatedAt; + + static CategoryResponse fromMap(Map map) { + if (map == null) return null; + CategoryResponse categoryResponseBean = CategoryResponse(); + categoryResponseBean.id = map['id']; + categoryResponseBean.parentId = map['parent_id']; + categoryResponseBean.name = map['name']; + categoryResponseBean.updatedAt = map['updated_at']; + return categoryResponseBean; + } + + Map toJson() => { + "id": id, + "parent_id": parentId, + "name": name, + "updated_at": updatedAt, + }; +} \ No newline at end of file diff --git a/lib/core/models/dictionary/good_response.dart b/lib/core/models/dictionary/good_response.dart new file mode 100644 index 0000000..d871cc9 --- /dev/null +++ b/lib/core/models/dictionary/good_response.dart @@ -0,0 +1,52 @@ +/// id : 6 +/// category_id : 4 +/// name : "KENT SILVER" +/// ean : "46187413" +/// articul : 1 +/// price : 500 +/// opt_price : 500 +/// base_price : 500 +/// divisible : 0 +/// updated_at : "2021-02-03 11:37:34" + +class GoodResponse { + int id; + int categoryId; + String name; + String ean; + int articul; + int price; + int optPrice; + int basePrice; + int divisible; + String updatedAt; + + static GoodResponse fromMap(Map map) { + if (map == null) return null; + GoodResponse goodResponseBean = GoodResponse(); + goodResponseBean.id = map['id']; + goodResponseBean.categoryId = map['category_id']; + goodResponseBean.name = map['name']; + goodResponseBean.ean = map['ean']; + goodResponseBean.articul = map['articul']; + goodResponseBean.price = map['price']; + goodResponseBean.optPrice = map['opt_price']; + goodResponseBean.basePrice = map['base_price']; + goodResponseBean.divisible = map['divisible']; + goodResponseBean.updatedAt = map['updated_at']; + return goodResponseBean; + } + + Map toJson() => { + "id": id, + "category_id": categoryId, + "name": name, + "ean": ean, + "articul": articul, + "price": price, + "opt_price": optPrice, + "base_price": basePrice, + "divisible": divisible, + "updated_at": updatedAt, + }; +} \ No newline at end of file diff --git a/lib/core/models/flow/product_dao.dart b/lib/core/models/flow/product_dao.dart new file mode 100644 index 0000000..1e9fb5d --- /dev/null +++ b/lib/core/models/flow/product_dao.dart @@ -0,0 +1,11 @@ +class ProductDao { + int id; + int categoryId; + num count; + num price; + String productName; + String categoryName; + String eanCode; + int article; + String excise; +} \ No newline at end of file diff --git a/lib/core/models/response.dart b/lib/core/models/response.dart new file mode 100644 index 0000000..22cf2a8 --- /dev/null +++ b/lib/core/models/response.dart @@ -0,0 +1,32 @@ +/// list : [] +/// message : "" +/// operation : true + +class Response { + List list; + String message; + bool operation; + + Response(); + + factory Response.fromMapList(Map map, Function parser) { + if (map == null) return null; + + List list = []; + if (map['list'] != null) { + (map['list'] as List).forEach((element) { + if(parser == null) + list.add(element); + else + list.add(parser(element)); + }); + } + Response responseBean = Response(); + responseBean.list = list; + responseBean.message = map['message']; + responseBean.operation = map['operation']; + return responseBean; + } + + +} diff --git a/lib/core/redux/actions/sell_actions.dart b/lib/core/redux/actions/sell_actions.dart new file mode 100644 index 0000000..ddd0fcd --- /dev/null +++ b/lib/core/redux/actions/sell_actions.dart @@ -0,0 +1,44 @@ +import 'package:meta/meta.dart'; +import 'package:redux/redux.dart'; +import 'package:redux_thunk/redux_thunk.dart'; +import 'package:satu/core/entity/Category.dart'; +import 'package:satu/core/entity/Goods.dart'; +import 'package:satu/core/models/flow/product_dao.dart'; +import 'package:satu/core/redux/state/sell_state.dart'; +import 'package:satu/core/services/db_service.dart'; +import 'package:satu/core/services/dialog_service.dart'; +import 'package:satu/core/utils/locator.dart'; + +import '../store.dart'; + +@immutable +class SetSellStateAction { + final SellState sellState; + + SetSellStateAction(this.sellState); +} + +final DbService _dbService = locator(); + +ThunkAction addSellItem({Good good, String excise}) { + return (Store store) async { + ProductDao item = new ProductDao() + ..id = good.id + ..price = good.price + ..article = good.articul + ..count = 1.0 + ..eanCode = good.ean + ..productName = good.name + ..excise = excise; + //category add logic + if (good.categoryId != null) { + List> set = + await _dbService.queryRowsWithWhere(CategoryTableName, 'id = ?', [good.categoryId]); + if (set.isNotEmpty) { + Category category = Category.fromMap(set.first); + item.categoryId = category.id; + } + } + store.dispatch(SetSellStateAction(SellState())); + }; +} diff --git a/lib/core/redux/actions/user_actions.dart b/lib/core/redux/actions/user_actions.dart index 43cfd61..57610ee 100644 --- a/lib/core/redux/actions/user_actions.dart +++ b/lib/core/redux/actions/user_actions.dart @@ -2,10 +2,10 @@ import 'package:redux/redux.dart'; import 'package:meta/meta.dart'; import 'package:redux_thunk/redux_thunk.dart'; import 'package:satu/core/models/auth/auth_response.dart'; -import 'package:satu/core/redux/constants/auth_type_const.dart'; import 'package:satu/core/redux/state/user_state.dart'; import 'package:satu/core/services/api_service.dart'; import 'package:satu/core/services/dialog_service.dart'; +import 'package:satu/core/services/dictionary_service.dart'; import 'package:satu/core/services/navigator_service.dart'; import 'package:satu/core/utils/locator.dart'; import 'package:satu/routes/route_names.dart'; @@ -21,6 +21,8 @@ final ApiService _api = locator(); final NavigatorService _navigation = locator(); final DialogService _dialogService = locator(); +final DictionaryService _dictionaryService = locator(); + ThunkAction authenticate(String email, String password) { return (Store store) async { @@ -31,6 +33,7 @@ ThunkAction authenticate(String email, String password) { _api.token = result.token; store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: result))); _navigation.replace(MainViewRoute); + _afterAuth(store); } else { _dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message); } @@ -42,6 +45,29 @@ ThunkAction authenticate(String email, String password) { }; } +Future auth(Store store) async { + store.dispatch(SetUserStateAction(UserState(isLoading: true))); + try { + UserState state = store.state.userState; + if(state.auth.operation == false) { + _navigation.replace(LoginViewRoute); + } else { + AuthResponse response = await _api.auth(state.auth.token); + if(response.operation){ + _api.token = response.token; + _navigation.replace(MainViewRoute); + _afterAuth(store); + } else { + _navigation.replace(LoginViewRoute); + } + } + } catch (e) { + print(e); + } finally { + store.dispatch(SetUserStateAction(UserState(isLoading: false))); + } +} + Future logout(Store store) async { store.dispatch(SetUserStateAction(UserState(isLoading: true))); try { @@ -60,3 +86,7 @@ Future logout(Store store) async { } } +Future _afterAuth(Store store) async { + await _dictionaryService.refreshFull(); +} + diff --git a/lib/core/redux/constants/auth_type_const.dart b/lib/core/redux/constants/auth_type_const.dart deleted file mode 100644 index 2227403..0000000 --- a/lib/core/redux/constants/auth_type_const.dart +++ /dev/null @@ -1,2 +0,0 @@ -const String AuthenticateTypeQr = 'AuthenticateTypeQr'; -const String AuthenticateTypeLogin = 'AuthenticateTypeLogin'; \ No newline at end of file diff --git a/lib/core/redux/constants/operation_const.dart b/lib/core/redux/constants/operation_const.dart deleted file mode 100644 index 8557ec6..0000000 --- a/lib/core/redux/constants/operation_const.dart +++ /dev/null @@ -1,2 +0,0 @@ -const String OperationTypePay = 'OperationTypePay'; -const String OperationTypeReturn = 'OperationTypeReturn'; \ No newline at end of file diff --git a/lib/core/redux/constants/setting_const.dart b/lib/core/redux/constants/setting_const.dart deleted file mode 100644 index 787527a..0000000 --- a/lib/core/redux/constants/setting_const.dart +++ /dev/null @@ -1,6 +0,0 @@ -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/core/redux/reducers/sell_reducer.dart b/lib/core/redux/reducers/sell_reducer.dart new file mode 100644 index 0000000..e7fe923 --- /dev/null +++ b/lib/core/redux/reducers/sell_reducer.dart @@ -0,0 +1,11 @@ +import 'package:satu/core/redux/actions/sell_actions.dart'; +import 'package:satu/core/redux/actions/user_actions.dart'; +import 'package:satu/core/redux/state/sell_state.dart'; +import 'package:satu/core/redux/state/user_state.dart'; + +sellReducer(SellState prevState, SetSellStateAction action) { + final payload = action.sellState; + return prevState.copyWith( + items: payload.items + ); +} \ No newline at end of file diff --git a/lib/core/redux/state/sell_state.dart b/lib/core/redux/state/sell_state.dart new file mode 100644 index 0000000..d23f862 --- /dev/null +++ b/lib/core/redux/state/sell_state.dart @@ -0,0 +1,20 @@ +import 'package:meta/meta.dart'; +import 'package:satu/core/models/auth/auth_response.dart'; +import 'package:satu/core/models/flow/product_dao.dart'; + +@immutable +class SellState { + final List items; + + SellState({ + this.items, + }); + + factory SellState.initial() => SellState( + items: [], + ); + + SellState copyWith({@required List items}) { + return SellState(items: items ?? this.items); + } +} diff --git a/lib/core/redux/state/user_state.dart b/lib/core/redux/state/user_state.dart index 5c9021d..55e167d 100644 --- a/lib/core/redux/state/user_state.dart +++ b/lib/core/redux/state/user_state.dart @@ -19,7 +19,7 @@ class UserState { factory UserState.initial(UserState payload) => UserState( isLoading: false, isError: false, - auth: payload?.auth ?? AuthResponse(), + auth: payload?.auth ?? (AuthResponse()..operation=false), ); UserState copyWith({ diff --git a/lib/core/redux/store.dart b/lib/core/redux/store.dart index a7a5d17..728032b 100644 --- a/lib/core/redux/store.dart +++ b/lib/core/redux/store.dart @@ -8,6 +8,7 @@ import 'package:satu/core/redux/actions/nav_actions.dart'; import 'package:satu/core/redux/reducers/nav_reducer.dart'; import 'package:satu/core/redux/reducers/user_reducer.dart'; import 'package:satu/core/redux/state/nav_state.dart'; +import 'package:satu/core/redux/state/sell_state.dart'; import 'package:satu/core/redux/state/user_state.dart'; import 'actions/user_actions.dart'; @@ -32,21 +33,25 @@ AppState appReducer(AppState state, dynamic action) { class AppState { final UserState userState; final NavState navState; + final SellState sellState; AppState({ this.userState, this.navState, + this.sellState }); //stable work AppState copyWith({ UserState userState, NavState navState, + SellState sellState, }) { return AppState( userState: userState ?? this.userState, navState: navState ?? this.navState, + sellState: sellState ?? this.sellState ); } @@ -85,9 +90,9 @@ class Redux { ); final initialState = await persist.load(); - final userStateInitial = UserState.initial(initialState?.userState); final navStateInitial = NavState.initial(); + final sellStateInitial = SellState.initial(); _store = Store( appReducer, @@ -95,6 +100,7 @@ class Redux { initialState: AppState( userState: userStateInitial, navState: navStateInitial, + sellState: sellStateInitial, ) ); } diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index 5e4e76f..592f15b 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:satu/core/base/base_service.dart'; import 'package:http/http.dart' as http; import 'package:satu/core/models/auth/auth_response.dart'; +import 'package:satu/core/models/response.dart'; /// The service responsible for networking requests class ApiService extends BaseService { @@ -41,7 +42,9 @@ class ApiService extends BaseService { headers.addAll(header); } String url = '$endpoint$point'; - print(jsonEncode(requestBody)); + if(requestBody!=null) { + log.i(jsonEncode(requestBody)); + } final response = await http.post(Uri.https(host, url), body: jsonEncode(requestBody), headers: headers); return response.body; @@ -106,4 +109,17 @@ class ApiService extends BaseService { } return result; } + + Future dictionaries(String target) async { + Response result; + try { + Map headers = {HttpHeaders.authorizationHeader: 'Bearer $token'}; + String response = await _post(target, header: headers); + result = Response.fromMapList(json.decode(response), null); + } catch (e, stack) { + log.e("dictionaries", e, stack); + result = new Response()..operation=false..list=[]; + } + return result; + } } diff --git a/lib/core/services/data_service.dart b/lib/core/services/data_service.dart index bab9c77..d834642 100644 --- a/lib/core/services/data_service.dart +++ b/lib/core/services/data_service.dart @@ -11,4 +11,6 @@ class DataService extends BaseService { final ApiService _api = locator(); final DbService _db = locator(); + + } diff --git a/lib/core/services/db_service.dart b/lib/core/services/db_service.dart index 8cd65ef..61fe492 100644 --- a/lib/core/services/db_service.dart +++ b/lib/core/services/db_service.dart @@ -3,14 +3,13 @@ import 'dart:io'; import 'package:satu/core/base/base_service.dart'; import 'package:satu/core/entity/Category.dart'; import 'package:satu/core/entity/Goods.dart'; -import 'package:satu/core/entity/Service.dart'; -import 'package:satu/core/entity/Voucher.dart'; +import 'package:satu/core/entity/Transaction.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; class DbService extends BaseService { - static final _databaseName = "AmanSatuFlutterDb.db"; + static final _databaseName = "AmanSatuDb.db"; static final _databaseVersion = 1; // make this a singleton class @@ -39,15 +38,10 @@ class DbService extends BaseService { Future _onUpdate(Database db, int oldVersion, int newVersion) async { log.i('update from $oldVersion to $newVersion'); //Goods table - 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;'); + await db.execute('DROP TABLE IF EXISTS $GoodTableName;'); + await db.execute('DROP TABLE IF EXISTS $CategoryTableName;'); //await db.execute('DROP TABLE IF EXISTS $Voucher_tableName;'); log.i('dropped tables'); - if (newVersion > 16) { - //Не удалять таблицу с чеками - } - _onCreate(db, newVersion); } @@ -55,57 +49,38 @@ class DbService extends BaseService { log.i('create tables'); //Goods table await db.execute(''' - CREATE TABLE IF NOT EXISTS $Goog_tableName ( - $Goog_columnId integer primary key unique, - $Goog_columnArticul integer not null, - $Goog_columnName text not null, - $Goog_columnPrice real not null, - $Goog_columnCategoryId integer not null, - $Goog_columnEan text, - $Goog_columnAppCompanyId integer, - $Goog_columnDescription text, - $Goog_columnShowPrice real, - $Goog_columnOkei integer, - $Goog_columnDiscount real + CREATE TABLE IF NOT EXISTS $GoodTableName ( + $GoodColumnId integer primary key unique, + $GoodColumnArticul integer not null, + $GoodColumnName text not null, + $GoodColumnPrice real not null, + $GoodColumnCategoryId integer not null, + $GoodColumnEan text, + $GoodColumnAppCompanyId integer, + $GoodColumnOptPrice real, + $GoodColumnBasePrice real, + $GoodColumnDivisible integer, + $GoodColumnUpdatedAt text not null ); '''); 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_columnAppCompanyId integer + CREATE TABLE IF NOT EXISTS $CategoryTableName ( + $CategoryColumnId integer primary key unique, + $CategoryColumnName text not null, + $CategoryColumnParentIn integer, + $CategoryColumnAppCompanyId integer, + $CategoryColumnUpdatedAt text not null ); '''); - //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_columnAppCompanyId integer, - $Service_columnDescription text, - $Service_columnShowPrice real, - $Service_columnOkei text, - $Service_columnDiscount real + CREATE TABLE IF NOT EXISTS $TransactionTableName ( + $TransactionColumnId integer primary key autoincrement, + $TransactionColumnUuid text, + $TransactionColumnType integer not null, + $TransactionColumnData text, + $TransactionColumnCreatedAt text not null ); '''); - //Voucher - await db.execute(''' - CREATE TABLE IF NOT EXISTS $Voucher_tableName ( - $Voucher_columnId integer primary key AUTOINCREMENT, - $Voucher_columnName text not null, - $Voucher_columnTotal real, - $Voucher_columnData text, - $Voucher_columnBase64Data text, - $Voucher_columnDateTime text not null, - $Service_columnAppCompanyId integer, - $Voucher_columnKassaId integer, - $Voucher_columnType text not null, - $Voucher_columnUrl text - ); - '''); } // Inserts a row in the database where each key in the Map is a column name diff --git a/lib/core/services/dictionary_service.dart b/lib/core/services/dictionary_service.dart new file mode 100644 index 0000000..e5ccef2 --- /dev/null +++ b/lib/core/services/dictionary_service.dart @@ -0,0 +1,129 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:satu/core/base/base_service.dart'; +import 'package:satu/core/entity/Category.dart'; +import 'package:satu/core/entity/Goods.dart'; +import 'package:satu/core/models/dictionary/category_response.dart'; +import 'package:satu/core/models/dictionary/good_response.dart'; +import 'package:satu/core/models/response.dart'; +import 'package:satu/core/redux/store.dart'; +import 'package:satu/core/utils/locator.dart'; + +import 'api_service.dart'; +import 'db_service.dart'; + +class DictionaryService extends BaseService { + final ApiService _api = locator(); + final DbService _db = locator(); + + Future refreshFull() async { + _db.deleteAll(CategoryTableName); + await refreshCategory(); + _db.deleteAll(GoodTableName); + await refreshGood(); + } + + Future refreshCategory() async { + try { + int appCompanyId = Redux.store.state.userState.auth.companyId; + Response categories = await _api.dictionaries('/categories'); + if (categories.operation && categories.list.isNotEmpty) { + for (dynamic map in categories.list) { + CategoryResponse cat = CategoryResponse.fromMap(map); + Category entity = new Category() + ..id = cat.id + ..name = cat.name + ..updatedAt = cat.updatedAt + ..parentId = cat.parentId + ..appCompanyId = appCompanyId; + _db.insert(CategoryTableName, entity.toMap()); + } + } + } catch (e, stack) { + log.e("categories", e, stack); + } + } + + Future> getCategoryByParentId(int parentId ) async { + List list = []; + try { + int appCompanyId = Redux.store.state.userState.auth.companyId; + List> elements = await _db.queryRowsWithWhere(CategoryTableName, '$CategoryColumnParentIn = ?', [parentId]); + elements.forEach((element) { + list.add(Category.fromMap(element)); + }); + } catch (e, stack) { + log.e("getCategoryByParentId", e, stack); + } + return list; + } + + Future> getGoodsByCategoryId(int categoryId ) async { + List list = []; + try { + int appCompanyId = Redux.store.state.userState.auth.companyId; + List> elements = await _db.queryRowsWithWhere(GoodTableName, '$GoodColumnAppCompanyId = ? and $GoodColumnCategoryId = ?', [appCompanyId, categoryId]); + elements.forEach((element) { + list.add(Good.fromMap(element)); + }); + } catch (e, stack) { + log.e("getGoodsByCategoryId", e, stack); + } + return list; + } + + Future> getGoodsByNameOrEan( String query ) async { + List list = []; + try { + int appCompanyId = Redux.store.state.userState.auth.companyId; + String where = '( $GoodColumnAppCompanyId = ? and $GoodColumnName like ? ) '; + List args = [appCompanyId, '%$query%']; + if(_isNumericInt(query)){ + where += ' or $GoodColumnEan like ?'; + args.add('${int.parse(query).toString()}%'); + } + List> elements = await _db.queryRowsWithWhere(GoodTableName, where, args); + elements.forEach((element) { + list.add(Good.fromMap(element)); + }); + } catch (e, stack) { + log.e("getGoodsByCategoryId", e, stack); + } + return list; + } + + bool _isNumericInt(String str) { + if(str == null) { + return false; + } + return int.tryParse(str) != null; + } + + Future refreshGood() async { + try { + int appCompanyId = Redux.store.state.userState.auth.companyId; + Response categories = await _api.dictionaries('/goods'); + if (categories.operation && categories.list.isNotEmpty) { + for (dynamic map in categories.list) { + GoodResponse good = GoodResponse.fromMap(map); + Good entity = new Good() + ..id = good.id + ..name = good.name + ..categoryId = good.categoryId + ..ean = good.ean + ..articul = good.articul + ..price = good.price + ..optPrice = good.optPrice + ..basePrice = good.basePrice + ..divisible = good.divisible + ..updatedAt = good.updatedAt + ..appCompanyId = appCompanyId; + _db.insert(GoodTableName, entity.toMap()); + } + } + } catch (e, stack) { + log.e("goods", e, stack); + } + } +} diff --git a/lib/core/services/navigator_service.dart b/lib/core/services/navigator_service.dart index 6b9b31f..cc47dc1 100644 --- a/lib/core/services/navigator_service.dart +++ b/lib/core/services/navigator_service.dart @@ -7,20 +7,20 @@ class NavigatorService extends BaseService { final GlobalKey scaffoldDrawerKey = GlobalKey(); Future push(String routeName, {dynamic arguments}) { - log.i('routeName: $routeName'); + log.d('routeName: $routeName'); return navigatorKey.currentState .pushNamed(routeName, arguments: arguments); } Future replace(String routeName, {dynamic arguments}) { - log.i('routeName: $routeName'); + log.d('routeName: $routeName'); return navigatorKey.currentState .pushNamedAndRemoveUntil(routeName, (Route route) => false, arguments: arguments); } Future navigateToPage(MaterialPageRoute pageRoute) async { - log.i('navigateToPage: pageRoute: ${pageRoute.settings.name}'); + log.d('navigateToPage: pageRoute: ${pageRoute.settings.name}'); if (navigatorKey.currentState == null) { log.e('navigateToPage: Navigator State is null'); return null; @@ -30,7 +30,7 @@ class NavigatorService extends BaseService { Future navigateToPageWithReplacement( MaterialPageRoute pageRoute) async { - log.i('navigateToPageWithReplacement: ' + log.d('navigateToPageWithReplacement: ' 'pageRoute: ${pageRoute.settings.name}'); if (navigatorKey.currentState == null) { log.e('navigateToPageWithReplacement: Navigator State is null'); @@ -40,7 +40,7 @@ class NavigatorService extends BaseService { } void pop([T result]) { - log.i('goBack:'); + log.d('goBack:'); if (navigatorKey.currentState == null) { log.e('goBack: Navigator State is null'); return; diff --git a/lib/core/utils/locator.dart b/lib/core/utils/locator.dart index 7d50a5a..97a7e3c 100644 --- a/lib/core/utils/locator.dart +++ b/lib/core/utils/locator.dart @@ -4,6 +4,7 @@ import 'package:satu/core/services/api_service.dart'; import 'package:satu/core/services/data_service.dart'; import 'package:satu/core/services/db_service.dart'; import 'package:satu/core/services/dialog_service.dart'; +import 'package:satu/core/services/dictionary_service.dart'; import 'package:satu/core/services/navigator_service.dart'; import 'logger.dart'; @@ -29,5 +30,7 @@ class LocatorInjector { _log.d('Initializing DataService Service'); locator.registerLazySingleton(() => DataService()); + _log.d('Initializing DictionaryService Service'); + locator.registerLazySingleton(() => DictionaryService()); } } \ No newline at end of file diff --git a/lib/core/utils/logger.dart b/lib/core/utils/logger.dart index fc9ffc6..7d2cba4 100644 --- a/lib/core/utils/logger.dart +++ b/lib/core/utils/logger.dart @@ -18,7 +18,7 @@ class SimpleLogPrinter extends LogPrinter { if (event.stackTrace == null) { stack = formatStackTrace(StackTrace.current, 2); } else { - stack = formatStackTrace(event.stackTrace, 2); + stack = formatStackTrace(event.stackTrace, 1); } print(color(' $emoji $message $error -> $stack ')); return []; diff --git a/lib/views/add_product/add_product_view.dart b/lib/views/add_product/add_product_view.dart index 1a23f11..4e15a31 100644 --- a/lib/views/add_product/add_product_view.dart +++ b/lib/views/add_product/add_product_view.dart @@ -1,4 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:satu/core/entity/Category.dart'; +import 'package:satu/core/entity/Goods.dart'; +import 'package:satu/core/redux/actions/sell_actions.dart'; +import 'package:satu/core/redux/store.dart'; +import 'package:satu/core/services/dictionary_service.dart'; +import 'package:satu/core/services/navigator_service.dart'; +import 'package:satu/core/utils/locator.dart'; import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/ui_helpers.dart'; import 'package:satu/views/add_product/component/add_category_list_item.dart'; @@ -13,14 +20,34 @@ class AddProductView extends StatefulWidget { } class _AddProductViewState extends State { - + DictionaryService _dictionaryService = locator(); + NavigatorService _navigatorService = locator(); TextEditingController _searchTextController; final FocusNode _searchFocusNode = new FocusNode(); + + List _history; + List _categories; + List _goods; + + @override void initState() { _searchTextController = TextEditingController(); + _searchTextController.addListener(() { + if(_searchTextController.text.isNotEmpty){ + searchByField(_searchTextController.text); + } else { + reset(); + } + }); + _history = [Category() + ..id = 0 + ]; + _categories = []; + _goods = []; super.initState(); + navigateCategory(0); } @override @@ -32,34 +59,42 @@ class _AddProductViewState extends State { @override Widget build(BuildContext context) { + int catSize = _categories?.length ?? 0; + int goodSize = _goods?.length ?? 0; return Scaffold( appBar: AddProductAppBar(title: 'Товар', actions: actions(),), body: Column( children: [ - InputField(placeholder: 'Поиск по наименованию и коду товара', search: true, controller: _searchTextController, fieldFocusNode: _searchFocusNode,), + InputField(placeholder: 'Поиск по наименованию и коду товара', + search: true, + controller: _searchTextController, + fieldFocusNode: _searchFocusNode,), verticalSpaceTiny, Expanded( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0 ), + padding: const EdgeInsets.symmetric(horizontal: 8.0), child: ListView.builder( - itemCount: 50, + physics: BouncingScrollPhysics(), + itemCount: catSize + goodSize, itemBuilder: (BuildContext context, int index) { - if(index < 5) { + if (index < catSize) { + Category category = _categories[index]; return AddCategoryListItem( - name: 'Категория', - isOdd: index % 2 ==0, - key: Key('category_${index}'), + name: category.name, + isOdd: index % 2 == 0, + key: Key('category_${category.id}'), + onPress: () => onCategoryPress(category), ); } - + Good good = _goods[index - catSize]; return AddProductListItem( - key: Key('product_${index}'), - ean: '1234567890123', - isOdd: index % 2 ==0, - name: 'Хлеб ржаной который необходимо покупать каждый раз когда придет мысль об этом - ${index +1}. ', - price: 75, - count: 15, - categoryName: 'Хлебобулочные изделия', + key: Key('product_${good.id}'), + ean: good.ean, + isOdd: index % 2 == 0, + name: good.name, + price: good.price, + categoryName: _history.last?.name, + onPress: () => onGoodPress(good), ); }, ), @@ -71,10 +106,52 @@ class _AddProductViewState extends State { ); } + onCategoryPress(Category category) { + _history.add(category); + navigateCategory(category.id); + } + + onGoodPress(Good good) { + Redux.store.dispatch(addSellItem(good: good)); + _navigatorService.pop(); + } + List actions() { return [ - FlatButton(onPressed: () {}, child: Text('Очистить', style: TextStyle( color: Colors.black ),) ,) + if(_history.length > 1) + FlatButton(onPressed: () { + _history.removeLast(); + navigateCategory(_history.last.id); + }, child: Text('Назад', style: TextStyle(color: Colors.black),),), + + FlatButton(onPressed: reset, child: Text('Сбросить', style: TextStyle(color: Colors.black),),) ]; } + void reset() { + _history = [Category() + ..id = 0 + ]; + navigateCategory(0); + _searchTextController.clear(); + } + + void navigateCategory(int categoryId) async { + List categories = await _dictionaryService.getCategoryByParentId(categoryId); + List goods = await _dictionaryService.getGoodsByCategoryId(categoryId); + setState(() { + _categories = categories; + _goods = goods; + }); + } + + void searchByField(String query) async { + List categories = []; + List goods = await _dictionaryService.getGoodsByNameOrEan(query); + setState(() { + _categories = categories; + _goods = goods; + }); + } + } diff --git a/lib/views/add_product/component/add_category_list_item.dart b/lib/views/add_product/component/add_category_list_item.dart index 22733cb..141e6ca 100644 --- a/lib/views/add_product/component/add_category_list_item.dart +++ b/lib/views/add_product/component/add_category_list_item.dart @@ -7,13 +7,15 @@ import 'package:satu/shared/ui_helpers.dart'; class AddCategoryListItem extends StatelessWidget { final String name; final bool isOdd; + final Function onPress; - const AddCategoryListItem({Key key, this.name, this.isOdd}) : super(key: key); + const AddCategoryListItem({Key key, this.name, this.isOdd, this.onPress }) : super(key: key); @override Widget build(BuildContext context) { return Card( child: ListTile( + onTap: onPress, contentPadding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), title: Padding( padding: const EdgeInsets.only(top: 4.0), diff --git a/lib/views/add_product/component/add_product_list_item.dart b/lib/views/add_product/component/add_product_list_item.dart index 68b8f74..f4d1e7f 100644 --- a/lib/views/add_product/component/add_product_list_item.dart +++ b/lib/views/add_product/component/add_product_list_item.dart @@ -11,13 +11,15 @@ class AddProductListItem extends StatelessWidget { final num price; final num count; final bool isOdd; + final Function onPress; - const AddProductListItem({Key key, this.name, this.ean, this.categoryName, this.price, this.count, this.isOdd}) : super(key: key); + const AddProductListItem({Key key, this.name, this.ean, this.categoryName, this.price, this.count, this.isOdd, this.onPress}) : super(key: key); @override Widget build(BuildContext context) { return Card( child: ListTile( + onTap: onPress, contentPadding: const EdgeInsets.symmetric( horizontal: 8.0 ,vertical: 4.0 ), title: Padding( padding: const EdgeInsets.all(4.0), diff --git a/lib/views/start_up/start_up_view.dart b/lib/views/start_up/start_up_view.dart index 6fff936..f731ee5 100644 --- a/lib/views/start_up/start_up_view.dart +++ b/lib/views/start_up/start_up_view.dart @@ -1,9 +1,11 @@ import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter/material.dart'; +import 'package:satu/core/models/auth/auth_response.dart'; import 'package:satu/core/redux/actions/user_actions.dart'; import 'package:satu/core/redux/state/user_state.dart'; import 'package:satu/core/redux/store.dart'; +import 'package:satu/core/services/api_service.dart'; import 'package:satu/core/services/navigator_service.dart'; import 'package:satu/core/utils/locator.dart'; import 'package:satu/routes/route_names.dart'; @@ -16,6 +18,7 @@ class StartUpView extends StatefulWidget { class _StartUpViewState extends State { final NavigatorService _navigation = locator(); + final ApiService _api = locator(); @override void initState() { @@ -52,7 +55,7 @@ class _StartUpViewState extends State { } void redirect() async { - await Future.delayed(Duration(seconds: 3)); - _navigation.replace(LoginViewRoute); + await Future.delayed(Duration(milliseconds: 100)); + Redux.store.dispatch(auth); } } diff --git a/lib/views/work/tabs/sell_view.dart b/lib/views/work/tabs/sell_view.dart index f962549..bbef1da 100644 --- a/lib/views/work/tabs/sell_view.dart +++ b/lib/views/work/tabs/sell_view.dart @@ -8,23 +8,33 @@ import 'package:satu/views/work/tabs/component/products_app_bar.dart'; import 'package:satu/views/work/tabs/component/products_header_bar.dart'; class SellView extends StatelessWidget { - @override Widget build(BuildContext context) { return Scaffold( - appBar: ProductsAppBar(title: 'Продажа', actions: actions(), elevation: 2.0, child: ProductHeaderBar( count: 14, sum: 25000,), backgroundColor: backgroundColor, childHeight: 80,), + appBar: ProductsAppBar( + title: 'Продажа', + actions: actions(), + elevation: 2.0, + child: ProductHeaderBar( + count: 14, + sum: 25000, + ), + backgroundColor: backgroundColor, + childHeight: 80, + ), body: Column( children: [ //ProductHeaderBar(count: 14, sum: 25000,), Expanded( child: ListView.builder( physics: BouncingScrollPhysics(), - itemCount: 50, + itemCount: 5, itemBuilder: (BuildContext context, int index) { return ProductListItem( ean: '1234567890123', - isOdd: index % 2 ==0, - name: 'Хлеб ржаной который необходимо покупать каждый раз когда придет мысль об этом - ${index +1}. ', + isOdd: index % 2 == 0, + name: + 'Хлеб ржаной который необходимо покупать каждый раз когда придет мысль об этом - ${index + 1}. ', price: 75, count: 15, categoryName: 'Хлебобулочные изделия', @@ -41,15 +51,19 @@ class SellView extends StatelessWidget { return [ Padding( padding: const EdgeInsets.all(8.0), - child: IconButton(icon: Icon(Icons.add_box, size: 30.0, color: yellowColor), onPressed: () { - locator().push(AddProductViewRoute); - }), + child: IconButton( + icon: Icon(Icons.add_box, size: 30.0, color: yellowColor), + onPressed: () { + locator().push(AddProductViewRoute); + }), ), Padding( padding: const EdgeInsets.all(8.0), - child: IconButton(icon: Icon(Icons.camera_enhance_rounded, size: 30.0, color: yellowColor), onPressed: () { - locator().push(AddByBarcodeViewRoute); - }), + child: IconButton( + icon: Icon(Icons.camera_enhance_rounded, size: 30.0, color: yellowColor), + onPressed: () { + locator().push(AddByBarcodeViewRoute); + }), ) ]; }