|
|
|
|
@ -1,8 +1,12 @@
|
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/core/utils/validation_utils.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/habib_wallet/models/patient_advance_balance_response_model.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/refund_request/models/req_models/submit_refund_request_model.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/refund_request/models/resp_models/refundable_invoices_response_model.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/refund_request/models/resp_models/refund_request_list_response_model.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/features/refund_request/refund_request_repo.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
|
|
|
|
@ -28,6 +32,8 @@ class HabibWalletViewModel extends ChangeNotifier {
|
|
|
|
|
// ── Refundable Advances ───────────────────────────────────────────────────
|
|
|
|
|
bool isAdvancesLoading = false;
|
|
|
|
|
double totalAdvancesBalance = 0.0;
|
|
|
|
|
List<RefundableAdvancesItem> refundableAdvancesList = [];
|
|
|
|
|
bool isSubmittingWithdrawal = false;
|
|
|
|
|
|
|
|
|
|
bool isSearchedFileNumberDataShown = false;
|
|
|
|
|
|
|
|
|
|
@ -103,9 +109,7 @@ class HabibWalletViewModel extends ChangeNotifier {
|
|
|
|
|
_ibanError = LocaleKeys.ibanIsRequired.tr();
|
|
|
|
|
isValid = false;
|
|
|
|
|
} else {
|
|
|
|
|
// KSA IBAN format: SA followed by 2 check digits + 18 alphanumeric chars = 22 chars total
|
|
|
|
|
final ksaIbanRegex = RegExp(r'^SA\d{2}[0-9A-Z]{18}$', caseSensitive: false);
|
|
|
|
|
if (!ksaIbanRegex.hasMatch(iban.trim().replaceAll(' ', ''))) {
|
|
|
|
|
if (!ValidationUtils.validateKsaIban(iban.trim())) {
|
|
|
|
|
_ibanError = LocaleKeys.invalidIbanFormat.tr();
|
|
|
|
|
isValid = false;
|
|
|
|
|
}
|
|
|
|
|
@ -158,6 +162,7 @@ class HabibWalletViewModel extends ChangeNotifier {
|
|
|
|
|
Future<void> fetchAdvancesForHospital() async {
|
|
|
|
|
isAdvancesLoading = true;
|
|
|
|
|
totalAdvancesBalance = 0.0;
|
|
|
|
|
refundableAdvancesList = [];
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
|
|
final result = await refundRequestRepo.getRefundableAdvances();
|
|
|
|
|
@ -170,13 +175,86 @@ class HabibWalletViewModel extends ChangeNotifier {
|
|
|
|
|
(apiResponse) {
|
|
|
|
|
isAdvancesLoading = false;
|
|
|
|
|
if (apiResponse.data != null) {
|
|
|
|
|
totalAdvancesBalance = apiResponse.data!.refundableAdvancesItems.fold(0.0, (sum, item) => sum + (item.balanceAmount ?? 0.0));
|
|
|
|
|
refundableAdvancesList = apiResponse.data!.refundableAdvancesItems;
|
|
|
|
|
totalAdvancesBalance = refundableAdvancesList.fold(0.0, (sum, item) => sum + (item.balanceAmount ?? 0.0));
|
|
|
|
|
}
|
|
|
|
|
notifyListeners();
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> submitWalletWithdrawal({
|
|
|
|
|
required String iban,
|
|
|
|
|
required String remarks,
|
|
|
|
|
required String patientName,
|
|
|
|
|
required String patientId,
|
|
|
|
|
required String patientMobileNumber,
|
|
|
|
|
required String patientNationalId,
|
|
|
|
|
required int projectId,
|
|
|
|
|
required String projectName,
|
|
|
|
|
Function(SubmitRefundResponseModel)? onSuccess,
|
|
|
|
|
Function(String)? onError,
|
|
|
|
|
}) async {
|
|
|
|
|
isSubmittingWithdrawal = true;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
|
|
final advances = refundableAdvancesList
|
|
|
|
|
.map((a) => SubmitRefundAdvanceItem(
|
|
|
|
|
advanceNo: (a.advanceNo ?? 0).toString(),
|
|
|
|
|
paidAmount: a.paidAmount ?? 0.0,
|
|
|
|
|
balanceAmount: a.balanceAmount ?? 0.0,
|
|
|
|
|
advanceDate: a.advanceDate ?? '',
|
|
|
|
|
))
|
|
|
|
|
.toList();
|
|
|
|
|
|
|
|
|
|
final request = SubmitRefundRequestModel(
|
|
|
|
|
projectId: projectId,
|
|
|
|
|
refundType: '2', // wallet withdrawal
|
|
|
|
|
refundProject: projectName,
|
|
|
|
|
refundProjectId: projectId,
|
|
|
|
|
refundPatientId: patientId,
|
|
|
|
|
patientMobileNumber: patientMobileNumber,
|
|
|
|
|
refundPatientName: patientName,
|
|
|
|
|
refundNationalId: patientNationalId,
|
|
|
|
|
refundInvoiceNo: '',
|
|
|
|
|
refundAppointmentNo: '',
|
|
|
|
|
refundDoctorId: 0,
|
|
|
|
|
refundDoctorName: '',
|
|
|
|
|
refundClinicId: 0,
|
|
|
|
|
refundClinicName: '',
|
|
|
|
|
refundDestination: '2', // bank transfer
|
|
|
|
|
refundIban: iban,
|
|
|
|
|
refundRemarks: remarks,
|
|
|
|
|
refundTotalAmount: totalAdvancesBalance,
|
|
|
|
|
refundProceduresList: const [],
|
|
|
|
|
refundAdvancesList: advances,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final result = await refundRequestRepo.submitRefund(request: request);
|
|
|
|
|
result.fold(
|
|
|
|
|
(failure) {
|
|
|
|
|
isSubmittingWithdrawal = false;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
if (onError != null) {
|
|
|
|
|
onError(failure.message);
|
|
|
|
|
} else {
|
|
|
|
|
errorHandlerService.handleError(failure: failure);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
(apiResponse) {
|
|
|
|
|
isSubmittingWithdrawal = false;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
if (apiResponse.data != null) {
|
|
|
|
|
if (onSuccess != null) onSuccess(apiResponse.data!);
|
|
|
|
|
} else {
|
|
|
|
|
if (onError != null) {
|
|
|
|
|
onError(apiResponse.errorMessage ?? LocaleKeys.failed.tr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initHabibWalletProvider() {
|
|
|
|
|
isWalletAmountLoading = true;
|
|
|
|
|
isBottomSheetContentLoading = false;
|
|
|
|
|
@ -203,6 +281,20 @@ class HabibWalletViewModel extends ChangeNotifier {
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Resets all state related to the wallet withdrawal form.
|
|
|
|
|
/// Pass [silent] = true when calling from dispose() to avoid notifyListeners
|
|
|
|
|
/// while the widget tree is locked.
|
|
|
|
|
void resetWithdrawForm({bool silent = false}) {
|
|
|
|
|
selectedHospital = null;
|
|
|
|
|
totalAdvancesBalance = 0.0;
|
|
|
|
|
refundableAdvancesList = [];
|
|
|
|
|
isAdvancesLoading = false;
|
|
|
|
|
isSubmittingWithdrawal = false;
|
|
|
|
|
_ibanError = null;
|
|
|
|
|
_withdrawDescriptionError = null;
|
|
|
|
|
if (!silent) notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setWalletRechargeAmount(num amount) {
|
|
|
|
|
walletRechargeAmount = amount;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|