From 4f9f76515d53c0942bab3e0fb9ccac1c56fb319b Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Thu, 8 Jan 2026 10:20:15 +0300 Subject: [PATCH 01/23] added form design for installation and pullout, handle pullout type task and other improvements --- .../task_request/task_request_model.dart | 83 ++-------- lib/modules/cm_module/cm_detail_page.dart | 8 +- lib/modules/cx_module/chat/chat_widget.dart | 6 +- .../loan_module/models/loan_form_model.dart | 2 - .../loan_installation_pullout_form_model.dart | 25 +++ .../pages/create_loan_request_page.dart | 17 +- .../pages/installation_pullout_form_view.dart | 152 ++++++++++++++++++ .../pages/loan_equipment_detail_page.dart | 103 ++++++------ .../tasks/task_request_detail_view.dart | 2 +- .../tasks/update_task_request_view.dart | 47 +++--- .../task_request_provider.dart | 15 -- 11 files changed, 296 insertions(+), 164 deletions(-) create mode 100644 lib/modules/loan_module/models/loan_installation_pullout_form_model.dart create mode 100644 lib/modules/loan_module/pages/installation_pullout_form_view.dart diff --git a/lib/models/new_models/task_request/task_request_model.dart b/lib/models/new_models/task_request/task_request_model.dart index d1b6dc1a..6d7c9956 100644 --- a/lib/models/new_models/task_request/task_request_model.dart +++ b/lib/models/new_models/task_request/task_request_model.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:test_sa/models/base.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/new_models/assistant_employee.dart'; @@ -83,6 +85,7 @@ class TaskData { String? estimationDeliveryDate; String? reasonOfFSCA; String? correctiveActionDescription; + String? signature; TaskContactUser? evaluatorUser; List? taskJobActivityEngineerTimers = []; TimerModel? taskTimerModel = TimerModel(); @@ -126,6 +129,7 @@ class TaskData { this.alertNo, this.estimationDeliveryDate, this.reasonOfFSCA, + this.signature, this.correctiveActionDescription, this.evaluatorUser, this.taskTimePicker}); @@ -193,6 +197,7 @@ class TaskData { alertNo = json['alertNo']; estimationDeliveryDate = json['estimationDeliveryDate']; reasonOfFSCA = json['reasonOfFSCA']; + signature = json['signature']; correctiveActionDescription = json['correctiveActionDescription']; evaluatorUser = json['evaluatorUser'] != null ? TaskContactUser.fromJson(json['evaluatorUser']) : null; site = json["site"] == null ? null : Site.fromJson(json["site"]); @@ -239,7 +244,7 @@ class TaskData { floor = taskData.floor; department = taskData.department; room = taskData.room; - + signature = taskData.signature; taskTimerModel = taskData.taskTimerModel; totalWorkingHours = taskData.totalWorkingHours; timerModelList = taskData.timerModelList; @@ -350,79 +355,6 @@ class TaskData { return data; } - // Map toJson() { - // final Map data = {}; - // - // data['id'] = id; - // data['statusValue'] = statusValue; - // data['taskJobNo'] = taskJobNo; - // - // if (userCreated != null) { - // data['userCreated'] = userCreated!.toJson(); - // } - // - // if (taskJobContactPersons != null) { - // data['taskJobContactPersons'] = taskJobContactPersons!.map((e) => e.toJson()).toList(); - // } - // - // if (taskType != null) { - // data['taskType'] = taskType!.toJson(); - // } - // - // if (taskJobStatus != null) { - // data['taskJobStatus'] = taskJobStatus!.toJson(); - // } - // - // data['asset'] = asset?.toJson(); - // data['site'] = site; - // data['building'] = building; - // data['floor'] = floor; - // data['department'] = department; - // data['room'] = room; - // data['callComment'] = callComment; - // - // if (assignedEngineer != null) { - // data['assignedEngineer'] = assignedEngineer!.toJson(); - // } - // - // if (taskJobAssistantEmployees != null) { - // data['taskJobAssistantEmployees'] = taskJobAssistantEmployees!.map((v) => v.toJson()).toList(); - // } - // if (taskJobHistories != null) { - // data['taskJobHistories'] = taskJobHistories!.map((e) => e.toJson()).toList(); - // } - // if (installationBuilding != null) { - // data['installationBuilding'] = installationBuilding!.toJson(); - // } - // data['installationFloor'] = installationFloor; - // data['installationDepartment'] = installationDepartment; - // data['serialNo'] = serialNo; - // data['installationDate'] = installationDate; - // data['completedAction'] = completedAction; - // data['impactStatus'] = impactStatus; - // data['isUserAcknowledge'] = isUserAcknowledge; - // data['typeOfAlert'] = typeOfAlert; - // data['riskLevel'] = riskLevel; - // data['resource'] = resource; - // data['actionNeeded'] = actionNeeded; - // data['alertNo'] = alertNo; - // data['estimationDeliveryDate'] = estimationDeliveryDate; - // data['reasonOfFSCA'] = reasonOfFSCA; - // data['correctiveActionDescription'] = correctiveActionDescription; - // - // if (evaluatorUser != null) { - // data['evaluatorUser'] = evaluatorUser!.toJson(); - // } - // if (taskJobActivityEngineerTimers != null) { - // data['taskJobActivityEngineerTimers'] = taskJobActivityEngineerTimers!.map((e) => e.toJson()).toList(); - // } - // if (taskJobAttachments != null) { - // data['taskJobAttachments'] = taskJobAttachments?.map((e) => e.toJson()).toList(); - // } - // - // return data; - // } - Map toEngineerUpdateJson() { final Map data = {}; data['id'] = id; @@ -449,6 +381,9 @@ class TaskData { } data['impactStatusId'] = impactStatus?.id; data['isUserAcknowledge'] = isUserAcknowledge; + if (signature != null) { + data['signature'] = signature; + } return data; } } diff --git a/lib/modules/cm_module/cm_detail_page.dart b/lib/modules/cm_module/cm_detail_page.dart index d396e598..997ff44e 100644 --- a/lib/modules/cm_module/cm_detail_page.dart +++ b/lib/modules/cm_module/cm_detail_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -99,6 +101,7 @@ class _CMDetailPageState extends State { CMDetailProvider provider = Provider.of(context, listen: false); int? statusValue = provider.currentWorkOrder?.data?.status?.value; if (statusValue == 2 || statusValue == 3 || statusValue == 5 || statusValue == 6) { + //Need to refactor bad approach calling api inside build getChatToken(moduleId, provider.currentWorkOrder?.data?.workOrderNo ?? ""); return Consumer(builder: (pContext, requestProvider, _) { return IconButton( @@ -135,8 +138,11 @@ class _CMDetailPageState extends State { return const SizedBox(); } else { CMDetailProvider provider = Provider.of(context, listen: false); + //TODO need to verify the check with backend workOrderNextStepEnum int? statusValue = provider.currentWorkOrder?.data?.status?.value; - if (statusValue == 2) { + WorkOrderNextStepEnum? workOrderNextStepEnum = provider.currentWorkOrder?.data?.nextStep?.workOrderNextStepEnum; + log('next step ${workOrderNextStepEnum.toString()}'); + if (statusValue == 2 && workOrderNextStepEnum==WorkOrderNextStepEnum.activity) { return Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6), margin: const EdgeInsets.only(left: 2), diff --git a/lib/modules/cx_module/chat/chat_widget.dart b/lib/modules/cx_module/chat/chat_widget.dart index 4d28bd1b..4924bbf3 100644 --- a/lib/modules/cx_module/chat/chat_widget.dart +++ b/lib/modules/cx_module/chat/chat_widget.dart @@ -40,8 +40,10 @@ class _ChatWidgetState extends State { @override void initState() { super.initState(); - Provider.of(context, listen: false).reset(); - getChatToken(); + WidgetsBinding.instance.addPostFrameCallback((_) { + Provider.of(context, listen: false).reset(); + getChatToken(); + }); } void getChatToken() { diff --git a/lib/modules/loan_module/models/loan_form_model.dart b/lib/modules/loan_module/models/loan_form_model.dart index 79d459ca..d594432c 100644 --- a/lib/modules/loan_module/models/loan_form_model.dart +++ b/lib/modules/loan_module/models/loan_form_model.dart @@ -109,9 +109,7 @@ class LoanAttachments { num? loanId; String? attachmentName; String? attachmentDescription; - LoanAttachments({this.id, this.loanAttachmentTypeId, this.attachmentName, this.loanId, this.attachmentDescription}); - LoanAttachments.fromJson(dynamic json) { id = json['id']; loanAttachmentTypeId = json['loanAttachmentTypeId']; diff --git a/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart b/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart new file mode 100644 index 00000000..11b48644 --- /dev/null +++ b/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart @@ -0,0 +1,25 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:test_sa/modules/loan_module/models/loan_form_model.dart'; + +class LoanInstallationPullOutFormModel { + String? snNo; + DateTime? date; + Uint8List? signature; + List? loanAttachment; + + LoanInstallationPullOutFormModel({ + this.loanAttachment, + }); + + Map toJson() { + //Need to check payload parm they need + return { + 'snNo': snNo, + 'InstallationDate': date?.toIso8601String(), + "loanAttachments": loanAttachment != null ? loanAttachment!.map((v) => v.toJson()).toList() : [], + "signature": signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature!)}" : null, + }; + } +} diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index 32616761..a6f39c0f 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -61,6 +61,15 @@ class _CreateLoanRequestPageState extends State with Tick Provider.of(context, listen: false).reset(); Provider.of(context, listen: false).reset(); loanTypes = [Lookup(id: 0, name: "Standard", value: 1), Lookup(id: 1, name: "Backup", value: 2)]; + + if(isBackUpRequest){ + fillSiteDeptInfo(); + } + } + + void fillSiteDeptInfo (){ + _loanFormModel.mappedSite = MappedSite.fromJson(widget.workOrder!.site!.toJson()); + _loanFormModel.mappedDepartment = TrafDepartment.fromJson(widget.workOrder!.department!.toJson()); } @override @@ -94,7 +103,7 @@ class _CreateLoanRequestPageState extends State with Tick 'Asset Information'.addTranslation.bodyText(context).custom(color: AppColor.black10), 8.height, Text( - '${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}', + '${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( @@ -106,11 +115,11 @@ class _CreateLoanRequestPageState extends State with Tick style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - '${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace?.capitalizeFirstOfEach}', + '${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - '${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace?.capitalizeFirstOfEach}', + '${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), 16.height, @@ -274,6 +283,7 @@ class _CreateLoanRequestPageState extends State with Tick title: context.translation.site, initialValue: _loanFormModel.mappedSite, showShadow: false, + enabled: !isBackUpRequest, validator: (value) { if (value == null) return "Please select a site"; return null; @@ -295,6 +305,7 @@ class _CreateLoanRequestPageState extends State with Tick context: context, title: context.translation.department, showShadow: false, + enabled: !isBackUpRequest, validator: (value) { if (value == null) return "Please select a department"; return null; diff --git a/lib/modules/loan_module/pages/installation_pullout_form_view.dart b/lib/modules/loan_module/pages/installation_pullout_form_view.dart new file mode 100644 index 00000000..a0379ee2 --- /dev/null +++ b/lib/modules/loan_module/pages/installation_pullout_form_view.dart @@ -0,0 +1,152 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/generic_attachment_model.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/modules/loan_module/models/loan_installation_pullout_form_model.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; +import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; +import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; + +class InstallationPullOutFormView extends StatefulWidget { + final bool isPullout; + const InstallationPullOutFormView({super.key,required this.isPullout}); + + @override + State createState() => _InstallationPullOutFormViewState(); +} + +class _InstallationPullOutFormViewState extends State { + final _formKey = GlobalKey(); + final _snController = TextEditingController(); + List _attachments = []; + final _formData = LoanInstallationPullOutFormModel(); + + @override + void dispose() { + _snController.dispose(); + super.dispose(); + } + + void _pickInstallationDate(DateTime date) async { + final time = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ); + if (time == null) return; + setState(() { + _formData.date = DateTime( + date.year, + date.month, + date.day, + time.hour, + time.minute, + ); + }); + } + + void _onSignatureChanged(Uint8List signature) { + if (signature.isEmpty) return; + setState(() { + _formData.signature = signature; + }); + } + + void _submitForm() { + if (!_formKey.currentState!.validate()) return; + //Validation if required . + + // if (_formData.date == null) { + // context.showSnackBar('Please select installation date'); + // return; + // } + // + // if (_formData.signature == null || _formData.signature!.isEmpty) { + // context.showSnackBar('Signature is required'); + // return; + // } + + _formData.snNo = _snController.text; + + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: DefaultAppBar(title: 'Installation Report'.addTranslation), + body: SafeArea( + child: Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if(widget.isPullout==false)...[ + AppTextFormField( + controller: _snController, + labelText: context.translation.snNo, + backgroundColor: AppColor.fieldBgColor(context), + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + hintStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.text, + textInputAction: TextInputAction.next, + showShadow: false, + validator: (v) => + (v == null || v.isEmpty) ? 'Required' : null, + ), + 8.height, + ], + ADatePicker( + label: widget.isPullout?"Installation Date".addTranslation:"Installation Date".addTranslation, + hideShadow: true, + backgroundColor: AppColor.fieldBgColor(context), + to: DateTime.now().add(const Duration(days: 365)), + formatDateWithTime: true, + onDatePicker: _pickInstallationDate, + ), + 8.height, + ESignature( + title: 'End-user signature'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + oldSignature:'', + newSignature: _formData.signature, + onChange: _onSignatureChanged, + ), + 24.height, + AttachmentPicker( + label: context.translation.attachments, + attachment: _attachments, + ), + ], + ).toShadowContainer(context, borderRadius: 20), + ).expanded, + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + buttonColor: AppColor.primary10, + label: context.translation.submitRequest, + onPressed: _submitForm, + ), + ), + ], + ), + ), + ), + ); + } +} + diff --git a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart index f9ed2c0e..1878a1fe 100644 --- a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart +++ b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; @@ -9,23 +7,17 @@ import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; -import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart'; -import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_data_model.dart'; -import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/update_equipment_internal_audit_page.dart'; -import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/update_system_internal_audit_page.dart'; -import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart'; import 'package:test_sa/modules/loan_module/models/loan_attachment_model.dart'; import 'package:test_sa/modules/loan_module/provider/loan_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; - -import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; import '../models/loan_request_model.dart'; +import 'installation_pullout_form_view.dart'; class LoanEquipmentDetailPage extends StatelessWidget { static const String id = "/loan-equipment-detail-page"; @@ -46,50 +38,69 @@ class LoanEquipmentDetailPage extends StatelessWidget { List allAttachments = snapshot.data!.loanAttachments!; - return ListView( - padding: const EdgeInsets.all(16), + return Column( children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, + ListView( + padding: const EdgeInsets.all(16), children: [ - Row( + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - StatusLabel( - label: snapshot.data!.loanStatusName!, - textColor: AppColor.getRequestStatusTextColorByName(context, snapshot.data!.loanStatusName!), - backgroundColor: AppColor.getRequestStatusColorByName(context, snapshot.data!.loanStatusName!), - ), - 1.width.expanded, - Text( - snapshot.data!.createdDate?.toServiceRequestCardFormat ?? "-", - textAlign: TextAlign.end, - style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + StatusLabel( + label: snapshot.data!.loanStatusName!, + textColor: AppColor.getRequestStatusTextColorByName(context, snapshot.data!.loanStatusName!), + backgroundColor: AppColor.getRequestStatusColorByName(context, snapshot.data!.loanStatusName!), + ), + 1.width.expanded, + Text( + snapshot.data!.createdDate?.toServiceRequestCardFormat ?? "-", + textAlign: TextAlign.end, + style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + ), + ], ), + 12.height, + ...requesterDetails(context, snapshot.data!), + 12.height, + ...requestDetails(context, snapshot.data!), + 12.height, + ...assetDetails(context, snapshot.data!), + 12.height, + ...installationDetails(context, snapshot.data!), + 12.height, + ...doctorDetails(context, snapshot.data!), + 12.height, + ...vendorDetails(context, snapshot.data!), + if (allAttachments.isNotEmpty) ...[ + const Divider().defaultStyle(context), + Text( + "Attachments".addTranslation, + style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []), + ], ], - ), - 12.height, - ...requesterDetails(context, snapshot.data!), - 12.height, - ...requestDetails(context, snapshot.data!), - 12.height, - ...assetDetails(context, snapshot.data!), - 12.height, - ...installationDetails(context, snapshot.data!), - 12.height, - ...doctorDetails(context, snapshot.data!), - 12.height, - ...vendorDetails(context, snapshot.data!), - if (allAttachments.isNotEmpty) ...[ - const Divider().defaultStyle(context), - Text( - "Attachments".addTranslation, - style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), - ), - FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []), - ], + ).toShadowContainer(context, padding: 12), ], - ).toShadowContainer(context, padding: 12), + ).expanded, + if (context.userProvider.isEngineer&&(snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8)) + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + onPressed: () async { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InstallationPullOutFormView( + isPullout: snapshot.data?.loanStatusValue == 8, + ))); + }, + label: snapshot.data?.loanStatusValue == 5 ? 'Installation Report' : 'PullOut Report', + ), + ) ], ); }), diff --git a/lib/modules/tm_module/tasks/task_request_detail_view.dart b/lib/modules/tm_module/tasks/task_request_detail_view.dart index 91a75fc7..647b7a9b 100644 --- a/lib/modules/tm_module/tasks/task_request_detail_view.dart +++ b/lib/modules/tm_module/tasks/task_request_detail_view.dart @@ -47,10 +47,10 @@ class _TaskRequestDetailsViewState extends State { @override void initState() { + super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { getTaskData(); }); - super.initState(); } @override diff --git a/lib/modules/tm_module/tasks/update_task_request_view.dart b/lib/modules/tm_module/tasks/update_task_request_view.dart index 20b6148e..72fd8ab3 100644 --- a/lib/modules/tm_module/tasks/update_task_request_view.dart +++ b/lib/modules/tm_module/tasks/update_task_request_view.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; @@ -35,6 +36,7 @@ import 'package:test_sa/providers/task_request_provider/task_job_provider.dart'; import 'package:test_sa/providers/task_request_provider/task_request_provider.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @@ -65,6 +67,7 @@ class _UpdateTaskRequestState extends State { String comments = ''; List timerList = []; double totalWorkingHours = 0; + Uint8List? newSignature; @override void initState() { @@ -152,12 +155,24 @@ class _UpdateTaskRequestState extends State { if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[ recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!), ], - // if (previousComments.isNotEmpty) ...[ - // 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50), - // 8.height, + //Not good approach need to use enums .... + if (taskProvider.taskRequestModel?.taskType?.typeName == "PullOut") ...[ + ESignature( + title: "End-user signature", + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + oldSignature: taskProvider.taskRequestModel?.signature, + newSignature: newSignature, + onSaved: (signature) { + newSignature = signature; + if (signature == null || signature.isEmpty) return; + taskProvider.taskRequestModel?.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + 8.height, + ], buildPreviousComments(taskProvider: taskProvider), - // 8.height, - // ], + AppTextFormField( initialValue: "", labelText: context.translation.technicalComment, @@ -186,7 +201,6 @@ class _UpdateTaskRequestState extends State { TaskRequestAssistantEmployeeList( assetId: taskProvider.taskRequestModel?.asset?.id, createdDate: widget.createdDate ?? '', - //widget.requestDetails?.date assistantEmployeeList: taskProvider.taskRequestModel?.taskJobAssistantEmployees, cardPadding: 0, onListChanged: (updatedList) { @@ -233,15 +247,9 @@ class _UpdateTaskRequestState extends State { void _updateTask({required BuildContext context, required int status}) async { TaskRequestProvider taskRequestProvider = Provider.of(context, listen: false); - + _formKey.currentState?.save(); TaskData? taskModel = TaskData.copyWith(taskRequestProvider.taskRequestModel!); - taskModel?.statusValue = status; - - // taskModel.taskTimePicker = taskRequestProvider.taskRequestModel?.taskTimePicker; - // taskModel.totalWorkingHours = taskRequestProvider.taskRequestModel?.totalWorkingHours; - // taskModel.taskTimerModel = taskRequestProvider.taskRequestModel?.taskTimerModel; - // taskModel.timerModelList = taskRequestProvider.taskRequestModel?.timerModelList; - + taskModel.statusValue = status; if (validate(model: taskModel)) { showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); @@ -253,10 +261,10 @@ class _UpdateTaskRequestState extends State { String fileName = CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? ''; taskAttachment.add(TaskJobAttachment(id: item.id, name: fileName)); } - taskModel?.taskJobAttachments = taskAttachment; + taskModel.taskJobAttachments = taskAttachment; - if (taskModel?.taskTimePicker != null) { - int durationInSecond = taskModel!.taskTimePicker!.endAt!.difference(taskModel.taskTimePicker!.startAt!).inSeconds; + if (taskModel.taskTimePicker != null) { + int durationInSecond = taskModel.taskTimePicker!.endAt!.difference(taskModel.taskTimePicker!.startAt!).inSeconds; taskModel.taskJobActivityEngineerTimers?.add( TaskJobActivityEngineerTimer( id: 0, @@ -267,11 +275,10 @@ class _UpdateTaskRequestState extends State { ), ); } - - taskModel?.timerModelList?.forEach((timer) { + taskModel.timerModelList?.forEach((timer) { int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds; taskModel.taskJobActivityEngineerTimers?.add( - TaskJobActivityEngineerTimer ( + TaskJobActivityEngineerTimer( id: 0, startDate: timer.startAt!.toIso8601String(), endDate: timer.endAt?.toIso8601String(), totalWorkingHour: ((durationInSecond) / 60 / 60), comment: timer.comments ?? comments), ); }); diff --git a/lib/providers/task_request_provider/task_request_provider.dart b/lib/providers/task_request_provider/task_request_provider.dart index 1a517d73..72aeb1e9 100644 --- a/lib/providers/task_request_provider/task_request_provider.dart +++ b/lib/providers/task_request_provider/task_request_provider.dart @@ -6,28 +6,13 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; -import 'package:test_sa/controllers/providers/api/hospitals_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; -import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/new_models/building.dart'; import 'package:test_sa/models/new_models/department.dart'; import 'package:test_sa/models/new_models/floor.dart'; import 'package:test_sa/models/new_models/site.dart'; import 'package:test_sa/models/new_models/task_request/task_request_model.dart'; -import 'package:test_sa/models/new_models/task_request/task_type_model.dart'; -import 'package:test_sa/models/service_request/pending_service_request_model.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/models/service_request/service_request_search.dart'; -import 'package:test_sa/models/service_request/spare_parts.dart'; -import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; -import 'package:test_sa/models/service_request/supplier_engineer_model.dart'; import 'package:test_sa/models/timer_model.dart'; - -import '../../models/service_request/search_work_order.dart'; -import '../../models/service_request/wo_call_request.dart'; -import '../../models/user.dart'; import '../../new_views/common_widgets/app_lazy_loading.dart'; class TaskRequestProvider extends ChangeNotifier { From bfb2685c55e5d8915325d931f0d958101f9caef9 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Sun, 11 Jan 2026 14:31:50 +0300 Subject: [PATCH 02/23] added form design for installation and pullout, handle pullout type task and other improvements --- .../loan_installation_pullout_form_model.dart | 15 ++++ .../pages/installation_pullout_form_view.dart | 51 +++++++++-- .../pages/intallation_details_view.dart | 87 +++++++++++++++++++ .../pages/loan_equipment_detail_page.dart | 19 ++-- .../pages/pullout_detail_page.dart | 80 +++++++++++++++++ 5 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 lib/modules/loan_module/pages/intallation_details_view.dart create mode 100644 lib/modules/loan_module/pages/pullout_detail_page.dart diff --git a/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart b/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart index 11b48644..bcbbff31 100644 --- a/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart +++ b/lib/modules/loan_module/models/loan_installation_pullout_form_model.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/modules/loan_module/models/loan_form_model.dart'; class LoanInstallationPullOutFormModel { @@ -8,9 +9,20 @@ class LoanInstallationPullOutFormModel { DateTime? date; Uint8List? signature; List? loanAttachment; + TimerModel? timerModel = TimerModel(); + DateTime? startTime; + DateTime? endTime; + double? totalHours; LoanInstallationPullOutFormModel({ this.loanAttachment, + this.timerModel, + this.snNo, + this.signature, + this.date, + this.startTime, + this.endTime, + this.totalHours, }); Map toJson() { @@ -20,6 +32,9 @@ class LoanInstallationPullOutFormModel { 'InstallationDate': date?.toIso8601String(), "loanAttachments": loanAttachment != null ? loanAttachment!.map((v) => v.toJson()).toList() : [], "signature": signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature!)}" : null, + 'startTime': startTime?.toIso8601String(), + 'endTime': endTime?.toIso8601String(), + 'totalHours': totalHours, }; } } diff --git a/lib/modules/loan_module/pages/installation_pullout_form_view.dart b/lib/modules/loan_module/pages/installation_pullout_form_view.dart index a0379ee2..11a3cbfd 100644 --- a/lib/modules/loan_module/pages/installation_pullout_form_view.dart +++ b/lib/modules/loan_module/pages/installation_pullout_form_view.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -7,6 +8,7 @@ import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/generic_attachment_model.dart'; +import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/loan_module/models/loan_installation_pullout_form_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; @@ -16,10 +18,13 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; +import 'package:test_sa/views/widgets/timer/app_timer.dart'; class InstallationPullOutFormView extends StatefulWidget { final bool isPullout; - const InstallationPullOutFormView({super.key,required this.isPullout}); + final String? createdDate; + + const InstallationPullOutFormView({super.key, required this.isPullout, this.createdDate}); @override State createState() => _InstallationPullOutFormViewState(); @@ -76,13 +81,24 @@ class _InstallationPullOutFormViewState extends State - (v == null || v.isEmpty) ? 'Required' : null, + validator: (v) => (v == null || v.isEmpty) ? 'Required' : null, ), 8.height, ], ADatePicker( - label: widget.isPullout?"Installation Date".addTranslation:"Installation Date".addTranslation, + label: !widget.isPullout ? "Installation Date".addTranslation : "Validation Date".addTranslation, hideShadow: true, backgroundColor: AppColor.fieldBgColor(context), to: DateTime.now().add(const Duration(days: 365)), @@ -118,11 +133,32 @@ class _InstallationPullOutFormViewState extends State URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []), + ], + ], + ).toShadowContainer(context, borderRadius: 20), + ); + } + + Widget detailContent({required BuildContext context, required String label, required String heading}) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + heading.bodyText(context).custom(color: AppColor.neutral120), + 6.height, + //TODO Need to check which value need to show here + label.bodyText(context).custom(color: AppColor.neutral120), + ], + ); + } +} diff --git a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart index 1878a1fe..00dc04eb 100644 --- a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart +++ b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart @@ -8,6 +8,7 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/loan_module/models/loan_attachment_model.dart'; +import 'package:test_sa/modules/loan_module/pages/pullout_detail_page.dart'; import 'package:test_sa/modules/loan_module/provider/loan_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; @@ -86,17 +87,21 @@ class LoanEquipmentDetailPage extends StatelessWidget { ).toShadowContainer(context, padding: 12), ], ).expanded, - if (context.userProvider.isEngineer&&(snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8)) + if (context.userProvider.isEngineer && (snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8)) FooterActionButton.footerContainer( context: context, child: AppFilledButton( onPressed: () async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => InstallationPullOutFormView( - isPullout: snapshot.data?.loanStatusValue == 8, - ))); + if (snapshot.data?.loanStatusValue == 5) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PullOutDetailsPage( + loanData: snapshot.data, + ))); + return; + } + Navigator.push(context, MaterialPageRoute(builder: (context) => const InstallationPullOutFormView(isPullout: false))); }, label: snapshot.data?.loanStatusValue == 5 ? 'Installation Report' : 'PullOut Report', ), diff --git a/lib/modules/loan_module/pages/pullout_detail_page.dart b/lib/modules/loan_module/pages/pullout_detail_page.dart new file mode 100644 index 00000000..09b81048 --- /dev/null +++ b/lib/modules/loan_module/pages/pullout_detail_page.dart @@ -0,0 +1,80 @@ +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/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/loan_module/models/loan_request_model.dart'; +import 'package:test_sa/modules/loan_module/pages/installation_pullout_form_view.dart'; +import 'package:test_sa/modules/loan_module/pages/intallation_details_view.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; + +class PullOutDetailsPage extends StatefulWidget { + final LoanRequestModel? loanData; + + PullOutDetailsPage({Key? key, required this.loanData}) : super(key: key); + + @override + _PullOutDetailsPageState createState() { + return _PullOutDetailsPageState(); + } +} + +class _PullOutDetailsPageState extends State { + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: DefaultAppBar( + title: 'Loan Request'.addTranslation, + ), + body: DefaultTabController( + length: 2, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), + decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)), + child: TabBar( + padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), + labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, + unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, + unselectedLabelStyle: AppTextStyles.bodyText, + labelStyle: AppTextStyles.bodyText, + indicatorPadding: EdgeInsets.zero, + indicatorSize: TabBarIndicatorSize.tab, + dividerColor: Colors.transparent, + indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)), + onTap: (index) { + // setState(() {}); + }, + tabs: [ + Tab(text: 'Installation'.addTranslation, height: 57.toScreenHeight), + Tab(text: 'Pull Out'.addTranslation, height: 57.toScreenHeight), + ], + ), + ), + 12.height, + TabBarView( + children: [ + Align( + alignment: Alignment.topCenter, + child: InstallationDetailsView( + loanData: widget.loanData!, + ), + ), + const InstallationPullOutFormView(isPullout: true), + ], + ).expanded, + ], + ), + )); + } +} From 0908cda2b0786040a57e0637d50740609b5b5758 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Tue, 20 Jan 2026 17:52:33 +0300 Subject: [PATCH 03/23] Ui improvement and delivery inspection new apis implemented --- lib/controllers/api_routes/urls.dart | 2 + .../providers/api/devices_provider.dart | 4 +- .../helper_function.dart | 4 +- .../delivery_inspection_form_model.dart | 6 +- .../technical_inspection_asset_model.dart | 4 + .../pages/asset_delivery_page.dart | 10 +- .../pages/attachment_view.dart | 21 +- .../delivery_inspection_form_view.dart | 203 +++++++----------- .../inpection_bottomsheet.dart | 117 +++++++--- .../end_user_cost_center_list_view.dart | 2 +- ...ate_end_user_cost_center_details_view.dart | 10 +- .../pages/history_log_view.dart | 132 ++++++------ .../status_checklist_view.dart | 14 +- .../technical_inpection_asset_card_view.dart | 5 + .../technical_inspection_lines_list_view.dart | 2 +- .../update_child_asset_view.dart | 31 +-- .../update_parent_asset_view.dart | 49 ++--- ...pdate_technical_inspection_lines_view.dart | 27 +-- .../provider/asset_delivery_provider.dart | 46 ++++ .../common_widgets/app_filled_button.dart | 4 +- .../widgets/e_signature/e_signature.dart | 108 ++++++---- 21 files changed, 434 insertions(+), 367 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 0930ace5..fc41f648 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -412,6 +412,8 @@ class URLs { static get getAssetDeliveryInspectionData => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetAssetDeliveryExternalDeliveryInspectionByDeliveryId'; static get getOracleUserList => '$_baseUrl/AssetDeliveryExternal/GetEmployeesFromOracle'; + static get saveMasterInfoDeliveryInspection => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/SaveMaseterInfoDeliveryInspection'; + static get sendEmailToAddSignature => '$_baseUrl/Signature/SendEmailToAddSignature'; static get getLineFromExternalPo => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetLineFromExternalPo'; static get getCostCenterListToLineDeliveryInspection => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetCostCenterToLineDeliveryInspection'; diff --git a/lib/controllers/providers/api/devices_provider.dart b/lib/controllers/providers/api/devices_provider.dart index ab196c11..bc0e5a61 100644 --- a/lib/controllers/providers/api/devices_provider.dart +++ b/lib/controllers/providers/api/devices_provider.dart @@ -40,7 +40,7 @@ class AssetProvider extends ChangeNotifier { List _devices = []; List _searchDevices = []; - List technicalInspectionAsset= []; + List technicalInspectionAsset = []; List get devices => _devices; @@ -133,8 +133,6 @@ class AssetProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { List equipmentListJson = json.decode(response.body)["data"]; var dList = equipmentListJson.map((asset) => TechnicalInspectionAssetBasicInfoModel.fromJson(asset)).toList() ?? []; - log('dlist ${dList.length}'); - technicalInspectionAsset.addAll(dList); nextPage = true; } else { diff --git a/lib/modules/asset_delivery_module/helper_function.dart b/lib/modules/asset_delivery_module/helper_function.dart index 0cfb122e..f2958ebe 100644 --- a/lib/modules/asset_delivery_module/helper_function.dart +++ b/lib/modules/asset_delivery_module/helper_function.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/attachment_view.dart'; @@ -58,7 +60,7 @@ class HelperFunction { children: [ SingleItemDropDownMenu( context: context, - title: context.translation.reason, + title: 'Attachment Type'.addTranslation, onSelect: (value) { Navigator.pop(context, value); }, diff --git a/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart b/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart index 4d73b496..e15082f7 100644 --- a/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart +++ b/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart @@ -44,13 +44,13 @@ class DeliveryInspectionFormModel { 'deliveryInspectionInspectedDateTo': deliveryInspectionInspectedDateTo?.toIso8601String(), 'totalTime': totalTime, 'deliveryInspectionInspectedBy': inspectedByModel?.name, - "deliveryInspectionInspectedBySignature": inspectedByModel?.signature, + // "deliveryInspectionInspectedBySignature": inspectedByModel?.signature, "deliveryInspectionInspectedByEmail": inspectedByModel?.email, 'deliveryInspectionApprovedBy': approvedByModel?.name, - "deliveryInspectionApprovedBySignature": approvedByModel?.signature, + // "deliveryInspectionApprovedBySignature": approvedByModel?.signature, "deliveryInspectionApprovedByEmail": approvedByModel?.email, "deliveryInspectionThirdApproverBy": thirdApprovalModel?.name, - "deliveryInspectionThirdApproverBySignature": thirdApprovalModel?.signature, + // "deliveryInspectionThirdApproverBySignature": thirdApprovalModel?.signature, "deliveryInspectionThirdApproverByEmail": thirdApprovalModel?.email, }; } diff --git a/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart b/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart index fafcc277..31f2913d 100644 --- a/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart +++ b/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart @@ -14,6 +14,7 @@ class TechnicalInspectionAssetModel { num? id; num? tableItemId; num? lineId; + num? lineNo; num? assetDeliveryInternalDetailAssetId; num? assetDeliveryInternalDetailAssetChildId; num? costCenterId; @@ -47,6 +48,7 @@ class TechnicalInspectionAssetModel { this.tableItemId, this.status, this.lineId, + this.lineNo, this.costCenterId, this.assetNumber, this.assetOrigin, @@ -73,6 +75,7 @@ class TechnicalInspectionAssetModel { TechnicalInspectionAssetModel.fromJson(Map json) { id = json['id']; + lineNo = json['lineNo']; assetDeliveryInternalDetailAssetId = json['assetDeliveryInternalDetailAssetId']; assetDeliveryInternalDetailAssetChildId = json['assetDeliveryInternalDetailAssetChildId']; assetNumber = json['assetNumber']; @@ -106,6 +109,7 @@ class TechnicalInspectionAssetModel { Map toJson() { final Map data = {}; data['id'] = id; + // data['lineNo'] = lineNo; data['assetDeliveryInternalDetailAssetId'] = assetDeliveryInternalDetailAssetId; data['assetDeliveryExternalDeliveryId'] = tableItemId; data['assetDeliveryExternalDetailId'] = lineId; diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart index a4ce0983..28391201 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart @@ -87,13 +87,13 @@ class _AssetDeliveryPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - requestDetailCard(context), - const Divider().defaultStyle(context), + requestDetailCard(context).toShadowContainer(context, borderRadius: 20), + 20.height, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Asset Delivery Table", + "Asset Delivery Table".addTranslation, style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), Row( @@ -130,10 +130,10 @@ class _AssetDeliveryPageState extends State { }), ], ), - 8.height, + 16.height, assetDeliveryTableList(context: context, assetDeliveryProvider: provider), ], - ).toShadowContainer(context, borderRadius: 20), + ), ); }, ), diff --git a/lib/modules/asset_delivery_module/pages/attachment_view.dart b/lib/modules/asset_delivery_module/pages/attachment_view.dart index 2f4020e7..5759ebe8 100644 --- a/lib/modules/asset_delivery_module/pages/attachment_view.dart +++ b/lib/modules/asset_delivery_module/pages/attachment_view.dart @@ -27,10 +27,10 @@ class AssetDeliveryAttachmentView extends StatefulWidget { bool viewOnly = false; final List attachmentList; - AssetDeliveryAttachmentView({ + AssetDeliveryAttachmentView({ super.key, required this.attachmentList, - this.viewOnly=false, + this.viewOnly = false, this.attachmentType, this.tableItemId, }); @@ -106,15 +106,16 @@ class _AssetDeliveryAttachmentViewState extends State ), ]); model = results[0] as DeliveryInspectionFormModel; - setState(() { - isLoading = false; - }); + if (mounted) { + setState(() { + isLoading = false; + }); + } } @override @@ -91,12 +93,6 @@ class _DeliveryInspectionFormViewState extends State Widget build(BuildContext context) { return Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, - // appBar: DefaultAppBar( - // title: 'Delivery Inspection'.addTranslation, - // onBackPress: () { - // Navigator.pop(context); - // }, - // ), body: isLoading ? const CircularProgressIndicator(color: AppColor.primary10).center : Form( @@ -104,51 +100,38 @@ class _DeliveryInspectionFormViewState extends State child: Column( children: [ SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (!viewOnly) ...[inspectionDetailsForm()] else ...[inspectionDetails()], - 8.height, - Text( - 'Total Time'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - Text( - formatInspectionDuration(model.totalTime), - style: AppTextStyles.bodyText2.copyWith( - color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, - ), - ), - - // Text( - // model.totalTime != null ? '${model.totalTime.toString()} hours' : '-', - // style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - // ), - 8.height, - const Divider().defaultStyle(context), - Text( - "Lines", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - linesList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!viewOnly) ...[inspectionDetailsForm()] else ...[inspectionDetails()], + 20.height, + Text( + "Lines", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + linesList(context), + ], + )).expanded, FooterActionButton.footerContainer( context: context, child: !viewOnly ? Column( children: [ - AppFilledButton( - buttonColor: AppColor.primary10, - label: 'Attachments'.addTranslation, - maxWidth: true, - onPressed: () { - HelperFunction.attachmentTap(context: context, assetDeliveryProvider: assetDeliveryProvider!, deliveryTableItemId: widget.deliveryTableModel.id); - }), + Row( + children: [ + AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap).expanded, + 8.width, + AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Attachments'.addTranslation, + maxWidth: true, + onPressed: () { + HelperFunction.attachmentTap(context: context, assetDeliveryProvider: assetDeliveryProvider!, deliveryTableItemId: widget.deliveryTableModel.id); + }).expanded, + ], + ), 16.height, Row( children: [ @@ -247,6 +230,7 @@ class _DeliveryInspectionFormViewState extends State Widget inspectionDetailsForm() { return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ _inspectionTile( title: 'Inspected by'.addTranslation, @@ -264,7 +248,6 @@ class _DeliveryInspectionFormViewState extends State } }, ), - 8.height, _inspectionTile( title: 'Approved by'.addTranslation, @@ -285,13 +268,13 @@ class _DeliveryInspectionFormViewState extends State if (widget.requestModel?.paymentTerm?.value == 2) ...[ 8.height, _inspectionTile( - title: 'Third Approved by'.addTranslation, + title: 'ThirdApprover'.addTranslation, model: model.thirdApprovalModel, isHmg: widget.requestModel?.isHMG == true, onTap: () async { final result = await showInspectionBottomSheet( context, - title: 'Third Approved by'.addTranslation, + title: 'ThirdApprover'.addTranslation, isHmg: widget.requestModel?.isHMG == true, initialModel: model.thirdApprovalModel ?? InspectionPersonModel(), ); @@ -301,57 +284,6 @@ class _DeliveryInspectionFormViewState extends State }, ), ], - - // if (widget.requestModel?.isHMG == true) ...[ - // OracleUserAutoCompleteField( - // clearAfterPick: false, - // initialValue: model.deliveryInspectionInspectedBy ?? '', - // label: 'Inspected by'.addTranslation, - // onPick: (value) { - // model.deliveryInspectionInspectedBy = value.fullName; - // setState(() {}); - // }, - // onChanged: (value) {}, - // ), - // 8.height, - // OracleUserAutoCompleteField( - // clearAfterPick: false, - // initialValue: model.deliveryInspectionApprovedBy ?? '', - // label: 'Approved by'.addTranslation, - // onChanged: (value) {}, - // onPick: (value) { - // model.deliveryInspectionApprovedBy = value.fullName; - // setState(() {}); - // }, - // ), - // ] //No HMG user free text insted of dropdown ... - // else ...[ - // AppTextFormField( - // labelText: 'Inspected by'.addTranslation, - // backgroundColor: AppColor.fieldBgColor(context), - // initialValue: model.deliveryInspectionInspectedBy ?? '', - // textAlign: TextAlign.center, - // labelStyle: AppTextStyles.textFieldLabelStyle, - // showShadow: false, - // onChange: (value) { - // model.deliveryInspectionInspectedBy = value; - // }, - // style: Theme.of(context).textTheme.titleMedium, - // ), - // 8.height, - // AppTextFormField( - // labelText: 'Approved by'.addTranslation, - // backgroundColor: AppColor.fieldBgColor(context), - // initialValue: model.deliveryInspectionApprovedBy ?? '', - // textAlign: TextAlign.center, - // labelStyle: AppTextStyles.textFieldLabelStyle, - // showShadow: false, - // onChange: (value) { - // model.deliveryInspectionApprovedBy = value; - // }, - // style: Theme.of(context).textTheme.titleMedium, - // ), - // ], 8.height, ADatePicker( label: 'Inspected Date/Time From'.addTranslation, @@ -385,7 +317,6 @@ class _DeliveryInspectionFormViewState extends State setState(() {}); }, ), - 8.height, ADatePicker( label: 'Inspected Date/Time To'.addTranslation, @@ -424,8 +355,20 @@ class _DeliveryInspectionFormViewState extends State setState(() {}); }, ), + 8.height, + Text( + 'Total Time'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + formatInspectionDuration(model.totalTime), + style: AppTextStyles.bodyText2.copyWith( + color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, + ), + ), ], - ); + ).toShadowContainer(context, borderRadius: 20, padding: 12); } bool _validateInspectionDates({DateTime? from, DateTime? to}) { @@ -552,8 +495,20 @@ class _DeliveryInspectionFormViewState extends State model.deliveryInspectionInspectedDateTo != null ? model.deliveryInspectionInspectedDateTo!.toString().toServiceRequestDetailsFormat : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), + 8.height, + Text( + 'Total Time'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + formatInspectionDuration(model.totalTime), + style: AppTextStyles.bodyText2.copyWith( + color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, + ), + ), ], - ); + ).toShadowContainer(context, borderRadius: 20, padding: 12); } Widget _inspectionTile({ @@ -603,24 +558,6 @@ class _DeliveryInspectionFormViewState extends State ); } - Future showAttachmentTypePicker() { - return showDialog( - context: context, - builder: (_) { - return AlertDialog( - content: SingleItemDropDownMenu( - context: context, - title: context.translation.reason, - showAsFullScreenDialog: false, - onSelect: (value) { - Navigator.pop(context, value); - }, - ), - ); - }, - ); - } - void _cancelTap() async { showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); await assetDeliveryProvider!.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { @@ -632,6 +569,19 @@ class _DeliveryInspectionFormViewState extends State }); } + void _saveTap() async { + _formKey.currentState!.save(); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + model.assetDeliveryExternalDeliveryId = widget.deliveryTableModel.id; + await assetDeliveryProvider!.saveMasterInfoDeliveryInspection(requestPayload: model.toJson()).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); + } + void _nextTap() { if (widget.deliveryTableModel.isContainsTechnicalInspection == true) { // Navigator.push( @@ -678,8 +628,8 @@ class _DeliveryInspectionFormViewState extends State void _changeStatusTap() async { _formKey.currentState!.save(); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - model.assetDeliveryExternalDeliveryId = widget.deliveryTableModel.id; - await assetDeliveryProvider!.changeDeliveryStatus(requestPayload: model.toJson()).then((status) async { + // await assetDeliveryProvider!.changeDeliveryStatus(requestPayload: model.toJson()).then((status) async { + await assetDeliveryProvider!.changeDeliveryStatus(itemId: widget.deliveryTableModel.id).then((status) async { Navigator.pop(context); if (status) { Navigator.pop(context); @@ -707,6 +657,7 @@ class _DeliveryInspectionFormViewState extends State return InspectionPersonBottomSheet( title: title, isHmg: isHmg, + tableId: widget.deliveryTableModel.id, model: InspectionPersonModel( name: initialModel.name, email: initialModel.email, diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/inpection_bottomsheet.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/inpection_bottomsheet.dart index 434f3382..de928263 100644 --- a/lib/modules/asset_delivery_module/pages/delivery_inspection/inpection_bottomsheet.dart +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/inpection_bottomsheet.dart @@ -2,14 +2,19 @@ import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/dashboard_latest/widgets/app_bar_widget.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/asset_delivery_module/models/inspection_person_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; @@ -17,12 +22,14 @@ class InspectionPersonBottomSheet extends StatefulWidget { final String title; bool isHmg; final InspectionPersonModel model; + int? tableId; InspectionPersonBottomSheet({ super.key, required this.title, required this.isHmg, required this.model, + this.tableId, }); @override @@ -67,7 +74,7 @@ class _InspectionPersonBottomSheetState extends State(context, listen: false); + if (nameController.text.isEmpty) { + return 'Enter Name'.showToast; + } + String type = ''; + if (widget.title.contains('Inspected')) { + type = 'Inspected'; + } else if (widget.title.contains('Approved')) { + type = 'Approved'; + } else if (widget.title.contains('ThirdApprover')) { + type = 'ThirdApprover'; + } + + Map payload = { + "recordId": widget.tableId, + "parameter1": "DeliveryInspection", + "parameter2": type, + "username": nameController.text, + "email": emailController.text + }; + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.sendEmailToAddSignature(requestPayload: payload).then((status) async { + Navigator.pop(context); + if (status) { + 'Email sent successfully'.showToast; + } + }); + + //send email. + }), + ], + ], ), - 12.height, + 8.height, ESignature( title: '', + editable: false, oldSignature: _model.localSignature == null ? _model.signature : null, newSignature: _model.localSignature, backgroundColor: AppColor.neutral100, showShadow: false, - onChange: (signature) { - if (signature.isEmpty) return; - setState(() { - _model.localSignature = signature; - _model.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, - onSaved: (signature) { - if (signature == null || signature.isEmpty) return; - setState(() { - _model.localSignature = signature; - _model.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, + // onChange: (signature) { + // if (signature.isEmpty) return; + // setState(() { + // _model.localSignature = signature; + // _model.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + // }); + // }, + // onSaved: (signature) { + // if (signature == null || signature.isEmpty) return; + // setState(() { + // _model.localSignature = signature; + // _model.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + // }); + // }, ), - 20.height, + 12.height, AppFilledButton( label: context.translation.save, maxWidth: true, diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart index f032d75a..7b9336bc 100644 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart @@ -83,7 +83,7 @@ class _EndUserCostCenterLIstViewState extends State { : Column( children: [ //Refactor this - SingleChildScrollView(padding: const EdgeInsets.all(16), child: linesList(context).toShadowContainer(context, borderRadius: 20, padding: 12)).expanded, + SingleChildScrollView(padding: const EdgeInsets.all(16), child: linesList(context)).expanded, !viewOnly ? FooterActionButton.footerContainer( diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart index 1234a018..3b5d74bb 100644 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart @@ -108,9 +108,7 @@ class _UpdateEndUserCostCenterDetailsViewState extends State createState() => _AssetDeliveryHistoryLogViewState(); } - - - class _AssetDeliveryHistoryLogViewState extends State { List history = []; + bool loading = false; + @override void initState() { WidgetsBinding.instance.addPostFrameCallback((_) { @@ -33,10 +33,18 @@ class _AssetDeliveryHistoryLogViewState extends State(context, listen: false).getHistory(tableItemId: widget.tableItemId); + if (mounted) { + setState(() { + loading = false; + }); + } } + @override Widget build(BuildContext context) { return Scaffold( @@ -47,65 +55,64 @@ class _AssetDeliveryHistoryLogViewState extends State(builder: (context, provider, _) { - return provider.isLoading - ? const CircularProgressIndicator(color: AppColor.primary10).center - : Stack( - children: [ - Padding( - padding: EdgeInsets.only(left: 122.toScreenWidth), - child: const VerticalDivider( - color: AppColor.white40, - thickness: 2, - width: 20, - indent: 10, - endIndent: 10, - ), - ), - SafeArea( - child: Builder(builder: (cxt) { - List items = []; - String lastStatus = ""; - DateTime? nextDate; - for (int i = 0; i < history.length; i++) { - var object = history[i]; - String currentStatus = object.status!.name!; - if (lastStatus.isEmpty) { - lastStatus = currentStatus; - } - if (lastStatus == currentStatus) { - if (i + 1 < history.length) { - nextDate = history[i + 1].createdDate; - String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); - object.timeDifference = timeDifference; - } else { - object.timeDifference = ''; // Empty string for the last action + body: loading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Stack( + children: [ + Padding( + padding: EdgeInsets.only(left: 122.toScreenWidth), + child: const VerticalDivider( + color: AppColor.white40, + thickness: 2, + width: 20, + indent: 10, + endIndent: 10, + ), + ), + SafeArea( + child: Builder(builder: (cxt) { + List items = []; + String lastStatus = ""; + DateTime? nextDate; + for (int i = 0; i < history.length; i++) { + var object = history[i]; + String currentStatus = object.status!.name!; + if (lastStatus.isEmpty) { + lastStatus = currentStatus; + } + if (lastStatus == currentStatus) { + if (i + 1 < history.length) { + nextDate = history[i + 1].createdDate; + String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); + object.timeDifference = timeDifference; + } else { + object.timeDifference = ''; // Empty string for the last action + } + items.add(historyLogCard(cxt, object)); + } else { + items.add(statusCard(cxt, lastStatus)); + lastStatus = currentStatus; + if (i + 1 < history.length) { + nextDate = history[i + 1].createdDate; + String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); + object.timeDifference = timeDifference; + } else { + object.timeDifference = ''; // Empty string for the last action + } + items.add(historyLogCard(cxt, object)); + } } - items.add(historyLogCard(cxt, object)); - } else { items.add(statusCard(cxt, lastStatus)); - lastStatus = currentStatus; - if (i + 1 < history.length) { - nextDate = history[i + 1].createdDate; - String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); - object.timeDifference = timeDifference; - } else { - object.timeDifference = ''; // Empty string for the last action - } - items.add(historyLogCard(cxt, object)); - } - } - items.add(statusCard(cxt, lastStatus)); - return SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column(children: items), - ); - }), + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column(children: items), + ); + }), + ), + ], ), - ], - ); - }), - );} + ); + } Widget historyLogCard(BuildContext context, AssetDeliveryHistoryModel object) { String title = object.status!.name!; @@ -148,7 +155,8 @@ class _AssetDeliveryHistoryLogViewState extends State { } Widget inspectionStatusRadioWidget({required int index, required InspectionChecklistItem model, required BuildContext context}) { - bool status = (model.status == null || model.status == null) ? true : (model.status != null ? (model.status == 'true' ? true : false) : false); + bool status = (model.status == null) ? false : (model.status != null ? (model.status == 'true' ? true : false) : false); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( + // ' (${index+1}) ${model.title}', model.title ?? '', - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? Colors.white : AppColor.white936), + softWrap: true, + // maxLines: 1, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? Colors.white : AppColor.white936, height: 1.5), ), - 14.height, + 7.height, // Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ @@ -119,6 +120,7 @@ class _InspectionCheckListViewState extends State { status = !status; model.status = status.toString(); }); + updateStatus(index, status.toString()); }, child: Container( width: 99.toScreenWidth, @@ -158,7 +160,7 @@ class _InspectionCheckListViewState extends State { ), ), ], - ).paddingOnly(top: 4, bottom: 4); + ).paddingOnly(top: 14); } Widget buildToggleOption({ diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart index b09eb878..c609d6ab 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart @@ -66,6 +66,11 @@ class TechnicalInspectionAssetCard extends StatelessWidget { ), 2.height, ], + if (!ischild) + Text( + 'Line No: ${assetModel.lineNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), Text( 'Asset Name: ${assetModel.modelDefinition?.assetName ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart index e2c05093..80b2308a 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart @@ -130,7 +130,7 @@ class _TechnicalInspectionLinesListViewState extends State { inspectionDetailsForm( lineId: widget.lineId, provider: provider, - ), - 8.height, - const Divider().defaultStyle(context), - 8.height, + ).toShadowContainer(context, borderRadius: 20, padding: 12), + 20.height, testLines( context: context, ) ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) + )) .expanded, FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), ], @@ -165,26 +163,7 @@ class _UpdateChildAssetViewState extends State { showShadow: false, enable: false, style: Theme.of(context).textTheme.titleMedium, - ).onPress(() async { - var data = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TechnicalInspectionSearchAssetView( - lineId: lineId, - ))); - if (data != null) { - TechnicalInspectionAssetModel? assetModel = await provider.getAssetDetails(assetId: data?.id); - - if (assetModel != null) { - provider.setChildModel(assetModel); - if (assetModel.site != null) { - await provider.getSiteData(siteId: assetModel.site?.id, model: provider.childFormModel); - } - provider.setParentModel(assetModel); - populateTextFields(model: provider.childFormModel); - } - } - }), + ), 8.height, AppTextFormField( labelText: 'Asset Name'.addTranslation, @@ -415,7 +394,7 @@ class _UpdateChildAssetViewState extends State { orElse: () => InspectionChecklistItem(status: 'FAIL'), ) .status == - 'PASS'; + 'true'; } buildInspectionPayload(List checklist) { diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart index ceafcfe6..41beefcb 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart @@ -114,34 +114,31 @@ class _UpdateParentAssetViewState extends State { : Column( children: [ SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + inspectionDetailsForm(lineId: widget.lineId, provider: provider).toShadowContainer(context, borderRadius: 20, padding: 12), + 20.height, + Row( children: [ - inspectionDetailsForm(lineId: widget.lineId, provider: provider), - 8.height, - const Divider().defaultStyle(context), - 8.height, - Row( - children: [ - Text( - "Test List", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.width, - 'web_link_icon'.toSvgAsset().onPress(() { - openInspectionChecklist(context); - }), - ], + Text( + "Test List", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), - 8.height, - childList( - context: context, - provider: provider, - ) + 8.width, + 'web_link_icon'.toSvgAsset().onPress(() { + openInspectionChecklist(context); + }), ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, + ), + 16.height, + childList( + context: context, + provider: provider, + ) + ], + )).expanded, FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), ], ); @@ -468,7 +465,7 @@ class _UpdateParentAssetViewState extends State { orElse: () => InspectionChecklistItem(status: 'FAIL'), ) .status == - 'PASS'; + 'true'; } buildInspectionPayload(List checklist) { diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart index 035fffe3..9edda2f6 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart @@ -89,24 +89,27 @@ class _UpdateTechnicalInspectionLinesViewState extends State saveMasterInfoDeliveryInspection({ + Map? requestPayload, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.saveMasterInfoDeliveryInspection, body: requestPayload??{}); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } else { + isLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return false; + } + } + + Future sendEmailToAddSignature({ + Map? requestPayload, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.sendEmailToAddSignature, body: requestPayload??{}); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } else { + isLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return false; + } + } + Future getAssetDeliveryInspectionData({int? itemId}) async { isLoading = true; DeliveryInspectionFormModel deliveryInspectionFormModel = DeliveryInspectionFormModel(); diff --git a/lib/new_views/common_widgets/app_filled_button.dart b/lib/new_views/common_widgets/app_filled_button.dart index f543615a..1ab0daf5 100644 --- a/lib/new_views/common_widgets/app_filled_button.dart +++ b/lib/new_views/common_widgets/app_filled_button.dart @@ -18,6 +18,7 @@ class AppFilledButton extends StatelessWidget { final bool showBorder; final double radius; final int height; + final double? width; final bool disableButton; const AppFilledButton( @@ -29,6 +30,7 @@ class AppFilledButton extends StatelessWidget { this.fontSize, this.loading = false, this.height = 56, + this.width, this.showBorder = false, this.disableButton = false, this.buttonColor, @@ -41,7 +43,7 @@ class AppFilledButton extends StatelessWidget { Widget build(BuildContext context) { return Container( height: height.toScreenHeight, - width: maxWidth ? double.infinity : null, + width: maxWidth ? double.infinity : width, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), diff --git a/lib/views/widgets/e_signature/e_signature.dart b/lib/views/widgets/e_signature/e_signature.dart index 71f76ab0..64d297e3 100644 --- a/lib/views/widgets/e_signature/e_signature.dart +++ b/lib/views/widgets/e_signature/e_signature.dart @@ -4,6 +4,7 @@ import 'package:signature/signature.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; @@ -16,10 +17,12 @@ class ESignature extends StatefulWidget { final Function(Uint8List?)? onSaved; final Color? backgroundColor; final Function(Uint8List)? onChange; + final bool editable; final bool showShadow; final String title; - const ESignature({Key? key, required this.title, required this.oldSignature, this.backgroundColor, this.onSaved, this.onChange, this.showShadow = true, required this.newSignature}) + const ESignature( + {Key? key, required this.title, required this.oldSignature, this.backgroundColor, this.onSaved, this.onChange, this.editable = true, this.showShadow = true, required this.newSignature}) : super(key: key); @override @@ -39,7 +42,6 @@ class _ESignatureState extends State { if (widget.newSignature != null) { signature = widget.newSignature; } - super.initState(); } @@ -69,54 +71,70 @@ class _ESignatureState extends State { borderRadius: _editable ? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)) : BorderRadius.circular(10), boxShadow: widget.showShadow ? [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)] : null, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - widget.title.tinyFont(context).paddingOnly(top: 8), - (!_editable - ? "edit".toSvgAsset(width: 48).paddingOnly(top: 8) - : Container( - width: 48.toScreenWidth, - height: 48.toScreenWidth, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(color: AppColor.neutral30)), - padding: const EdgeInsets.all(11), - margin: const EdgeInsets.only(top: 8), - child: "done".toSvgAsset(width: 26), - )) - .onPress(() async { - if (_editable) { - signature = await _controller!.toPngBytes(); - if (widget.onChange != null && signature != null) { - widget.onChange!(signature!); - } - } - _editable = !_editable; - setState(() {}); - }), - ], - ), - ((widget.oldSignature != null || signature != null) && !_editable) - ? Container( + child: widget.editable == false + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Signature'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + Container( height: 135.toScreenHeight, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.only(bottom: 8), child: signature != null ? Image.memory(signature!) : ImageLoader(showDefaultIcon: true, boxFit: BoxFit.contain, url: URLs.getFileUrl(widget.oldSignature) ?? ''), - ) - : AbsorbPointer( - absorbing: !_editable, - child: Signature( - controller: _controller!, - height: 135.toScreenHeight, - width: MediaQuery.of(context).size.width - 64.toScreenWidth, - backgroundColor: Colors.transparent, - ), ), - ], - ), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + widget.title.tinyFont(context).paddingOnly(top: 8), + (!_editable + ? "edit".toSvgAsset(width: 48).paddingOnly(top: 8) + : Container( + width: 48.toScreenWidth, + height: 48.toScreenWidth, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(color: AppColor.neutral30)), + padding: const EdgeInsets.all(11), + margin: const EdgeInsets.only(top: 8), + child: "done".toSvgAsset(width: 26), + )) + .onPress(() async { + if (_editable) { + signature = await _controller!.toPngBytes(); + if (widget.onChange != null && signature != null) { + widget.onChange!(signature!); + } + } + _editable = !_editable; + setState(() {}); + }), + ], + ), + ((widget.oldSignature != null || signature != null) && !_editable) + ? Container( + height: 135.toScreenHeight, + width: MediaQuery.of(context).size.width, + padding: const EdgeInsets.only(bottom: 8), + child: signature != null ? Image.memory(signature!) : ImageLoader(showDefaultIcon: true, boxFit: BoxFit.contain, url: URLs.getFileUrl(widget.oldSignature) ?? ''), + ) + : AbsorbPointer( + absorbing: !_editable, + child: Signature( + controller: _controller!, + height: 135.toScreenHeight, + width: MediaQuery.of(context).size.width - 64.toScreenWidth, + backgroundColor: Colors.transparent, + ), + ), + ], + ), ), if (_editable) Container( From 9b00c0c158e8f586127a8fc9b12c012215595140 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 20 Jan 2026 18:06:21 +0300 Subject: [PATCH 04/23] improvements --- .../delivery_inspection_form_view.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart index c3acbdf4..2ac68d13 100644 --- a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart @@ -121,8 +121,6 @@ class _DeliveryInspectionFormViewState extends State children: [ Row( children: [ - AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap).expanded, - 8.width, AppFilledButton( buttonColor: AppColor.primary10, label: 'Attachments'.addTranslation, @@ -130,9 +128,11 @@ class _DeliveryInspectionFormViewState extends State onPressed: () { HelperFunction.attachmentTap(context: context, assetDeliveryProvider: assetDeliveryProvider!, deliveryTableItemId: widget.deliveryTableModel.id); }).expanded, + 12.width, + AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap).expanded, ], ), - 16.height, + 12.height, Row( children: [ AppFilledButton( @@ -521,7 +521,7 @@ class _DeliveryInspectionFormViewState extends State onTap: onTap, borderRadius: BorderRadius.circular(12), child: Container( - padding: const EdgeInsets.all(14), + padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.fieldBgColor(context), borderRadius: BorderRadius.circular(12), @@ -530,6 +530,7 @@ class _DeliveryInspectionFormViewState extends State children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ Text(title, style: AppTextStyles.textFieldLabelStyle), 6.height, From e544fc640e3580dd8aaf30aa1b0b2e95e2f9e6d0 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 21 Jan 2026 17:06:13 +0300 Subject: [PATCH 05/23] add 0 in gas refill --- lib/modules/tm_module/gas_refill/update_gas_refill_request.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart b/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart index 7f0fc8c3..5184dd54 100644 --- a/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart +++ b/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart @@ -63,6 +63,7 @@ class _UpdateGasRefillRequestState extends State { List timerList = []; static List deliveredQuantity = [ + Lookup(name: "0", id: 0, value: 0), Lookup(name: "1", id: 1, value: 1), Lookup(name: "2", id: 2, value: 2), Lookup(name: "3", id: 3, value: 3), From 9704c26af9cdc510d2d5f1b2b33a66db3bb8de8d Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Sun, 25 Jan 2026 10:04:40 +0300 Subject: [PATCH 06/23] confirmation dialoge added for cancel request --- .../helper_function.dart | 25 +++++++++++ .../pages/asset_delivery_page.dart | 44 ++++++++++++------- .../delivery_inspection_form_view.dart | 30 +++++++++---- .../end_user_cost_center_list_view.dart | 17 +++---- .../technical_inspection_lines_list_view.dart | 17 +++---- 5 files changed, 92 insertions(+), 41 deletions(-) diff --git a/lib/modules/asset_delivery_module/helper_function.dart b/lib/modules/asset_delivery_module/helper_function.dart index f2958ebe..2f6f9399 100644 --- a/lib/modules/asset_delivery_module/helper_function.dart +++ b/lib/modules/asset_delivery_module/helper_function.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/string_extensions.dart'; @@ -9,6 +10,7 @@ import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_pr import 'package:test_sa/modules/asset_delivery_module/provider/attachment_type_provider.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +import 'package:test_sa/new_views/swipe_module/dialoge/acknowledge_work_dialog.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; class HelperFunction { @@ -39,6 +41,29 @@ class HelperFunction { } } + static void cancelRequest({required BuildContext context, int ?itemId, int? requestId}) async { + AssetDeliveryProvider assetDeliveryProvider = Provider.of(context, listen: false); + showDialog( + context: context, + builder: (BuildContext cxt) => AcknowledgeWorkDialog( + message: "Are you sure you want to change this request status to cancel ", + confirmButtonText: 'Ok', + cancelButtonText: 'Cancel', + onSave: () async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.changeDeliveryStatusToCancel(itemId: itemId).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider.getAssetDeliveryTableListById(requestId: requestId); + } + }); + }, + onDiscard: () {}, + ), + ); + } + static Future showAttachmentTypeBottomSheet(BuildContext context) { return showModalBottomSheet( context: context, diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart index 28391201..ff681ee5 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; @@ -5,6 +7,7 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/helper_function.dart'; import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_stage_tab_page.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart'; @@ -210,16 +213,8 @@ class _AssetDeliveryPageState extends State { style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, - //Need to verify this with backend ... - // widget.poInternal?? '-', Text( - dataModel?.isHMG == true - ? dataModel?.poNumber != null - ? dataModel!.poNumber.toString() - : '-' - : dataModel?.poNumber != null - ? dataModel!.poNumber.toString() - : '-', + getPOExternal(), style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, @@ -288,6 +283,20 @@ class _AssetDeliveryPageState extends State { ); } + String getPOExternal() { + String poNo = '-'; + if (dataModel?.isHMG == true) { + if (dataModel?.poNumber != null) { + poNo = dataModel!.poNumber.toString(); + } + return poNo; + } + if (dataModel?.purchaseOrderMaster != null) { + poNo = dataModel!.purchaseOrderMaster!.poNumber.toString(); + } + return poNo; + } + Widget assetDeliveryTableList({required BuildContext context, required AssetDeliveryProvider assetDeliveryProvider}) { List assetDeliveryTableList = assetDeliveryProvider.assetDeliveryTableList; return assetDeliveryProvider.isDeliveryTableListLoading @@ -310,14 +319,15 @@ class _AssetDeliveryPageState extends State { AssetDeliveryBottomSheet.changeStatusBottomSheet( context: context, cancelStatusTap: () async { - showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - await assetDeliveryProvider.changeDeliveryStatusToCancel(itemId: model.id).then((status) async { - Navigator.pop(context); - if (status) { - Navigator.pop(context); - await assetDeliveryProvider.getAssetDeliveryTableListById(requestId: widget.requestId); - } - }); + HelperFunction.cancelRequest(context: context, itemId: model.id, requestId: widget.requestId); + // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + // await assetDeliveryProvider.changeDeliveryStatusToCancel(itemId: model.id).then((status) async { + // Navigator.pop(context); + // if (status) { + // Navigator.pop(context); + // await assetDeliveryProvider.getAssetDeliveryTableListById(requestId: widget.requestId); + // } + // }); }, statusChangeTap: () async { showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart index c3acbdf4..a19a59be 100644 --- a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart @@ -9,6 +9,7 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/modules/asset_delivery_module/helper_function.dart'; import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; @@ -28,6 +29,7 @@ import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +import 'package:test_sa/new_views/swipe_module/dialoge/acknowledge_work_dialog.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; @@ -559,14 +561,26 @@ class _DeliveryInspectionFormViewState extends State } void _cancelTap() async { - showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - await assetDeliveryProvider!.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { - Navigator.pop(context); - if (status) { - Navigator.pop(context); - await assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); - } - }); + HelperFunction.cancelRequest(context: context, itemId: widget.deliveryTableModel.id!, requestId: widget.requestModel?.id); + // showDialog( + // context: context, + // builder: (BuildContext cxt) => AcknowledgeWorkDialog( + // message: "Are you sure you want to mark this request as cancel ", + // confirmButtonText: 'Ok', + // cancelButtonText: 'Cancel', + // onSave: () async { + // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + // await assetDeliveryProvider!.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + // Navigator.pop(context); + // if (status) { + // Navigator.pop(context); + // await assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + // } + // }); + // }, + // onDiscard: () {}, + // ), + // ); } void _saveTap() async { diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart index 7b9336bc..0084d570 100644 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart @@ -171,14 +171,15 @@ class _EndUserCostCenterLIstViewState extends State { } void _cancelTap() async { - showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { - Navigator.pop(context); - if (status) { - Navigator.pop(context); - await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); - } - }); + HelperFunction.cancelRequest(context: context, itemId: widget.deliveryTableModel.id!, requestId: widget.requestModel?.id); + // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + // await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + // Navigator.pop(context); + // if (status) { + // Navigator.pop(context); + // await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + // } + // }); } void _changeStatusTap() async { diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart index 80b2308a..0f925ce0 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart @@ -250,14 +250,15 @@ class _TechnicalInspectionLinesListViewState extends State const AppLazyLoading()); - await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { - Navigator.pop(context); - if (status) { - Navigator.pop(context); - await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); - } - }); + HelperFunction.cancelRequest(context: context, itemId: widget.deliveryTableModel.id!, requestId: widget.requestModel?.id); + // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + // await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + // Navigator.pop(context); + // if (status) { + // Navigator.pop(context); + // await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + // } + // }); } void _nextTap() async { From 7c8855c423395d5c15f7ee35774afbd44455f325 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Mon, 26 Jan 2026 16:01:09 +0300 Subject: [PATCH 07/23] bug fixes --- .../create_medical_gas_request_page.dart | 51 ++++++++++--------- .../update_delivery_notes_page.dart | 16 ++++++ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart index 0bbd9e66..0e0dbb53 100644 --- a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart +++ b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart @@ -1,7 +1,7 @@ - import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; @@ -145,25 +145,6 @@ class _CreateMedicalGasRequestPageState extends State( - // context: context, - // title: context.translation.department, - // showShadow: false, - // validator: (value) { - // if (value == null) return "Please select a department"; - // return null; - // }, - // showAsBottomSheet: true, - // initialValue: _medicalGasFormModel.department, - // requestById: context.userProvider.user?.clientId, - // backgroundColor: AppColor.fieldBgColor(context), - // onSelect: (value) { - // _medicalGasFormModel.department = value; - // setState(() {}); - // }, - // ), - // 8.height, SingleItemDropDownMenu( context: context, title: context.translation.supplier, @@ -171,6 +152,10 @@ class _CreateMedicalGasRequestPageState extends State _update({bool isSubmitted = false}) async { + if (!_formKey.currentState!.validate()) return; + _formKey.currentState?.save(); if (medicalGasInfo != null && medicalGasInfo!.attributeInfo!.isNotEmpty) { _medicalGasFormModel.gasRequestDetail = []; for (var item in medicalGasInfo!.attributeInfo!) { @@ -284,15 +285,19 @@ class _CreateMedicalGasRequestPageState extends State const AppLazyLoading()); await medicalGasInspectionProvider.saveMedicalGas(model: _medicalGasFormModel).then((status) async { Navigator.pop(context); if (status) { Navigator.pop(context, true); + AllRequestsProvider allRequestsProvider = Provider.of(context, listen: false); + allRequestsProvider.reset(); + await allRequestsProvider.getAllRequests(context, typeTransaction: 14); } else { //This should be handled from backend. - Fluttertoast.showToast(msg: 'No gas available for selected site', toastLength: Toast.LENGTH_LONG); + Fluttertoast.showToast(msg: 'Something went wrong', toastLength: Toast.LENGTH_LONG); } }); } diff --git a/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart b/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart index 925f5193..9d12a0e6 100644 --- a/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart +++ b/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart @@ -340,6 +340,22 @@ class _UpdateDeliveryNotesState extends State { right: TextFormField( keyboardType: TextInputType.number, initialValue: model.deliveredQuantity != null ? model.deliveredQuantity?.toStringAsFixed(0) : '', + validator: (value) { + if (value == null || value.trim().isEmpty) { + return "This field is required"; + } + + final intVal = int.tryParse(value); + if (intVal == null) { + return "Enter a valid number"; + } + + if (intVal <= 0) { + return "Value must be greater than 0"; + } + + return null; + }, decoration: InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 5.toScreenWidth), filled: true, From 20b362142c7e84355114900abf0a66f11e95e9ca Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Mon, 26 Jan 2026 16:13:26 +0300 Subject: [PATCH 08/23] bug fixes --- .../create_medical_gas_request_page.dart | 1 + .../models/medical_gas_supplier_model.dart | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart index 0e0dbb53..f5674dad 100644 --- a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart +++ b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart @@ -239,6 +239,7 @@ class _CreateMedicalGasRequestPageState extends State json) { id = json['id']; medicalGasAttributeId = json['medicalGasAttributeId']; requestedQuantity = json['requestedQuantity']; + value = json['value']; itemName = json['itemName']; oracleName = json['oracleName']; oracleCode = json['oracleCode']; From afa165dc3dba78fde9fab09d4d4cb73c3cea59ea Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Tue, 27 Jan 2026 16:49:06 +0300 Subject: [PATCH 09/23] added vendor dropdown along with free text --- lib/controllers/api_routes/urls.dart | 8 +- .../loan_module/models/loan_form_model.dart | 9 ++ .../pages/create_loan_request_page.dart | 152 ++++++++++++------ 3 files changed, 120 insertions(+), 49 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 06d5bff2..2bbf315e 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 = "32"; - static const host1 = "https://atomsm.hmg.com"; // production 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 const host1 = "https://atomsmuat.hmg.com"; // local UAT url // static final String _baseUrl = "$_host/mobile"; // host local UAT - // 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 and for internal audit dev - static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM + // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation static const String chatHubUrl = "https://apiderichat.hmg.com/chathub"; diff --git a/lib/modules/loan_module/models/loan_form_model.dart b/lib/modules/loan_module/models/loan_form_model.dart index d594432c..575dd147 100644 --- a/lib/modules/loan_module/models/loan_form_model.dart +++ b/lib/modules/loan_module/models/loan_form_model.dart @@ -2,6 +2,8 @@ import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/new_models/mapped_sites.dart'; import 'package:test_sa/models/new_models/site.dart'; import 'package:test_sa/models/new_models/traf_department.dart'; +import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; +import 'package:test_sa/models/service_request/supplier_details.dart'; import 'package:test_sa/modules/loan_module/models/medical_department_model.dart'; class LoanFormModel { @@ -12,12 +14,15 @@ class LoanFormModel { String? requestDescription; String? model; String? manufacturer; + bool isNewVendor; Lookup? loanProvided; String? vendorName; String? vendorRepresentativeName; String? vendorNumber; String? vendorEmail; Site? site; + SupplierDetails? supplier; + SuppEngineerWorkOrders? supEngineer; MedicalDepartmentModel? department; List? loanAttachment; MappedSite? mappedSite; @@ -25,6 +30,7 @@ class LoanFormModel { LoanFormModel({ this.docName, + this.isNewVendor=false, this.docNumber, this.docEmail, this.itemDescription, @@ -38,6 +44,8 @@ class LoanFormModel { this.vendorEmail, this.loanAttachment, this.site, + this.supplier, + this.supEngineer, this.department, this.mappedSite, this.mappedDepartment, @@ -94,6 +102,7 @@ class LoanFormModel { "vendorNumber": vendorNumber, "vendorContact": vendorNumber, "vendorEmail": vendorEmail, + "isNewVendor": isNewVendor, // 'siteId': site?.id, 'siteId': mappedSite?.id, // 'departmentId': department?.id, diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index a6f39c0f..a896526d 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -15,6 +15,8 @@ import 'package:test_sa/models/new_models/mapped_sites.dart'; import 'package:test_sa/models/new_models/task_request/task_type_model.dart'; import 'package:test_sa/models/new_models/traf_department.dart'; import 'package:test_sa/models/new_models/work_order_detail_model.dart'; +import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; +import 'package:test_sa/models/service_request/supplier_details.dart'; import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/loan_module/models/loan_form_model.dart'; @@ -28,6 +30,7 @@ import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/lookups/department_lookup_provider.dart'; +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'; @@ -47,9 +50,11 @@ class _CreateLoanRequestPageState extends State with Tick final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); TaskType? selectedType; - final LoanFormModel _loanFormModel = LoanFormModel(); + final LoanFormModel _loanFormModel = LoanFormModel(isNewVendor: false); TextEditingController commentController = TextEditingController(); + TextEditingController vendorPhoneController = TextEditingController(); + TextEditingController vendorEmailController = TextEditingController(); bool get isBackUpRequest => widget.workOrderId != null; @@ -62,14 +67,21 @@ class _CreateLoanRequestPageState extends State with Tick Provider.of(context, listen: false).reset(); loanTypes = [Lookup(id: 0, name: "Standard", value: 1), Lookup(id: 1, name: "Backup", value: 2)]; - if(isBackUpRequest){ + if (isBackUpRequest) { fillSiteDeptInfo(); } } - void fillSiteDeptInfo (){ - _loanFormModel.mappedSite = MappedSite.fromJson(widget.workOrder!.site!.toJson()); - _loanFormModel.mappedDepartment = TrafDepartment.fromJson(widget.workOrder!.department!.toJson()); + @override + void dispose() { + vendorPhoneController.dispose(); + vendorEmailController.dispose(); + super.dispose(); + } + + void fillSiteDeptInfo() { + _loanFormModel.mappedSite = MappedSite.fromJson(widget.workOrder!.site!.toJson()); + _loanFormModel.mappedDepartment = TrafDepartment.fromJson(widget.workOrder!.department!.toJson()); } @override @@ -291,13 +303,12 @@ class _CreateLoanRequestPageState extends State with Tick backgroundColor: AppColor.fieldBgColor(context), showAsBottomSheet: true, onSelect: (value) { - if(value!=null){ + if (value != null) { _loanFormModel.mappedSite = value; _loanFormModel.mappedDepartment = null; - Provider.of(context,listen:false).getData(id:_loanFormModel.mappedSite?.id); + Provider.of(context, listen: false).getData(id: _loanFormModel.mappedSite?.id); setState(() {}); } - }, ), 8.height, @@ -430,44 +441,95 @@ class _CreateLoanRequestPageState extends State with Tick return [ 'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), 8.height, - AppTextFormField( - initialValue: "", - labelText: "Vendor Name", - validator: (value) { - if ((value ?? "").isEmpty) return "Mandatory"; - return null; - }, - style: Theme.of(context).textTheme.titleMedium, - backgroundColor: AppColor.fieldBgColor(context), - labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - showShadow: false, - textInputType: TextInputType.name, - textInputAction: TextInputAction.next, - onChange: (value) { - _loanFormModel.vendorName = value; - }, - ), - 8.height, - AppTextFormField( - initialValue: "", - labelText: "Vendor Representative Name", - validator: (value) { - if ((value ?? "").isEmpty) return "Mandatory"; - return null; - }, - style: Theme.of(context).textTheme.titleMedium, - backgroundColor: AppColor.fieldBgColor(context), - labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - showShadow: false, - textInputType: TextInputType.name, - textInputAction: TextInputAction.next, - onChange: (value) { - _loanFormModel.vendorRepresentativeName = value; - }, - ), + if (!_loanFormModel.isNewVendor) ...[ + SingleItemDropDownMenu( + context: context, + title: 'Vendor Name'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: _loanFormModel.supplier, + showAsBottomSheet: true, + validator: (value) { + if (value == null) return "Please select vendor name"; + return null; + }, + showShadow: false, + showCancel: true, + onSelect: (person) { + _loanFormModel.supplier = person; + _loanFormModel.vendorName = person?.name; + _loanFormModel.supEngineer = null; + _loanFormModel.vendorRepresentativeName = null; + vendorPhoneController.text = person?.contact ?? ''; + vendorEmailController.text = person?.email ?? ''; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + backgroundColor: _loanFormModel.supplier?.suppliername == null + ? context.isDark + ? AppColor.neutral20 + : AppColor.neutral40 + : AppColor.fieldBgColor(context), + title: "Representative Name".addTranslation, + showShadow: false, + validator: (value) { + if (value == null) return "Please select representative name"; + return null; + }, + enabled: _loanFormModel.supplier?.suppPersons?.isNotEmpty ?? false, + staticData: _loanFormModel.supplier?.suppPersons, + showAsBottomSheet: true, + initialValue: _loanFormModel.supEngineer == null ? null : SuppPersons.fromJson(_loanFormModel.supEngineer?.toJson()), + onSelect: (suppPerson) { + if (suppPerson != null) { + _loanFormModel.vendorRepresentativeName = suppPerson.name; + _loanFormModel.supEngineer = SuppEngineerWorkOrders.fromJson(suppPerson.toJson()); + setState(() {}); + } + }, + ), + ] else ...[ + AppTextFormField( + initialValue: "", + labelText: "Vendor Name", + validator: (value) { + if ((value ?? "").isEmpty) return "Mandatory"; + return null; + }, + style: Theme.of(context).textTheme.titleMedium, + backgroundColor: AppColor.fieldBgColor(context), + labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + showShadow: false, + textInputType: TextInputType.name, + textInputAction: TextInputAction.next, + onChange: (value) { + _loanFormModel.vendorName = value; + }, + ), + 8.height, + AppTextFormField( + initialValue: "", + labelText: "Vendor Representative Name", + validator: (value) { + if ((value ?? "").isEmpty) return "Mandatory"; + return null; + }, + style: Theme.of(context).textTheme.titleMedium, + backgroundColor: AppColor.fieldBgColor(context), + labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + showShadow: false, + textInputType: TextInputType.name, + textInputAction: TextInputAction.next, + onChange: (value) { + _loanFormModel.vendorRepresentativeName = value; + }, + ), + ], 8.height, AppTextFormField( - initialValue: "", + controller: vendorPhoneController, labelText: "Vendor Number", validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; @@ -485,7 +547,7 @@ class _CreateLoanRequestPageState extends State with Tick ), 8.height, AppTextFormField( - initialValue: "", + controller: vendorEmailController, labelText: "Vendor Email", validator: (value) { if ((value ?? "").isEmpty) { From 3d77a96fda98b4b12a237ad6e7d9751a110bdbf8 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Wed, 28 Jan 2026 09:42:15 +0300 Subject: [PATCH 10/23] added vendor dropdown along with free text --- .../pages/create_loan_request_page.dart | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index a896526d..b544eb99 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -439,7 +439,42 @@ class _CreateLoanRequestPageState extends State with Tick List vendorDetailsSection() { return [ - 'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + 'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), + Row( + children: [ + Container( + height: 24, + width: 24, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColor.primary10, // or AppColor.blueStatus(context) + ), + alignment: Alignment.center, + child: Icon( + !_loanFormModel.isNewVendor? Icons.add:Icons.search, + color: Colors.white, + size: 16, + ), + ), + 4.width, + Text( + !_loanFormModel.isNewVendor ? "Add new vendor" : "Select existing vendor", + style: AppTextStyles.bodyText.copyWith( + color: context.isDark ? AppColor.neutral30 : AppColor.neutral50, + // decoration: TextDecoration.underline, + ), + ), + ], + ).onPress(() async { + setState(() { + _loanFormModel.isNewVendor = !_loanFormModel.isNewVendor; + }); + }), + ], + ), 8.height, if (!_loanFormModel.isNewVendor) ...[ SingleItemDropDownMenu( From 5a5995306b1a1ede6e9db7ce006e564b79c50f3c Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 28 Jan 2026 09:49:35 +0300 Subject: [PATCH 11/23] improvement. --- lib/modules/asset_delivery_module/helper_function.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/asset_delivery_module/helper_function.dart b/lib/modules/asset_delivery_module/helper_function.dart index 2f6f9399..747c34c6 100644 --- a/lib/modules/asset_delivery_module/helper_function.dart +++ b/lib/modules/asset_delivery_module/helper_function.dart @@ -46,7 +46,7 @@ class HelperFunction { showDialog( context: context, builder: (BuildContext cxt) => AcknowledgeWorkDialog( - message: "Are you sure you want to change this request status to cancel ", + message: "Are you sure you want to change this request status to cancel?", confirmButtonText: 'Ok', cancelButtonText: 'Cancel', onSave: () async { From 8f2e9db0628ad0b15f303a4d3dba7b0da474d681 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 28 Jan 2026 15:22:01 +0300 Subject: [PATCH 12/23] existing loan check api added. --- lib/controllers/api_routes/urls.dart | 1 + lib/modules/cm_module/cm_detail_page.dart | 82 +++++++++++++++---- .../pages/create_loan_request_page.dart | 8 +- .../pages/loan_equipment_detail_page.dart | 38 ++++----- .../loan_module/provider/loan_provider.dart | 13 +++ 5 files changed, 103 insertions(+), 39 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 2bbf315e..f4bf299a 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -390,6 +390,7 @@ class URLs { static get getMedDepartmentBasedOnSite => "$_baseUrl/TRAFDataSource/GetDepartmentBasedOnSite"; static get getLoanById => '$_baseUrl/Loan/GetLoanById'; + static get getLoanByWorkOrderId => '$_baseUrl/Loan/GetLoanByWorkOrderId'; static get addLoan => '$_baseUrl/Loan/AddLoan'; } diff --git a/lib/modules/cm_module/cm_detail_page.dart b/lib/modules/cm_module/cm_detail_page.dart index 15b1b503..452f3138 100644 --- a/lib/modules/cm_module/cm_detail_page.dart +++ b/lib/modules/cm_module/cm_detail_page.dart @@ -6,6 +6,7 @@ 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 'package:test_sa/helper/utils.dart'; import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/work_order_next_step.dart'; import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart'; @@ -16,6 +17,8 @@ import 'package:test_sa/modules/cx_module/chat/chat_provider.dart'; import 'package:test_sa/modules/cx_module/chat/chat_widget.dart'; import 'package:test_sa/modules/cx_module/survey/survey_page.dart'; import 'package:test_sa/modules/loan_module/pages/create_loan_request_page.dart'; +import 'package:test_sa/modules/loan_module/pages/loan_equipment_detail_page.dart'; +import 'package:test_sa/modules/loan_module/provider/loan_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @@ -104,7 +107,9 @@ class _CMDetailPageState extends State { (provider.currentWorkOrder?.data?.workOrderContactPerson?.isNotEmpty ?? false)) { return ChatWidget( moduleId: widget.moduleId, - isShow: context.settingProvider.isUserFlowMedical && (context.userProvider.isEngineer || context.userProvider.isNurse) && provider.currentWorkOrder?.data?.assignedEmployee != null, + isShow: context.settingProvider.isUserFlowMedical && + (context.userProvider.isEngineer || context.userProvider.isNurse) && + provider.currentWorkOrder?.data?.assignedEmployee != null, isReadOnly: _requestProvider.isReadOnlyRequest, requestId: widget.requestId.toInt(), assigneeEmployeeNumber: provider.currentWorkOrder?.data?.assignedEmployee!.employeeId!, @@ -115,23 +120,64 @@ class _CMDetailPageState extends State { return const SizedBox(); } }), - isNurse - ? IconButton( - icon: 'qr'.toSvgAsset( - height: 24, - width: 24, - ), - onPressed: () { - ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context); - }, - ) - : IconButton( - icon: const Icon(Icons.home), - onPressed: () { - // stopTimer(); - Navigator.pop(context); - }, - ), + if (isNurse) + IconButton( + icon: 'qr'.toSvgAsset(height: 24, width: 24), + onPressed: () { + ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context); + }, + ) + else ...[ + Selector( + selector: (_, myModel) => myModel.isLoading, // Selects only the userName + builder: (_, isLoading, __) { + if (isLoading) { + return const SizedBox(); + } else { + CMDetailProvider provider = Provider.of(context, listen: false); + //TODO need to verify the check with backend workOrderNextStepEnum + int? statusValue = provider.currentWorkOrder?.data?.status?.value; + WorkOrderNextStepEnum? workOrderNextStepEnum = provider.currentWorkOrder?.data?.nextStep?.workOrderNextStepEnum; + if (statusValue == 2 && workOrderNextStepEnum == WorkOrderNextStepEnum.activity) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6), + margin: const EdgeInsets.only(left: 2), + decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.add, size: 20, color: AppColor.black1E), + Text( + "Loan", + style: AppTextStyles.bodyText2.copyWith(color: AppColor.black1E), + ), + 4.width, + ], + ), + ).onPress(() async { + LoanProvider loanProvider = Provider.of(context, listen: false); + Utils.showLoading(context); + var data = await loanProvider.getLoanByWorkOrderId(widget.requestId); + Utils.hideLoading(context); + if (data == null) { + CMDetailProvider cmProvider = Provider.of(context, listen: false); + Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: cmProvider.currentWorkOrder!.data))); + } else { + Navigator.push(context, MaterialPageRoute(builder: (context) => LoanEquipmentDetailPage(loanId: data.id!))); + } + }); + } + return const SizedBox(); + } + }), + IconButton( + icon: const Icon(Icons.home), + onPressed: () { + // stopTimer(); + Navigator.pop(context); + }, + ) + ], ], ), body: DefaultTabController( diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index b544eb99..0b2dc53e 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -453,8 +453,8 @@ class _CreateLoanRequestPageState extends State with Tick color: AppColor.primary10, // or AppColor.blueStatus(context) ), alignment: Alignment.center, - child: Icon( - !_loanFormModel.isNewVendor? Icons.add:Icons.search, + child: Icon( + !_loanFormModel.isNewVendor ? Icons.add : Icons.search, color: Colors.white, size: 16, ), @@ -469,6 +469,10 @@ class _CreateLoanRequestPageState extends State with Tick ), ], ).onPress(() async { + _loanFormModel.supplier = null; + _loanFormModel.vendorName = null; + _loanFormModel.supEngineer = null; + _loanFormModel.vendorRepresentativeName = null; setState(() { _loanFormModel.isNewVendor = !_loanFormModel.isNewVendor; }); diff --git a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart index 00dc04eb..8506292c 100644 --- a/lib/modules/loan_module/pages/loan_equipment_detail_page.dart +++ b/lib/modules/loan_module/pages/loan_equipment_detail_page.dart @@ -87,25 +87,25 @@ class LoanEquipmentDetailPage extends StatelessWidget { ).toShadowContainer(context, padding: 12), ], ).expanded, - if (context.userProvider.isEngineer && (snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8)) - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton( - onPressed: () async { - if (snapshot.data?.loanStatusValue == 5) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PullOutDetailsPage( - loanData: snapshot.data, - ))); - return; - } - Navigator.push(context, MaterialPageRoute(builder: (context) => const InstallationPullOutFormView(isPullout: false))); - }, - label: snapshot.data?.loanStatusValue == 5 ? 'Installation Report' : 'PullOut Report', - ), - ) + // if (context.userProvider.isEngineer && (snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8)) + // FooterActionButton.footerContainer( + // context: context, + // child: AppFilledButton( + // onPressed: () async { + // if (snapshot.data?.loanStatusValue == 5) { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => PullOutDetailsPage( + // loanData: snapshot.data, + // ))); + // return; + // } + // Navigator.push(context, MaterialPageRoute(builder: (context) => const InstallationPullOutFormView(isPullout: false))); + // }, + // label: snapshot.data?.loanStatusValue == 5 ? 'Installation Report' : 'PullOut Report', + // ), + // ) ], ); }), diff --git a/lib/modules/loan_module/provider/loan_provider.dart b/lib/modules/loan_module/provider/loan_provider.dart index b2a3a5e3..01153eef 100644 --- a/lib/modules/loan_module/provider/loan_provider.dart +++ b/lib/modules/loan_module/provider/loan_provider.dart @@ -35,4 +35,17 @@ class LoanProvider extends ChangeNotifier { } return loanData; } + + Future getLoanByWorkOrderId(int id) async { + LoanRequestModel? loanData; + try { + Response response = await ApiManager.instance.get(URLs.getLoanByWorkOrderId + "?woId=$id", enableToastMessage: false); + if (response.statusCode >= 200 && response.statusCode < 300) { + loanData = LoanRequestModel.fromJson(json.decode(response.body)["data"]); + } + } catch (error) { + print(error); + } + return loanData; + } } From 1df25cc9ddc24bcaf94f471d7414e15d64460716 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Thu, 29 Jan 2026 17:40:03 +0300 Subject: [PATCH 13/23] validation added for forms --- .../create_medical_gas_request_page.dart | 43 +- .../update_delivery_notes_page.dart | 441 ++++++++++-------- 2 files changed, 264 insertions(+), 220 deletions(-) diff --git a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart index f5674dad..88813f58 100644 --- a/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart +++ b/lib/modules/medical_gas_inspection/create_medical_gas_request_page.dart @@ -45,6 +45,7 @@ class _CreateMedicalGasRequestPageState extends State(context, listen: false).reset(); medicalGasInspectionProvider = Provider.of(context, listen: false); + siteProvider = Provider.of(context, listen: false); _populateFormData(); } _populateFormData() { + if (siteProvider.items.isEmpty) { + siteProvider.reset(); + } if (widget.dataModel != null) { MedicalGasDataModel dataModel = widget.dataModel!; _medicalGasFormModel = MedicalGasFormModel( @@ -97,7 +102,7 @@ class _CreateMedicalGasRequestPageState extends State { late MedicalGasInspectionProvider medicalGasInspectionProvider; bool pressureTestAcknowledgement = false; bool leakTestAcknowledgement = false; + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); // List selectedItemList = []; @@ -56,7 +58,7 @@ class _UpdateDeliveryNotesState extends State { MedicalGasDataModel dataModel = widget.dataModel!; formModel = DeliveryNotesFormModel( id: dataModel.id, - deliveredItemList: dataModel.requestDetailDtos, + deliveredItemList: dataModel.requestDetailDtos.where((item) => item.requestedQuantity! > 0).toList(), isInspectedGasLeak: dataModel.isInspectedGasLeak, isPressureChecked: dataModel.isPressureChecked, deliveredDate: dataModel.deliveredDate, @@ -79,207 +81,210 @@ class _UpdateDeliveryNotesState extends State { // }, ), body: SafeArea( - child: Column( - children: [ - ListView( - padding: const EdgeInsets.all(16), - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ADatePicker( - label: "Delivered Date", - hideShadow: true, - backgroundColor: AppColor.fieldBgColor(context), - from: DateTime.now().subtract(const Duration(days: 365 * 3)), - date: formModel.deliveredDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).then((selectedTime) { - if (selectedTime != null) { - formModel.deliveredDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - setState(() {}); - } - }); - }, - ), - 16.height, - AppTextFormField( - initialValue: formModel.deliveryNoteNumber, - labelText: "Delivery Notes", - validator: (value) { - if ((value ?? "").isEmpty) return "Mandatory"; - return null; - }, - backgroundColor: AppColor.fieldBgColor(context), - labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - showShadow: false, - textInputType: TextInputType.multiline, - makeMultiLinesNull: true, - onChange: (value) { - formModel.deliveryNoteNumber = value; - }, - ), - 16.height, + child: Form( + key: _formKey, + child: Column( + children: [ + ListView( + padding: const EdgeInsets.all(16), + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ADatePicker( + label: "Delivered Date", + hideShadow: true, + backgroundColor: AppColor.fieldBgColor(context), + from: DateTime.now().subtract(const Duration(days: 365 * 3)), + date: formModel.deliveredDate, + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ).then((selectedTime) { + if (selectedTime != null) { + formModel.deliveredDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + setState(() {}); + } + }); + }, + ), + 16.height, + AppTextFormField( + initialValue: formModel.deliveryNoteNumber, + labelText: "Delivery Notes", + // validator: (value) { + // if ((value ?? "").isEmpty) return "Delivery Notes Required"; + // return null; + // }, + backgroundColor: AppColor.fieldBgColor(context), + labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + showShadow: false, + textInputType: TextInputType.multiline, + makeMultiLinesNull: true, + onChange: (value) { + formModel.deliveryNoteNumber = value; + }, + ), + 16.height, - //Older design code - // MultipleItemDropDownMenu( - // context: context, - // showAsBottomSheet: true, - // backgroundColor: AppColor.neutral100, - // showShadow: false, - // showCancel: true, - // requestById: context.userProvider.user?.clientId, - // title: 'Delivered Items'.addTranslation, - // staticData: formModel.deliveredItemList, - // initialValue: selectedItemList, - // onSelect: (value) { - // if ((value ?? []).isNotEmpty) { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // if (!mounted) return; - // setState(() { - // selectedItemList = value ?? []; - // }); - // }); - // } - // }, - // ), - // if (selectedItemList.isNotEmpty) ...[ - // 8.height, - // ListView.separated( - // separatorBuilder: (_, __) => 12.height, - // itemCount: selectedItemList.length, - // shrinkWrap: true, - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (context, index) { - // MedicalGasRequestDetailModel model = selectedItemList[index]; - // return AppTextFormField( - // labelText: '${model.name} (Req Qty =${model.requestedQuantity})', - // hintText: 'Enter Delivered Quantity'.addTranslation, - // backgroundColor: AppColor.fieldBgColor(context), - // initialValue: model.deliveredQuantity != null ? model.deliveredQuantity?.toInt().toString() : '', - // textAlign: TextAlign.center, - // enable: true, - // textInputType: TextInputType.number, - // labelStyle: AppTextStyles.textFieldLabelStyle, - // showShadow: false, - // onChange: (value) { - // if (value.isNotEmpty) { - // model.deliveredQuantity = double.tryParse(value); - // } - // }, - // style: Theme.of(context).textTheme.titleMedium, - // ); - // }, - // ) - // ], - if (formModel.deliveredItemList.isNotEmpty) ...[ - _ItemRowLayout( - left: 'Items'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), - right: 'Delivered Qty'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), + //Older design code + // MultipleItemDropDownMenu( + // context: context, + // showAsBottomSheet: true, + // backgroundColor: AppColor.neutral100, + // showShadow: false, + // showCancel: true, + // requestById: context.userProvider.user?.clientId, + // title: 'Delivered Items'.addTranslation, + // staticData: formModel.deliveredItemList, + // initialValue: selectedItemList, + // onSelect: (value) { + // if ((value ?? []).isNotEmpty) { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // if (!mounted) return; + // setState(() { + // selectedItemList = value ?? []; + // }); + // }); + // } + // }, + // ), + // if (selectedItemList.isNotEmpty) ...[ + // 8.height, + // ListView.separated( + // separatorBuilder: (_, __) => 12.height, + // itemCount: selectedItemList.length, + // shrinkWrap: true, + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (context, index) { + // MedicalGasRequestDetailModel model = selectedItemList[index]; + // return AppTextFormField( + // labelText: '${model.name} (Req Qty =${model.requestedQuantity})', + // hintText: 'Enter Delivered Quantity'.addTranslation, + // backgroundColor: AppColor.fieldBgColor(context), + // initialValue: model.deliveredQuantity != null ? model.deliveredQuantity?.toInt().toString() : '', + // textAlign: TextAlign.center, + // enable: true, + // textInputType: TextInputType.number, + // labelStyle: AppTextStyles.textFieldLabelStyle, + // showShadow: false, + // onChange: (value) { + // if (value.isNotEmpty) { + // model.deliveredQuantity = double.tryParse(value); + // } + // }, + // style: Theme.of(context).textTheme.titleMedium, + // ); + // }, + // ) + // ], + if (formModel.deliveredItemList.isNotEmpty) ...[ + _ItemRowLayout( + left: 'Items'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), + right: 'Delivered Qty'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), + ), + 8.height, + ListView.separated( + separatorBuilder: (_, __) => 12.height, + itemCount: formModel.deliveredItemList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + MedicalGasRequestDetailModel model = formModel.deliveredItemList[index]; + return itemQuantityFieldWidget(index: index, model: model, context: context); + }, + ) + ], + 16.height, + + AttachmentPicker( + label: 'Upload Attachment', + attachment: formModel.attachments, + buttonColor: AppColor.primary10, + // showAsListView: true, + onlyImages: false, + buttonIcon: 'attachment_icon'.toSvgAsset( + color: AppColor.primary10, + ), + ), + 16.height, + //should create a reusable widget. + Row( + children: [ + Checkbox( + value: formModel.isPressureChecked, + visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), + activeColor: AppColor.blueStatus(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (value) { + setState(() { + formModel.isPressureChecked = value!; + }); + }), + 12.width, + "I Acknowledge that the received medical gases cylinders have been tested for pressure." + .addTranslation + .bodyText(context) + .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) + .expanded, + ], ), 8.height, - ListView.separated( - separatorBuilder: (_, __) => 12.height, - itemCount: formModel.deliveredItemList.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - MedicalGasRequestDetailModel model = formModel.deliveredItemList[index]; - return itemQuantityFieldWidget(index: index, model: model, context: context); - }, - ) + Row( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Checkbox( + value: formModel.isInspectedGasLeak, + visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), + activeColor: AppColor.blueStatus(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (value) { + setState(() { + formModel.isInspectedGasLeak = value!; + }); + }), + 12.width, + "I Acknowledge that the received medical gases cylinders have been inspected for leak test." + .addTranslation + .bodyText(context) + .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) + .expanded, + ], + ), ], - 16.height, - - AttachmentPicker( - label: 'Upload Attachment', - attachment: formModel.attachments, + ).toShadowContainer(context, padding: 12), + ], + ).expanded, + FooterActionButton.footerContainer( + context: context, + child: Row( + children: [ + AppFilledButton( buttonColor: AppColor.primary10, - // showAsListView: true, - onlyImages: false, - buttonIcon: 'attachment_icon'.toSvgAsset( - color: AppColor.primary10, - ), - ), - 16.height, - //should create a reusable widget. - Row( - children: [ - Checkbox( - value: formModel.isPressureChecked, - visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), - activeColor: AppColor.blueStatus(context), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onChanged: (value) { - setState(() { - formModel.isPressureChecked = value!; - }); - }), - 12.width, - "I Acknowledge that the received medical gases cylinders have been tested for pressure." - .addTranslation - .bodyText(context) - .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) - .expanded, - ], - ), - 8.height, - Row( - // mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Checkbox( - value: formModel.isInspectedGasLeak, - visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), - activeColor: AppColor.blueStatus(context), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onChanged: (value) { - setState(() { - formModel.isInspectedGasLeak = value!; - }); - }), - 12.width, - "I Acknowledge that the received medical gases cylinders have been inspected for leak test." - .addTranslation - .bodyText(context) - .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) - .expanded, - ], - ), + label: 'Save'.addTranslation, + onPressed: () { + _update(context: context); + }, + // buttonColor: AppColor.primary10, + ).expanded, + 8.width, + AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Submit'.addTranslation, + onPressed: () { + _update(context: context, isSubmitted: true); + }, + // buttonColor: AppColor.primary10, + ).expanded, ], - ).toShadowContainer(context, padding: 12), - ], - ).expanded, - FooterActionButton.footerContainer( - context: context, - child: Row( - children: [ - AppFilledButton( - buttonColor: AppColor.primary10, - label: 'Save'.addTranslation, - onPressed: () { - _update(context: context); - }, - // buttonColor: AppColor.primary10, - ).expanded, - 8.width, - AppFilledButton( - buttonColor: AppColor.primary10, - label: 'Submit'.addTranslation, - onPressed: () { - _update(context: context, isSubmitted: true); - }, - // buttonColor: AppColor.primary10, - ).expanded, - ], + ), ), - ), - ], + ], + ), ), )); // .handlePopScope( @@ -290,6 +295,24 @@ class _UpdateDeliveryNotesState extends State { } void _update({required BuildContext context, bool isSubmitted = false}) async { + if (!_formKey.currentState!.validate()) return; + if (formModel.deliveredDate == null) { + 'Delivered Date Required'.addTranslation.showToast; + return; + } + if (formModel.deliveryNoteNumber == null) { + 'Delivery Notes Required'.addTranslation.showToast; + return; + } + if (formModel.isPressureChecked == null || formModel.isPressureChecked == false) { + 'Please acknowledge cylinders are tested for pressure'.addTranslation.showToast; + return; + } + if (formModel.isInspectedGasLeak == null || formModel.isInspectedGasLeak == false) { + 'Please acknowledge cylinders have been inspected for leak test'.addTranslation.showToast; + return; + } + _formKey.currentState?.save(); formModel.gasDeliveredQuantityDtos = []; formModel.isSubmitted = isSubmitted; for (var item in formModel.deliveredItemList) { @@ -331,7 +354,7 @@ class _UpdateDeliveryNotesState extends State { color: context.isDark ? Colors.white : AppColor.white936, fontWeight: FontWeight.w500, ), - 'Req Qty ${model.requestedQuantity}'.bodyText2(context).custom( + 'Req Qty ${model.requestedQuantity?.toStringAsFixed(0)}'.bodyText2(context).custom( color: context.isDark ? Colors.white : AppColor.white936, fontWeight: FontWeight.w500, ), @@ -357,16 +380,32 @@ class _UpdateDeliveryNotesState extends State { return null; }, decoration: InputDecoration( - contentPadding: EdgeInsets.symmetric(horizontal: 5.toScreenWidth), + isDense: true, + contentPadding: EdgeInsets.symmetric( + horizontal: 5.toScreenWidth, + vertical: 6, // keeps normal height ~30 + ), filled: true, fillColor: AppColor.fieldBgColor(context), - constraints: BoxConstraints( - maxHeight: 30.toScreenHeight, - ), border: border, enabledBorder: border, focusedBorder: border, + errorStyle: const TextStyle( + height: 1.2, // controls extra height when error appears + fontSize: 12, + ), ), + // decoration: InputDecoration( + // contentPadding: EdgeInsets.symmetric(horizontal: 5.toScreenWidth), + // filled: true, + // fillColor: AppColor.fieldBgColor(context), + // constraints: BoxConstraints( + // maxHeight: 40.toScreenHeight, + // ), + // border: border, + // enabledBorder: border, + // focusedBorder: border, + // ), onChanged: (value) { model.deliveredQuantity = int.tryParse(value); }, @@ -387,7 +426,7 @@ class _ItemRowLayout extends StatelessWidget { @override Widget build(BuildContext context) { return Row( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: left), // Items column SizedBox( From 8b2e47df09cd7fef0bc06f35139e18d2ac136402 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 3 Feb 2026 14:50:01 +0300 Subject: [PATCH 14/23] check request type is new, user can change the quantity, improvement. --- .../traf_module/create_traf_request_page.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/modules/traf_module/create_traf_request_page.dart b/lib/modules/traf_module/create_traf_request_page.dart index 66133805..8a7f5435 100644 --- a/lib/modules/traf_module/create_traf_request_page.dart +++ b/lib/modules/traf_module/create_traf_request_page.dart @@ -117,6 +117,7 @@ class _CreateTRAFRequestPageState extends State { // trafRequest?.qty = 0; } else if (requestType?.value == 2) { trafRequest?.assetNDId = null; + trafRequest?.qty = 1; } setState(() {}); }, @@ -133,6 +134,23 @@ class _CreateTRAFRequestPageState extends State { // setState(() {}); }, ), + 12.height, + AppTextFormField( + initialValue: trafRequest?.qty?.toString() ?? "", + makeMultiLinesNull: true, + labelText: "Quantity", + validator: (value) { + if ((value ?? "").isEmpty) return "Mandatory"; + return null; + }, + backgroundColor: AppColor.fieldBgColor(context), + labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + showShadow: false, + textInputType: TextInputType.number, + onChange: (value) { + trafRequest?.qty = int.parse(value); + }, + ), ], if (requestType?.value == 2) ...[ 12.height, From 9dc19354a2cb9b087aa735f5178cebdaa20cb3f3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 10 Feb 2026 11:19:55 +0300 Subject: [PATCH 15/23] hide loan for release --- lib/controllers/api_routes/urls.dart | 4 ++-- .../create_request_type_bottom_sheet.dart | 11 ++++++----- .../my_request/all_requests_filter_page.dart | 16 +++++++++------- .../land_page/my_request/my_requests_page.dart | 18 ++++++++++-------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 20c6305d..aaa1469c 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -7,8 +7,8 @@ class URLs { // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url static const host1 = "https://atomsmuat.hmg.com"; // local UAT url - // static final String _baseUrl = "$_host/mobile"; // host local UAT - static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + static final String _baseUrl = "$_host/mobile"; // host local UAT + // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/mobile"; // host local UAT and for internal audit dev // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation diff --git a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart index f19edb97..d01098a2 100644 --- a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart +++ b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart @@ -117,9 +117,9 @@ class CreateRequestModel { list.add(CreateRequestModel("Equipment Internal Audit Checklist".addTranslation, "add_icon", CreateEquipmentInternalAuditForm.id)); list.add(CreateRequestModel("System Internal Audit Checklist".addTranslation, "add_icon", CreateSystemInternalAuditForm.id)); } - // else if (context.userProvider.isAssessor) { - // list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); - // } + else if (context.userProvider.isAssessor) { + list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + } else if (context.userProvider.isEngineer) { if (Provider.of(context, listen: false).engineerCanCreateCM) { list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateCMRequest.id)); @@ -137,8 +137,9 @@ class CreateRequestModel { list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id)); //TODO uncommit this to enable task. list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); - // list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); - list.add(CreateRequestModel('Loan Equipment Request'.addTranslation, "add_icon", CreateLoanRequestPage.id)); + list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + // Hide Loan + // list.add(CreateRequestModel('Loan Equipment Request'.addTranslation, "add_icon", CreateLoanRequestPage.id)); } return list; } diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index 35253c86..7cb33051 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -74,7 +74,9 @@ class _AllRequestsFilterPageState extends State { context.translation.transferAsset: 3, context.translation.preventiveMaintenance: 4, context.translation.task: 6, - "Loan Equipment": 12, + + // Hide Loan + // "Loan Equipment": 12, }; if (isEngineer) { @@ -95,13 +97,13 @@ class _AllRequestsFilterPageState extends State { } }); //Hide traf - // if (!isEngineer) { - // types['TRAF'] = 9; - // } + if (!isEngineer) { + types['TRAF'] = 9; + } - // if (context.userProvider.isAssessor) { - // types = {"TRAF": 9}; - // } + if (context.userProvider.isAssessor) { + types = {"TRAF": 9}; + } if (context.userProvider.isQualityUser) { if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7}; if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10; diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index e28dca9c..2d1d1c40 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -63,10 +63,10 @@ class _MyRequestsPageState extends State { } }); //Hide TRAF. - // if (context.userProvider.user!.type == UsersTypes.normal_user) { - // requestsList.add(Request(9, 'TRAF')); - // } - if (context.userProvider.isEngineer &&context.settingProvider.isUserFlowMedical) { + if (context.userProvider.user!.type == UsersTypes.normal_user) { + requestsList.add(Request(9, 'TRAF')); + } + if (context.userProvider.isEngineer && context.settingProvider.isUserFlowMedical) { requestsList.add(Request(10, 'Equipment Internal Audit')); requestsList.add(Request(11, 'System Internal Audit')); //Need to be added for new user role commissioning engineer @@ -74,12 +74,14 @@ class _MyRequestsPageState extends State { requestsList.add(Request(14, "Medical Gas Inspection")); } - requestsList.add(Request(12, "Loan Equipment")); + + // Hide Loan + // requestsList.add(Request(12, "Loan Equipment")); if (context.userProvider.isAssessor) { requestsList = [ Request(null, context.translation.allWorkOrder), - // Request(9, 'TRAF'), + Request(9, 'TRAF'), ]; } if (context.userProvider.isCommissioningEngineer) { @@ -93,8 +95,8 @@ class _MyRequestsPageState extends State { requestsList = [ Request(null, context.translation.allWorkOrder), if (context.settingProvider.isUserFlowMedical) Request(7, 'Recall and Alert'), - if (context.settingProvider.isUserFlowMedical) Request(10, 'Equipment Internal Audit'), - if (context.settingProvider.isUserFlowMedical) Request(11, 'System Internal Audit'), + if (context.settingProvider.isUserFlowMedical) Request(10, 'Equipment Internal Audit'), + if (context.settingProvider.isUserFlowMedical) Request(11, 'System Internal Audit'), ]; } From 267a4445d1925dcbe7d751fefe1e71bc747ffa4b Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 10 Feb 2026 12:49:02 +0300 Subject: [PATCH 16/23] ui improvements --- .../widgets/request_category_fragment.dart | 2 +- .../common_widgets/default_app_bar.dart | 45 ++++++++++--------- .../my_request/my_requests_page.dart | 2 +- lib/views/widgets/equipment/asset_picker.dart | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lib/dashboard_latest/widgets/request_category_fragment.dart b/lib/dashboard_latest/widgets/request_category_fragment.dart index 0736fe80..c33e8747 100644 --- a/lib/dashboard_latest/widgets/request_category_fragment.dart +++ b/lib/dashboard_latest/widgets/request_category_fragment.dart @@ -73,7 +73,7 @@ class RequestCategoryFragment extends StatelessWidget { Widget getTabs({required BuildContext context, required DashBoardProvider requestsProvider, required UsersTypes? userType}) { List tabs = CategoryTabs.getTabs(userType: userType ?? UsersTypes.normal_user, context: context); return SizedBox( - height: 44 + (context.isTablet() ? 36 : 16), + height: 44 + (context.isTablet() ? 36 : 16).toScreenHeight, child: ListView.separated( scrollDirection: Axis.horizontal, separatorBuilder: (cxt, index) => 12.width, diff --git a/lib/new_views/common_widgets/default_app_bar.dart b/lib/new_views/common_widgets/default_app_bar.dart index 3b3fcf3f..58ac9631 100644 --- a/lib/new_views/common_widgets/default_app_bar.dart +++ b/lib/new_views/common_widgets/default_app_bar.dart @@ -17,7 +17,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { final VoidCallback? onWillPopScope; final TextStyle? titleStyle; - const DefaultAppBar({this.title, this.onBackPress, this.onWillPopScope, this.actions,this.titleStyle, this.showHomeActionButton = false, this.showBackButton = true, Key? key}) : super(key: key); + const DefaultAppBar({this.title, this.onBackPress, this.onWillPopScope, this.actions, this.titleStyle, this.showHomeActionButton = false, this.showBackButton = true, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -43,30 +43,31 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { titleSpacing: 16, title: Row( children: [ - if(showBackButton) - const Icon(Icons.arrow_back_ios).onPress(() { - if (onWillPopScope != null) { - showDialog( - context: context, - builder: (BuildContext cxt) => AcknowledgeWorkDialog( - onSave: onWillPopScope!, - onDiscard: () { - Navigator.of(cxt).pop(); - }, - ), - ); - return; - } - if (onBackPress != null) { - onBackPress!(); - } else { - Navigator.of(context).pop(); - } - }), + if (showBackButton) + const Icon(Icons.arrow_back_ios).onPress(() { + if (onWillPopScope != null) { + showDialog( + context: context, + builder: (BuildContext cxt) => AcknowledgeWorkDialog( + onSave: onWillPopScope!, + onDiscard: () { + Navigator.of(cxt).pop(); + }, + ), + ); + return; + } + if (onBackPress != null) { + onBackPress!(); + } else { + Navigator.of(context).pop(); + } + }), 10.width, Text( title ?? "", - style:titleStyle?? AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + style: titleStyle ?? + (context.isTablet() ? AppTextStyles.heading4 : AppTextStyles.heading3).copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ).expanded, ], ), diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index 2d1d1c40..8209f2c8 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -114,7 +114,7 @@ class _MyRequestsPageState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Container( - height: 40, + height: 40.toScreenHeight, padding: const EdgeInsets.only(left: 16, right: 8), alignment: Alignment.center, decoration: ShapeDecoration( diff --git a/lib/views/widgets/equipment/asset_picker.dart b/lib/views/widgets/equipment/asset_picker.dart index a57a08f0..d94d0d2b 100644 --- a/lib/views/widgets/equipment/asset_picker.dart +++ b/lib/views/widgets/equipment/asset_picker.dart @@ -62,7 +62,7 @@ class AssetPicker extends StatelessWidget { children: [ if (device == null && deviceList.isEmpty) Container( - height: 50, + height: 50.toScreenHeight, alignment: Alignment.center, decoration: BoxDecoration( color: buttonColor ?? backgroundColor ?? AppColor.blueStatus(context), From df8d22f7925d14102025b85757136e68371105ea Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 10 Feb 2026 15:18:57 +0300 Subject: [PATCH 17/23] chat employee id changes. --- .../medical_gas_inspection_detail_page.dart | 148 ++++--- .../update_delivery_notes_page.dart | 394 +++++++++--------- .../device_transfer_details.dart | 4 +- .../gas_refill/gas_refill_details.dart | 2 +- .../gas_refill/update_gas_refill_request.dart | 1 - .../create_request_type_bottom_sheet.dart | 16 +- .../my_request/all_requests_filter_page.dart | 14 +- .../my_request/my_requests_page.dart | 3 +- 8 files changed, 288 insertions(+), 294 deletions(-) diff --git a/lib/modules/medical_gas_inspection/medical_gas_inspection_detail_page.dart b/lib/modules/medical_gas_inspection/medical_gas_inspection_detail_page.dart index 023af466..9cb704a7 100644 --- a/lib/modules/medical_gas_inspection/medical_gas_inspection_detail_page.dart +++ b/lib/modules/medical_gas_inspection/medical_gas_inspection_detail_page.dart @@ -53,90 +53,88 @@ class _MedicalGasInspectionDetailPageState extends State URLs.getFileUrl(e.name ?? '') ?? '').toList() ?? []), + 1.width.expanded, + Text(model!.requestedDate!.toServiceRequestCardFormat, + textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50)) ], + ), + 8.height, + Text("Request Details", style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50)), + '${context.translation.requestNo}: ${model?.requestNumber ?? '-'}'.bodyText(context), + 'Requested by: ${model?.requestedBy ?? '-'}'.bodyText(context), + if (model?.lastModifiedBy != null) + 'Last Modified by: ${model?.lastModifiedBy ?? '-'}'.bodyText(context), + 'Order Type: ${model?.requestOrderType ?? '-'}'.bodyText(context), + 'Item Type: ${model?.itemType ?? '-'}'.bodyText(context), + 'Site: ${model?.site ?? '-'}'.bodyText(context), + 'Supplier Name: ${model?.supplier ?? '-'}'.bodyText(context), + 'Supplier Contact: ${model?.contact ?? '-'}'.bodyText(context), + 'Supplier Email: ${model?.email ?? '-'}'.bodyText(context), + if (model!.deliveryNoteAttachmentDto.isNotEmpty) ...[ + const Divider().defaultStyle(context), + Text( + "Attachments".addTranslation, + style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + FilesList(images: model!.deliveryNoteAttachmentDto.map((e) => URLs.getFileUrl(e.name ?? '') ?? '').toList() ?? []), ], - ).toShadowContainer(context, padding: 12), - ], - ).expanded, - if (model?.requestStatus?.value != null && model!.requestStatus!.value! < 3) - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton( - buttonColor: AppColor.primary10, - label: model?.isSubmitted == true ? "Upload Delivery Note" : 'Update', - onPressed: () async { - if (model?.isSubmitted == true) { - bool? isRefresh = await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateDeliveryNotes(dataModel: model))); - if (isRefresh == true) { - _loadData(); - } - return; - } - bool? isRefresh = await Navigator.of(context).push(MaterialPageRoute( - builder: (_) => CreateMedicalGasRequestPage( - dataModel: model, - ))); + ], + ).toShadowContainer(context, padding: 12), + ], + ).expanded, + if (model?.requestStatus?.value != null && model!.requestStatus!.value! < 3) + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + buttonColor: AppColor.primary10, + label: model?.isSubmitted == true ? "Upload Delivery Note" : 'Update', + onPressed: () async { + if (model?.isSubmitted == true) { + bool? isRefresh = await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateDeliveryNotes(dataModel: model))); if (isRefresh == true) { _loadData(); } - }), - ), - ], - ), - )); + return; + } + bool? isRefresh = await Navigator.of(context).push(MaterialPageRoute( + builder: (_) => CreateMedicalGasRequestPage( + dataModel: model, + ))); + if (isRefresh == true) { + _loadData(); + } + }), + ), + ], + )); } Widget labelValueText(BuildContext context, String label, String? value) { diff --git a/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart b/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart index 9351070a..45f2e604 100644 --- a/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart +++ b/lib/modules/medical_gas_inspection/update_delivery_notes_page.dart @@ -80,211 +80,209 @@ class _UpdateDeliveryNotesState extends State { // _update(context: context); // }, ), - body: SafeArea( - child: Form( - key: _formKey, - child: Column( - children: [ - ListView( - padding: const EdgeInsets.all(16), - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ADatePicker( - label: "Delivered Date", - hideShadow: true, - backgroundColor: AppColor.fieldBgColor(context), - from: DateTime.now().subtract(const Duration(days: 365 * 3)), - date: formModel.deliveredDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).then((selectedTime) { - if (selectedTime != null) { - formModel.deliveredDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - setState(() {}); - } - }); - }, - ), - 16.height, - AppTextFormField( - initialValue: formModel.deliveryNoteNumber, - labelText: "Delivery Notes", - // validator: (value) { - // if ((value ?? "").isEmpty) return "Delivery Notes Required"; - // return null; - // }, - backgroundColor: AppColor.fieldBgColor(context), - labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), - showShadow: false, - textInputType: TextInputType.multiline, - makeMultiLinesNull: true, - onChange: (value) { - formModel.deliveryNoteNumber = value; - }, - ), - 16.height, - - //Older design code - // MultipleItemDropDownMenu( - // context: context, - // showAsBottomSheet: true, - // backgroundColor: AppColor.neutral100, - // showShadow: false, - // showCancel: true, - // requestById: context.userProvider.user?.clientId, - // title: 'Delivered Items'.addTranslation, - // staticData: formModel.deliveredItemList, - // initialValue: selectedItemList, - // onSelect: (value) { - // if ((value ?? []).isNotEmpty) { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // if (!mounted) return; - // setState(() { - // selectedItemList = value ?? []; - // }); - // }); - // } - // }, - // ), - // if (selectedItemList.isNotEmpty) ...[ - // 8.height, - // ListView.separated( - // separatorBuilder: (_, __) => 12.height, - // itemCount: selectedItemList.length, - // shrinkWrap: true, - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (context, index) { - // MedicalGasRequestDetailModel model = selectedItemList[index]; - // return AppTextFormField( - // labelText: '${model.name} (Req Qty =${model.requestedQuantity})', - // hintText: 'Enter Delivered Quantity'.addTranslation, - // backgroundColor: AppColor.fieldBgColor(context), - // initialValue: model.deliveredQuantity != null ? model.deliveredQuantity?.toInt().toString() : '', - // textAlign: TextAlign.center, - // enable: true, - // textInputType: TextInputType.number, - // labelStyle: AppTextStyles.textFieldLabelStyle, - // showShadow: false, - // onChange: (value) { - // if (value.isNotEmpty) { - // model.deliveredQuantity = double.tryParse(value); - // } - // }, - // style: Theme.of(context).textTheme.titleMedium, - // ); - // }, - // ) - // ], - if (formModel.deliveredItemList.isNotEmpty) ...[ - _ItemRowLayout( - left: 'Items'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), - right: 'Delivered Qty'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), - ), - 8.height, - ListView.separated( - separatorBuilder: (_, __) => 12.height, - itemCount: formModel.deliveredItemList.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - MedicalGasRequestDetailModel model = formModel.deliveredItemList[index]; - return itemQuantityFieldWidget(index: index, model: model, context: context); - }, - ) - ], - 16.height, + body: Form( + key: _formKey, + child: Column( + children: [ + ListView( + padding: const EdgeInsets.all(16), + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ADatePicker( + label: "Delivered Date", + hideShadow: true, + backgroundColor: AppColor.fieldBgColor(context), + from: DateTime.now().subtract(const Duration(days: 365 * 3)), + date: formModel.deliveredDate, + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ).then((selectedTime) { + if (selectedTime != null) { + formModel.deliveredDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + setState(() {}); + } + }); + }, + ), + 16.height, + AppTextFormField( + initialValue: formModel.deliveryNoteNumber, + labelText: "Delivery Notes", + // validator: (value) { + // if ((value ?? "").isEmpty) return "Delivery Notes Required"; + // return null; + // }, + backgroundColor: AppColor.fieldBgColor(context), + labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + showShadow: false, + textInputType: TextInputType.multiline, + makeMultiLinesNull: true, + onChange: (value) { + formModel.deliveryNoteNumber = value; + }, + ), + 16.height, - AttachmentPicker( - label: 'Upload Attachment', - attachment: formModel.attachments, - buttonColor: AppColor.primary10, - // showAsListView: true, - onlyImages: false, - buttonIcon: 'attachment_icon'.toSvgAsset( - color: AppColor.primary10, - ), - ), - 16.height, - //should create a reusable widget. - Row( - children: [ - Checkbox( - value: formModel.isPressureChecked, - visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), - activeColor: AppColor.blueStatus(context), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onChanged: (value) { - setState(() { - formModel.isPressureChecked = value!; - }); - }), - 12.width, - "I Acknowledge that the received medical gases cylinders have been tested for pressure." - .addTranslation - .bodyText(context) - .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) - .expanded, - ], + //Older design code + // MultipleItemDropDownMenu( + // context: context, + // showAsBottomSheet: true, + // backgroundColor: AppColor.neutral100, + // showShadow: false, + // showCancel: true, + // requestById: context.userProvider.user?.clientId, + // title: 'Delivered Items'.addTranslation, + // staticData: formModel.deliveredItemList, + // initialValue: selectedItemList, + // onSelect: (value) { + // if ((value ?? []).isNotEmpty) { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // if (!mounted) return; + // setState(() { + // selectedItemList = value ?? []; + // }); + // }); + // } + // }, + // ), + // if (selectedItemList.isNotEmpty) ...[ + // 8.height, + // ListView.separated( + // separatorBuilder: (_, __) => 12.height, + // itemCount: selectedItemList.length, + // shrinkWrap: true, + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (context, index) { + // MedicalGasRequestDetailModel model = selectedItemList[index]; + // return AppTextFormField( + // labelText: '${model.name} (Req Qty =${model.requestedQuantity})', + // hintText: 'Enter Delivered Quantity'.addTranslation, + // backgroundColor: AppColor.fieldBgColor(context), + // initialValue: model.deliveredQuantity != null ? model.deliveredQuantity?.toInt().toString() : '', + // textAlign: TextAlign.center, + // enable: true, + // textInputType: TextInputType.number, + // labelStyle: AppTextStyles.textFieldLabelStyle, + // showShadow: false, + // onChange: (value) { + // if (value.isNotEmpty) { + // model.deliveredQuantity = double.tryParse(value); + // } + // }, + // style: Theme.of(context).textTheme.titleMedium, + // ); + // }, + // ) + // ], + if (formModel.deliveredItemList.isNotEmpty) ...[ + _ItemRowLayout( + left: 'Items'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), + right: 'Delivered Qty'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), ), 8.height, - Row( - // mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Checkbox( - value: formModel.isInspectedGasLeak, - visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), - activeColor: AppColor.blueStatus(context), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onChanged: (value) { - setState(() { - formModel.isInspectedGasLeak = value!; - }); - }), - 12.width, - "I Acknowledge that the received medical gases cylinders have been inspected for leak test." - .addTranslation - .bodyText(context) - .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) - .expanded, - ], - ), + ListView.separated( + separatorBuilder: (_, __) => 12.height, + itemCount: formModel.deliveredItemList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + MedicalGasRequestDetailModel model = formModel.deliveredItemList[index]; + return itemQuantityFieldWidget(index: index, model: model, context: context); + }, + ) ], - ).toShadowContainer(context, padding: 12), - ], - ).expanded, - FooterActionButton.footerContainer( - context: context, - child: Row( - children: [ - AppFilledButton( - buttonColor: AppColor.primary10, - label: 'Save'.addTranslation, - onPressed: () { - _update(context: context); - }, - // buttonColor: AppColor.primary10, - ).expanded, - 8.width, - AppFilledButton( + 16.height, + + AttachmentPicker( + label: 'Upload Attachment', + attachment: formModel.attachments, buttonColor: AppColor.primary10, - label: 'Submit'.addTranslation, - onPressed: () { - _update(context: context, isSubmitted: true); - }, - // buttonColor: AppColor.primary10, - ).expanded, + // showAsListView: true, + onlyImages: false, + buttonIcon: 'attachment_icon'.toSvgAsset( + color: AppColor.primary10, + ), + ), + 16.height, + //should create a reusable widget. + Row( + children: [ + Checkbox( + value: formModel.isPressureChecked, + visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), + activeColor: AppColor.blueStatus(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (value) { + setState(() { + formModel.isPressureChecked = value!; + }); + }), + 12.width, + "I Acknowledge that the received medical gases cylinders have been tested for pressure." + .addTranslation + .bodyText(context) + .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) + .expanded, + ], + ), + 8.height, + Row( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Checkbox( + value: formModel.isInspectedGasLeak, + visualDensity: const VisualDensity(horizontal: -4.0, vertical: -4.0), + activeColor: AppColor.blueStatus(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (value) { + setState(() { + formModel.isInspectedGasLeak = value!; + }); + }), + 12.width, + "I Acknowledge that the received medical gases cylinders have been inspected for leak test." + .addTranslation + .bodyText(context) + .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120) + .expanded, + ], + ), ], - ), + ).toShadowContainer(context, padding: 12), + ], + ).expanded, + FooterActionButton.footerContainer( + context: context, + child: Row( + children: [ + AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Save'.addTranslation, + onPressed: () { + _update(context: context); + }, + // buttonColor: AppColor.primary10, + ).expanded, + 8.width, + AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Submit'.addTranslation, + onPressed: () { + _update(context: context, isSubmitted: true); + }, + // buttonColor: AppColor.primary10, + ).expanded, + ], ), - ], - ), + ), + ], ), )); // .handlePopScope( diff --git a/lib/modules/tm_module/device_transfer/device_transfer_details.dart b/lib/modules/tm_module/device_transfer/device_transfer_details.dart index 6e843398..9ef3aac9 100644 --- a/lib/modules/tm_module/device_transfer/device_transfer_details.dart +++ b/lib/modules/tm_module/device_transfer/device_transfer_details.dart @@ -228,7 +228,7 @@ class _DeviceTransferDetailsState extends State { requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber, + contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeId ?? _model!.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && isCurrentRequestEditAble) @@ -289,7 +289,7 @@ class _DeviceTransferDetailsState extends State { requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: isSender ? _deviceTransfer.senderAssignedEmployeeNumber! : _deviceTransfer.receiverAssignedEmployeeNumber!, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, + contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeId ?? _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && !isCurrentRequestClosed) diff --git a/lib/modules/tm_module/gas_refill/gas_refill_details.dart b/lib/modules/tm_module/gas_refill/gas_refill_details.dart index c785a6a1..91fac826 100644 --- a/lib/modules/tm_module/gas_refill/gas_refill_details.dart +++ b/lib/modules/tm_module/gas_refill/gas_refill_details.dart @@ -73,7 +73,7 @@ class _GasRefillDetailsPageState extends State { requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, + contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeId ?? _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, ); }) ], diff --git a/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart b/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart index 5184dd54..2084be5a 100644 --- a/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart +++ b/lib/modules/tm_module/gas_refill/update_gas_refill_request.dart @@ -254,7 +254,6 @@ class _UpdateGasRefillRequestState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - 8.height, SingleItemDropDownMenu( context: context, title: context.translation.quantity, diff --git a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart index d01098a2..2f0fdf37 100644 --- a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart +++ b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart @@ -116,11 +116,9 @@ class CreateRequestModel { if (context.userProvider.isQualityUser && context.settingProvider.isUserFlowMedical) { list.add(CreateRequestModel("Equipment Internal Audit Checklist".addTranslation, "add_icon", CreateEquipmentInternalAuditForm.id)); list.add(CreateRequestModel("System Internal Audit Checklist".addTranslation, "add_icon", CreateSystemInternalAuditForm.id)); - } - else if (context.userProvider.isAssessor) { + } else if (context.userProvider.isAssessor) { list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); - } - else if (context.userProvider.isEngineer) { + } else if (context.userProvider.isEngineer) { if (Provider.of(context, listen: false).engineerCanCreateCM) { list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateCMRequest.id)); } @@ -128,16 +126,18 @@ class CreateRequestModel { //TODO uncommit this to enable task. list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); //Need to add check from permission Api. - // if (Provider.of(context, listen: false).engineerCanCreateCM) { - list.add(CreateRequestModel('Medical Gas'.addTranslation, "add_icon", CreateMedicalGasRequestPage.id)); - // } + if ((context.settingProvider.isUserFlowMedical)) { + list.add(CreateRequestModel('Medical Gas'.addTranslation, "add_icon", CreateMedicalGasRequestPage.id)); + } } else { list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateCMRequest.id)); list.add(CreateRequestModel(context.translation.gasRefill, "add_icon", GasRefillRequestForm.routeName)); list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id)); //TODO uncommit this to enable task. list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); - list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + if ((context.settingProvider.isUserFlowMedical)) { + list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + } // Hide Loan // list.add(CreateRequestModel('Loan Equipment Request'.addTranslation, "add_icon", CreateLoanRequestPage.id)); } diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index 7cb33051..bca9e7f6 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -81,9 +81,9 @@ class _AllRequestsFilterPageState extends State { if (isEngineer) { types[context.translation.recurrentWo] = 5; - if (context.settingProvider.isUserFlowMedical) types["Equipment Internal Audit".addTranslation] = 10; - if (context.settingProvider.isUserFlowMedical) types["System Internal Audit".addTranslation] = 11; - if (context.settingProvider.isUserFlowMedical) types["Medical Gas Inspection".addTranslation] = 11; + if (context.settingProvider.isUserFlowMedical) types["Equipment Internal Audit".addTranslation] = 10; + if (context.settingProvider.isUserFlowMedical) types["System Internal Audit".addTranslation] = 11; + if (context.settingProvider.isUserFlowMedical) types["Medical Gas Inspection".addTranslation] = 11; } if (context.settingProvider.isUserFlowMedical && isEngineer) { @@ -97,17 +97,17 @@ class _AllRequestsFilterPageState extends State { } }); //Hide traf - if (!isEngineer) { + if (!isEngineer && context.settingProvider.isUserFlowMedical) { types['TRAF'] = 9; } - if (context.userProvider.isAssessor) { + if (context.settingProvider.isUserFlowMedical && context.userProvider.isAssessor) { types = {"TRAF": 9}; } if (context.userProvider.isQualityUser) { if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7}; - if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10; - if (context.settingProvider.isUserFlowMedical) types['System Internal Audit'] = 11; + if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10; + if (context.settingProvider.isUserFlowMedical) types['System Internal Audit'] = 11; } if (context.userProvider.isCommissioningEngineer) { ///TODO need to check what other requests type needed here. diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index 8209f2c8..dc3f93c5 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -63,7 +63,7 @@ class _MyRequestsPageState extends State { } }); //Hide TRAF. - if (context.userProvider.user!.type == UsersTypes.normal_user) { + if (context.settingProvider.isUserFlowMedical && context.userProvider.user!.type == UsersTypes.normal_user) { requestsList.add(Request(9, 'TRAF')); } if (context.userProvider.isEngineer && context.settingProvider.isUserFlowMedical) { @@ -74,7 +74,6 @@ class _MyRequestsPageState extends State { requestsList.add(Request(14, "Medical Gas Inspection")); } - // Hide Loan // requestsList.add(Request(12, "Loan Equipment")); From f0d79da6db8ec82fee7988db8f298578158f0541 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 10 Feb 2026 16:54:16 +0300 Subject: [PATCH 18/23] release config added. --- lib/controllers/api_routes/urls.dart | 10 +++++----- .../notification/firebase_notification_manger.dart | 7 ++++--- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index aaa1469c..3a10ecd7 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,16 +1,16 @@ class URLs { URLs._(); - static const String appReleaseBuildNumber = "32"; + static const String appReleaseBuildNumber = "33"; - // static const host1 = "https://atomsm.hmg.com"; // production 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 const host1 = "https://atomsmuat.hmg.com"; // local UAT url - static final String _baseUrl = "$_host/mobile"; // host local UAT + // static final String _baseUrl = "$_host/mobile"; // host local UAT // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/mobile"; // host local UAT and for internal audit dev - // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM + static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation // static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module diff --git a/lib/controllers/notification/firebase_notification_manger.dart b/lib/controllers/notification/firebase_notification_manger.dart index 243e8a57..9866be33 100644 --- a/lib/controllers/notification/firebase_notification_manger.dart +++ b/lib/controllers/notification/firebase_notification_manger.dart @@ -16,6 +16,7 @@ import 'package:test_sa/modules/pm_module/recurrent_wo/recurrent_work_order_view import 'package:test_sa/modules/tm_module/device_transfer/device_transfer_details.dart'; import 'package:test_sa/modules/tm_module/tasks/task_request_detail_view.dart'; import 'package:test_sa/modules/tm_module/gas_refill/gas_refill_details.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @pragma('vm:entry-point') @@ -121,7 +122,7 @@ class FirebaseNotificationManger { break; default: - serviceClass = const Scaffold(body: Center(child: NoDataFound())); + serviceClass = const Scaffold(appBar: DefaultAppBar(), body: Center(child: NoDataFound())); } Navigator.of(context).push(MaterialPageRoute(builder: (_) => serviceClass!)); @@ -134,7 +135,7 @@ class FirebaseNotificationManger { // SparePartTransaction= 8, // GasRefill=9, // TechnicalRetirmentWO = 11, - // Recurrent = 12,​ + // Recurrent = 12, switch (transactionType) { case "1": serviceClass = PpmDetailsPage(requestId: int.parse(messageData["requestNumber"].toString())); @@ -172,7 +173,7 @@ class FirebaseNotificationManger { // requestDetails: RequestsDetails(nameOfType: messageData["sourceName"], status: messageData["statusName"], priority: messageData["priorityName"], date: messageData["createdDate"])); // return; default: - serviceClass = const Scaffold(body: Center(child: NoDataFound())); + serviceClass = const Scaffold(appBar: DefaultAppBar(), body: Center(child: NoDataFound())); } // if (messageData["requestType"] == "Service request to engineer") { diff --git a/pubspec.yaml b/pubspec.yaml index 678fdb0f..289e9f21 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.0+32 +version: 1.6.0+33 environment: sdk: ">=3.5.0 <4.0.0" From 2997eef5ad6d27d9a7d9870a593ba05e9070b0d5 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 11 Feb 2026 12:40:21 +0300 Subject: [PATCH 19/23] chat sync fixes. --- lib/modules/cx_module/chat/chat_provider.dart | 2 +- .../tm_module/device_transfer/device_transfer_details.dart | 6 +++--- lib/modules/tm_module/gas_refill/gas_refill_details.dart | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/modules/cx_module/chat/chat_provider.dart b/lib/modules/cx_module/chat/chat_provider.dart index 8d56bcf2..0755d74f 100644 --- a/lib/modules/cx_module/chat/chat_provider.dart +++ b/lib/modules/cx_module/chat/chat_provider.dart @@ -167,7 +167,7 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { if (!readOnly) { await buildHubConnection(chatParticipantModel!.id!.toString()); } - + userChatHistory = null; userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, assigneeEmployeeNumber); chatResponseList = userChatHistory ?? []; chatResponseList.sort((a, b) => b.createdDate!.compareTo(a.createdDate!)); diff --git a/lib/modules/tm_module/device_transfer/device_transfer_details.dart b/lib/modules/tm_module/device_transfer/device_transfer_details.dart index 9ef3aac9..de9da297 100644 --- a/lib/modules/tm_module/device_transfer/device_transfer_details.dart +++ b/lib/modules/tm_module/device_transfer/device_transfer_details.dart @@ -226,9 +226,9 @@ class _DeviceTransferDetailsState extends State { isShow: context.settingProvider.isUserFlowMedical && _model!.senderMachineStatusValue! != 4, isReadOnly: _model!.senderMachineStatusValue! != 1, requestId: widget.model.id!.toInt(), - assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber, + assigneeEmployeeNumber: _model!.senderAssignedEmployeeId, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeId ?? _model!.assetTransferContactPersons!.first.employeeNumber, + contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber ?? _model!.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && isCurrentRequestEditAble) @@ -289,7 +289,7 @@ class _DeviceTransferDetailsState extends State { requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: isSender ? _deviceTransfer.senderAssignedEmployeeNumber! : _deviceTransfer.receiverAssignedEmployeeNumber!, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeId ?? _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, + contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber ?? _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && !isCurrentRequestClosed) diff --git a/lib/modules/tm_module/gas_refill/gas_refill_details.dart b/lib/modules/tm_module/gas_refill/gas_refill_details.dart index 91fac826..e5dec643 100644 --- a/lib/modules/tm_module/gas_refill/gas_refill_details.dart +++ b/lib/modules/tm_module/gas_refill/gas_refill_details.dart @@ -73,7 +73,7 @@ class _GasRefillDetailsPageState extends State { requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, - contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeId ?? _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, + contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, ); }) ], From 31a9296a8e7586f0774c96466f82dbcc5005801a Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 11 Feb 2026 14:57:00 +0300 Subject: [PATCH 20/23] improvements --- lib/controllers/providers/api/all_requests_provider.dart | 4 ++-- .../tm_module/device_transfer/device_transfer_details.dart | 2 +- .../pages/land_page/create_request_type_bottom_sheet.dart | 2 +- .../pages/land_page/my_request/all_requests_filter_page.dart | 2 +- .../pages/land_page/my_request/my_requests_page.dart | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/controllers/providers/api/all_requests_provider.dart b/lib/controllers/providers/api/all_requests_provider.dart index 86579328..7a7f2c0d 100644 --- a/lib/controllers/providers/api/all_requests_provider.dart +++ b/lib/controllers/providers/api/all_requests_provider.dart @@ -163,11 +163,11 @@ class AllRequestsProvider extends ChangeNotifier { } }); - if (context.userProvider.isNurse) { + if (context.settingProvider.isUserFlowMedical && context.userProvider.isNurse) { list.add(9); // } list.add(12); - if (context.userProvider.isCommissioningEngineer) { + if (context.userProvider.isCommissioningEngineer && context.settingProvider.isUserFlowMedical) { list = [13]; } // loan module diff --git a/lib/modules/tm_module/device_transfer/device_transfer_details.dart b/lib/modules/tm_module/device_transfer/device_transfer_details.dart index de9da297..709fde85 100644 --- a/lib/modules/tm_module/device_transfer/device_transfer_details.dart +++ b/lib/modules/tm_module/device_transfer/device_transfer_details.dart @@ -226,7 +226,7 @@ class _DeviceTransferDetailsState extends State { isShow: context.settingProvider.isUserFlowMedical && _model!.senderMachineStatusValue! != 4, isReadOnly: _model!.senderMachineStatusValue! != 1, requestId: widget.model.id!.toInt(), - assigneeEmployeeNumber: _model!.senderAssignedEmployeeId, + assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber, myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber ?? _model!.assetTransferContactPersons!.first.employeeNumber, ), diff --git a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart index 2f0fdf37..b8970b77 100644 --- a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart +++ b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart @@ -116,7 +116,7 @@ class CreateRequestModel { if (context.userProvider.isQualityUser && context.settingProvider.isUserFlowMedical) { list.add(CreateRequestModel("Equipment Internal Audit Checklist".addTranslation, "add_icon", CreateEquipmentInternalAuditForm.id)); list.add(CreateRequestModel("System Internal Audit Checklist".addTranslation, "add_icon", CreateSystemInternalAuditForm.id)); - } else if (context.userProvider.isAssessor) { + } else if (context.userProvider.isAssessor && context.settingProvider.isUserFlowMedical) { list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); } else if (context.userProvider.isEngineer) { if (Provider.of(context, listen: false).engineerCanCreateCM) { diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index bca9e7f6..6a854af3 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -109,7 +109,7 @@ class _AllRequestsFilterPageState extends State { if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10; if (context.settingProvider.isUserFlowMedical) types['System Internal Audit'] = 11; } - if (context.userProvider.isCommissioningEngineer) { + if (context.userProvider.isCommissioningEngineer && context.settingProvider.isUserFlowMedical) { ///TODO need to check what other requests type needed here. types = { 'Asset Delivery': 13, diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index dc3f93c5..e4b0953c 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -83,7 +83,7 @@ class _MyRequestsPageState extends State { Request(9, 'TRAF'), ]; } - if (context.userProvider.isCommissioningEngineer) { + if (context.userProvider.isCommissioningEngineer && context.settingProvider.isUserFlowMedical) { ///TODO need to show only allowed ids for all workOrder requestsList = [ Request(null, context.translation.allWorkOrder), From cdc69fcee091a1f6a5a276bcbcf4e390b57ecaa1 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 11 Feb 2026 15:14:14 +0300 Subject: [PATCH 21/23] asset scan user feedback if not found. --- lib/helper/utils.dart | 4 ++-- lib/views/widgets/qr/asset_scan_qr.dart | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/helper/utils.dart b/lib/helper/utils.dart index f4db3acd..41026321 100644 --- a/lib/helper/utils.dart +++ b/lib/helper/utils.dart @@ -33,11 +33,11 @@ class Utils { static bool get isLoading => _isLoadingVisible; - static void showToast(String message, {bool longDuration = true}) { + static void showToast(String message, {bool longDuration = true, ToastGravity toastGravity = ToastGravity.BOTTOM}) { Fluttertoast.showToast( msg: message, toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT, - gravity: ToastGravity.BOTTOM, + gravity: toastGravity, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, diff --git a/lib/views/widgets/qr/asset_scan_qr.dart b/lib/views/widgets/qr/asset_scan_qr.dart index 39610965..1737b65e 100644 --- a/lib/views/widgets/qr/asset_scan_qr.dart +++ b/lib/views/widgets/qr/asset_scan_qr.dart @@ -1,15 +1,19 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/models/device/asset.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/tm_module/device_transfer/search_device_page.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import '../../../controllers/providers/api/devices_provider.dart'; @@ -32,6 +36,7 @@ class _AssetScanQrState extends State { // Barcode result; QRViewController? _controller; bool _scanDone = false; + bool _scanning = false; final GlobalKey qrKey = GlobalKey(debugLabel: 'QR_scanner'); late AssetProvider _devicesProvider; @@ -93,7 +98,14 @@ class _AssetScanQrState extends State { _scanDone = false; } } else { + _controller?.pauseCamera(); + setState(() { + _scanning = true; + }); final result = await _getDevice(scanData.code!, isQr: true); + setState(() { + _scanning = false; + }); if (result.isNotEmpty) { if (widget.multiSelection) { Navigator.of(context).pop([result[0]]); @@ -101,6 +113,8 @@ class _AssetScanQrState extends State { Navigator.of(context).pop(result[0]); } } else { + Utils.showToast("No Item Found. Try Again", toastGravity: ToastGravity.CENTER); + _controller?.resumeCamera(); _scanDone = false; } } @@ -115,6 +129,14 @@ class _AssetScanQrState extends State { fit: BoxFit.fitHeight, ), ), + if (_scanning) + Container( + width: 56.toScreenHeight, + height: 56.toScreenHeight, + padding: const EdgeInsets.all(8), + decoration: const BoxDecoration(shape: BoxShape.circle, color: Colors.white), + child: const CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 3), + ).center ], ).expanded, if (widget.enablePickManually) From 53a3282da076bf5c2bfcd45081d9aabca5df015b Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 11 Feb 2026 18:46:14 +0300 Subject: [PATCH 22/23] v1.6.0 uploaded on stores --- lib/dashboard_latest/widgets/app_bar_widget.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dashboard_latest/widgets/app_bar_widget.dart b/lib/dashboard_latest/widgets/app_bar_widget.dart index 5134875a..d86a1750 100644 --- a/lib/dashboard_latest/widgets/app_bar_widget.dart +++ b/lib/dashboard_latest/widgets/app_bar_widget.dart @@ -58,7 +58,7 @@ class AppBarWidget extends StatelessWidget { style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, fontSize: context.isTablet() ? 12 : null), ), ], - ), + ).expanded, const Spacer(), Consumer(builder: (context, settingProvider, child) { return Container( From 3576bf032ab36948f95726f4bb250e850df86c54 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 12 Feb 2026 07:02:06 +0300 Subject: [PATCH 23/23] ios changes for release --- ios/Runner.xcodeproj/project.pbxproj | 104 +++++++++++++-------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index edbf0bd9..3a3ea2b6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -11,15 +11,15 @@ 00C3AFCE29769C38002E7B47 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 00C3AFCD29769C37002E7B47 /* GoogleService-Info.plist */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 7116B13B2016C1B081C63974 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B9D24AC2EE56E204217B187 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 84713E5C1A48D35EB02DB255 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC2334F09AFE7D4C8720A3D2 /* Pods_Runner.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + E50AEC852F3CD47400480356 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; @@ -37,12 +37,12 @@ 00C3AFCD29769C37002E7B47 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2E3CB8321FC9463EA4F59770 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 5B9D24AC2EE56E204217B187 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 834C7D121918F9FF211C5314 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 7FC568C44F174E173A0E36F5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -50,8 +50,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B01BA1F7378A0B9F7249FF2A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - DC2334F09AFE7D4C8720A3D2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A231AA589F4F59D80E8AF17E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + ADC3DDCEFAF7F30FE0D8CEDF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -59,7 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84713E5C1A48D35EB02DB255 /* Pods_Runner.framework in Frameworks */, + 7116B13B2016C1B081C63974 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -69,13 +69,21 @@ 577ED37A491ADCF557B4F6D9 /* Pods */ = { isa = PBXGroup; children = ( - 2E3CB8321FC9463EA4F59770 /* Pods-Runner.debug.xcconfig */, - B01BA1F7378A0B9F7249FF2A /* Pods-Runner.release.xcconfig */, - 834C7D121918F9FF211C5314 /* Pods-Runner.profile.xcconfig */, + ADC3DDCEFAF7F30FE0D8CEDF /* Pods-Runner.debug.xcconfig */, + 7FC568C44F174E173A0E36F5 /* Pods-Runner.release.xcconfig */, + A231AA589F4F59D80E8AF17E /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; }; + 93938E05E88B2AC688D7ECF2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5B9D24AC2EE56E204217B187 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -95,7 +103,7 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 577ED37A491ADCF557B4F6D9 /* Pods */, - ACFB4E3E17DB02D4A9B63D84 /* Frameworks */, + 93938E05E88B2AC688D7ECF2 /* Frameworks */, ); sourceTree = ""; }; @@ -124,14 +132,6 @@ path = Runner; sourceTree = ""; }; - ACFB4E3E17DB02D4A9B63D84 /* Frameworks */ = { - isa = PBXGroup; - children = ( - DC2334F09AFE7D4C8720A3D2 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -139,15 +139,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - F8BE49D37BC14FBD6C4F3196 /* [CP] Check Pods Manifest.lock */, + 8CD9A20F25CF79461AA21605 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - B921EEB42AD074FA76A076B1 /* [CP] Embed Pods Frameworks */, - A65B36E3496C62B7D376B428 /* [CP] Copy Pods Resources */, + E50AEC852F3CD47400480356 /* Embed Frameworks */, + 5C70B483506D887A89BE3626 /* [CP] Embed Pods Frameworks */, + C902EF1B5AA2B6EF0A294F1F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -225,75 +225,75 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 5C70B483506D887A89BE3626 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "Run Script"; - outputPaths = ( + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - A65B36E3496C62B7D376B428 /* [CP] Copy Pods Resources */ = { + 8CD9A20F25CF79461AA21605 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B921EEB42AD074FA76A076B1 /* [CP] Embed Pods Frameworks */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + inputPaths = ( ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + name = "Run Script"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - F8BE49D37BC14FBD6C4F3196 /* [CP] Check Pods Manifest.lock */ = { + C902EF1B5AA2B6EF0A294F1F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */