import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/payment_models/pay_order_detail_resp_model.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/subscriptions_view_model.dart'; import 'package:provider/provider.dart'; import '../classes/app_state.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; } updateSelectedPaymentMethod(PaymentMethods selectedMethod) { selectedPaymentMethod = selectedMethod; notifyListeners(); } Future onContinuePressed(BuildContext context, {required PaymentTypes paymentType}) async { switch (selectedPaymentMethod) { case PaymentMethods.mada: // TODO: Handle this case. break; case PaymentMethods.visa: await onVisaCardSelected(context, paymentType); break; case PaymentMethods.applePay: // TODO: Handle this case. break; case PaymentMethods.masterCard: // TODO: Handle this case. break; case PaymentMethods.tamara: // TODO: Handle this case. break; } return; } Future onAdsPaymentSuccess({required BuildContext context, required int currentAdId, required int paymentTypeId}) async { Utils.showLoading(context); PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentTypeId, adId: currentAdId); await Future.delayed(const Duration(seconds: 2)); Utils.hideLoading(context); log("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}"); if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) { Utils.showToast("Payment Failed!"); return; } if (payOrderDetailRespModel.isPaid != null && payOrderDetailRespModel.isPaid!) { Utils.showToast("Payment Successful"); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } } Future onAppointmentPaymentSuccess({required BuildContext context, required int currentAdId, required int paymentTypeId}) async { Utils.showLoading(context); //TODO: CONFIRM FROM ZAHOOR THAT WILL THIS METHOD WORK FOR APPOINTMENT PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentTypeId, adId: currentAdId); await Future.delayed(const Duration(seconds: 2)); Utils.hideLoading(context); log("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}"); if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) { Utils.showToast("Payment Failed!"); return; } if (payOrderDetailRespModel.isPaid != null && payOrderDetailRespModel.isPaid!) { Utils.showToast("Payment Successful"); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } } 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( // This will be request ID for request payment || ad ID for Ad Related Payment || OrderProviderSubscriptionID for SubscriptionPayment id: getIdTypeByPaymentType(paymentTypeEnum), appointmentIds: appointmentIdsForPayment, paymentType: paymentTypeEnum, onFailure: () { Utils.showToast("Payment Failed!"); switch (paymentTypeEnum) { case PaymentTypes.subscription: // TODO: Handle this case. break; case PaymentTypes.appointment: // TODO: Handle this case. log("Appointment Payment has been Failed!!"); break; case PaymentTypes.adReserve: // TODO: Handle this case. break; case PaymentTypes.ads: // TODO: Handle this case. break; case PaymentTypes.request: // TODO: Handle this case. break; case PaymentTypes.extendAds: // TODO: Handle this case. break; case PaymentTypes.partialAppointment: log("Partial Appointment Payment has been Failed!!"); break; } }, onSuccess: () async { // TOD0: we have to take payment confirmation methods from Backend team and make success callbacks like onAdsPaymentSuccess switch (paymentTypeEnum) { case PaymentTypes.subscription: onSubscriptionSuccess(context); break; case PaymentTypes.appointment: log("Appointment Payment has been Succeeded"); break; case PaymentTypes.request: break; case PaymentTypes.adReserve: case PaymentTypes.ads: case PaymentTypes.extendAds: await onAdsPaymentSuccess(context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), currentAdId: currentAdId); break; case PaymentTypes.partialAppointment: log("Partial Appointment Payment has been Succeeded"); break; } }, ); } onSubscriptionSuccess(BuildContext context){ pop(context); pop(context); pop(context); context.read().getMySubscriptions( AppState() .getUser .data ?.userInfo ?.providerId .toString() ?? ""); } 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: // TODO: Handle this case. 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; } } }