diff --git a/lib/core/models/ui_dao/popup_item_dao.dart b/lib/core/models/ui_dao/popup_item_dao.dart new file mode 100644 index 0000000..9b355e0 --- /dev/null +++ b/lib/core/models/ui_dao/popup_item_dao.dart @@ -0,0 +1,7 @@ +import 'package:satu/core/utils/utils_parse.dart'; + +class PopupItemDao { + PopupItemDao({required this.code, required this.name}); + String name; + String code; +} diff --git a/lib/views/login/login_view.dart b/lib/views/login/login_view.dart index 6d6852c..c68cde1 100644 --- a/lib/views/login/login_view.dart +++ b/lib/views/login/login_view.dart @@ -19,8 +19,6 @@ import 'package:satu/widgets/fields/input_field.dart'; import 'package:satu/widgets/ui/logo.dart'; class LoginView extends StatefulWidget { - - @override _LoginViewState createState() => _LoginViewState(); } @@ -32,15 +30,13 @@ class _LoginViewState extends State { final FocusNode passwordNode = new FocusNode(); - - final DialogService _dialogService = locator(); @override void initState() { super.initState(); - emailController = TextEditingController(text: 'test11@gmail.com'); - passwordController = TextEditingController(); + emailController = TextEditingController(text: 'test11@gmail.com'); + passwordController = TextEditingController(); } @override @@ -57,61 +53,69 @@ class _LoginViewState extends State { converter: (store) => store.state.userState!, builder: (context, vm) { return Scaffold( - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - LogoSatu(), - InputField( - placeholder: 'Введите почту', - controller: emailController, - textInputType: TextInputType.emailAddress, - nextFocusNode: passwordNode, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Введите пароль', - password: true, - controller: passwordController, - fieldFocusNode: passwordNode, - enterPressed: _pressBtnEnter, - textInputAction: TextInputAction.done, - ), - verticalSpaceMedium, - Padding( - padding: EdgeInsets.only( left: 45.sp, right: 45.sp, top: 30.sp ), - child: BusyButton( - title: 'ВОЙТИ', - busy: vm.isLoading!, - onPressed: _pressBtnEnter, + body: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: constraints.maxHeight), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const LogoSatu(), + InputField( + placeholder: 'Введите почту', + controller: emailController, + textInputType: TextInputType.emailAddress, + nextFocusNode: passwordNode, + ), + verticalSpaceSmall, + InputField( + placeholder: 'Введите пароль', + password: true, + controller: passwordController, + fieldFocusNode: passwordNode, + enterPressed: _pressBtnEnter, + textInputAction: TextInputAction.done, + ), + verticalSpaceMedium, + Padding( + padding: + EdgeInsets.only(left: 45.sp, right: 45.sp, top: 30.sp), + child: BusyButton( + title: 'ВОЙТИ', + busy: vm.isLoading!, + onPressed: _pressBtnEnter, + ), + ), + verticalSpaceLarge, + IconButton( + icon: const Icon(MdiIcons.qrcodeScan), + iconSize: ScreenUtil().setSp(40.0), + tooltip: 'Scan', + onPressed: scan, + ) + ], ), ), - verticalSpaceLarge, - IconButton( - icon: Icon(MdiIcons.qrcodeScan), - iconSize: ScreenUtil().setSp(40.0), - tooltip: "Scan", - onPressed: scan, - ) - ], - ), + ); + }, + )); }); } Future _pressBtnEnter() async { - Redux.store!.dispatch(authenticate(emailController.text, passwordController.text)); + Redux.store! + .dispatch(authenticate(emailController.text, passwordController.text)); } Future scan() async { - - final NavigatorService _nav = locator().push(addByBarcodeViewRoute) as NavigatorService; - final dynamic result = await _nav.push(addByBarcodeViewRoute) ; - if(result != null) { - if( result.length == 60 ) { + final NavigatorService _nav = locator(); + final dynamic result = await _nav.push(addByBarcodeViewRoute); + if (result != null) { + if (result.length == 60) { Redux.store?.dispatch(authenticateByToken(result as String)); } else { _dialogService.showDialog(description: 'Не верный формат QR кода'); @@ -154,5 +158,6 @@ class LoginModel { final String login; final String password; - LoginModel({required this.authType, required this.login, required this.password}); + LoginModel( + {required this.authType, required this.login, required this.password}); } diff --git a/lib/views/work/tabs/component/product_list_item.dart b/lib/views/work/tabs/component/product_list_item.dart index a2d175f..6a1244a 100644 --- a/lib/views/work/tabs/component/product_list_item.dart +++ b/lib/views/work/tabs/component/product_list_item.dart @@ -66,40 +66,16 @@ class _ProductListItemState extends State { ), direction: DismissDirection.endToStart, confirmDismiss: (DismissDirection direction) async { - DialogResponse response = await _dialogService.showConfirmationDialog( - title: 'Внимание', - description: 'Удалить товар' - '"${widget.name}"' - ' - ${widget.count} ед. ?', - confirmationTitle: 'Удалить', - cancelTitle: 'Отмена' - ); + final DialogResponse response = + await _dialogService.showConfirmationDialog( + title: 'Внимание', + description: 'Удалить из списка товар ' + '"${widget.name}"' + ' - ${widget.count} ед. ?', + confirmationTitle: 'Удалить', + cancelTitle: 'Отмена'); return response.confirmed; - - // return await showDialog( - // context: context, - // builder: (BuildContext context) { - // - // - // - // return AlertDialog( - // title: const Text('Внимание'), - // content: Text('Удалить товар ' - // '"${widget.name}"' - // ' - ${widget.count} ед. ?'), - // actions: [ - // TextButton( - // onPressed: () => Navigator.of(context).pop(true), - // child: const Text('Удалить')), - // TextButton( - // onPressed: () => Navigator.of(context).pop(false), - // child: const Text('Отмена'), - // ), - // ], - // ); - // }, - // ); }, onDismissed: (direction) { Redux.store! @@ -108,7 +84,9 @@ class _ProductListItemState extends State { key: Key(widget.name), child: ListTile( //onTap: () => _onItemTapped(context), - onTap: () {}, + onTap: () { + editProductModal(); + }, contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0), title: Row( @@ -142,8 +120,7 @@ class _ProductListItemState extends State { children: [ Material( color: Colors.transparent, - borderRadius: - BorderRadius.circular(5), + borderRadius: BorderRadius.circular(5), child: InkWell( onTap: () { Redux.store!.dispatch(counterOrEditSellItem( @@ -152,11 +129,12 @@ class _ProductListItemState extends State { }, child: Container( decoration: BoxDecoration( - //color: whiteColor, - borderRadius: BorderRadius.circular( - ScreenUtil().radius(5)), - border: Border.all( - width: 1, color: successColor)), + //color: whiteColor, + borderRadius: BorderRadius.circular( + ScreenUtil().radius(5), + ), + border: Border.all(color: successColor), + ), child: const Icon( Icons.add, color: successColor, @@ -170,31 +148,24 @@ class _ProductListItemState extends State { margin: const EdgeInsets.symmetric(horizontal: 5.0), decoration: BoxDecoration( color: whiteColor, - borderRadius: - BorderRadius.circular(5), + borderRadius: BorderRadius.circular(5), boxShadow: [cardShadowBox]), - child: InkWell( - onTap: () { - editProductModal(); - }, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 6.0), - child: SizedBox( - width: 45, - child: Text( - '${widget.count} шт', - style: const TextStyle( - fontSize: 10, color: placeholderColor), - textAlign: TextAlign.center, - ), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 6.0), + child: SizedBox( + width: 45, + child: Text( + '${widget.count} шт', + style: const TextStyle( + fontSize: 10, color: placeholderColor), + textAlign: TextAlign.center, ), ), ), ), Material( color: Colors.transparent, - borderRadius: - BorderRadius.circular(5), + borderRadius: BorderRadius.circular(5), child: InkWell( onTap: () { if (widget.count! > 1.0) { @@ -206,8 +177,7 @@ class _ProductListItemState extends State { child: Container( decoration: BoxDecoration( //color: whiteColor, - borderRadius: BorderRadius.circular( - 5), + borderRadius: BorderRadius.circular(5), border: Border.all( width: 1.0.sp, color: widget.count! <= 1.0 diff --git a/lib/views/work/tabs/sell_view.dart b/lib/views/work/tabs/sell_view.dart index 9d0e6d8..5d47953 100644 --- a/lib/views/work/tabs/sell_view.dart +++ b/lib/views/work/tabs/sell_view.dart @@ -134,9 +134,7 @@ class SellView extends StatelessWidget { mini: true, onPressed: () async { final NavigatorService _nav = - locator() - .push(addByBarcodeViewRoute) - as NavigatorService; + locator(); final dynamic result = await _nav.push(addByBarcodeViewRoute); if (result != null) { diff --git a/lib/views/work/views/add_by_barcode/add_by_barcode_view.dart b/lib/views/work/views/add_by_barcode/add_by_barcode_view.dart index fdb560a..b57c79f 100644 --- a/lib/views/work/views/add_by_barcode/add_by_barcode_view.dart +++ b/lib/views/work/views/add_by_barcode/add_by_barcode_view.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:satu/core/services/navigator_service.dart'; +import 'package:satu/core/utils/locator.dart'; import 'package:satu/widgets/bar/products_app_bar.dart'; import 'package:satu/widgets/tools/app_barcode_scanner_widget.dart'; @@ -20,7 +22,7 @@ class _AddByBarcodeViewState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: ProductsAppBar( + appBar: const ProductsAppBar( title: 'Сканер', ), body: Column( @@ -28,8 +30,10 @@ class _AddByBarcodeViewState extends State { Expanded( child: AppBarcodeScannerWidget.defaultStyle( resultCallback: (String code) { - Navigator.pop(context, code); - // print(code); + final NavigatorService _nav = locator(); + _nav.pop(code); + //Navigator.pop(context, code); + // setState(() { // _code = code; // }); diff --git a/lib/views/work/views/receipt/receipt_view.dart b/lib/views/work/views/receipt/receipt_view.dart index c454c31..3106152 100644 --- a/lib/views/work/views/receipt/receipt_view.dart +++ b/lib/views/work/views/receipt/receipt_view.dart @@ -4,9 +4,11 @@ import 'dart:io'; import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:satu/core/models/entity_data/transaction_data.dart'; import 'package:satu/core/models/flow/sell_response.dart'; import 'package:satu/core/models/settings/printer_setting.dart'; +import 'package:satu/core/models/ui_dao/popup_item_dao.dart'; import 'package:satu/core/redux/store.dart'; import 'package:satu/core/services/dialog_service.dart'; import 'package:satu/core/utils/locator.dart'; @@ -31,7 +33,16 @@ class _ReceiptViewState extends State { PrinterBluetoothManager printerManager = PrinterBluetoothManager(); bool printerLocked = false; - void print() async { + List menus = []; + + @override + void initState() { + //menus.add(PopupItemDao(code: 'return', name: 'Возврат')); + //menus.add(PopupItemDao(code: 'share', name: 'Поделится')); + super.initState(); + } + + void printRec() async { setState(() { printerLocked = true; }); @@ -53,10 +64,9 @@ class _ReceiptViewState extends State { ); } else { data = await getReceipt( - printerSetting.encoding!, - printerSetting.paperSize!, - widget.transactionData.sellResponse!.check! - ); + printerSetting.encoding!, + printerSetting.paperSize!, + widget.transactionData.sellResponse!.check!); } final PosPrintResult printResult = await printerManager.writeBytes( @@ -75,6 +85,10 @@ class _ReceiptViewState extends State { } } + void onSelectChoice(PopupItemDao itemDao ) { + print(itemDao.code); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -82,20 +96,31 @@ class _ReceiptViewState extends State { appBar: ProductsAppBar( title: 'Просмотр чека', actions: [ - StoreConnector( - converter: (store) => store.state.settingState!.printer!, - builder: (context, snapshot) { - final bool success = - snapshot.device != null && printerLocked == false; - return IconButton( - onPressed: success ? print : null, - icon: Icon( - Icons.print, - color: success ? textColor : placeholderColor, - ), - ); + // StoreConnector( + // converter: (store) => store.state.settingState!.printer!, + // builder: (context, snapshot) { + // final bool success = + // snapshot.device != null && printerLocked == false; + // return IconButton( + // onPressed: success ? print : null, + // icon: Icon( + // Icons.print, + // color: success ? textColor : placeholderColor, + // ), + // ); + // }, + // ) + PopupMenuButton( + onSelected: onSelectChoice, + itemBuilder: (BuildContext context) { + return menus.map((PopupItemDao choice) { + return PopupMenuItem( + value: choice, + child: Text(choice.name), + ); + }).toList(); }, - ) + ), ], ), body: Column( @@ -113,12 +138,22 @@ class _ReceiptViewState extends State { ), floatingActionButton: FloatingActionButton( onPressed: () { - // Add your onPressed code here! + final PrinterSetting printerSetting = + Redux.store!.state.settingState!.printer!; + final bool success = + printerSetting.device != null && printerLocked == false; + if (success) { + printRec(); + } else { + _dialogService.showDialog( + description: 'Необходимо настроить принтер', + ); + } }, backgroundColor: successColor, child: const Icon( - Icons.share_rounded, - size: 20, + Icons.print, + size: 25, ), ), ); diff --git a/lib/widgets/bar/bottom_bar.dart b/lib/widgets/bar/bottom_bar.dart index a4744b0..28cab50 100644 --- a/lib/widgets/bar/bottom_bar.dart +++ b/lib/widgets/bar/bottom_bar.dart @@ -15,7 +15,7 @@ class BottomBar extends StatelessWidget { elevation: 8.0, child: SafeArea( child: SizedBox( - height: 60.0, + height: 75.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -23,17 +23,20 @@ class BottomBar extends StatelessWidget { active: selectedIndex == 0, onTap: () => onTap(0), svgFile: 'sell', + name: 'Продажа', ), BottomButton( active: selectedIndex == 1, onTap: () => onTap(1), svgFile: 'buy', disable: true, + name: 'Покупка', ), BottomButton( active: selectedIndex == 2, onTap: () => onTap(2), svgFile: 'journal', + name: 'Журнал', ), ], ), @@ -48,6 +51,7 @@ class BottomButton extends StatelessWidget { {required this.svgFile, required this.onTap, required this.active, + required this.name, Key? key, this.disable = false}) : super(key: key); @@ -56,6 +60,7 @@ class BottomButton extends StatelessWidget { final void Function() onTap; final bool active; final bool disable; + final String name; @override Widget build(BuildContext context) { @@ -66,8 +71,9 @@ class BottomButton extends StatelessWidget { decoration: BoxDecoration( border: Border( top: BorderSide( - width: 3.0, - color: active ? primaryColor : Colors.transparent), + width: 3.0, + color: active ? primaryColor : Colors.transparent, + ), )), ), ), @@ -76,18 +82,33 @@ class BottomButton extends StatelessWidget { child: Material( color: Colors.transparent, child: InkWell( - onTap: disable == true ? (){} : onTap, + onTap: disable == true ? () {} : onTap, child: Padding( padding: const EdgeInsets.all(16.0), - child: SvgPicture.asset( - 'assets/images/svg/$svgFile.svg', - height: 30, - width: 30, - color: disable - ? disableColor - : active + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/svg/$svgFile.svg', + height: 25, + width: 25, + color: disable + ? disableColor + : active + ? primaryColor + : placeholderColor, + ), + SizedBox( + height: 5, + ), + Text( + name, + style: TextStyle(fontSize: 10, color: disable + ? disableColor + : active ? primaryColor - : placeholderColor, + : placeholderColor), + ) + ], ), ), ), diff --git a/pubspec.lock b/pubspec.lock index cd33ce9..0c13f95 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -42,7 +42,7 @@ packages: name: auto_size_text url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.0" + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -105,14 +105,14 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" device_info: dependency: "direct main" description: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" device_info_platform_interface: dependency: transitive description: @@ -267,7 +267,7 @@ packages: name: implicitly_animated_reorderable_list url: "https://pub.dartlang.org" source: hosted - version: "0.4.1" + version: "0.4.2" intl: dependency: "direct main" description: @@ -337,7 +337,7 @@ packages: name: material_floating_search_bar url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.6" meta: dependency: transitive description: @@ -379,14 +379,28 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.7" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" path_provider_macos: dependency: transitive description: @@ -407,14 +421,14 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.2.5" + version: "8.2.6" permission_handler_platform_interface: dependency: transitive description: @@ -428,7 +442,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "4.4.0" platform: dependency: transitive description: @@ -449,7 +463,7 @@ packages: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.2.3" + version: "4.2.4" provider: dependency: "direct main" description: @@ -526,7 +540,7 @@ packages: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_macos: dependency: transitive description: @@ -554,7 +568,7 @@ packages: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" sky_engine: dependency: transitive description: flutter @@ -713,7 +727,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.2.9" + version: "2.3.0" xdg_directories: dependency: transitive description: @@ -727,7 +741,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.3.0" + version: "5.3.1" sdks: dart: ">=2.14.0 <3.0.0" flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5b0113a..72e5b50 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,7 @@ environment: dependencies: flutter: sdk: flutter - cupertino_icons: ^1.0.3 + cupertino_icons: ^1.0.4 redux: ^5.0.0 flutter_redux: ^0.8.2 redux_thunk: ^0.4.0 @@ -36,22 +36,22 @@ dependencies: equatable: ^2.0.3 http: ^0.13.4 sqflite: ^2.0.0+4 - path_provider: ^2.0.5 + path_provider: ^2.0.7 material_design_icons_flutter: ^5.0.6295 intl: ^0.17.0 - device_info: ^2.0.2 - auto_size_text: ^3.0.0-nullsafety.0 + device_info: ^2.0.3 + auto_size_text: ^3.0.0 url_launcher: ^6.0.12 qr_flutter: ^4.0.0 mask_text_input_formatter: ^2.0.0 flutter_screenutil: ^5.0.0+2 shared_preferences: ^2.0.8 - material_floating_search_bar: ^0.3.4 - implicitly_animated_reorderable_list: ^0.4.1 + material_floating_search_bar: ^0.3.6 + implicitly_animated_reorderable_list: ^0.4.2 uuid: ^3.0.5 charset_converter: ^2.0.0 ai_barcode: ^3.0.1 - permission_handler: ^8.2.5 + permission_handler: ^8.2.6 flutter_svg: ^0.23.0+1 grouped_list: ^4.1.0 flutter_bluetooth_basic: ^0.1.7