From e30f1b346600c21565087221f76d0926f8ffed71 Mon Sep 17 00:00:00 2001 From: "Serik.Uvaissov" Date: Wed, 9 Sep 2020 16:18:18 +0600 Subject: [PATCH] barcode-scanner --- lib/core/services/DataService.dart | 8 + lib/views/home/tabs/KassaTab.dart | 306 ++++++++++++-------- lib/views/start_up/start_up_view.dart | 2 + lib/widgets/components/ProductListItem.dart | 84 +++++- pubspec.lock | 111 ++++--- pubspec.yaml | 15 +- 6 files changed, 340 insertions(+), 186 deletions(-) diff --git a/lib/core/services/DataService.dart b/lib/core/services/DataService.dart index c28b250..6385a54 100644 --- a/lib/core/services/DataService.dart +++ b/lib/core/services/DataService.dart @@ -41,6 +41,11 @@ class DataService extends BaseService { return list.map((e) => Good.fromMap(e)).toList(); } + Future> getGoodsByBarcode ({ String barcode}) async { + List> list = await _db.queryRowsWithWhere(Goog_tableName, ' $Goog_columnEan = ?', [barcode]); + return list.map((e) => Good.fromMap(e)).toList(); + } + CheckData _transformProductsToCheckData( {String paymentType, String tradeType, List items}) { List itemsList = []; @@ -128,6 +133,8 @@ class DataService extends BaseService { return null; } + + Future> sellOrReturn( {String paymentType, String tradeType, @@ -215,6 +222,7 @@ class DataService extends BaseService { if (goods.body.isNotEmpty) { for (var key in goods.body.keys) { Good row = Good.fromJson(goods.body[key]); + //log.i(row.toMap()); await _db.insert(Goog_tableName, row.toMap()); } log.i('Inserted ${goods.body.length} to table $Goog_tableName'); diff --git a/lib/views/home/tabs/KassaTab.dart b/lib/views/home/tabs/KassaTab.dart index ec7fced..bb88b8d 100644 --- a/lib/views/home/tabs/KassaTab.dart +++ b/lib/views/home/tabs/KassaTab.dart @@ -1,8 +1,11 @@ - +import 'package:aman_kassa_flutter/core/entity/Goods.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/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/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'; @@ -13,12 +16,19 @@ import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet. 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:barcode_scan/gen/protos/protos.pb.dart'; +import 'package:barcode_scan/gen/protos/protos.pbenum.dart'; +import 'package:barcode_scan/model/scan_options.dart'; +import 'package:barcode_scan/platform_wrapper.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_redux/flutter_redux.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; class KassaTab extends StatelessWidget { - final NavigatorService _navigatorService = locator(); + final DialogService _dialogService = locator(); + final DataService _dataService = locator(); final int index; @@ -33,107 +43,132 @@ class KassaTab extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.all(4), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: RaisedButton( - padding: EdgeInsets.all(8), - color: primaryColor, - child: Text( - "Добавить", - style: buttonBigTitleTextStyle, - ), - onPressed: () { showModalBottomSheetCatalog(context, 'add');}, - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: RaisedButton( - padding: EdgeInsets.all(8), - color: greenColor, - child: Text( - "Каталог", - style: buttonBigTitleTextStyle, - ), - onPressed: () { showModalBottomSheetCatalog(context, 'catalog');}, - ), - ), - ), - ], - ), - Expanded( - child: Container( - child: StoreConnector( - converter: (store) => store.state.kassaState, - builder: (context, vm) { - return ListView.builder( - itemCount: vm.kassaItems.length, - itemBuilder: (BuildContext ctxt, int index) => - buildItem(ctxt, index, vm.kassaItems[index])); - } - ), + return Scaffold( + floatingActionButton: Container( + padding: EdgeInsets.only(bottom: 65.0, left: 8.0), + child: Align( + alignment: Alignment.bottomLeft, + child: FloatingActionButton( + elevation: 3.0, + onPressed: scan, + child: Icon( + MdiIcons.barcode, + size: 30, ), ), - Divider(), - Container( - margin: const EdgeInsets.symmetric(vertical: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + body: Padding( + padding: const EdgeInsets.all(4), + child: Column( + children: [ + Row( children: [ - StoreConnector( - converter: (store) => store.state.kassaState, - builder: (context, vm) { - return Text(totalCalc(vm.kassaItems), style: TextStyle(fontSize: 25)); - } + Expanded( + child: Padding( + padding: const EdgeInsets.all(4.0), + child: RaisedButton( + padding: const EdgeInsets.all(8), + color: primaryColor, + child: Text( + "Добавить", + style: buttonBigTitleTextStyle, + ), + onPressed: () { + showModalBottomSheetCatalog(context, 'add'); + }, + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(4.0), + child: RaisedButton( + padding: EdgeInsets.all(8), + color: greenColor, + child: Text( + "Каталог", + style: buttonBigTitleTextStyle, + ), + onPressed: () { + showModalBottomSheetCatalog(context, 'catalog'); + }, + ), + ), ), ], ), - ), - Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: RaisedButton( - padding: EdgeInsets.all(8), - color: redColor, - child: Text( - "возврат", - style: buttonBigTitleTextStyle, - ), + Expanded( + child: Container( + child: StoreConnector( + converter: (store) => store.state.kassaState, + builder: (context, vm) { + return ListView.builder( + itemCount: vm.kassaItems.length, + itemBuilder: (BuildContext ctxt, int index) => + buildItem(ctxt, index, vm.kassaItems[index])); + }), + ), + ), + //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( + child: Padding( + padding: const EdgeInsets.all(4.0), + child: RaisedButton( + padding: const EdgeInsets.all(8), + color: redColor, + child: Text( + "возврат", + style: buttonBigTitleTextStyle, + ), + onPressed: () { + _navigatorService.push(PaymentViewRoute, + arguments: PaymentModel( + mode: SettingModeKassa, + operationType: OperationTypeReturn)); + }), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(4.0), + child: RaisedButton( + padding: const EdgeInsets.all(8), + color: greenColor, + child: Text( + "оплата", + style: buttonBigTitleTextStyle, + ), onPressed: () { - _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypeReturn) ); - } - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: RaisedButton( - padding: EdgeInsets.all(8), - color: greenColor, - child: Text( - "оплата", - style: buttonBigTitleTextStyle, + _navigatorService.push(PaymentViewRoute, + arguments: PaymentModel( + mode: SettingModeKassa, + operationType: OperationTypePay)); + }, ), - onPressed: () { - _navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypePay) ); - }, ), ), - ), - ], - ) - ], + ], + ) + ], + ), ), ); } @@ -141,32 +176,77 @@ class KassaTab extends StatelessWidget { String totalCalc(List kassaItems) { num total = 0.0; kassaItems.forEach((element) { - total+= element.total == null ? 0.0 : element.total.toDouble(); + total += element.total == null ? 0.0 : element.total.toDouble(); }); return total.toString(); } - void showModalBottomSheetCatalog(BuildContext context, String action) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (context){ - return DraggableScrollableSheet( - initialChildSize: 0.8, - maxChildSize: 0.95, - minChildSize: 0.5, - builder: (BuildContext context, ScrollController scrollController) { - if( action == 'add') { - return ProductAddBottomSheet(scrollController: scrollController,); - } else { - return CatalogBottomSheet(scrollController: scrollController,); - } - }, - ); + Future scan() async { + try { + var options = ScanOptions(strings: { + "cancel": 'Отмена', + "flash_on": 'Вкл фонарик', + "flash_off": 'Выкл фонарик', + }); + var result = await BarcodeScanner.scan(options: options); +// print(result.type); // The result type (barcode, cancelled, failed) +// print(result.rawContent); // The barcode content +// print(result.format); // The barcode format (as enum) +// print(result.formatNote); // If a unknown format was scanned this field contains a note + if (result.type == ResultType.Barcode && + (result.format == BarcodeFormat.ean13 || + result.format == BarcodeFormat.ean8)) { + String barcode = result.rawContent; + List goods = + await _dataService.getGoodsByBarcode(barcode: barcode); + if (goods != null && goods.isNotEmpty) { + Redux.store.dispatch(addProductToKassaItems(goods.first)); + } else { + _dialogService.showDialog( + description: 'Товар не найден: ${result.rawContent}'); + } + } else if (result.type == ResultType.Error) { + _dialogService.showDialog(description: 'Не верный формат QR кода'); } - ); + } on PlatformException catch (e) { + var result = ScanResult.create(); + result.type = ResultType.Error; + result.format = BarcodeFormat.unknown; + if (e.code == BarcodeScanner.cameraAccessDenied) { + result.rawContent = 'The user did not grant the camera permission!'; + _dialogService.showDialog( + description: 'Нет доступа до камеры устройства'); + } else { + result.rawContent = 'Unknown error: $e'; + _dialogService.showDialog(description: 'Неизвестная ошибка: $e'); + } + } } + + void showModalBottomSheetCatalog(BuildContext context, String action) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) { + return DraggableScrollableSheet( + initialChildSize: 0.8, + maxChildSize: 0.95, + minChildSize: 0.5, + builder: (BuildContext context, ScrollController scrollController) { + if (action == 'add') { + return ProductAddBottomSheet( + scrollController: scrollController, + ); + } else { + return CatalogBottomSheet( + scrollController: scrollController, + ); + } + }, + ); + }); + } } diff --git a/lib/views/start_up/start_up_view.dart b/lib/views/start_up/start_up_view.dart index eaa0b08..414cfb9 100644 --- a/lib/views/start_up/start_up_view.dart +++ b/lib/views/start_up/start_up_view.dart @@ -3,6 +3,7 @@ import 'package:aman_kassa_flutter/redux/state/user_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/screenutil.dart'; class StartUpView extends StatefulWidget { @@ -20,6 +21,7 @@ class _StartUpViewState extends State { @override Widget build(BuildContext context) { + ScreenUtil.init(context, width: 411.43, height: 683.43, allowFontScaling: false); return StoreConnector( converter: (store) => store.state.userState, builder: (context, userState) { diff --git a/lib/widgets/components/ProductListItem.dart b/lib/widgets/components/ProductListItem.dart index 3a66e99..677f8ec 100644 --- a/lib/widgets/components/ProductListItem.dart +++ b/lib/widgets/components/ProductListItem.dart @@ -55,14 +55,13 @@ class ProductListItem extends StatelessWidget { //margin: const EdgeInsets.symmetric(horizontal: 4), child: Row( children: [ - buildClipRect(primaryColor, Icons.remove, () { - Redux.store.dispatch( - counterProductFromKassaItems(index, -1)); - }), - buildClipRect(primaryColor, Icons.add, () { - Redux.store - .dispatch(counterProductFromKassaItems(index, 1)); + buildClipRect(primaryColor, Icons.edit, () { + editCountForm(context, item.count); }), +// buildClipRect(primaryColor, Icons.add, () { +// Redux.store +// .dispatch(counterProductFromKassaItems(index, 1)); +// }), Expanded( child: Container(), ), @@ -103,4 +102,75 @@ class ProductListItem extends StatelessWidget { ), ); } + + + void editCountForm(BuildContext context, num count) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + actionsPadding: const EdgeInsets.only(right: 15, bottom: 5), + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'request.title', + style: TextStyle(fontWeight: FontWeight.bold), + ), + //Divider(), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + //Text(request.description), + TextField( + autofocus: true, + decoration: InputDecoration( + labelText: 'request.description', + ), + //controller: _controller, + onSubmitted: (value) { + + }, + keyboardType: TextInputType.phone, + + ) + ], + ), + actions: [ + Row( + children: [ + RaisedButton( + color: redColor, + child: Text( + 'Отмена', + style: TextStyle(fontSize: 18), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + SizedBox( + width: 5, + ), + RaisedButton( + color: primaryColor, + child: Text( + 'Сохранить', + style: TextStyle(fontSize: 18), + ), + onPressed: () { + + }, + ), + ], + ), + ], + ); + }); + } } diff --git a/pubspec.lock b/pubspec.lock index a91ad99..cb129e2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,27 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.2" auto_size_text: dependency: "direct main" description: @@ -43,6 +29,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" charcode: dependency: transitive description: @@ -50,13 +43,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.3" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.13" convert: dependency: transitive description: @@ -70,7 +70,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" cupertino_icons: dependency: "direct main" description: @@ -84,14 +84,21 @@ packages: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.2+4" + version: "0.4.2+7" + device_info_platform_interface: + dependency: transitive + description: + name: device_info_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" equatable: dependency: "direct main" description: name: equatable url: "https://pub.dartlang.org" source: hosted - version: "1.2.3" + version: "1.2.4" esys_flutter_share: dependency: "direct main" description: @@ -99,6 +106,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" file: dependency: transitive description: @@ -125,6 +139,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.0" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" flutter_test: dependency: "direct dev" description: flutter @@ -163,13 +184,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" intl: dependency: "direct main" description: @@ -197,7 +211,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.8" material_design_icons_flutter: dependency: "direct main" description: @@ -225,14 +239,14 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.7.0" path_provider: dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.11" + version: "1.6.14" path_provider_linux: dependency: transitive description: @@ -253,7 +267,7 @@ packages: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" pedantic: dependency: transitive description: @@ -261,13 +275,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" platform: dependency: transitive description: @@ -309,7 +316,7 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.3.1" + version: "4.3.2+1" pub_semver: dependency: transitive description: @@ -331,13 +338,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" redux: dependency: "direct main" description: @@ -379,14 +379,14 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "0.5.8" + version: "0.5.10" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "0.0.2+1" + version: "0.0.2+2" shared_preferences_macos: dependency: transitive description: @@ -440,7 +440,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -475,14 +475,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.17" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.2.0" url_launcher: dependency: "direct main" description: @@ -517,7 +517,7 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.2+1" vector_math: dependency: transitive description: @@ -532,13 +532,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.0" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" sdks: - dart: ">=2.8.0 <3.0.0" + dart: ">=2.9.0-14.0.dev <3.0.0" flutter: ">=1.17.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index e6e1d00..8044309 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,29 +7,30 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.3 - redux: ^4.0.0 + redux: ^4.0.0+3 flutter_redux: ^0.6.0 redux_thunk: ^0.3.0 redux_persist: ^0.8.4 redux_persist_flutter: ^0.8.2 responsive_builder: ^0.2.0+2 - provider: ^4.3.1 - logger: ^0.9.1 - get_it: ^4.0.2 - equatable: ^1.2.2 + provider: ^4.3.2+1 + logger: ^0.9.2 + get_it: ^4.0.4 + equatable: ^1.2.4 http: ^0.12.2 sqflite: ^1.3.1 - path_provider: ^1.6.11 + path_provider: ^1.6.14 google_fonts: ^1.1.0 material_design_icons_flutter: ^4.0.5345 intl: ^0.16.1 barcode_scan: ^3.0.1 - device_info: ^0.4.2+4 + device_info: ^0.4.2+7 esys_flutter_share: ^1.0.2 auto_size_text: ^2.1.0 url_launcher: ^5.5.0 qr_flutter: ^3.2.0 mask_text_input_formatter: ^1.0.7 + flutter_screenutil: ^2.3.1 dev_dependencies: flutter_test: sdk: flutter