From b20f42848b0e4c0bbaa2b6c7e1763456b1e3523e Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 8 Feb 2026 10:29:50 +0300 Subject: [PATCH] supplier attachment, extend demo period and submit evaluation. --- lib/extensions/enum_extensions.dart | 6 +- .../action_button/footer_action_button.dart | 8 +-- .../demo_module/demo_detail_view_page.dart | 13 ++++- .../demo_module/evaluation_form_page.dart | 44 +++++++++++++- .../models/demo_request_model.dart | 4 ++ .../demo_module/provider/demo_provider.dart | 11 ++-- .../demo_module/update_demo-request_view.dart | 57 ++++++++++++++----- 7 files changed, 115 insertions(+), 28 deletions(-) diff --git a/lib/extensions/enum_extensions.dart b/lib/extensions/enum_extensions.dart index 0083aedf..23a066f5 100644 --- a/lib/extensions/enum_extensions.dart +++ b/lib/extensions/enum_extensions.dart @@ -125,12 +125,14 @@ extension IntExtensionsDemoRequest on int { return DemoRequestStepEnum.qAuditorRejectAccept; case 5: return DemoRequestStepEnum.updateRequest; + + case 21: + return DemoRequestStepEnum.updateRequest; return DemoRequestStepEnum.viewOnly; case 15: return DemoRequestStepEnum.extendDemoPeriod; default: - // return DemoRequestStepEnum.viewOnly; - return DemoRequestStepEnum.updateRequest; + return DemoRequestStepEnum.viewOnly; } } } diff --git a/lib/modules/cm_module/views/components/action_button/footer_action_button.dart b/lib/modules/cm_module/views/components/action_button/footer_action_button.dart index b3bcb6e4..b9935e7a 100644 --- a/lib/modules/cm_module/views/components/action_button/footer_action_button.dart +++ b/lib/modules/cm_module/views/components/action_button/footer_action_button.dart @@ -21,6 +21,7 @@ import 'package:test_sa/modules/cm_module/views/components/bottom_sheets/service import 'package:test_sa/modules/cm_module/views/components/verify_arrival_view.dart'; import 'package:test_sa/modules/cm_module/views/forms/asset_retired/verify_asset_detail.dart'; import 'package:test_sa/modules/demo_module/demo_extension_bottom_sheet.dart'; +import 'package:test_sa/modules/demo_module/evaluation_form_page.dart'; import 'package:test_sa/modules/demo_module/models/demo_request_model.dart'; import 'package:test_sa/modules/demo_module/provider/demo_provider.dart'; import 'package:test_sa/modules/demo_module/update_demo-request_view.dart'; @@ -445,12 +446,7 @@ class FooterActionButton { // maxWidth: true, buttonColor: AppColor.primary10, onPressed: () async { - bool? isRefresh = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => UpdateDemoRequestView( - dataModel: dataModel, - ))); + bool? isRefresh = await Navigator.push(context, MaterialPageRoute(builder: (context) => EvaluationFormPage())); if (isRefresh == true) { refreshData(); } diff --git a/lib/modules/demo_module/demo_detail_view_page.dart b/lib/modules/demo_module/demo_detail_view_page.dart index e5127315..20be2563 100644 --- a/lib/modules/demo_module/demo_detail_view_page.dart +++ b/lib/modules/demo_module/demo_detail_view_page.dart @@ -85,6 +85,7 @@ class _DemoDetailViewPageState extends State { if (snapshot.data == null) return const NoDataFound().center; List allAttachments = snapshot.data!.demoAttachments! ?? []; + List suppAttachments = snapshot.data!.supplierDemoAttachments! ?? []; DemoRequestModel demoData = snapshot.data!; @@ -126,12 +127,22 @@ class _DemoDetailViewPageState extends State { images: allAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList(), types: allAttachments.map((e) => e.documentType?.name ?? '').toList()), ], + if (suppAttachments.isNotEmpty) ...[ + const Divider().defaultStyle(context), + Text( + "Supplier Attachments".addTranslation, + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + FilesList( + showAsListView: true, + images: suppAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList(), + types: suppAttachments.map((e) => e.documentType?.name ?? '').toList()), + ], ], ).toShadowContainer(context, padding: 12), ).expanded, FooterActionButton.demoRequestDetailsFooterWidget( demoRequestStage: demoData.status!.demoRequestStepEnum!, - // demoRequestStage: DemoRequestStepEnum.updateRequest, dataModel: demoData, status: demoData.status!, context: context, diff --git a/lib/modules/demo_module/evaluation_form_page.dart b/lib/modules/demo_module/evaluation_form_page.dart index aec84a74..a8e97ecb 100644 --- a/lib/modules/demo_module/evaluation_form_page.dart +++ b/lib/modules/demo_module/evaluation_form_page.dart @@ -121,6 +121,46 @@ class _EvaluationFormPageState extends State { children: [ 'Clinical practice after using the new technology'.addTranslation.bodyText(context).custom(color: AppColor.black10), 16.height, + AppTextFormField( + initialValue: "", + hintText: "Some Comments", + labelText: "Advantages", + validator: (value) { + if ((value ?? "").isEmpty) return "Mandatory"; + return null; + }, + style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), + floatingLabelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + textInputType: TextInputType.multiline, + makeMultiLinesNull: false, + onChange: (value) { + formData['advantages'] = value; + }, + ), + 8.height, + AppTextFormField( + initialValue: "", + hintText: "Some Comments", + labelText: "Disadvantages", + validator: (value) { + if ((value ?? "").isEmpty) return "Mandatory"; + return null; + }, + style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), + floatingLabelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + textInputType: TextInputType.multiline, + makeMultiLinesNull: false, + onChange: (value) { + formData['disadvantages'] = value; + }, + ), + 8.height, AppTextFormField( initialValue: "", hintText: "Some Comments", @@ -324,7 +364,7 @@ class _EvaluationFormPageState extends State { textInputType: TextInputType.multiline, makeMultiLinesNull: false, onChange: (value) { - // _demoFormModel.docName = value; + formData['additionalComments'] = value; }, ), ]).toShadowContainer(context, borderRadius: 20); @@ -342,7 +382,7 @@ class _EvaluationFormPageState extends State { bool isSuccess = await demoProvider.addDemoTrialOutcome(formData); Utils.hideLoading(context); if (isSuccess) { - Navigator.pop(context); + Navigator.pop(context, true); } } } diff --git a/lib/modules/demo_module/models/demo_request_model.dart b/lib/modules/demo_module/models/demo_request_model.dart index 363a712e..f79c06a8 100644 --- a/lib/modules/demo_module/models/demo_request_model.dart +++ b/lib/modules/demo_module/models/demo_request_model.dart @@ -29,6 +29,7 @@ class DemoRequestModel { SuppEngineerWorkOrders? suppPerson; Lookup? status; List? demoAttachments; + List? supplierDemoAttachments; dynamic demoAsset; dynamic demoInstallationTaskJob; dynamic demoPullOutTaskJob; @@ -58,6 +59,7 @@ class DemoRequestModel { this.suppPerson, this.status, this.demoAttachments, + this.supplierDemoAttachments, this.demoAsset, this.demoInstallationTaskJob, this.demoPullOutTaskJob, @@ -88,6 +90,7 @@ class DemoRequestModel { suppPerson = json['suppPerson'] != null ? (SuppEngineerWorkOrders.fromJson(json['suppPerson'])) : null; status = json['status'] != null ? (Lookup.fromJson(json['status'])) : null; demoAttachments = json['demoAttachments'] != null ? (json['demoAttachments'] as List).map((e) => DemoAttachments.fromJson(e)).toList() : null; + supplierDemoAttachments = json['supplierDemoAttachments'] != null ? (json['supplierDemoAttachments'] as List).map((e) => DemoAttachments.fromJson(e)).toList() : null; demoAsset = json['demoAsset']; demoInstallationTaskJob = json['demoInstallationTaskJob']; demoPullOutTaskJob = json['demoPullOutTaskJob']; @@ -111,6 +114,7 @@ class DemoRequestModel { "supplierId": supplier?.id, "suppPersonId": suppPerson?.id, "demoAttachments": demoAttachments != null ? demoAttachments!.map((v) => v.toJson()).toList() : [], + "supplierDemoAttachments": supplierDemoAttachments != null ? supplierDemoAttachments!.map((v) => v.toJson()).toList() : [], }; } } diff --git a/lib/modules/demo_module/provider/demo_provider.dart b/lib/modules/demo_module/provider/demo_provider.dart index 221bda12..8d9af0e0 100644 --- a/lib/modules/demo_module/provider/demo_provider.dart +++ b/lib/modules/demo_module/provider/demo_provider.dart @@ -44,7 +44,7 @@ class DemoProvider extends ChangeNotifier { Map payload = {"demoRequestId": requestId, "isApproved": status}; Response response = await ApiManager.instance.post(URLs.updateDemoRequestByAssessor, body: payload, showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { - String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? ""); + String message = (jsonDecode(response.body)["message"] ?? ""); Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); return true; } @@ -58,9 +58,12 @@ class DemoProvider extends ChangeNotifier { try { Response response = await ApiManager.instance.post(URLs.updateDemoRequest, body: body, showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { - String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? ""); + String message = (jsonDecode(response.body)["message"] ?? ""); Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); return true; + } else if (response.statusCode >= 400 && response.statusCode < 500) { + String message = (jsonDecode(response.body)["message"] ?? ""); + Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); } return false; } catch (error) { @@ -73,7 +76,7 @@ class DemoProvider extends ChangeNotifier { Map payload = {"demoRequestId": requestId, "demoPeriodId": demoPeriodId, "isDemoPeriodExtentionRequired": isUpdateRequired}; Response response = await ApiManager.instance.post(URLs.updateDemoPeriodByRequester, body: payload, showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { - String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? ""); + String message = (jsonDecode(response.body)["message"] ?? ""); Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); return true; } @@ -110,7 +113,7 @@ class DemoProvider extends ChangeNotifier { try { Response response = await ApiManager.instance.post(URLs.addDemoTrialOutcome, body: body, showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { - String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? ""); + String message = (jsonDecode(response.body)["message"] ?? ""); Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); return true; } diff --git a/lib/modules/demo_module/update_demo-request_view.dart b/lib/modules/demo_module/update_demo-request_view.dart index 7cf3adb0..bdf6408d 100644 --- a/lib/modules/demo_module/update_demo-request_view.dart +++ b/lib/modules/demo_module/update_demo-request_view.dart @@ -34,6 +34,7 @@ import 'package:test_sa/providers/work_order/vendor_provider.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../models/new_models/department.dart'; +import 'demo_document_lookup_provider.dart'; import 'models/demo_form_model.dart'; class UpdateDemoRequestView extends StatefulWidget { @@ -47,7 +48,7 @@ class UpdateDemoRequestView extends StatefulWidget { } class _UpdateDemoRequestViewState extends State with TickerProviderStateMixin { - final List attachments = []; + final List attachments = []; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); DemoFormModel _demoFormModel = DemoFormModel(); @@ -65,6 +66,7 @@ class _UpdateDemoRequestViewState extends State with Tick late SiteProvider siteProvider; late DemoProvider demoProvider; bool isLoading = true; + Lookup? demoDocumentLookup; @override void initState() { @@ -161,7 +163,7 @@ class _UpdateDemoRequestViewState extends State with Tick for (final item in widget.dataModel.demoAttachments!) { if ((item.attachmentName ?? '').isNotEmpty) { attachments.add( - DemoAttachments(attachmentName: item.attachmentName, id: item.id ?? 0, originalName: item.originalName), + GenericAttachmentModel(name: item.attachmentName, id: item.id ?? 0, originalName: item.originalName, documentTypeId: item.documentType), ); } } @@ -197,14 +199,36 @@ class _UpdateDemoRequestViewState extends State with Tick 16.height, ...vendorDetailsSection(), 16.height, - // AttachmentPicker( - // label: context.translation.attachments, - // attachment: attachments, - // buttonColor: AppColor.black10, - // onlyImages: false, - // showAsListView: true, - // buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120), - // ), + "Attachments".bodyText(context).custom(color: AppColor.black10), + 8.height, + SingleItemDropDownMenu( + context: context, + height: 56.toScreenHeight, + title: "Document Type", + initialValue: demoDocumentLookup, + showShadow: false, + validator: (value) { + if (value == null) return "Mandatory"; + return null; + }, + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + onSelect: (value) { + demoDocumentLookup = value; + setState(() {}); + }, + ), + 16.height, + AttachmentPicker( + label: context.translation.attachments, + attachment: attachments, + buttonColor: AppColor.black10.withOpacity(demoDocumentLookup != null ? 1 : .4), + onlyImages: false, + documentType: demoDocumentLookup, + enabled: demoDocumentLookup != null, + showAsListView: true, + buttonIcon: 'image-plus'.toSvgAsset(color: (context.isDark ? AppColor.primary10 : AppColor.neutral120).withOpacity(demoDocumentLookup != null ? 1 : .4)), + ), ], ).toShadowContainer(context, borderRadius: 20), ).expanded, @@ -496,11 +520,18 @@ class _UpdateDemoRequestViewState extends State with Tick '${'Vendor Name'.addTranslation}: ${_demoFormModel.vendorName?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), - 8.height, Text( '${'Representative Name'.addTranslation}: ${_demoFormModel.vendorRepresentativeName?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), + Text( + '${'Contact'.addTranslation}: ${_demoFormModel.vendorContactNumber?.cleanupWhitespace.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + '${'Email'.addTranslation}: ${_demoFormModel.vendorEmail?.cleanupWhitespace.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), ], 8.height, @@ -582,9 +613,9 @@ class _UpdateDemoRequestViewState extends State with Tick _demoFormModel.demoAttachment = []; // _demoFormModel.id = 3; for (var item in attachments) { - // String fileName = CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? ''; + String fileName = CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? ''; //Todo need to pass attachmentType id as well. - // _demoFormModel.demoAttachment?.add(DemoAttachments(id: item.id, demoRequestId: _demoFormModel.id ?? 0, attachmentName: fileName)); + _demoFormModel.demoAttachment?.add(DemoAttachments(id: item.id, demoRequestId: _demoFormModel.id ?? 0, attachmentName: fileName,originalName: fileName, documentTypeId: item.documentTypeId!.id)); } Utils.showLoading(context); DemoProvider demoProvider = Provider.of(context, listen: false);