diff --git a/lib/core/models/dictionary/category_row_data.dart b/lib/core/models/dictionary/category_row_data.dart new file mode 100644 index 0000000..8e342f8 --- /dev/null +++ b/lib/core/models/dictionary/category_row_data.dart @@ -0,0 +1,10 @@ +class CategoryRowDao { + CategoryRowDao(this.name, this.parentName, this.id, + {this.parentId = 0, this.ean}); + + final String name; + final String parentName; + final String? ean; + final int? id; + final int? parentId; +} diff --git a/lib/core/models/dictionary/good_row_data.dart b/lib/core/models/dictionary/good_row_data.dart new file mode 100644 index 0000000..03c7b73 --- /dev/null +++ b/lib/core/models/dictionary/good_row_data.dart @@ -0,0 +1,11 @@ +class GoodRowDao { + GoodRowDao(this.name, this.categoryName, + {this.ean, this.id, this.categoryId} + ); + + final String name; + final String categoryName; + final int? categoryId; + final String? ean; + final int? id; +} \ No newline at end of file diff --git a/lib/core/services/data_service.dart b/lib/core/services/data_service.dart index d834642..4a516f9 100644 --- a/lib/core/services/data_service.dart +++ b/lib/core/services/data_service.dart @@ -1,4 +1,4 @@ -import 'dart:convert'; + import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:satu/core/base/base_service.dart'; diff --git a/lib/core/services/db_service.dart b/lib/core/services/db_service.dart index 1950651..ac7d4f0 100644 --- a/lib/core/services/db_service.dart +++ b/lib/core/services/db_service.dart @@ -26,7 +26,8 @@ class DbService extends BaseService { // this opens the database (and creates it if it doesn't exist) Future _initDatabase() async { - final Directory documentsDirectory = await getApplicationDocumentsDirectory(); + final Directory documentsDirectory = + await getApplicationDocumentsDirectory(); final String path = join(documentsDirectory.path, _databaseName); final Database db = await openDatabase(path, version: _databaseVersion, onUpgrade: _onUpdate, onCreate: _onCreate); @@ -100,22 +101,27 @@ class DbService extends BaseService { return result; } - Future>> queryRaw(String sql, List args) async { + Future>> queryRaw( + String sql, List args) async { final Database db = await instance.database; - final List> result = await db.rawQuery(sql, args ); + final List> result = await db.rawQuery(sql, args); return result; } - Future>> queryAllRowsOrderBy(String table, String orderBy) async { + Future>> queryAllRowsOrderBy( + String table, String orderBy) async { final Database db = await instance.database; - final List> result = await db.query(table, orderBy: orderBy); + final List> result = + await db.query(table, orderBy: orderBy); return result; } Future>> queryRowsWithWhere( - String table, String where, List args, { String? orderBy }) async { + String table, String where, List args, + {String? orderBy}) async { final Database db = await instance.database; - final List> result = await db.query(table, where: where, whereArgs: args, orderBy: orderBy); + final List> result = + await db.query(table, where: where, whereArgs: args, orderBy: orderBy); return result; } @@ -123,8 +129,8 @@ class DbService extends BaseService { // raw SQL commands. This method uses a raw query to give the row count. Future queryRowCount(String table) async { final Database db = await instance.database; - final int? result = Sqflite.firstIntValue( - await db.rawQuery('SELECT COUNT(*) FROM $table')); + final int? result = + Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM $table')); return result; } @@ -133,7 +139,8 @@ class DbService extends BaseService { Future update(String table, Map row) async { final Database db = await instance.database; final int id = row['id'] as int; - final int result = await db.update(table, row, where: 'id = ?', whereArgs: [id]); + final int result = + await db.update(table, row, where: 'id = ?', whereArgs: [id]); return result; } @@ -151,7 +158,8 @@ class DbService extends BaseService { return result; } - Future deleteByWhere(String table, String where, List args) async { + Future deleteByWhere( + String table, String where, List args) async { final Database db = await instance.database; final int result = await db.delete(table, where: where, whereArgs: args); return result; diff --git a/lib/core/utils/utils_parse.dart b/lib/core/utils/utils_parse.dart index 52d21eb..377716a 100644 --- a/lib/core/utils/utils_parse.dart +++ b/lib/core/utils/utils_parse.dart @@ -15,4 +15,9 @@ bool isNumeric(String? s) { String formatDecimal(double value) { if (value % 1 == 0) return value.toStringAsFixed(0).toString(); return value.toString(); +} + +double parseNumeric(String value) { + + return double.tryParse(value) ?? 0; } \ No newline at end of file diff --git a/lib/routes/router.dart b/lib/routes/router.dart index 8664945..c8cf06e 100644 --- a/lib/routes/router.dart +++ b/lib/routes/router.dart @@ -1,7 +1,10 @@ +import 'package:satu/core/models/dictionary/category_row_data.dart'; +import 'package:satu/core/models/dictionary/good_row_data.dart'; import 'package:satu/views/dictionaries/category/category_edit.dart'; import 'package:satu/views/dictionaries/category/category_select_view.dart'; import 'package:satu/views/dictionaries/category/category_view.dart'; +import 'package:satu/views/dictionaries/goods/goods_edit.dart'; import 'package:satu/views/dictionaries/goods/goods_view.dart'; import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart'; import 'package:satu/views/work/views/add_product/add_product_view.dart'; @@ -56,7 +59,7 @@ Route generateRoute(RouteSettings settings) { case paymentViewRoute: return _getPageRoute( routeName: settings.name!, - viewToShow: PaymentView(), + viewToShow: const PaymentView(), ); case categoryEditRoute: final CategoryRowDao category = settings.arguments! as CategoryRowDao; @@ -69,10 +72,11 @@ Route generateRoute(RouteSettings settings) { routeName: settings.name!, viewToShow: CategorySelectView(), ); - case goodsDictionaryViewRoute: + case goodsEditRoute: + final GoodRowDao good = settings.arguments! as GoodRowDao; return _getPageRoute( routeName: settings.name!, - viewToShow: GoodsDictionaryView(), + viewToShow: GoodEdit(good: good,), ); // case ImageShowRoute: diff --git a/lib/shared/shared_styles.dart b/lib/shared/shared_styles.dart index 7f0bea7..5b3d010 100644 --- a/lib/shared/shared_styles.dart +++ b/lib/shared/shared_styles.dart @@ -4,8 +4,8 @@ import 'app_colors.dart'; // Box Decorations BoxDecoration fieldDecoration = const BoxDecoration(color: whiteColor); -BoxDecoration disabledFieldDecoration = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); +BoxDecoration disabledFieldDecoration = + const BoxDecoration(color: disableColor); LinearGradient primaryGradient = const LinearGradient( colors: [ @@ -34,6 +34,6 @@ const TextStyle dropDownTradeTypeTextStyle = BoxShadow buttonShadowBox = const BoxShadow(blurRadius: 10, color: shadowColor, offset: Offset(0, 4)); BoxShadow inputShadowBox = -const BoxShadow(blurRadius: 1, color: shadowColor, offset: Offset(0, 2)); + const BoxShadow(blurRadius: 1, color: shadowColor, offset: Offset(0, 2)); BoxShadow cardShadowBox = const BoxShadow( blurRadius: 3, color: Color.fromRGBO(0, 0, 0, 0.15), offset: Offset(0, 1)); diff --git a/lib/views/dictionaries/category/category_edit.dart b/lib/views/dictionaries/category/category_edit.dart index c7743a4..b7ba197 100644 --- a/lib/views/dictionaries/category/category_edit.dart +++ b/lib/views/dictionaries/category/category_edit.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; import 'package:satu/core/entity/category_entity.dart'; import 'package:satu/core/models/dialog_models.dart'; +import 'package:satu/core/models/dictionary/category_row_data.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'; diff --git a/lib/views/dictionaries/category/category_select_view.dart b/lib/views/dictionaries/category/category_select_view.dart index 8109b9b..7edc166 100644 --- a/lib/views/dictionaries/category/category_select_view.dart +++ b/lib/views/dictionaries/category/category_select_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:satu/core/entity/category_entity.dart'; import 'package:satu/core/entity/goods_entity.dart'; +import 'package:satu/core/models/dictionary/category_row_data.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'; diff --git a/lib/views/dictionaries/category/category_view.dart b/lib/views/dictionaries/category/category_view.dart index 57e497a..bab2f00 100644 --- a/lib/views/dictionaries/category/category_view.dart +++ b/lib/views/dictionaries/category/category_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:satu/core/entity/category_entity.dart'; import 'package:satu/core/entity/goods_entity.dart'; +import 'package:satu/core/models/dictionary/category_row_data.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'; @@ -150,11 +151,3 @@ class _CategoryDictionaryViewState extends State { } } -class CategoryRowDao { - CategoryRowDao(this.name, this.parentName, this.id, {this.parentId = 0}); - - final String name; - final String parentName; - final int? id; - final int? parentId; -} diff --git a/lib/views/dictionaries/goods/goods_edit.dart b/lib/views/dictionaries/goods/goods_edit.dart new file mode 100644 index 0000000..2a0868f --- /dev/null +++ b/lib/views/dictionaries/goods/goods_edit.dart @@ -0,0 +1,175 @@ +import 'package:flutter/material.dart'; +import 'package:logger/logger.dart'; +import 'package:satu/core/entity/category_entity.dart'; +import 'package:satu/core/models/dialog_models.dart'; +import 'package:satu/core/models/dictionary/category_row_data.dart'; +import 'package:satu/core/models/dictionary/good_row_data.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/core/utils/logger.dart'; +import 'package:satu/routes/route_names.dart'; +import 'package:satu/shared/ui_helpers.dart'; +import 'package:satu/views/dictionaries/category/category_view.dart'; +import 'package:satu/widgets/bar/products_app_bar.dart'; +import 'package:satu/widgets/buttons/busy_button.dart'; +import 'package:satu/widgets/fields/input_field.dart'; +import 'package:satu/widgets/fields/line_tile.dart'; +import 'package:satu/widgets/fields/note_text.dart'; + +class GoodEdit extends StatefulWidget { + const GoodEdit({ + required this.good, + Key? key, + }) : super(key: key); + final GoodRowDao good; + + @override + _GoodEditState createState() => _GoodEditState(); +} + +class _GoodEditState extends State { + final NavigatorService _navigatorService = locator(); + final DictionaryService _dictionaryService = locator(); + final DialogService _dialogService = locator(); + final Logger log = getLogger('_GoodEditState'); + late TextEditingController _controller; + + String parentCategoryName = ''; + int? parentCategoryId; + + @override + void initState() { + super.initState(); + if (widget.good.categoryId != null) { + parentCategoryId = widget.good.categoryId; + } + _controller = TextEditingController(text: widget.good.name); + + getAndStateCategoryName(parentCategoryId); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + Future getAndStateCategoryName(int? id) async { + String name = ''; + if (id == null) { + } else if (id == 0) { + name = 'Корневая категория'; + } else { + log.i('message $id'); + final Category? category = await _dictionaryService.getCategoryById(id); + if (category != null) { + name = category.name; + } + log.i('message $name'); + } + + setState(() { + parentCategoryName = name; + parentCategoryId = id; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: ProductsAppBar( + title: widget.good.id == null + ? 'Создание товара' + : 'Редактирование товара', + ), + body: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + verticalSpaceSmall, + InputField( + isReadOnly: true, + controller: _controller, + labelText: 'Номенклатурный номер', + placeholder: 'Не присвоен', + ), + LineTile( + parentCategoryName, + onTap: selectCategory, + labelText: 'Категория', + placeholder: 'Выберите категорию', + ), + verticalSpaceSmall, + InputField( + controller: _controller, + labelText: 'Наименование', + placeholder: 'Введите наименование товара', + ), + InputField( + controller: _controller, + labelText: 'Розничная цена', + placeholder: 'Введите розничную цену', + ), + InputField( + controller: _controller, + labelText: 'Оптовая цена', + placeholder: 'Введите оптовую цену', + ), + InputField( + controller: _controller, + labelText: + 'Закупочная цена для автоматически пополняемого товара', + placeholder: 'Введите закупочную цену', + ), + InputField( + controller: _controller, + labelText: 'EAN Штрих-код', + placeholder: 'Введите EAN', + ), + InputField( + controller: _controller, + labelText: 'Наименование', + placeholder: 'Введите наименование товара', + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 45.0, vertical: 20.0), + child: BusyButton(title: 'СОХРАНИТЬ', onPressed: () {}), + ), + if (widget.good.id != null) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 45.0, vertical: 20.0), + child: BusyButton( + title: 'УДАЛИТЬ', + onPressed: () async { + DialogResponse response = + await _dialogService.showConfirmationDialog( + title: 'Внимание', + description: + 'Вы уверены, что хотите удалить категорию?', + confirmationTitle: 'Удалить', + cancelTitle: 'Отмена'); + + return response.confirmed; + }, + isDanger: true, + ), + ), + ], + ), + ), + ); + } + + Future selectCategory() async { + final dynamic result = + await _navigatorService.push(categorySelectViewRoute); + if (result != null) { + getAndStateCategoryName(result as int); + } + } +} diff --git a/lib/views/dictionaries/goods/goods_view.dart b/lib/views/dictionaries/goods/goods_view.dart index 18428d5..ceb80f5 100644 --- a/lib/views/dictionaries/goods/goods_view.dart +++ b/lib/views/dictionaries/goods/goods_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:satu/core/entity/category_entity.dart'; import 'package:satu/core/entity/goods_entity.dart'; +import 'package:satu/core/models/dictionary/good_row_data.dart'; import 'package:satu/core/redux/actions/sell_actions.dart'; import 'package:satu/core/services/dictionary_service.dart'; import 'package:satu/core/services/navigator_service.dart'; @@ -68,7 +69,7 @@ class _GoodsDictionaryViewState extends State { child: Material( color: Colors.transparent, child: InkWell( - onTap: (){}, + onTap: () {}, child: Padding( padding: const EdgeInsets.all(16.0), child: SvgPicture.asset( @@ -99,9 +100,13 @@ class _GoodsDictionaryViewState extends State { itemBuilder: (BuildContext context, int index) { final GoodRowDao good = items[index]; return DictionaryTile( + onPress: () { + locator() + .push(goodsEditRoute, arguments: good); + }, child: ProductTitleWidget( name: good.name, - categoryName: good.category, + categoryName: good.categoryName, ean: good.ean, ), ); @@ -118,7 +123,8 @@ class _GoodsDictionaryViewState extends State { ), floatingActionButton: FloatingActionButton( elevation: 2, - onPressed: () => locator().push(categoryEditRoute), + onPressed: () => locator() + .push(goodsEditRoute, arguments: GoodRowDao('', '')), child: const Icon( Icons.add_rounded, size: 34.0, @@ -149,7 +155,7 @@ class _GoodsDictionaryViewState extends State { }); final String parentName = category.name; final GoodRowDao rowDao = GoodRowDao(element.name, parentName, - ean: element.ean, id: element.id); + ean: element.ean, id: element.id, categoryId: element.categoryId); list.add(rowDao); }); setState(() { @@ -157,12 +163,3 @@ class _GoodsDictionaryViewState extends State { }); } } - -class GoodRowDao { - GoodRowDao(this.name, this.category, {this.ean, this.id}); - - final String name; - final String category; - final String? ean; - final int? id; -} diff --git a/lib/views/work/tabs/component/contagent_select_bar.dart b/lib/views/work/tabs/component/contagent_select_bar.dart index 2395bcf..6807cb6 100644 --- a/lib/views/work/tabs/component/contagent_select_bar.dart +++ b/lib/views/work/tabs/component/contagent_select_bar.dart @@ -23,25 +23,30 @@ class ContragentSelectBar extends StatelessWidget { locator().push(contragentSelectViewRoute); }, child: Padding( - padding: EdgeInsets.symmetric( vertical: 8.w, horizontal: 15.w ), + padding: EdgeInsets.symmetric(vertical: 8.w, horizontal: 15.w), child: Row( children: [ Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + const Text( 'Контрагент', - style: TextStyle(fontSize: ScreenUtil().setSp(10), color: placeholderColor), + style: + TextStyle(fontSize: 10, color: placeholderColor), ), Text( value, - style: TextStyle(fontSize: ScreenUtil().setSp(14), color: textColor), + style: + const TextStyle(fontSize: 14, color: textColor), ), ], )), - Center( - child: Icon(Icons.arrow_forward_ios, size: ScreenUtil().setSp(14),), + const Center( + child: Icon( + Icons.arrow_forward_ios, + size: 14, + ), ) ], ), diff --git a/lib/views/work/tabs/component/product_list_item.dart b/lib/views/work/tabs/component/product_list_item.dart index f7e007c..a2d175f 100644 --- a/lib/views/work/tabs/component/product_list_item.dart +++ b/lib/views/work/tabs/component/product_list_item.dart @@ -123,7 +123,7 @@ class _ProductListItemState extends State { ), ), SizedBox( - width: 100.w, + width: 100, child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -131,8 +131,8 @@ class _ProductListItemState extends State { padding: const EdgeInsets.only(bottom: 3.0), child: Text( '${widget.price} ₸', - style: TextStyle( - fontSize: 14.sp, + style: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w500, color: textColor), ), @@ -143,7 +143,7 @@ class _ProductListItemState extends State { Material( color: Colors.transparent, borderRadius: - BorderRadius.circular(ScreenUtil().radius(5)), + BorderRadius.circular(5), child: InkWell( onTap: () { Redux.store!.dispatch(counterOrEditSellItem( @@ -156,35 +156,35 @@ class _ProductListItemState extends State { borderRadius: BorderRadius.circular( ScreenUtil().radius(5)), border: Border.all( - width: 1.0.sp, color: successColor)), - child: Icon( + width: 1, color: successColor)), + child: const Icon( Icons.add, color: successColor, - size: 20.0.sp, + size: 20, ), ), ), ), Container( - width: 45.w, - margin: EdgeInsets.symmetric(horizontal: 5.w), + width: 45, + margin: const EdgeInsets.symmetric(horizontal: 5.0), decoration: BoxDecoration( color: whiteColor, borderRadius: - BorderRadius.circular(ScreenUtil().radius(5)), + BorderRadius.circular(5), boxShadow: [cardShadowBox]), child: InkWell( onTap: () { editProductModal(); }, child: Padding( - padding: EdgeInsets.symmetric(vertical: 6.0.w), + padding: const EdgeInsets.symmetric(vertical: 6.0), child: SizedBox( - width: 45.w, + width: 45, child: Text( '${widget.count} шт', - style: TextStyle( - fontSize: 10.sp, color: placeholderColor), + style: const TextStyle( + fontSize: 10, color: placeholderColor), textAlign: TextAlign.center, ), ), @@ -194,7 +194,7 @@ class _ProductListItemState extends State { Material( color: Colors.transparent, borderRadius: - BorderRadius.circular(ScreenUtil().radius(5)), + BorderRadius.circular(5), child: InkWell( onTap: () { if (widget.count! > 1.0) { @@ -207,7 +207,7 @@ class _ProductListItemState extends State { decoration: BoxDecoration( //color: whiteColor, borderRadius: BorderRadius.circular( - ScreenUtil().radius(5)), + 5), border: Border.all( width: 1.0.sp, color: widget.count! <= 1.0 @@ -218,7 +218,7 @@ class _ProductListItemState extends State { color: widget.count! <= 1.0 ? disableColor : dangerColor, - size: 20.0.sp, + size: 20, ), ), ), diff --git a/lib/views/work/tabs/sell_view.dart b/lib/views/work/tabs/sell_view.dart index fcb6fec..dbca1c4 100644 --- a/lib/views/work/tabs/sell_view.dart +++ b/lib/views/work/tabs/sell_view.dart @@ -61,7 +61,8 @@ class SellView extends StatelessWidget { shrinkWrap: true, itemCount: state.items!.length, itemBuilder: (BuildContext context, int index) { - final ProductDao product = state.items!.elementAt(index); + final ProductDao product = + state.items!.elementAt(index); return ProductListItem( key: UniqueKey(), ean: product.eanCode, @@ -109,8 +110,8 @@ class SellView extends StatelessWidget { mini: true, elevation: 2, backgroundColor: successColor, - onPressed: () => locator() - .push(paymentViewRoute), + onPressed: () => + locator().push(paymentViewRoute), child: Icon(Icons.check, color: whiteColor, size: 35.sp), )), Column( diff --git a/lib/views/work/tabs/utils/product_utils.dart b/lib/views/work/tabs/utils/product_utils.dart index 5b14fc7..8238789 100644 --- a/lib/views/work/tabs/utils/product_utils.dart +++ b/lib/views/work/tabs/utils/product_utils.dart @@ -1,12 +1,12 @@ import 'package:satu/core/models/flow/product_dao.dart'; -num sumProducts(List list) { - num result = 0.0; +double sumProducts(List list) { + double result = 0.0; if (list.isNotEmpty) { for( final ProductDao product in list) { final String val = (product.price! * product.count!).toStringAsFixed(5); // result += product.price! * product.count!; - result += num.parse(val); + result += double.parse(val); } } return result; diff --git a/lib/views/work/views/payment/component/combine_dock.dart b/lib/views/work/views/payment/component/combine_dock.dart index 5af3d96..ee16749 100644 --- a/lib/views/work/views/payment/component/combine_dock.dart +++ b/lib/views/work/views/payment/component/combine_dock.dart @@ -1,13 +1,24 @@ import 'package:flutter/material.dart'; +import 'package:satu/core/utils/utils_parse.dart'; import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/ui_helpers.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class CombineDock extends StatelessWidget { - const CombineDock({Key? key}) : super(key: key); + const CombineDock({ + required this.bankSum, + required this.cashNum, + required this.totalSum, + Key? key, + }) : super(key: key); + final double bankSum; + final double cashNum; + final double totalSum; @override Widget build(BuildContext context) { + final double total = bankSum + cashNum; + final double shortChange = (total - totalSum) < 0 ? 0 : total - totalSum; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -29,16 +40,16 @@ class CombineDock extends StatelessWidget { padding: const EdgeInsets.all(15.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'К оплате', style: TextStyle( fontSize: 14, ), ), Text( - '1200 ₸', - style: TextStyle(fontSize: 20), + '${formatDecimal(total)} ₸', + style: const TextStyle(fontSize: 20), ), ], ), @@ -54,48 +65,48 @@ class CombineDock extends StatelessWidget { children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'Банковская карта', style: TextStyle(fontSize: 12, color: placeholderColor), ), Text( - '1200 ₸', - style: - TextStyle(fontSize: 12, color: placeholderColor), + '${formatDecimal(bankSum)} ₸', + style: const TextStyle( + fontSize: 12, color: placeholderColor), ), ], ), verticalSpaceSmall, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'Наличными', style: TextStyle(fontSize: 12, color: placeholderColor), ), Text( - '0 ₸', - style: - TextStyle(fontSize: 12, color: placeholderColor), + '${formatDecimal(cashNum)} ₸', + style: const TextStyle( + fontSize: 12, color: placeholderColor), ), ], ), verticalSpaceSmall, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'Сдача', style: TextStyle(fontSize: 12, color: placeholderColor), ), Text( - '0 ₸', - style: - TextStyle(fontSize: 12, color: placeholderColor), + '${formatDecimal(shortChange)} ₸', + style: const TextStyle( + fontSize: 12, color: placeholderColor), ), ], ) diff --git a/lib/views/work/views/payment/payment_view.dart b/lib/views/work/views/payment/payment_view.dart index 2be89e4..9c7fdc9 100644 --- a/lib/views/work/views/payment/payment_view.dart +++ b/lib/views/work/views/payment/payment_view.dart @@ -16,23 +16,53 @@ import 'package:satu/widgets/fields/line_checkbox.dart'; class PaymentView extends StatefulWidget { const PaymentView(); + @override _PaymentViewState createState() => _PaymentViewState(); } class _PaymentViewState extends State { bool combine = true; - late num _sum; + late double _sum; + double _bankSum = 0; + double _cashSum = 0; + bool isCard = false; late TextEditingController _bankSumCtrl; late TextEditingController _cashSumCtrl; + final FocusNode _focusCash = FocusNode(); + @override void initState() { super.initState(); _sum = sumProducts(Redux.store!.state.sellState!.items!); - _bankSumCtrl = TextEditingController(text: formatDecimal(_sum.toDouble())); - _cashSumCtrl = TextEditingController(text: '0'); + _bankSum = _sum; + _cashSum = 0; + _bankSumCtrl = TextEditingController(text: formatDecimal(_bankSum)); + _cashSumCtrl = TextEditingController(text: formatDecimal(_cashSum)); + _bankSumCtrl.addListener(() { + if( _bankSumCtrl.text.isNotEmpty) { + setState(() { + _bankSum = parseNumeric(_bankSumCtrl.text); + }); + } else { + setState(() { + _bankSum = 0 ; + }); + } + }); + _cashSumCtrl.addListener(() { + if( _cashSumCtrl.text.isNotEmpty) { + setState(() { + _cashSum = parseNumeric(_cashSumCtrl.text); + }); + } else { + setState(() { + _cashSum = 0 ; + }); + } + }); } @override @@ -114,6 +144,7 @@ class _PaymentViewState extends State { labelText: 'Банковская карта', placeholder: 'Укажите сумму', suffixText: '₸', + nextFocusNode: _focusCash, textInputType: const TextInputType.numberWithOptions(decimal: true), ), InputField( @@ -121,25 +152,43 @@ class _PaymentViewState extends State { labelText: 'Наличные', placeholder: 'Укажите сумму наличных', suffixText: '₸', + fieldFocusNode: _focusCash, + enterPressed: () { + FocusScope.of(context).unfocus(); + }, textInputType: const TextInputType.numberWithOptions(decimal: true), ), - const CombineDock() + CombineDock( + bankSum: _bankSum, + cashNum: _cashSum, + totalSum: _sum, + ) ], ); } return Column( - children: const [ + children: [ LineCheckBox( 'Банковская карта', - value: true, + value: isCard == true, + onTap: () { + setState(() { + isCard = true; + }); + }, ), - Divider( + const Divider( height: 1, color: disableColor, ), LineCheckBox( 'Оплата наличными', - value: false, + value: isCard == false, + onTap: () { + setState(() { + isCard = false; + }); + }, ), ], ); diff --git a/lib/views/work/views/receipt/receipt_view.dart b/lib/views/work/views/receipt/receipt_view.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/widgets/fields/input_field.dart b/lib/widgets/fields/input_field.dart index 3b2f869..2b28713 100644 --- a/lib/widgets/fields/input_field.dart +++ b/lib/widgets/fields/input_field.dart @@ -122,9 +122,7 @@ class _InputFieldState extends State { child: TextFormField( style: TextStyle( color: textColor, - fontSize: widget.smallVersion - ? 12 - : 14), + fontSize: widget.smallVersion ? 12 : 14), controller: widget.controller, keyboardType: widget.textInputType, focusNode: widget.fieldFocusNode, @@ -152,7 +150,7 @@ class _InputFieldState extends State { filled: true, suffixText: widget.suffixText, suffixStyle: const TextStyle(color: textColor), - fillColor: whiteColor, + fillColor: widget.isReadOnly ? disableColor : whiteColor, border: InputBorder.none, hintStyle: TextStyle( fontSize: widget.smallVersion diff --git a/lib/widgets/fields/line_checkbox.dart b/lib/widgets/fields/line_checkbox.dart index 79819fb..4427975 100644 --- a/lib/widgets/fields/line_checkbox.dart +++ b/lib/widgets/fields/line_checkbox.dart @@ -44,12 +44,14 @@ class LineCheckBox extends StatelessWidget { ), ), SizedBox( - width: 20.w, + width: 20, + height: 20, child: Visibility( visible: value, child: const Icon( Icons.check, color: primaryColor, + size: 20, ), ), ) diff --git a/lib/widgets/fields/line_tile.dart b/lib/widgets/fields/line_tile.dart index f911624..5badfdc 100644 --- a/lib/widgets/fields/line_tile.dart +++ b/lib/widgets/fields/line_tile.dart @@ -5,8 +5,11 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'note_text.dart'; class LineTile extends StatelessWidget { - const LineTile(this.text, { required this.onTap, this.labelText }); + const LineTile(this.text, + {required this.onTap, this.labelText, this.placeholder = 'Выберите'}); + final String text; + final String placeholder; final String? labelText; final Function() onTap; @@ -18,13 +21,11 @@ class LineTile extends StatelessWidget { if (labelText != null) Padding( padding: - const EdgeInsets.symmetric(horizontal: 14.0, vertical: 5.0), + const EdgeInsets.symmetric(horizontal: 14.0, vertical: 5.0), child: NoteText(labelText ?? ''), ), Container( - decoration: const BoxDecoration( - color: whiteColor - ), + decoration: const BoxDecoration(color: whiteColor), child: Material( color: Colors.transparent, child: InkWell( @@ -34,17 +35,25 @@ class LineTile extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - text, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.normal, - color: textColor + if (text.isNotEmpty) + Text( + text, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: textColor), ), - ), - SizedBox( + if (text.isEmpty) + Text( + placeholder, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.normal, + color: placeholderColor), + ), + const SizedBox( width: 20, - child: const Icon( + child: Icon( Icons.chevron_right, color: textColor, ), diff --git a/lib/widgets/ui/product_title_widget.dart b/lib/widgets/ui/product_title_widget.dart index a042dbf..74639e7 100644 --- a/lib/widgets/ui/product_title_widget.dart +++ b/lib/widgets/ui/product_title_widget.dart @@ -20,7 +20,7 @@ class ProductTitleWidget extends StatelessWidget { children: [ Text( name, - style: TextStyle(fontSize: 14.sp, color: textColor), + style: const TextStyle(fontSize: 14, color: textColor), overflow: TextOverflow.ellipsis, maxLines: 2, ), @@ -28,12 +28,12 @@ class ProductTitleWidget extends StatelessWidget { if (ean != null) Text( 'Штрих-код: $ean', - style: TextStyle(color: placeholderColor, fontSize: 10.sp), + style: const TextStyle(color: placeholderColor, fontSize: 10), ), if (categoryName != null) Text( 'Категория: $categoryName', - style: TextStyle(color: placeholderColor, fontSize: 10.sp), + style: const TextStyle(color: placeholderColor, fontSize: 10), ) ], );