From 24c40707b99e30ae993781e616ce85ca808b02ed Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Thu, 5 Nov 2026 03:49:24 +0300 Subject: [PATCH] localizations --- assets/langs/ar-SA.json | 7 ++-- assets/langs/en-US.json | 9 +++--- lib/core/api/api_client.dart | 32 ++++++++++++------- lib/core/api_consts.dart | 3 +- .../refundable_invoices_response_model.dart | 2 +- .../refund_request_view_model.dart | 9 ++++-- lib/generated/locale_keys.g.dart | 1 + .../refund_request_create_page.dart | 14 ++++++-- 8 files changed, 53 insertions(+), 24 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 971677fa..f3c744a2 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1927,6 +1927,7 @@ "cash": "نقدي", "selectRefundReason": "اختر سبب الاسترداد", "refundReason": "سبب الاسترداد", + "optional": "(اختياري)", "requestRejectionReason": "سبب رفض الطلب", "procedureRejectionReason": "سبب رفض الإجراء", "done": "تم", @@ -1968,11 +1969,11 @@ "image": "صورة", "refundCannotBeProcessedPatientAdmitted": "لا يمكن معالجة الاسترداد أثناء إقامة المريض", "cashRefundLimitExceeded": "لا يمكن معالجة المبالغ المستردة التي تزيد عن 5000 ريال سعودي نقداً. يرجى اختيار وجهة استرداد أخرى.", - "cashRefundInstructions": "قم بزيارة صراف مستشفى الحبيب الطبي أو الحبيب للرعاية الأولية لاستلام النقد. عند نافذة الصراف، سوف تتلقى رمز التحقق على رقم هاتفك المسجل بمجرد قيام الصراف بإنشاء معاملة الاسترداد. قدم الرمز للصراف للتحقق منه. سيتم صرف النقد فقط بعد التحقق الناجح.", - "cashRefundApprovalInstructions": "قم بزيارة صراف {hospital} لاستلام النقد. عند نافذة الصراف، سوف تتلقى رمز التحقق على رقم هاتفك المسجل بمجرد قيام الصراف بإنشاء معاملة الاسترداد. قدم الرمز للصراف للتحقق منه. سيتم صرف النقد فقط بعد التحقق الناجح.", "bankTransferRefundProcessingInstructions": "سيتم تنفيذ التحويل البنكي خلال 5 أيام عمل، وذلك بعد التحقق من الأهلية.", - "packageRefundValidationMessage": "طلب استرداد الباقة الخاص بك يتطلب التحقق بسبب استخدام الباقة والفواتير الفرعية ذات الصلة. سنقوم بمراجعة ومعالجة الطلب خلال 5 أيام عمل بعد تأكيد الأهلية.", "inpatientRefundValidationMessage": "طلب استرداد فاتورة التنويم الخاصة بك يتطلب التحقق بسبب إجراءات التنويم المتعلقة بالإجراءات أو الأدوية. سنقوم بمراجعة ومعالجة الطلب خلال 5 أيام عمل بعد تأكيد الأهلية.", + "cashRefundInstructions": "قم بزيارة {hospitalName} لاستلام النقد. عند نافذة الصراف، سوف تتلقى رمز التحقق على رقم هاتفك المسجل بمجرد قيام الصراف بإنشاء معاملة الاسترداد. قدم الرمز للصراف للتحقق منه. سيتم صرف النقد فقط بعد التحقق الناجح.", + "cashRefundApprovalInstructions": "قم بزيارة {hospitalName} لاستلام النقد. عند نافذة الصراف، سوف تتلقى رمز التحقق على رقم هاتفك المسجل بمجرد قيام الصراف بإنشاء معاملة الاسترداد. قدم الرمز للصراف للتحقق منه. سيتم صرف النقد فقط بعد التحقق الناجح.", + "packageRefundValidationMessage": "طلب استرداد الباقة الخاص بك يتطلب التحقق بسبب استخدام الباقة والفواتير الفرعية ذات الصلة. سنقوم بمراجعة ومعالجة الطلب خلال 5 أيام عمل بعد تأكيد الأهلية.", "pharmacyRefundPhysicalVisitNotice": "تتطلب استردادات الصيدلية زيارة شخصية لتسليم الأدوية ومعالجة الاسترداد.", "parkingQR": "رمز الاستجابة السريعة لوقوف السيارات", "parkingQRDesc": "امسح رمز الاستجابة السريعة (QR Code) أدناه عند بوابة الخروج من موقف السيارات:", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 7bcac22d..7f333586 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1920,6 +1920,7 @@ "cash": "Cash", "selectRefundReason": "Select Refund Reason", "refundReason": "Refund Reason", + "optional": "(Optional)", "requestRejectionReason": "Request Rejection Reason", "procedureRejectionReason": "Procedure Rejection Reason", "done": "Done", @@ -1959,11 +1960,10 @@ "image": "Image", "refundCannotBeProcessedPatientAdmitted": "Refund cannot be processed while the patient is admitted", "cashRefundLimitExceeded": "Refunds over 5000 SAR cannot be processed as cash. Please select another refund destination.", - "cashRefundInstructions": "Visit HMG Hospital or HMG Primary Care cashier to receive cash. At the cashier counter, you will receive an OTP on your registered mobile number once the cashier has created the refund transaction. Provide the OTP to the cashier for validation. Cash will be released only after successful validation.", - "cashRefundApprovalInstructions": "Visit {hospital} cashier to receive cash. At the cashier counter, you will receive an OTP on your registered mobile number once the cashier has created the refund transaction. Provide the OTP to the cashier for validation. Cash will be released only after successful validation.", - "bankTransferRefundProcessingInstructions": "The bank transfer will be processed within 5 working days, subject to eligibility.", + "cashRefundInstructions": "Visit {hospitalName} to receive cash. At the cashier counter, you will receive an OTP on your registered mobile number once the cashier has created the refund transaction. Provide the OTP to the cashier for validation. Cash will be released only after successful validation.", + "cashRefundApprovalInstructions": "Visit {hospitalName} to receive cash. At the cashier counter, you will receive an OTP on your registered mobile number once the cashier has created the refund transaction. Provide the OTP to the cashier for validation. Cash will be released only after successful validation.", "packageRefundValidationMessage": "Your package refund request requires validation because of package use and related child invoices. We will review and process the request within 5 working days after confirming eligibility.", - "inpatientRefundValidationMessage": "Your Inpatient invoice refund request requires validation because of inpatient validations related procedure / medications. We will review and process the request within 5 working days after confirming eligibility.", + "bankTransferRefundProcessingInstructions": "The bank transfer will be processed within 5 working days, subject to eligibility.", "pharmacyRefundPhysicalVisitNotice": "Pharmacy refunds require a physical visit to hand over medications and process the refund.", "parkingQR": "Parking QR Code", "parkingQRDesc": "Scan the below QR Code at the exit parking gate:", @@ -1973,6 +1973,7 @@ "doctorSchedule": "Doctor Schedule", "weeklyShift": "Weekly Shift", "dayOff": "Off", + "inpatientRefundValidationMessage": "Your Inpatient invoice refund request requires validation because of inpatient validations related procedure / medications. We will review and process the request within 5 working days after confirming eligibility.", "notAvailable": "Not Available", "hide": "Hide", "viewPatientQR": "View Patient QR Code", diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 03c880b2..e1aae0c5 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -138,7 +138,8 @@ class ApiClientImp implements ApiClient { } else {} if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] ?? IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; + body['isDentalAllowedBackend'] = + body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] ?? IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; } if (!body.containsKey('IsPublicRequest')) { @@ -209,11 +210,12 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - body['TokenID'] = "@dm!n"; + // body['TokenID'] = "@dm!n"; // body['PatientID'] = 6424682; // body['PatientID'] = 4772785; // body['PatientID'] = 4776766; - body['PatientID'] = 4776462; + // body['PatientID'] = 4776370; + // body['PatientID'] = 4776462; // body['PatientID'] = 4776463; // body['PatientID'] = 4776359; // body['PatientID'] = 4776466; @@ -390,19 +392,24 @@ class ApiClientImp implements ApiClient { onFailure( parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode, - failureType: UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), + failureType: + UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), ); // logApiEndpointError(endPoint, "session logged out", statusCode); } if (isAllowAny) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['IsAuthenticated'] == null) { if (parsed['isSMSSent'] == true) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['MessageStatus'] == 1) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['Result'] == 'OK') { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { onFailure( parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], @@ -412,7 +419,8 @@ class ApiClientImp implements ApiClient { logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } // else if (parsed['IsAuthenticated'] == false) { // onFailure( @@ -424,7 +432,8 @@ class ApiClientImp implements ApiClient { // } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null && parsed['ErrorMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { @@ -458,7 +467,8 @@ class ApiClientImp implements ApiClient { } } else { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, + messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { if (parsed['message'] != null) { onFailure( diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index cbfa1b4a..af2b349b 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -873,7 +873,8 @@ var GET_CUSTOMER_INFO = "VerifyCustomer"; //Pharmacy -var GET_PHARMACY_CATEGORISE = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; +var GET_PHARMACY_CATEGORISE = + 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; var GET_OFFERS_CATEGORISE = 'discountcategories'; var GET_OFFERS_PRODUCTS = 'offerproducts/'; var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; diff --git a/lib/features/refund_request/models/resp_models/refundable_invoices_response_model.dart b/lib/features/refund_request/models/resp_models/refundable_invoices_response_model.dart index 0178be6c..d973617f 100644 --- a/lib/features/refund_request/models/resp_models/refundable_invoices_response_model.dart +++ b/lib/features/refund_request/models/resp_models/refundable_invoices_response_model.dart @@ -139,7 +139,7 @@ class RefundableInvoicesDetailsObject { .toList() : [], statusCode: json['StatusCode'] as int?, - needITGApproval: json['NeedITGApproval'] as bool?, + needITGApproval: false, ); } } diff --git a/lib/features/refund_request/refund_request_view_model.dart b/lib/features/refund_request/refund_request_view_model.dart index ab039864..7c139762 100644 --- a/lib/features/refund_request/refund_request_view_model.dart +++ b/lib/features/refund_request/refund_request_view_model.dart @@ -251,8 +251,13 @@ class RefundRequestViewModel extends ChangeNotifier { List get selectedProcedures => procedures.where((p) => p.isSelected).toList(); - bool get allSelectedProceduresHaveReasons => - selectedProcedures.isNotEmpty && selectedProcedures.every((p) => p.refundReason != null && p.refundReason!.isNotEmpty); + bool get allSelectedProceduresHaveReasons { + // If ITG approval is not needed, refund reason is optional + if (!needITGApproval) return true; + + // If ITG approval is needed, refund reason is mandatory + return selectedProcedures.isNotEmpty && selectedProcedures.every((p) => p.refundReason != null && p.refundReason!.isNotEmpty); + } // ── Calculation ─────────────────────────────────────────────────────────── double get totalRefundableAmount { diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 1d945e1a..2f000804 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1912,6 +1912,7 @@ abstract class LocaleKeys { static const bankTransfer = 'bankTransfer'; static const selectRefundReason = 'selectRefundReason'; static const refundReason = 'refundReason'; + static const optional = 'optional'; static const requestRejectionReason = 'requestRejectionReason'; static const procedureRejectionReason = 'procedureRejectionReason'; static const refundReason1 = 'refundReason1'; diff --git a/lib/presentation/refund_request/refund_request_create_page.dart b/lib/presentation/refund_request/refund_request_create_page.dart index 2dce1c4a..6333f3b2 100644 --- a/lib/presentation/refund_request/refund_request_create_page.dart +++ b/lib/presentation/refund_request/refund_request_create_page.dart @@ -709,8 +709,18 @@ class _RefundRequestCreatePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.refundReason.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true), - (procedure.refundReason ?? LocaleKeys.selectRefundReason.tr(context: context)).toText14(color: AppColors.textColor, isBold: true), + Row( + children: [ + LocaleKeys.refundReason.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true), + // Show "(Optional)" label when ITG approval is not needed + if (!_refundRequestViewModel.needITGApproval) ...[ + SizedBox(width: 4.w), + "(${LocaleKeys.optional.tr(context: context)})".toText10(color: AppColors.greyTextColor), + ], + ], + ), + (procedure.refundReason ?? LocaleKeys.selectRefundReason.tr(context: context)) + .toText14(color: AppColors.textColor, isBold: true), ], ), ),