From 88048fb11ed670745685a0d1b61b2eec5597c32c Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Thu, 16 Nov 2023 12:46:58 +0300 Subject: [PATCH] Multiple parts in create work order --- .../work_order/create_service_report.dart | 36 ++--- .../requests/work_order/part_no_button.dart | 130 ++++++++++++++++++ 2 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 lib/views/pages/user/requests/work_order/part_no_button.dart diff --git a/lib/views/pages/user/requests/work_order/create_service_report.dart b/lib/views/pages/user/requests/work_order/create_service_report.dart index cb0406a4..409d77b8 100644 --- a/lib/views/pages/user/requests/work_order/create_service_report.dart +++ b/lib/views/pages/user/requests/work_order/create_service_report.dart @@ -15,10 +15,10 @@ import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/service_request/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; -import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/providers/work_order/service_type_provider.dart'; +import 'package:test_sa/views/pages/user/requests/work_order/part_no_button.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; @@ -62,6 +62,7 @@ class _CreateServiceReportState extends State with TickerPr final GlobalKey _scaffoldKey = GlobalKey(); final TextEditingController _faultController = TextEditingController(); final TextEditingController _workPreformedController = TextEditingController(); + final TextEditingController _partQtyController = TextEditingController(); @override void initState() { @@ -82,6 +83,7 @@ class _CreateServiceReportState extends State with TickerPr void dispose() { _faultController.dispose(); _workPreformedController.dispose(); + _partQtyController.dispose(); super.dispose(); } @@ -239,30 +241,6 @@ class _CreateServiceReportState extends State with TickerPr }, ), 8.height, - SingleItemDropDownMenu( - context: context, - title: context.translation.partNo, - staticData: _spareParts, - initialValue: (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) ? _serviceReport.sparePartsWorkOrders.first.sparePart : null, - onSelect: (part) { - _serviceReport.sparePartsWorkOrders.clear(); - _serviceReport.sparePartsWorkOrders.add(SparePartsWorkOrders(id: 0, sparePart: part, qty: 0)); - setState(() {}); - }, - ), - 8.height, - AppTextFormField( - labelText: context.translation.quantity, - textInputType: TextInputType.number, - enable: _serviceReport.sparePartsWorkOrders.isNotEmpty, - initialValue: (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) ? _serviceReport.sparePartsWorkOrders.first.qty?.toString() : null, - onSaved: (text) { - if (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) { - _serviceReport.sparePartsWorkOrders.first.qty = num.tryParse(text ?? ""); - } - }, - ), - 8.height, AppTextFormField( labelText: context.translation.travelingExpense, initialValue: _serviceReport?.travelingExpenses?.toString(), @@ -291,6 +269,14 @@ class _CreateServiceReportState extends State with TickerPr }, ), 8.height, + PartNoButton( + controller: _partQtyController, + spareParts: _spareParts, + onAdd: (parts) { + _serviceReport.sparePartsWorkOrders = parts; + }, + ), + 8.height, MultiFilesPicker(label: context.translation.attachImage, files: _files), 8.height, ESignature( diff --git a/lib/views/pages/user/requests/work_order/part_no_button.dart b/lib/views/pages/user/requests/work_order/part_no_button.dart new file mode 100644 index 00000000..e7badb17 --- /dev/null +++ b/lib/views/pages/user/requests/work_order/part_no_button.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; + +import '../../../../../controllers/validator/validator.dart'; +import '../../../../../models/service_request/spare_parts.dart'; +import '../../../../../new_views/app_style/app_color.dart'; +import '../../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../../new_views/common_widgets/app_text_form_field.dart'; +import '../../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; +import '../../../../../providers/loading_list_notifier.dart'; + +class PartNoButton extends StatefulWidget { + final List spareParts; + final List initialList; + final TextEditingController controller; + final Function(List sparePart) onAdd; + const PartNoButton({@required this.spareParts, @required this.controller, this.initialList, this.onAdd, Key key}) : super(key: key); + + @override + State createState() => _PartNoButtonState(); +} + +class _PartNoButtonState extends State { + final GlobalKey _formKey = GlobalKey(); + List list = []; + SparePartsWorkOrders current = SparePartsWorkOrders(); + + @override + void initState() { + super.initState(); + list = widget.initialList ?? []; + } + + @override + void didUpdateWidget(covariant PartNoButton oldWidget) { + if (widget.initialList != oldWidget.initialList) { + setState(() { + list = widget.initialList ?? []; + }); + } + super.didUpdateWidget(oldWidget); + } + + @override + Widget build(BuildContext context) { + return Form( + key: _formKey, + child: ExpansionTile( + title: context.translation.partNo.heading6(context), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + collapsedShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + tilePadding: const EdgeInsets.symmetric(horizontal: 16), + childrenPadding: const EdgeInsets.symmetric(horizontal: 16), + backgroundColor: Theme.of(context).cardColor, + collapsedBackgroundColor: Theme.of(context).cardColor, + children: [ + SingleItemDropDownMenu( + context: context, + title: context.translation.partNo, + staticData: widget.spareParts, + initialValue: current?.sparePart, + // initialValue: (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) ? _serviceReport.sparePartsWorkOrders.first.sparePart : null, + onSelect: (part) { + current = SparePartsWorkOrders(id: 0, sparePart: part, qty: 0); + setState(() {}); + }, + ), + 8.height, + AppTextFormField( + controller: widget.controller, + labelText: context.translation.quantity, + textInputType: TextInputType.number, + enable: current != null, + validator: (value) => value == null || value.isEmpty + ? context.translation.requiredField + : Validator.isNumeric(value) + ? null + : context.translation.onlyNumbers, + onSaved: (text) { + current.qty = num.tryParse(text ?? ""); + }, + ), + 8.height, + AppFilledButton( + label: context.translation.add, + maxWidth: true, + textColor: Colors.white, + buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50, + onPressed: () { + if (current != null && _formKey.currentState.validate()) { + _formKey.currentState.save(); + list.add(current); + if (widget.onAdd != null) widget.onAdd(list); + current = SparePartsWorkOrders(); + widget.controller.text = ""; + setState(() {}); + } + }, + ), + 16.height, + const Divider().defaultStyle(context), + if (list.isNotEmpty) 16.height, + if (list.isNotEmpty) + ListView.separated( + shrinkWrap: true, + itemCount: list.length, + padding: EdgeInsets.only(bottom: 16.toScreenHeight), + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) => Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "${list[index].sparePart.partNo} / ${list[index].sparePart.partName}".bodyText(context).expanded, + list[index].qty.toString().bodyText(context), + 32.width, + "trash".toSvgAsset().onPress(() { + list.remove(list[index]); + setState(() {}); + }), + ], + ).paddingOnly(top: 4, bottom: 4), + separatorBuilder: (context, index) => 8.height, + ) + ], + ), + ); + } +}