import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/repositories/payments_repo.dart'; import 'package:mc_common_app/services/payments_service.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; class PaymentVM extends ChangeNotifier { final PaymentService paymentService; final PaymentsRepo paymentRepo; PaymentVM({required this.paymentService, required this.paymentRepo}); PaymentMethods selectedPaymentMethod = PaymentMethods.mada; PaymentTypes currentPaymentType = PaymentTypes.ads; int currentAdId = -1; void updateCurrentAdId({required int id}) { currentAdId = id; } int requestId = -1; void updateRequestId({required int id}) { requestId = id; } int orderProviderSubscriptionId = -1; void updateOrderProviderSubscriptionId({required int id}) { orderProviderSubscriptionId = id; } List appointmentIdsForPayment = []; void updateAppointmentIdsForPayment({required List ids}) { appointmentIdsForPayment = ids; log("appointmentIdsForPayment: ${appointmentIdsForPayment}"); } updateSelectedPaymentMethod(PaymentMethods selectedMethod) { selectedPaymentMethod = selectedMethod; notifyListeners(); } Future onContinuePressed(BuildContext context, {required PaymentTypes paymentType}) async { switch (selectedPaymentMethod) { case PaymentMethods.mada: break; case PaymentMethods.visa: await onVisaCardSelected(context, paymentType); break; case PaymentMethods.applePay: break; case PaymentMethods.masterCard: break; case PaymentMethods.tamara: break; } return; } Future verifyPayments( {required BuildContext context, required int id, List? appointmentIds, required int paymentTypeId, required Function() onVerified, bool isForAppointment = false}) async { try { Utils.showLoading(context); bool isPaid = await paymentRepo.verifyPayment( paymentTypeId: paymentTypeId, id: id, isForAppointments: isForAppointment, appointmentIds: appointmentIds, ); Utils.hideLoading(context); // TODO: VERIFY THIS WITH ZAHOOR if (!isPaid) { // Utils.showToast(LocaleKeys.paymentFailed.tr()); // pop(context); return; } else { Utils.showToast(LocaleKeys.paymentSuccessful.tr()); } onVerified(); } catch (e) { Utils.showToast(e.toString()); return; } } int getIdTypeByPaymentType(PaymentTypes paymentTypes) { switch (paymentTypes) { case PaymentTypes.subscription: return orderProviderSubscriptionId; case PaymentTypes.appointment: case PaymentTypes.partialAppointment: return -1; case PaymentTypes.request: return requestId; case PaymentTypes.adReserve: case PaymentTypes.ads: case PaymentTypes.extendAds: return currentAdId; } } Future placeThePayment({required PaymentTypes paymentTypeEnum, required BuildContext context}) async { await paymentService.placePayment( id: getIdTypeByPaymentType(paymentTypeEnum), // This will be request ID for request payment || ad ID for Ad Related Payment || OrderProviderSubscriptionID for SubscriptionPayment appointmentIds: appointmentIdsForPayment, paymentType: paymentTypeEnum, onFailure: () { Utils.showToast(LocaleKeys.paymentFailed.tr()); switch (paymentTypeEnum) { case PaymentTypes.subscription: case PaymentTypes.appointment: case PaymentTypes.adReserve: case PaymentTypes.ads: case PaymentTypes.request: case PaymentTypes.extendAds: case PaymentTypes.partialAppointment: break; } }, onSuccess: () async { // Utils.showToast("Verifying Payment.."); switch (paymentTypeEnum) { case PaymentTypes.subscription: await verifyPayments( context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), id: orderProviderSubscriptionId, onVerified: () => onSubscriptionPaymentSuccess(context), ); break; case PaymentTypes.appointment: case PaymentTypes.partialAppointment: await verifyPayments( id: 0, isForAppointment: true, appointmentIds: appointmentIdsForPayment, context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), onVerified: () => onAppointmentSuccess(context), ); break; case PaymentTypes.request: await verifyPayments( context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), id: requestId, onVerified: () => onRequestPaymentSuccess(context), ); break; case PaymentTypes.adReserve: case PaymentTypes.ads: case PaymentTypes.extendAds: await verifyPayments( context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), id: currentAdId, onVerified: () => onAdsPaymentSuccess(context), ); } }, ); } void onRequestPaymentSuccess(BuildContext context) { if (AppState().currentAppType == AppType.provider) { context.read().onNavbarTapped(4); } else { context.read().onNavbarTapped(4); } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } void onAdsPaymentSuccess(BuildContext context) { context.read().updateIsExploreAds(false); if (AppState().currentAppType == AppType.provider) { context.read().onNavbarTapped(3); context.read().applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); } else { context.read().onNavbarTapped(3); context.read().applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForPost); } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsPayment); } void onSubscriptionPaymentSuccess(BuildContext context) { pop(context); // context.read().getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } void onAppointmentSuccess(BuildContext context) { if (AppState().currentAppType == AppType.provider) { context.read().onNavbarTapped(1); } else { context.read().onNavbarTapped(1); } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } Future onVisaCardSelected(BuildContext context, PaymentTypes paymentType) async { currentPaymentType = paymentType; switch (currentPaymentType) { case PaymentTypes.appointment: case PaymentTypes.partialAppointment: if (appointmentIdsForPayment.isEmpty) return; await placeThePayment(context: context, paymentTypeEnum: paymentType); break; case PaymentTypes.request: if (requestId == -1) return; await placeThePayment(context: context, paymentTypeEnum: paymentType); break; case PaymentTypes.subscription: await placeThePayment(context: context, paymentTypeEnum: paymentType); break; case PaymentTypes.ads: case PaymentTypes.adReserve: case PaymentTypes.extendAds: if (currentAdId == -1) return; await placeThePayment(context: context, paymentTypeEnum: paymentType); break; } } }