From 1e5c43d02e10f810f33390f011df1159ddb4f69f Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Tue, 17 Jun 2025 14:58:53 +0300 Subject: [PATCH] cost parameters and activity assign user check added. --- lib/controllers/api_routes/urls.dart | 8 +- .../workorder/work_order_helper_models.dart | 7 +- .../new_models/work_order_detail_model.dart | 19 +- .../components/activities_list_view.dart | 96 ++-- .../service_request_detail_view.dart | 9 + .../forms/cost/cost_detail_form_screen.dart | 45 ++ .../forms/spare_part/spare_part_request.dart | 467 +++++++++--------- 7 files changed, 362 insertions(+), 289 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index d0b31e04..f3135161 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -3,14 +3,14 @@ class URLs { static const String appReleaseBuildNumber = "16"; - static const host1 = "https://atomsm.hmg.com"; // production url - // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url + // static const host1 = "https://atomsm.hmg.com"; // production url + static const host1 = "https://atomsmdev.hmg.com"; // local DEV url // static const host1 = "https://atomsmuat.hmg.com"; // local UAT url // static String _baseUrl = "$_host/mobile"; - // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/mobile"; // host local UAT - static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM + // static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM static String _host = host1; diff --git a/lib/models/helper_data_models/workorder/work_order_helper_models.dart b/lib/models/helper_data_models/workorder/work_order_helper_models.dart index ecdf5470..917760c6 100644 --- a/lib/models/helper_data_models/workorder/work_order_helper_models.dart +++ b/lib/models/helper_data_models/workorder/work_order_helper_models.dart @@ -159,10 +159,13 @@ class WorkOrderCostModel { num? sparePartCost; num? labourCost; num? travelCost; + num? qAmount; + String? prNo; + String? poNo; - WorkOrderCostModel({this.workOrderId, this.sparePartCost, this.labourCost, this.travelCost}); + WorkOrderCostModel({this.workOrderId, this.sparePartCost, this.labourCost, this.travelCost, this.qAmount, this.poNo, this.prNo}); Map toJson() { - return {'workOrderId': workOrderId, 'sparePartCost': sparePartCost, 'laborCost': labourCost, 'travelCost': travelCost}; + return {'workOrderId': workOrderId, 'sparePartCost': sparePartCost, 'laborCost': labourCost, 'travelCost': travelCost, 'qAmount': qAmount, 'prNo': prNo, 'poNo': poNo}; } } diff --git a/lib/models/new_models/work_order_detail_model.dart b/lib/models/new_models/work_order_detail_model.dart index 2162d16b..faa2c75a 100644 --- a/lib/models/new_models/work_order_detail_model.dart +++ b/lib/models/new_models/work_order_detail_model.dart @@ -96,10 +96,13 @@ class WorkOrderData { this.labourCost, this.sparePartCost, this.travelCost, + this.qAmount, + this.prNo, + this.poNo, required this.workOrderHistory, required this.activities, required this.activityAssetToBeRetireds, - this.itgFormWorkOrderStatus, + this.itgFormWorkOrderStatus, }); int? requestId; @@ -157,6 +160,9 @@ class WorkOrderData { num? sparePartCost; num? labourCost; num? travelCost; + num? qAmount; + String? prNo; + String? poNo; List workOrderHistory; List activities; List activityAssetToBeRetireds; @@ -190,6 +196,9 @@ class WorkOrderData { travelCost: json['travelCost'], sparePartCost: json['sparePartCost'], labourCost: json['laborCost'], + qAmount: json['qAmount'], + prNo: json['prNo'], + poNo: json['poNo'], assetType: json["assetType"] == null ? null : Lookup.fromJson(json["assetType"]), assignedEmployee: json["assignedEmployee"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["assignedEmployee"]), lastActivityStatus: json["lastActivityStatus"] != null ? Lookup.fromJson(json["lastActivityStatus"]) : null, @@ -451,15 +460,19 @@ class ActivitySparePart { int? id; PartCatalogItem? partCatalogItem; double? quantity; + double? installQty; + double? returnQty; String? comment; List? acitiySparePartAttachments; - ActivitySparePart({this.id, this.partCatalogItem, this.quantity, this.comment, this.acitiySparePartAttachments}); + ActivitySparePart({this.id, this.partCatalogItem, this.quantity,this.installQty,this.returnQty, this.comment, this.acitiySparePartAttachments}); ActivitySparePart.fromJson(Map json) { id = json['id']; partCatalogItem = json['partCatalogItem'] != null ? new PartCatalogItem.fromJson(json['partCatalogItem']) : null; quantity = json['quantity']; + installQty = json['installQty']; + returnQty = json['returnQty']; comment = json['comment']; if (json['acitiySparePartAttachments'] != null) { acitiySparePartAttachments = []; @@ -476,6 +489,8 @@ class ActivitySparePart { data['partCatalogItem'] = partCatalogItem!.toJson(); } data['quantity'] = quantity; + data['installQty'] = installQty; + data['returnQty'] = returnQty; data['comment'] = comment; if (acitiySparePartAttachments != null) { data['acitiySparePartAttachments'] = acitiySparePartAttachments!.map((v) => v.toJson()).toList(); diff --git a/lib/modules/cm_module/views/components/activities_list_view.dart b/lib/modules/cm_module/views/components/activities_list_view.dart index 46be8029..3b6021ca 100644 --- a/lib/modules/cm_module/views/components/activities_list_view.dart +++ b/lib/modules/cm_module/views/components/activities_list_view.dart @@ -167,32 +167,16 @@ class _ActivitiesListViewState extends State { backgroundColor: AppColor.primary10, ), // "drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160), - if (userProvider.user!.type == UsersTypes.engineer && requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) + if (userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId && + userProvider.user!.type == UsersTypes.engineer && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ "edit_icon".toSvgAsset(height: 21, width: 21).onPress(() { - requestDetailProvider.sparePartHelperModel = SparePartHelperModel( - id: activity.id, - workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, - comment: activity.activitySparePart?.comment, - sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [], - activityStatus: activity.activityStatus, - sparePart: SparePart( - id: activity.activitySparePart?.partCatalogItem?.id, - partName: activity.activitySparePart?.partCatalogItem?.partName, - partNo: activity.activitySparePart?.partCatalogItem?.partNumber, - oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode), - quantity: activity.activitySparePart?.quantity, - activityStatusId: activity.activityStatus?.id, - ); - - requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel); - - Navigator.of(context).push(MaterialPageRoute( - builder: (_) => const SparePartRequest(), - )); + editSparePartRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity); }), 24.width, "delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async { @@ -241,26 +225,14 @@ class _ActivitiesListViewState extends State { ], ], ).toShadowContainer(context, padding: 12, showShadow: false).onPress(() { - // if(requestDetailProvider.currentWorkOrder?.data?.status?.id ==3498){ - // requestDetailProvider.sparePartHelperModel = SparePartHelperModel( - // id: activity.id, - // workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, - // comment: activity.activitySparePart?.comment, - // sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [], - // activityStatus: activity.activityStatus, - // sparePart: SparePart( - // id: activity.activitySparePart?.partCatalogItem?.id, - // partName: activity.activitySparePart?.partCatalogItem?.partName, - // partNo: activity.activitySparePart?.partCatalogItem?.partNumber, - // oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode), - // quantity: activity.activitySparePart?.quantity, - // activityStatusId: activity.activityStatus?.id, - // ); - // requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel); - // Navigator.of(context).push(MaterialPageRoute( - // builder: (_) => const SparePartRequest(), - // )); - // } + if (userProvider.user!.userID != requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId) { + requestDetailProvider.isReadOnlyRequest = true; + } else { + requestDetailProvider.isReadOnlyRequest = false; + } + if (requestDetailProvider.isReadOnlyRequest) { + editSparePartRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity); + } }); } @@ -297,13 +269,16 @@ class _ActivitiesListViewState extends State { ), // "drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160), - if (userProvider.user!.type == UsersTypes.engineer && requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) + if (userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId && + userProvider.user!.type == UsersTypes.engineer && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ "edit_icon".toSvgAsset(height: 21, width: 21).onPress(() { - onEditMaintenanceRequestPress(context: context, requestDetailProvider: requestDetailProvider, activity: activity); + editMaintenanceRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity); }), 24.width, "delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async { @@ -364,13 +339,19 @@ class _ActivitiesListViewState extends State { // ] ], ).toShadowContainer(context, padding: 12, showShadow: false).onPress(() { + if (userProvider.user!.userID != requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId) { + requestDetailProvider.isReadOnlyRequest = true; + } else { + requestDetailProvider.isReadOnlyRequest = false; + } + if (requestDetailProvider.isReadOnlyRequest) { - onEditMaintenanceRequestPress(context: context, requestDetailProvider: requestDetailProvider, activity: activity); + editMaintenanceRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity); } }); } - void onEditMaintenanceRequestPress({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async { + void editMaintenanceRequest({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async { Map assistEmpData = {}; try { if (activity.activityMaintenance?.assistantEmployees != null && activity.activityMaintenance!.assistantEmployees!.isNotEmpty) { @@ -428,6 +409,31 @@ class _ActivitiesListViewState extends State { } Navigator.of(context).push(MaterialPageRoute(builder: (_) => MaintenanceRequestForm())); } + + void editSparePartRequest({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async { + requestDetailProvider.sparePartHelperModel = SparePartHelperModel( + id: activity.id, + workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, + comment: activity.activitySparePart?.comment, + sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [], + activityStatus: activity.activityStatus, + sparePart: SparePart( + id: activity.activitySparePart?.partCatalogItem?.id, + partName: activity.activitySparePart?.partCatalogItem?.partName, + partNo: activity.activitySparePart?.partCatalogItem?.partNumber, + oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode), + quantity: activity.activitySparePart?.quantity, + installQty: activity.activitySparePart?.installQty, + returnQty: activity.activitySparePart?.returnQty, + activityStatusId: activity.activityStatus?.id, + ); + + requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel); + + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => const SparePartRequest(), + )); + } } class ReorderWidget extends StatelessWidget { diff --git a/lib/modules/cm_module/views/components/service_request_detail_view.dart b/lib/modules/cm_module/views/components/service_request_detail_view.dart index e54e78fe..06d26e48 100644 --- a/lib/modules/cm_module/views/components/service_request_detail_view.dart +++ b/lib/modules/cm_module/views/components/service_request_detail_view.dart @@ -483,6 +483,15 @@ class _ServiceRequestDetailViewState extends State { Text( 'Travel Cost: ${provider.currentWorkOrder!.data?.travelCost ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), Text( + 'Quot Amount: ${provider.currentWorkOrder!.data?.qAmount ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), Text( + 'PR No: ${provider.currentWorkOrder!.data?.prNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), Text( + 'PO No: ${provider.currentWorkOrder!.data?.poNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), ], ), diff --git a/lib/modules/cm_module/views/forms/cost/cost_detail_form_screen.dart b/lib/modules/cm_module/views/forms/cost/cost_detail_form_screen.dart index 13aee549..923e91b0 100644 --- a/lib/modules/cm_module/views/forms/cost/cost_detail_form_screen.dart +++ b/lib/modules/cm_module/views/forms/cost/cost_detail_form_screen.dart @@ -43,6 +43,9 @@ class _CostDetailFormScreenState extends State with Ticker labourCost: currentWorkOrderData.labourCost, sparePartCost: currentWorkOrderData.sparePartCost, travelCost: currentWorkOrderData.travelCost, + qAmount: currentWorkOrderData.qAmount, + prNo: currentWorkOrderData.prNo, + poNo: currentWorkOrderData.poNo, ); } @@ -107,6 +110,48 @@ class _CostDetailFormScreenState extends State with Ticker }, style: Theme.of(context).textTheme.titleMedium, ), + 8.height, + AppTextFormField( + labelText: "Quot Amount", + backgroundColor: AppColor.neutral100, + initialValue: requestDetailProvider.workOrderCostModel?.qAmount?.toString(), + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + onChange: (value) { + requestDetailProvider.workOrderCostModel?.qAmount = num.parse(value); + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: "PR No", + backgroundColor: AppColor.neutral100, + initialValue: requestDetailProvider.workOrderCostModel?.prNo, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.text, + showShadow: false, + onChange: (value) { + requestDetailProvider.workOrderCostModel?.prNo = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: "PO No", + backgroundColor: AppColor.neutral100, + initialValue: requestDetailProvider.workOrderCostModel?.poNo, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.text, + showShadow: false, + onChange: (value) { + requestDetailProvider.workOrderCostModel?.poNo = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), ], ).toShadowContainer(context).paddingAll(16), ).expanded, diff --git a/lib/modules/cm_module/views/forms/spare_part/spare_part_request.dart b/lib/modules/cm_module/views/forms/spare_part/spare_part_request.dart index 1517b341..fd604b62 100644 --- a/lib/modules/cm_module/views/forms/spare_part/spare_part_request.dart +++ b/lib/modules/cm_module/views/forms/spare_part/spare_part_request.dart @@ -27,7 +27,6 @@ import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/views/widgets/images/new_multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; - class SparePartRequest extends StatefulWidget { static const String id = "/spare-part-request"; @@ -60,18 +59,18 @@ class _SparePartRequestState extends State with TickerProvider super.initState(); _partsProvider = Provider.of(context, listen: false); _requestDetailProvider = Provider.of(context, listen: false); - _requestDetailProvider?.sparePartHelperModel = SparePartHelperModel( - id: _requestDetailProvider?.sparePartHelperModel?.id ?? 0, - workOrderId: _requestDetailProvider?.sparePartHelperModel?.workOrderId ?? _requestDetailProvider?.currentWorkOrder?.data?.requestId, - sparePartAttachments: _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments ?? [], - sparePart: _requestDetailProvider?.sparePartHelperModel?.sparePart ?? SparePart(), - quantity: _requestDetailProvider?.sparePartHelperModel?.quantity, - installQty: _requestDetailProvider?.sparePartHelperModel?.installQty, - returnQty: _requestDetailProvider?.sparePartHelperModel?.returnQty, - activityStatusId: _requestDetailProvider?.sparePartHelperModel?.activityStatusId ?? statusLookup.id, - activityStatus: _requestDetailProvider?.sparePartHelperModel?.activityStatus ?? statusLookup, - comment: _requestDetailProvider?.sparePartHelperModel?.comment ?? '', - ); + // _requestDetailProvider?.sparePartHelperModel = SparePartHelperModel( + // id: _requestDetailProvider?.sparePartHelperModel?.id ?? 0, + // workOrderId: _requestDetailProvider?.sparePartHelperModel?.workOrderId ?? _requestDetailProvider?.currentWorkOrder?.data?.requestId, + // sparePartAttachments: _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments ?? [], + // sparePart: _requestDetailProvider?.sparePartHelperModel?.sparePart ?? SparePart(), + // quantity: _requestDetailProvider?.sparePartHelperModel?.quantity, + // installQty: _requestDetailProvider?.sparePartHelperModel?.installQty, + // returnQty: _requestDetailProvider?.sparePartHelperModel?.returnQty, + // activityStatusId: _requestDetailProvider?.sparePartHelperModel?.activityStatusId ?? statusLookup.id, + // activityStatus: _requestDetailProvider?.sparePartHelperModel?.activityStatus ?? statusLookup, + // comment: _requestDetailProvider?.sparePartHelperModel?.comment ?? '', + // ); _partQtyController.text = _requestDetailProvider?.sparePartHelperModel?.quantity != null ? _requestDetailProvider!.sparePartHelperModel!.quantity!.round().toString() : ''; _installQtyController.text = _requestDetailProvider?.sparePartHelperModel?.installQty != null ? _requestDetailProvider!.sparePartHelperModel!.installQty!.round().toString() : ''; _returnQtyController.text = _requestDetailProvider?.sparePartHelperModel?.returnQty != null ? _requestDetailProvider!.sparePartHelperModel!.returnQty!.round().toString() : ''; @@ -83,7 +82,6 @@ class _SparePartRequestState extends State with TickerProvider _files = _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments?.map((e) => MultiFilesPickerModel(e.id!, File(e.name!))).toList() ?? []; setState(() {}); _spareParts = await _partsProvider!.getPartsListByDisplayName(assetId: _requestDetailProvider?.currentWorkOrder?.data?.asset?.id); - _isLoading = false; setState(() {}); }); @@ -127,100 +125,81 @@ class _SparePartRequestState extends State with TickerProvider child: Column( children: [ SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Card( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - context.translation.sparePartDetails.heading5(context), - // 12.height, - // SingleItemDropDownMenu( - // context: context, - // height: 56.toScreenHeight, - // title: context.translation.activityStatus, - // showShadow: false, - // backgroundColor: AppColor.neutral100, - // initialValue: requestDetailProvider.sparePartHelperModel?.activityStatus, - // onSelect: (status) { - // requestDetailProvider.sparePartHelperModel?.activityStatus = status; - // }, - // ), - 12.height, - SingleItemDropDownMenu( - context: context, - title: context.translation.part, - staticData: _spareParts, - showShadow: false, - showAsBottomSheet: true, - loading: _isLoading, - initialValue: requestDetailProvider.sparePartHelperModel?.sparePart, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - onSelect: (part) async { - if (part != null) { - requestDetailProvider.sparePartHelperModel?.sparePart = part; - _oracleNoController.text = part.oracleCode ?? ''; - requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel); - } - }, - ), - - if(requestDetailProvider.sparePartHelperModel?.sparePart?.id!=null)...[ + child: IgnorePointer( + ignoring: _requestDetailProvider!.isReadOnlyRequest, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + context.translation.sparePartDetails.heading5(context), + // 12.height, + // SingleItemDropDownMenu( + // context: context, + // height: 56.toScreenHeight, + // title: context.translation.activityStatus, + // showShadow: false, + // backgroundColor: AppColor.neutral100, + // initialValue: requestDetailProvider.sparePartHelperModel?.activityStatus, + // onSelect: (status) { + // requestDetailProvider.sparePartHelperModel?.activityStatus = status; + // }, + // ), 12.height, - SizedBox( - height: 30.toScreenHeight, - child: Text('View Parts Availability',style:TextStyle( - fontSize: 12.toScreenWidth, - fontWeight: FontWeight.w500, - fontStyle: FontStyle.normal, - color:AppColor.primary10 , - decorationColor: AppColor.primary10, - decoration: TextDecoration.underline, - )).onPress( - () async { - requestDetailProvider.getStoreAvailabilityById(partId: requestDetailProvider.sparePartHelperModel?.sparePart?.id); - showModalBottomSheet( - context: context, - isScrollControlled: true, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical( - top: Radius.circular(20), + SingleItemDropDownMenu( + context: context, + title: context.translation.part, + staticData: _spareParts, + showShadow: false, + showAsBottomSheet: true, + loading: _isLoading, + initialValue: requestDetailProvider.sparePartHelperModel?.sparePart, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, + onSelect: (part) async { + if (part != null) { + requestDetailProvider.sparePartHelperModel?.sparePart = part; + _oracleNoController.text = part.oracleCode ?? ''; + requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel); + } + }, + ), + + if (requestDetailProvider.sparePartHelperModel?.sparePart?.id != null) ...[ + 12.height, + SizedBox( + height: 30.toScreenHeight, + child: Text('View Parts Availability', + style: TextStyle( + fontSize: 12.toScreenWidth, + fontWeight: FontWeight.w500, + fontStyle: FontStyle.normal, + color: AppColor.primary10, + decorationColor: AppColor.primary10, + decoration: TextDecoration.underline, + )).onPress( + () async { + requestDetailProvider.getStoreAvailabilityById(partId: requestDetailProvider.sparePartHelperModel?.sparePart?.id); + showModalBottomSheet( + context: context, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), ), - ), - clipBehavior: Clip.antiAliasWithSaveLayer, - builder: (BuildContext context) => PartDetailBottomSheetSheet(), - ); - }, + clipBehavior: Clip.antiAliasWithSaveLayer, + builder: (BuildContext context) => PartDetailBottomSheetSheet(), + ); + }, + ), ), - ), - ], - 12.height, - AppTextFormField( - controller: _partQtyController, - labelText: context.translation.quantity, - textInputType: TextInputType.number, - labelStyle: AppTextStyles.textFieldLabelStyle, - showWithoutDecoration: true, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null, - validator: (value) => value == null || value.isEmpty - ? context.translation.requiredField - : Validator.isNumeric(value) - ? null - : context.translation.onlyNumbers, - onChange: (value) { - requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(value ?? ""); - }, - onSaved: (text) { - requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(text ?? ""); - }, - ), - 12.height, - if(showInstallAndReturnQty) ...[ + ], + 12.height, AppTextFormField( - controller: _installQtyController, - labelText: context.translation.installedQty, + controller: _partQtyController, + labelText: context.translation.quantity, textInputType: TextInputType.number, labelStyle: AppTextStyles.textFieldLabelStyle, showWithoutDecoration: true, @@ -229,170 +208,186 @@ class _SparePartRequestState extends State with TickerProvider validator: (value) => value == null || value.isEmpty ? context.translation.requiredField : Validator.isNumeric(value) - ? null - : context.translation.onlyNumbers, + ? null + : context.translation.onlyNumbers, onChange: (value) { - requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(value ?? ""); + requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(value ?? ""); }, onSaved: (text) { - requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(text ?? ""); + requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(text ?? ""); }, ), 12.height, + if (showInstallAndReturnQty) ...[ + AppTextFormField( + controller: _installQtyController, + labelText: context.translation.installedQty, + textInputType: TextInputType.number, + labelStyle: AppTextStyles.textFieldLabelStyle, + showWithoutDecoration: true, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, + enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null, + validator: (value) => value == null || value.isEmpty + ? context.translation.requiredField + : Validator.isNumeric(value) + ? null + : context.translation.onlyNumbers, + onChange: (value) { + requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(value ?? ""); + }, + onSaved: (text) { + requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(text ?? ""); + }, + ), + 12.height, + AppTextFormField( + controller: _returnQtyController, + labelText: context.translation.returnQty, + textInputType: TextInputType.number, + labelStyle: AppTextStyles.textFieldLabelStyle, + showWithoutDecoration: true, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, + enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null, + validator: (value) => value == null || value.isEmpty + ? context.translation.requiredField + : Validator.isNumeric(value) + ? null + : context.translation.onlyNumbers, + onChange: (value) { + requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(value ?? ""); + }, + onSaved: (text) { + requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(text ?? ""); + }, + ), + 12.height, + ], AppTextFormField( - controller: _returnQtyController, - labelText: context.translation.returnQty, - textInputType: TextInputType.number, labelStyle: AppTextStyles.textFieldLabelStyle, + controller: _oracleNoController, + labelText: context.translation.oracleNo, + textInputType: TextInputType.number, showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null, - validator: (value) => value == null || value.isEmpty - ? context.translation.requiredField - : Validator.isNumeric(value) - ? null - : context.translation.onlyNumbers, + enable: false, + ), + 12.height, + AppTextFormField( + initialValue: requestDetailProvider.sparePartHelperModel?.comment, + labelStyle: AppTextStyles.textFieldLabelStyle, + controller: _descriptionController, + showSpeechToText: true, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, + labelText: "Engineer Comment", + alignLabelWithHint: true, + showWithoutDecoration: true, + textInputType: TextInputType.multiline, onChange: (value) { - requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(value ?? ""); + requestDetailProvider.sparePartHelperModel?.comment = value; }, - onSaved: (text) { - requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(text ?? ""); + onSaved: (value) { + requestDetailProvider.sparePartHelperModel?.comment = value; }, ), 12.height, + NewMultiFilesPicker( + label: context.translation.attachQuotation, + files: _files, + buttonIcon: 'quotation_icon'.toSvgAsset(), + buttonColor: AppColor.primary10, + ), ], - AppTextFormField( - labelStyle: AppTextStyles.textFieldLabelStyle, - controller: _oracleNoController, - labelText: context.translation.oracleNo, - textInputType: TextInputType.number, - showWithoutDecoration: true, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: false, - ), - 12.height, - AppTextFormField( - initialValue: requestDetailProvider.sparePartHelperModel?.comment, - labelStyle: AppTextStyles.textFieldLabelStyle, - controller: _descriptionController, - showSpeechToText: true, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - labelText: "Engineer Comment", - alignLabelWithHint: true, - showWithoutDecoration: true, - textInputType: TextInputType.multiline, - onChange: (value) { - requestDetailProvider.sparePartHelperModel?.comment = value; - }, - onSaved: (value) { - requestDetailProvider.sparePartHelperModel?.comment = value; - }, - ), - 12.height, - NewMultiFilesPicker( - label: context.translation.attachQuotation, - files: _files, - buttonIcon: 'quotation_icon'.toSvgAsset(), - buttonColor: AppColor.primary10, - ), - ], - ).paddingAll(16), - ), - 8.height, - ], + ).paddingAll(16), + ), + 8.height, + ], + ), ), ).paddingAll(12).expanded, - FooterActionButton.footerContainer( - child: AppFilledButton( - label: _requestDetailProvider?.sparePartHelperModel?.id == 0 ? context.translation.addSparePartActivity : context.translation.updateSparePartActivity, - buttonColor: AppColor.green70, - onPressed: () async { - requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.clear(); - for (var pickerObject in _files) { - String fileData = - _isLocalUrl(pickerObject.file.path) ? ("${pickerObject.file.path.split("/").last}|${base64Encode(File(pickerObject.file.path).readAsBytesSync())}") : pickerObject.file.path; - requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.add(SparePartAttachments(id: pickerObject.id, name: fileData)); - } - showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - int status = -1; - if (_requestDetailProvider?.sparePartHelperModel?.id == 0) { - status = await requestDetailProvider.createActivitySparePart(); - } else { - status = await requestDetailProvider.updateActivitySparePart(); - } - if (status == 200) { - await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); - //this is for hide the dialoge... - Navigator.pop(context); - Navigator.pop(context); - //show this only for add form.. + if (!requestDetailProvider.isReadOnlyRequest) + FooterActionButton.footerContainer( + child: AppFilledButton( + label: _requestDetailProvider?.sparePartHelperModel?.id == 0 ? context.translation.addSparePartActivity : context.translation.updateSparePartActivity, + buttonColor: AppColor.green70, + onPressed: () async { + requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.clear(); + for (var pickerObject in _files) { + String fileData = + _isLocalUrl(pickerObject.file.path) ? ("${pickerObject.file.path.split("/").last}|${base64Encode(File(pickerObject.file.path).readAsBytesSync())}") : pickerObject.file.path; + requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.add(SparePartAttachments(id: pickerObject.id, name: fileData)); + } + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + int status = -1; if (_requestDetailProvider?.sparePartHelperModel?.id == 0) { - ServiceRequestBottomSheet.addAnotherSpareRequestBottomSheet(context: context); - SizedBox().flushBar(context: context, title: context.translation.sparePartActivitySuccess, message: ''); + status = await requestDetailProvider.createActivitySparePart(); + } else { + status = await requestDetailProvider.updateActivitySparePart(); } - } else { - Navigator.pop(context); - } - }, - )), + if (status == 200) { + await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + //this is for hide the dialoge... + Navigator.pop(context); + Navigator.pop(context); + //show this only for add form.. + if (_requestDetailProvider?.sparePartHelperModel?.id == 0) { + ServiceRequestBottomSheet.addAnotherSpareRequestBottomSheet(context: context); + SizedBox().flushBar(context: context, title: context.translation.sparePartActivitySuccess, message: ''); + } + } else { + Navigator.pop(context); + } + }, + )), ], ), )); }), ); } - } - class PartDetailBottomSheetSheet extends StatelessWidget { - - PartDetailBottomSheetSheet( {Key? key}) : super(key: key); + PartDetailBottomSheetSheet({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return SizedBox( - height: SizeConfig.screenHeight!/2.2, - width: SizeConfig.screenWidth, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 8.height, - 'Parts Availability'.heading6(context).paddingOnly(top: 12,start: 12), - Consumer( - builder: (context, requestDetailProvider,child) { - return requestDetailProvider.isLoading - ? const CircularProgressIndicator(color: AppColor.primary10).center - : requestDetailProvider.storeAvailability.isEmpty - ? const NoDataFound().center - : ListView.separated( - padding: const EdgeInsets.all(16), - itemCount: requestDetailProvider.storeAvailability.length, - separatorBuilder: (czt, index) => 12.height, - itemBuilder: (context, index) { - StoreAvailability model = requestDetailProvider.storeAvailability[index]; - return partAvailableQuantityCard(context: context,model:model); - }, - ); - } - ).expanded, - ], - ), - ); + return SizedBox( + height: SizeConfig.screenHeight! / 2.2, + width: SizeConfig.screenWidth, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 8.height, + 'Parts Availability'.heading6(context).paddingOnly(top: 12, start: 12), + Consumer(builder: (context, requestDetailProvider, child) { + return requestDetailProvider.isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : requestDetailProvider.storeAvailability.isEmpty + ? const NoDataFound().center + : ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: requestDetailProvider.storeAvailability.length, + separatorBuilder: (czt, index) => 12.height, + itemBuilder: (context, index) { + StoreAvailability model = requestDetailProvider.storeAvailability[index]; + return partAvailableQuantityCard(context: context, model: model); + }, + ); + }).expanded, + ], + ), + ); } - Widget partAvailableQuantityCard({required StoreAvailability model,required BuildContext context }){ - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 'Site Name: ${model.siteName??''}'.bodyText2(context).custom(color: AppColor.neutral120), - 8.height, - 'Store Name: ${model.storeName??''}'.bodyText2(context).custom(color: AppColor.neutral120), - 8.height, - 'Available Quantity: ${model.availablityQty??''}'.bodyText2(context).custom(color: AppColor.neutral120), - 8.height, - ] - ).toShadowContainer(context, padding: 12, showShadow: false,backgroundColor: AppColor.neutral110); + + Widget partAvailableQuantityCard({required StoreAvailability model, required BuildContext context}) { + return Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ + 'Site Name: ${model.siteName ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120), + 8.height, + 'Store Name: ${model.storeName ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120), + 8.height, + 'Available Quantity: ${model.availablityQty ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120), + 8.height, + ]).toShadowContainer(context, padding: 12, showShadow: false, backgroundColor: AppColor.neutral110); } }