fixed PMA 1205 and PMA 1204

faiz_dev
faizatflutter 3 weeks ago
parent 556aa6171c
commit 7855258529

@ -1938,6 +1938,7 @@
"refundReason5": "الخدمة لم تُنجز / غير متاحة بسبب عطل الجهاز / رفض المريض",
"refundReason6": "تم إلغاء الإجراء السريري أو تغييره من قِبل الطبيب المحيل",
"refundReason7": "تم إلغاء إجراء وحدة الخدمة / المختبر / الأشعة أو تغييره من قِبل الطبيب المحيل",
"refundReason8": "نقل المريض إلى الباقة",
"selectProcedures": "اختر العمليات",
"beforeUsingSymptomsChecker": "قبل استخدام فاحص الأعراض، يرجى قراءة شروط الخدمة وتذكر:",
"symptomsCheckerNotDiagnosis": "• فاحص الأعراض ليس تشخيصًا. إنه للمعلومات الخاصة بك فقط وليس رأيًا طبيًا مؤهلاً.",

@ -1930,6 +1930,7 @@
"refundReason5": "Service not done/not available due to machine breakdown/patient refusal",
"refundReason6": "Clinical procedure cancelled or changed by requesting doctor",
"refundReason7": "Service unit/lab/radiology procedure cancelled or changed by requesting doctor",
"refundReason8": "Patient Transfer to package",
"selectProcedures": "Select Procedures",
"beforeUsingSymptomsChecker": "Before using the Symptoms Checker, please read the Terms of Service and remember:",
"symptomsCheckerNotDiagnosis": "• Symptoms Checker isn't a diagnosis. It's only for your information and not a qualified medical opinion.",

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:clarity_flutter/clarity_flutter.dart';
@ -213,9 +212,9 @@ class ApiClientImp implements ApiClient {
// body['TokenID'] = "@dm!n";
// body['PatientID'] = 6424682;
// body['PatientID'] = 4772785;
// body['PatientID'] = 4776462;
// body['PatientID'] = 4776359;
// body['PatientID'] = 4776466;
// body['PatientID'] = 4769748;
// body['PatientID'] = 89754444;
// body['PatientTypeID'] = 1;

@ -286,13 +286,13 @@ class HabibWalletViewModel extends ChangeNotifier {
return true;
}
Future<void> fetchAdvancesForHospital() async {
Future<void> fetchAdvancesForHospital({required int projectId}) async {
isAdvancesLoading = true;
totalAdvancesBalance = 0.0;
refundableAdvancesList = [];
notifyListeners();
final result = await refundRequestRepo.getRefundableAdvances();
final result = await refundRequestRepo.getRefundableAdvances(projectID: projectId);
result.fold(
(failure) {
isAdvancesLoading = false;

@ -20,7 +20,7 @@ abstract class RefundRequestRepo {
required int projectId,
});
Future<Either<Failure, GenericApiModel<RefundableAdvancesObject>>> getRefundableAdvances();
Future<Either<Failure, GenericApiModel<RefundableAdvancesObject>>> getRefundableAdvances({required int projectID});
Future<Either<Failure, GenericApiModel<RefundStatusModel>>> getRefundStatus({required String referenceNumber});
@ -146,14 +146,16 @@ class RefundRequestRepoImp implements RefundRequestRepo {
}
@override
Future<Either<Failure, GenericApiModel<RefundableAdvancesObject>>> getRefundableAdvances() async {
Future<Either<Failure, GenericApiModel<RefundableAdvancesObject>>> getRefundableAdvances({required int projectID}) async {
try {
Map<String, dynamic> body = {"ProjectID": projectID};
GenericApiModel<RefundableAdvancesObject>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.getRefundableAdvances,
body: {},
body: body,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},

@ -148,7 +148,6 @@ class RefundRequestViewModel extends ChangeNotifier {
}
}
void clearHospital() {
selectedHospital = null;
selectedInvoice = null;
@ -431,46 +430,6 @@ class RefundRequestViewModel extends ChangeNotifier {
);
}
// Refundable Advances
RefundableAdvancesObject? refundableAdvances;
bool isRefundableAdvancesLoading = false;
Future<void> getRefundableAdvances({
Function(RefundableAdvancesObject)? onSuccess,
Function(String)? onError,
}) async {
isRefundableAdvancesLoading = true;
refundableAdvances = null;
notifyListeners();
final result = await refundRequestRepo.getRefundableAdvances();
result.fold(
(failure) {
isRefundableAdvancesLoading = false;
notifyListeners();
if (onError != null) {
onError(failure.message);
} else {
errorHandlerService.handleError(failure: failure);
}
},
(apiResponse) {
isRefundableAdvancesLoading = false;
if (apiResponse.messageStatus == 1 && apiResponse.data != null) {
refundableAdvances = apiResponse.data;
notifyListeners();
if (onSuccess != null) onSuccess(apiResponse.data!);
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? "Failed to load refundable advances");
}
}
},
);
}
// Refund Status
RefundStatusModel? refundStatus;
bool isRefundStatusLoading = false;

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
// ignore_for_file: constant_identifier_names
abstract class LocaleKeys {
abstract class LocaleKeys {
static const english = 'english';
static const arabic = 'arabic';
static const login = 'login';
@ -1921,6 +1921,7 @@ abstract class LocaleKeys {
static const refundReason5 = 'refundReason5';
static const refundReason6 = 'refundReason6';
static const refundReason7 = 'refundReason7';
static const refundReason8 = 'refundReason8';
static const selectProcedures = 'selectProcedures';
static const beforeUsingSymptomsChecker = 'beforeUsingSymptomsChecker';
static const symptomsCheckerNotDiagnosis = 'symptomsCheckerNotDiagnosis';

@ -285,8 +285,8 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
SizedBox(width: 12.w),
Expanded(
child: LocaleKeys.cashRefundApprovalInstructions.tr(context: context).toText12(
color: AppColors.greyInfoTextColor,
),
color: AppColors.greyInfoTextColor,
),
),
],
),
@ -345,9 +345,9 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
final isStep2Valid = vm.selectedWithdrawMethod != null &&
(isCash
? !vm.isCashWithdrawAmountExceeded // Cash: check amount limit
: (isBankTransfer &&
_bankDetailsController.text.trim().isNotEmpty &&
_descriptionController.text.trim().isNotEmpty)); // Bank: check fields
: (isBankTransfer
? (_bankDetailsController.text.trim().isNotEmpty && _descriptionController.text.trim().isNotEmpty) // Bank: check IBAN and description
: true)); // HMG Wallet: no additional validation
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -460,10 +460,10 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
child: SelectHospitalBottomSheet(
onHospitalSelected: (hospital) {
habibWalletViewModel.setSelectedHospital(hospital);
habibWalletViewModel.fetchAdvancesForHospital();
if (hospital.iD != null) {
final projectId = hospital.iD is int ? hospital.iD as int : int.tryParse(hospital.iD.toString());
if (projectId != null) {
habibWalletViewModel.fetchAdvancesForHospital(projectId: projectId);
habibWalletViewModel.getThresholdAmount(projectId: projectId);
}
}
@ -492,6 +492,7 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
Widget _buildBankInputDetails() {
return Consumer<HabibWalletViewModel>(
builder: (context, viewModel, _) {
final isBankTransfer = viewModel.selectedWithdrawMethod == RefundTabType.invoices;
final hasError = viewModel.ibanError != null || viewModel.withdrawDescriptionError != null;
return Container(
padding: EdgeInsets.all(16.h),
@ -505,32 +506,34 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
),
child: Column(
children: [
TextInputWidget(
labelText: LocaleKeys.addIbanDetails.tr(),
hintText: "SA0000000000000000000000",
controller: _bankDetailsController,
focusNode: _ibanFocusNode,
autoFocus: false,
keyboardType: TextInputType.text,
isEnable: true,
isReadOnly: false,
prefix: null,
isBorderAllowed: false,
isAllowLeadingIcon: true,
fontSize: 14.f,
isCountryDropDown: false,
leadingIcon: AppAssets.bankIcon,
fontFamily: "Poppins",
hasError: false,
errorMessage: viewModel.ibanError,
onChange: (value) {
viewModel.clearIbanError();
},
onSubmitted: (value) {
_descriptionFocusNode.requestFocus();
},
),
Divider(color: AppColors.bottomNAVBorder, thickness: 1).withVerticalPadding(16.h),
if (isBankTransfer) ...[
TextInputWidget(
labelText: LocaleKeys.addIbanDetails.tr(),
hintText: "SA0000000000000000000000",
controller: _bankDetailsController,
focusNode: _ibanFocusNode,
autoFocus: false,
keyboardType: TextInputType.text,
isEnable: true,
isReadOnly: false,
prefix: null,
isBorderAllowed: false,
isAllowLeadingIcon: true,
fontSize: 14.f,
isCountryDropDown: false,
leadingIcon: AppAssets.bankIcon,
fontFamily: "Poppins",
hasError: false,
errorMessage: viewModel.ibanError,
onChange: (value) {
viewModel.clearIbanError();
},
onSubmitted: (value) {
_descriptionFocusNode.requestFocus();
},
),
Divider(color: AppColors.bottomNAVBorder, thickness: 1).withVerticalPadding(16.h),
],
TextInputWidget(
labelText: LocaleKeys.description.tr(),
hintText: LocaleKeys.enterDescription.tr(),
@ -733,9 +736,17 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
final user = _appState.getAuthenticatedUser();
final hospital = vm.selectedHospital;
// Determine refund destination: '2' = Bank Transfer, '3' = Cash
// Determine refund destination: 1 = HMG Wallet, 2 = Bank Transfer, 3 = Cash
String refundDestination;
final isBankTransfer = vm.selectedWithdrawMethod == RefundTabType.invoices;
final isCash = vm.selectedWithdrawMethod == RefundTabType.cash;
final refundDestination = isCash ? '3' : '2';
if (isCash) {
refundDestination = '3';
} else if (isBankTransfer) {
refundDestination = '2';
} else {
refundDestination = '1'; // HMG Wallet
}
await vm.submitWalletWithdrawalRequest(
iban: _bankDetailsController.text.trim(),
@ -904,11 +915,9 @@ class _WithdrawRequestCreatePageState extends State<WithdrawRequestCreatePage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildRefundMethodSelection(habibWalletViewModel),
if (habibWalletViewModel.selectedWithdrawMethod == RefundTabType.invoices) ...[
if (habibWalletViewModel.selectedWithdrawMethod != null) ...[
SizedBox(height: 16.h),
_buildBankInputDetails(),
],
if (habibWalletViewModel.selectedWithdrawMethod != null) ...[
SizedBox(height: 16.h),
_buildImageUploadSection(habibWalletViewModel),
],

@ -340,11 +340,9 @@ class _RefundRequestCreatePageState extends State<RefundRequestCreatePage> {
),
),
],
if (vm.selectedPaymentMethod == RefundTabType.invoices) ...[
if (vm.selectedPaymentMethod != null) ...[
SizedBox(height: 16.h),
_buildBankInputDetails(vm),
],
if (vm.selectedPaymentMethod != null) ...[
SizedBox(height: 16.h),
_buildImageUploadSection(vm),
],
@ -507,6 +505,7 @@ class _RefundRequestCreatePageState extends State<RefundRequestCreatePage> {
// Bank Transfer Input
Widget _buildBankInputDetails(RefundRequestViewModel vm) {
final isBankTransfer = vm.selectedPaymentMethod == RefundTabType.invoices;
final hasError = vm.ibanError != null || vm.descriptionError != null;
return Container(
padding: EdgeInsets.all(16.h),
@ -520,32 +519,34 @@ class _RefundRequestCreatePageState extends State<RefundRequestCreatePage> {
),
child: Column(
children: [
TextInputWidget(
labelText: LocaleKeys.addIbanDetails.tr(),
hintText: "SA0000000000000000000000",
controller: _ibanController,
focusNode: _ibanFocusNode,
autoFocus: false,
keyboardType: TextInputType.text,
isEnable: true,
isReadOnly: false,
prefix: null,
isBorderAllowed: false,
isAllowLeadingIcon: true,
fontSize: 14.f,
isCountryDropDown: false,
leadingIcon: AppAssets.bankIcon,
fontFamily: "Poppins",
hasError: false,
errorMessage: vm.ibanError,
onChange: (value) {
vm.clearIbanError();
},
onSubmitted: (value) {
_descriptionFocusNode.requestFocus();
},
),
Divider(color: AppColors.bottomNAVBorder, thickness: 1).withVerticalPadding(16.h),
if (isBankTransfer) ...[
TextInputWidget(
labelText: LocaleKeys.addIbanDetails.tr(),
hintText: "SA0000000000000000000000",
controller: _ibanController,
focusNode: _ibanFocusNode,
autoFocus: false,
keyboardType: TextInputType.text,
isEnable: true,
isReadOnly: false,
prefix: null,
isBorderAllowed: false,
isAllowLeadingIcon: true,
fontSize: 14.f,
isCountryDropDown: false,
leadingIcon: AppAssets.bankIcon,
fontFamily: "Poppins",
hasError: false,
errorMessage: vm.ibanError,
onChange: (value) {
vm.clearIbanError();
},
onSubmitted: (value) {
_descriptionFocusNode.requestFocus();
},
),
Divider(color: AppColors.bottomNAVBorder, thickness: 1).withVerticalPadding(16.h),
],
TextInputWidget(
labelText: LocaleKeys.description.tr(),
hintText: LocaleKeys.enterDescription.tr(),
@ -813,7 +814,7 @@ class _RefundRequestCreatePageState extends State<RefundRequestCreatePage> {
refundClinicName: invoice.clinicName ?? '',
refundDestination: refundDestination,
refundIban: isBankTransfer ? _ibanController.text.trim() : '',
refundRemarks: isBankTransfer ? _descriptionController.text.trim() : '',
refundRemarks: _descriptionController.text.trim(),
refundTotalAmount: vm.totalRefundableAmount,
refundAttachmentsBase64List: vm.refundAttachmentList,
refundProceduresList: vm.selectedProcedures

@ -49,6 +49,7 @@ class _RefundReasonSheetContentState extends State<_RefundReasonSheetContent> {
LocaleKeys.refundReason5.tr(context: context),
LocaleKeys.refundReason6.tr(context: context),
LocaleKeys.refundReason7.tr(context: context),
LocaleKeys.refundReason8.tr(context: context),
];
@override

Loading…
Cancel
Save