Files
Fondex/lib/controllers/on_demand_order_details_controller.dart

256 lines
8.6 KiB
Dart

import 'dart:developer';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:customer/models/coupon_model.dart';
import 'package:customer/models/user_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import '../constant/constant.dart';
import '../models/onprovider_order_model.dart';
import '../models/wallet_transaction_model.dart';
import '../models/worker_model.dart';
import '../service/fire_store_utils.dart';
import '../service/send_notification.dart';
import '../themes/show_toast_dialog.dart';
class OnDemandOrderDetailsController extends GetxController {
Rx<UserModel?> providerUser = Rx<UserModel?>(null);
Rxn<OnProviderOrderModel> onProviderOrder = Rxn<OnProviderOrderModel>();
Rxn<WorkerModel> worker = Rxn<WorkerModel>();
Rx<TextEditingController> couponTextController = TextEditingController().obs;
Rx<TextEditingController> cancelBookingController = TextEditingController().obs;
RxDouble subTotal = 0.0.obs;
RxDouble price = 0.0.obs;
RxDouble discountAmount = 0.0.obs;
RxDouble totalAmount = 0.0.obs;
RxDouble quantity = 0.0.obs;
RxString discountType = "".obs;
RxString discountLabel = "".obs;
RxString offerCode = "".obs;
RxList<CouponModel> couponList = <CouponModel>[].obs;
final RxBool isLoading = false.obs;
@override
void onInit() {
super.onInit();
final args = Get.arguments;
if (args != null && args is OnProviderOrderModel) {
onProviderOrder.value = args;
}
getData();
}
Future<void> getData() async {
try {
final order = await FireStoreUtils.getProviderOrderById(onProviderOrder.value!.id);
if (order != null) {
onProviderOrder.value = order;
discountType.value = order.discountType ?? "";
discountLabel.value = order.discountLabel ?? "";
discountAmount.value = double.tryParse(order.discount.toString()) ?? 0.0;
offerCode.value = order.couponCode ?? "";
// Fetch provider
providerUser.value = await FireStoreUtils.getUserProfile(order.provider.author.toString());
// Fetch worker (if exists)
if (order.workerId != null && order.workerId!.isNotEmpty) {
worker.value = await FireStoreUtils.getWorker(order.workerId!);
} else {
worker.value = null;
}
calculatePrice();
// Load available coupons
FireStoreUtils.getProviderCouponAfterExpire(order.provider.author.toString()).then((expiredCoupons) {
couponList.assignAll(expiredCoupons);
});
} else {
onProviderOrder.value = null;
providerUser.value = null;
worker.value = null;
couponList.clear();
}
} catch (e, st) {
log("Error in getData: $e\n$st");
onProviderOrder.value = null;
providerUser.value = null;
worker.value = null;
couponList.clear();
}
}
void applyCoupon(CouponModel coupon) {
double discount = 0.0;
if (coupon.discountType == "Percentage" || coupon.discountType == "Percent") {
discount = price.value * (double.tryParse(coupon.discount.toString()) ?? 0) / 100;
} else {
discount = double.tryParse(coupon.discount.toString()) ?? 0;
}
if (subTotal.value > discount) {
discountType.value = coupon.discountType ?? '';
discountLabel.value = coupon.discount.toString();
offerCode.value = coupon.code ?? '';
calculatePrice();
} else {
Get.snackbar("Error", "Coupon cannot be applied");
}
}
void calculatePrice() {
double basePrice =
(onProviderOrder.value?.provider.disPrice == "" || onProviderOrder.value?.provider.disPrice == "0")
? double.tryParse(onProviderOrder.value?.provider.price.toString() ?? "0") ?? 0
: double.tryParse(onProviderOrder.value?.provider.disPrice.toString() ?? "0") ?? 0;
price.value = basePrice * (onProviderOrder.value?.quantity ?? 0.0);
// discount
if (discountType.value == "Percentage" || discountType.value == "Percent") {
discountAmount.value = price.value * (double.tryParse(discountLabel.value) ?? 0) / 100;
} else {
discountAmount.value = double.tryParse(discountLabel.value.isEmpty ? '0' : discountLabel.value) ?? 0;
}
subTotal.value = price.value - discountAmount.value;
// tax calculation
double total = subTotal.value;
for (var element in Constant.taxList) {
total += Constant.getTaxValue(amount: subTotal.value.toString(), taxModel: element);
}
totalAmount.value = total;
}
String getDate(String date) {
try {
DateTime dt = DateTime.parse(date);
return "${dt.day}-${dt.month}-${dt.year}";
} catch (e) {
return date;
}
}
Future<void> cancelBooking() async {
final order = onProviderOrder.value;
if (order == null) return;
ShowToastDialog.showLoader("Please wait...".tr());
try {
double total = 0.0;
// Calculate total
final pricePerUnit =
(order.provider.disPrice == "" || order.provider.disPrice == "0") ? double.tryParse(order.provider.price.toString()) ?? 0 : double.tryParse(order.provider.disPrice.toString()) ?? 0;
total = pricePerUnit * (order.quantity);
// Add tax
if (Constant.taxList.isNotEmpty) {
for (var tax in Constant.taxList) {
total += Constant.getTaxValue(amount: total.toString(), taxModel: tax);
}
}
// Admin commission
double adminComm = 0.0;
if ((order.adminCommission ?? '0') != '0' && (order.adminCommissionType ?? '').isNotEmpty) {
if (order.adminCommissionType!.toLowerCase() == 'percentage' || order.adminCommissionType!.toLowerCase() == 'percent') {
adminComm = (total * (double.tryParse(order.adminCommission!) ?? 0)) / 100;
} else {
adminComm = double.tryParse(order.adminCommission!) ?? 0;
}
}
// Refund customer wallet if not COD
if ((order.payment_method).toLowerCase() != 'cod') {
await FireStoreUtils.setWalletTransaction(
WalletTransactionModel(
id: Constant.getUuid(),
serviceType: 'ondemand-service',
amount: total,
date: Timestamp.now(),
paymentMethod: 'wallet',
transactionUser: 'customer',
userId: Constant.userModel?.id,
isTopup: true,
orderId: order.id,
note: 'Booking Amount Refund',
paymentStatus: "success".tr(),
),
);
// Deduct from provider if accepted
if (order.status == Constant.orderAccepted) {
await FireStoreUtils.setWalletTransaction(
WalletTransactionModel(
id: Constant.getUuid(),
serviceType: 'ondemand-service',
amount: total,
date: Timestamp.now(),
paymentMethod: 'wallet',
transactionUser: 'provider',
userId: order.provider.author ?? '',
isTopup: false,
orderId: order.id,
note: 'Booking Amount Refund',
paymentStatus: "success".tr(),
),
);
}
}
// Refund admin commission
if (order.status == Constant.orderAccepted && adminComm > 0) {
await FireStoreUtils.setWalletTransaction(
WalletTransactionModel(
id: Constant.getUuid(),
serviceType: 'ondemand-service',
amount: adminComm,
date: Timestamp.now(),
paymentMethod: 'wallet',
transactionUser: 'provider',
userId: order.provider.author ?? '',
isTopup: true,
orderId: order.id,
note: 'Admin commission refund',
paymentStatus: "success".tr(),
),
);
}
// Update order status & reason
order.status = Constant.orderCancelled;
order.reason = cancelBookingController.value.text;
await FireStoreUtils.updateOnDemandOrder(order); // Ensure this completes
// Notify provider
final provider = await FireStoreUtils.getUserProfile(order.provider.author ?? '');
if (provider != null) {
Map<String, dynamic> payload = {"type": 'provider_order', "orderId": order.id};
await SendNotification.sendFcmMessage(Constant.bookingPlaced, provider.fcmToken ?? '', payload);
}
ShowToastDialog.closeLoader();
Get.back();
ShowToastDialog.showToast("Booking cancelled successfully".tr());
} catch (e, st) {
log("Cancel error: $e\n$st");
ShowToastDialog.closeLoader();
ShowToastDialog.showToast("Something went wrong".tr());
}
}
}