import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/general/enums_model.dart'; import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/repositories/ads_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.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/base_view_model.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; class AdVM extends BaseVM { final CommonRepo commonRepo; final AdsRepo adsRepo; final CommonAppServices commonServices; AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo}); AdCreationSteps currentProgressStep = AdCreationSteps.vehicleDetails; VehicleDetailsModel? vehicleDetails; List vehicleTypes = []; List vehicleBrands = []; List vehicleModels = []; List vehicleModelYears = []; List vehicleColors = []; List vehicleConditions = []; List vehicleCategories = []; List vehicleMileages = []; List vehicleTransmissions = []; List vehicleSellerTypes = []; List vehicleDamageParts = []; List vehiclePartsSearchResults = []; List vehicleCountries = []; List vehicleCities = []; List vehicleAdsDurations = []; List vehicleAdsSpecialServices = []; SSCarCheckScheduleModel? ssCarCheckScheduleModel; SSPhotoOfficeScheduleModel? ssPhotoScheduleModel; String demandAmountError = ""; String vehicleVinError = ""; String vehicleTitleError = ""; String warrantyError = ""; String vehicleDescError = ""; String vehicleImageError = ""; String vehicleDamageImageError = ""; String adStartDateError = ""; String damagePartSearchValue = ""; String adReservePriceError = ""; String adPhoneNumberError = ""; List exploreAds = []; List exploreAdsFilteredList = []; List myAdsFilteredList = []; List myAds = []; List myReservedAdsRespModel = []; List myActiveAdsForHome = []; List vehicleDamageCards = []; void addNewDamagePartCard({required VehicleDamageCard damageCard}) { vehicleDamageCards.add(damageCard); notifyListeners(); } void clearDamageCards() { vehicleDamageCards.clear(); } List specialServiceCards = []; void addNewSpecialServiceCard({required SpecialServiceCard specialServiceCard}) { int index = vehicleAdsSpecialServices.indexWhere((element) => element.name == specialServiceCard.serviceSelectedId!.selectedOption); if (index != -1) { vehicleAdsSpecialServices[index].isSelected = true; } specialServiceCards.add(specialServiceCard); vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); adSpecialServiceDate = ""; notifyListeners(); } void removeSpecialServiceCard(int index) { String option = specialServiceCards.elementAt(index).serviceSelectedId!.selectedOption; for (var value in vehicleAdsSpecialServices) { if (value.name == option) { value.isSelected = false; break; } } specialServiceCards.removeAt(index); notifyListeners(); } void clearSpecialServiceCard() { specialServiceCards.clear(); notifyListeners(); } void onSearchChangedForDamagePart(String text) { vehiclePartsSearchResults.clear(); damagePartSearchValue = text; if (text.isEmpty) { notifyListeners(); return; } for (var damagePartDetail in vehicleDamageParts) { if (damagePartDetail.partName!.toLowerCase().contains(text.toLowerCase())) { vehiclePartsSearchResults.add(damagePartDetail); notifyListeners(); } } } bool isExploreAdsTapped = true; void updateIsExploreAds(bool value) async { isExploreAdsTapped = value; //To show the Active Ads applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.allAds); applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds); // if (value) { // await getExploreAds(); // } notifyListeners(); } List exploreAdsEnums = []; List myAdsEnums = []; List exploreAdsFilterOptions = []; List myAdsFilterOptions = []; populateAdsFilterList() async { if (myAdsEnums.isEmpty) { myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 18); //TODO: 18 is to get My Ad Filter Enums } if (exploreAdsEnums.isEmpty) { exploreAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 23); //TODO: 23 is to get Explore Ad Filter Enums } exploreAdsFilterOptions.clear(); myAdsFilterOptions.clear(); for (int i = 0; i < myAdsEnums.length; i++) { myAdsFilterOptions.add(FilterListModel(title: myAdsEnums[i].enumValueStr, isSelected: false, id: myAdsEnums[i].enumValue)); } myAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0)); for (int i = 0; i < exploreAdsEnums.length; i++) { exploreAdsFilterOptions.add(FilterListModel(title: "${exploreAdsEnums[i].enumValueStr} Ads", isSelected: false, id: exploreAdsEnums[i].enumValue)); } exploreAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0)); notifyListeners(); } applyFilterOnExploreAds({required CreatedByRoleEnum createdByRoleFilter}) { if (exploreAdsFilterOptions.isEmpty) return; int index = exploreAdsFilterOptions.indexWhere((element) => element.id.toCreatedByRoleEnum() == createdByRoleFilter); for (var value in exploreAdsFilterOptions) { value.isSelected = false; } exploreAdsFilterOptions[index].isSelected = true; if (createdByRoleFilter == CreatedByRoleEnum.allAds) { exploreAdsFilteredList = exploreAds; notifyListeners(); return; } exploreAdsFilteredList = exploreAds.where((element) => element.createdByRoleEnum == createdByRoleFilter).toList(); notifyListeners(); } applyFilterOnMyAds({required AdPostStatus adPostStatusEnum}) { if (myAdsFilterOptions.isEmpty) return; int index = myAdsFilterOptions.indexWhere((element) => element.id.toAdPostEnum() == adPostStatusEnum); for (var value in myAdsFilterOptions) { value.isSelected = false; } myAdsFilterOptions[index].isSelected = true; if (adPostStatusEnum.getIdFromAdPostStatusEnum() == 0) { myAdsFilteredList = myAds; notifyListeners(); return; } // this means if the filter is reserved ads dynamic selectedIds = []; if (index == 3 && adPostStatusEnum.getIdFromAdPostStatusEnum() == 9) { selectedIds = myReservedAdsRespModel.map((component) => component.adsID).toList(); myAdsFilteredList = myAds.where((element) => selectedIds.contains(element.id)).toList(); for (var ad in myAdsFilteredList) { ad.isReservedByMe = true; } notifyListeners(); return; } myAdsFilteredList = myAds.where((element) => element.statusID! == adPostStatusEnum.getIdFromAdPostStatusEnum()).toList(); notifyListeners(); } Future getMyAds() async { setState(ViewState.busy); myAds = await adsRepo.getAllAds(isMyAds: true); final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList(); myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds; await getMyReservedAds(); setState(ViewState.idle); } Future getMyReservedAds() async { setState(ViewState.busy); //TODO: BREAKING // myReservedAdsRespModel = await adsRepo.getMyReservedAds(); isFetchingLists = false; setState(ViewState.idle); } Future getExploreAds() async { setState(ViewState.busy); exploreAds = await adsRepo.getAllAds(isMyAds: false); exploreAdsFilteredList = exploreAds; setState(ViewState.idle); } Future getVehicleTypes() async { vehicleTypes = await adsRepo.getVehicleTypes(); notifyListeners(); } Future getVehicleAdsDuration() async { vehicleAdsDurations = await adsRepo.getAdsDuration(); notifyListeners(); } Future getVehicleAdsSpecialServices() async { vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceId: 1); notifyListeners(); } AdsBankDetailsModel? adsBankDetailsModel; Future getAdBankingAccountInfo({required int adId}) async { setState(ViewState.busy); try { adsBankDetailsModel = await adsRepo.getAdBankingAccountInfo(adId: 21); setState(ViewState.idle); } catch (e) { setState(ViewState.idle); Utils.showToast(e.toString()); } } Future markAdAsSold(BuildContext context, {required int adId}) async { Utils.showLoading(context); GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.sold); if (respModel.messageStatus != 1) { Utils.hideLoading(context); Utils.showToast(respModel.message ?? "Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("A has been marked as sold successfully!"); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.sold); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } Future deleteMyAd(BuildContext context, {required int adId}) async { Utils.showLoading(context); GenericRespModel respModel = await adsRepo.deleteAd(adId: adId); if (respModel.messageStatus != 1) { Utils.hideLoading(context); Utils.showToast(respModel.message ?? "Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("A has been deleted successfully!"); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } Future cancelMyAdReservation(BuildContext context, {required int adId}) async { Utils.showLoading(context); GenericRespModel respModel = await adsRepo.cancelMyAdReservation(adId: adId); if (respModel.messageStatus != 1) { Utils.hideLoading(context); Utils.showToast(respModel.message ?? "Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("Your reservation has been cancelled."); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } Future deactivateTheAd(BuildContext context, {required int adId}) async { Utils.showLoading(context); GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.cancelled); if (respModel.messageStatus != 1) { Utils.hideLoading(context); Utils.showToast(respModel.message ?? "Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("A has been deactivated successfully!"); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.cancelled); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } bool isFetchingLists = false; bool isCountryFetching = false; // Future getAllDataBasedOnVehicleTypeId() async { // if (vehicleTypeId.selectedId == -1) { // return; // } // isFetchingLists = true; // notifyListeners(); // vehicleModels = await adsRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId); // vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId); // vehicleColors = await adsRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId); // vehicleConditions = await adsRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId); // vehicleCategories = await adsRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId); // vehicleMileages = await adsRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId); // vehicleTransmissions = await adsRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId); // vehicleCountries = await adsRepo.getVehicleCountries(); // isFetchingLists = false; // notifyListeners(); // } getVehicleBrandsByVehicleTypeId() async { if (vehicleTypeId.selectedId == -1 || vehicleBrands.isNotEmpty) { return; } vehicleBrands = await adsRepo.getVehicleBrands(vehicleTypeId: vehicleTypeId.selectedId); notifyListeners(); } Future getVehicleDetailsByVehicleBrandId() async { if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) { return; } isFetchingLists = true; notifyListeners(); vehicleDetails = await adsRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId, vehicleBrandId: vehicleBrandId.selectedId); if (vehicleDetails != null) { vehicleModels = vehicleDetails!.vehicleModels!; vehicleModelYears = vehicleDetails!.vehicleModelYears!; vehicleColors = vehicleDetails!.vehicleColors!; vehicleConditions = vehicleDetails!.vehicleConditions!; vehicleCategories = vehicleDetails!.vehicleCategories!; vehicleMileages = vehicleDetails!.vehicleMileages!; vehicleSellerTypes = vehicleDetails!.vehicleSellerTypes!; vehicleTransmissions = vehicleDetails!.vehicleTransmissions!; vehicleCountries = vehicleDetails!.vehicleCountries!; } isFetchingLists = false; notifyListeners(); } String selectionDurationStartDate = ""; void updateSelectionDurationStartDate(String date) { selectionDurationStartDate = date; if (selectionDurationStartDate.isNotEmpty) adStartDateError = ""; notifyListeners(); } String adPhoneNumber = ""; void updateAdPhoneNumber(String date) { adPhoneNumber = date; if (adPhoneNumber.isNotEmpty) adPhoneNumberError = ""; notifyListeners(); } String adPhoneNumberDialCode = "+966"; void updateAdPhoneNumberDialCode(String date) { adPhoneNumberDialCode = date; notifyListeners(); } String adReserveAmount = ""; void updateAdReservePriceAmount(String date) { adReserveAmount = date; if (adReserveAmount.isNotEmpty) adReservePriceError = ""; notifyListeners(); } String adSpecialServiceDate = ""; void updateAdSpecialServiceDate(String date) { adSpecialServiceDate = date; if (adSpecialServiceDate.isNotEmpty) { adStartDateError = ""; } notifyListeners(); } SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleTypeId(SelectionModel id) async { vehicleTypeId = id; getVehicleBrandsByVehicleTypeId(); notifyListeners(); } SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) { if (isForSearch) { VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId); DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", ""); if (!ifAlreadyExist(list: vehicleBrandsAdSearchHistory, value: brandValue)) { addToVehicleBrandsAdSearchHistory(value: brandValue); } } vehicleBrandId = id; getVehicleDetailsByVehicleBrandId(); notifyListeners(); } SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleModelId(SelectionModel id) { vehicleModelId = id; notifyListeners(); } SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleModelYearId(SelectionModel id, {bool isForSearch = false}) { if (isForSearch) { VehicleYearModel year = vehicleModelYears.firstWhere((element) => element.id == id.selectedId); DropValue yearValue = DropValue(year.id ?? 0, year.modelYear ?? "", ""); if (!ifAlreadyExist(list: vehicleYearAdSearchHistory, value: yearValue)) { addToVehicleYearAdSearchHistory(value: yearValue); } } vehicleModelYearId = id; notifyListeners(); } SelectionModel vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleColorId(SelectionModel id) { vehicleColorId = id; notifyListeners(); } SelectionModel vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleConditionId(SelectionModel id) { vehicleConditionId = id; notifyListeners(); } SelectionModel vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCategoryId(SelectionModel id) { vehicleCategoryId = id; notifyListeners(); } SelectionModel vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleMileageId(SelectionModel id) { vehicleMileageId = id; notifyListeners(); } String vehicleVin = ""; void updateVehicleVin(String vin) { vehicleVin = vin; } String warrantyDuration = ""; void updateVehicleWarrantyDuration(String warranty) { warrantyDuration = warranty; } String vehicleDemandAmount = ""; void updateVehicleDemandAmount(String amount) { vehicleDemandAmount = amount; } String vehicleTitle = ""; void updateVehicleTitle(String title) { vehicleTitle = title; } String vehicleDescription = ""; void updateVehicleDescription(String desc) { vehicleDescription = desc; } SelectionModel vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleTransmissionId(SelectionModel id) { vehicleTransmissionId = id; notifyListeners(); } SelectionModel vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleSellerTypeId(SelectionModel id) { vehicleSellerTypeId = id; notifyListeners(); } // SelectionModel vehicleDamagePartId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleDamagePartId(SelectionModel id, int index) { vehicleDamageCards[index].partSelectedId = id; int partIndex = vehicleDamageParts.indexWhere((element) => element.partName == id.selectedOption); if (partIndex != -1) { // vehicleDamageParts[partIndex].isSelected = true; } notifyListeners(); } SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCountryId(SelectionModel id) async { vehicleCountryId = id; isCountryFetching = true; notifyListeners(); vehicleCities = await adsRepo.getVehicleCities(countryId: vehicleCountryId.selectedId); isCountryFetching = false; notifyListeners(); } SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCityId(SelectionModel id, {bool isForSearch = false}) async { if (isForSearch) { VehicleCityModel city = vehicleCities.firstWhere((element) => element.id == id.selectedId); DropValue cityValue = DropValue(city.id ?? 0, city.cityName ?? "", ""); if (!ifAlreadyExist(list: vehicleLocationAdSearchHistory, value: cityValue)) { addToVehicleLocationAdSearchHistory(value: cityValue); } } vehicleCityId = id; notifyListeners(); } SelectionModel vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdDurationId(SelectionModel id) { vehicleAdDurationId = id; notifyListeners(); } SelectionModel vehicleExtendAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleExtendAdDurationId(SelectionModel id) { vehicleAdDurationId = id; notifyListeners(); } SelectionModel vehicleAdReservableId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdReservableId(SelectionModel id) { vehicleAdReservableId = id; notifyListeners(); } SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdsSpecialServicesId(SelectionModel id) async { vehicleAdsSpecialServicesId = id; // isFetchingLists = true; // adSSTimeSlots.clear(); // vehicleAdsPhotoServiceDate = SelectionModel(selectedId: -1, selectedOption: ""); // vehicleAdsCarCheckServicesDate = SelectionModel(selectedId: -1, selectedOption: ""); // notifyListeners(); // if (id.selectedId == 1) { // ssPhotoScheduleModel = await commonRepo.getPhotographyServiceScheduleDetails(lat: 0.0, long: 0.0); // } else if (id.selectedId == 3) { // ssCarCheckScheduleModel = await commonRepo.getCarCheckServiceScheduleDetails(lat: 0.0, long: 0.0); // } else {} // isFetchingLists = false; notifyListeners(); } List adSSTimeSlots = []; int? slotSelectedIndex; void updateIsSelectedInSlots(int index) { for (var value in adSSTimeSlots) { value.isSelected = false; } slotSelectedIndex = index; notifyListeners(); adSSTimeSlots[index].isSelected = true; } SelectionModel vehicleAdsPhotoServiceDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleVehicleAdsPhotoServiceDate(SelectionModel id) { vehicleAdsPhotoServiceDate = id; adSSTimeSlots.clear(); slotSelectedIndex = null; for (var value in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) { if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsPhotoServiceDate.selectedOption) { adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!)); } } notifyListeners(); } SelectionModel vehicleAdsCarCheckServicesDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdsCarCheckServicesDate(SelectionModel id) { vehicleAdsCarCheckServicesDate = id; adSSTimeSlots.clear(); slotSelectedIndex = null; for (var value in ssCarCheckScheduleModel!.branchScheduleSlots!) { if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsCarCheckServicesDate.selectedOption) { adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!)); } } notifyListeners(); } String selectedTimeSlotForEngineCarCheck = ""; void updateSelectedTimeSlotForEngineCarCheck(String timeSlot) { selectedTimeSlotForEngineCarCheck = timeSlot; notifyListeners(); } bool isPresentInThisList({required List list, required String item}) { bool isPresent = false; for (var element in list) { if (element == item) { isPresent = true; break; } } return isPresent; } List populateScheduleDatesForAdPhotoService() { List vehicleAdsSpecialServiceDates = []; List slotDates = []; if (ssPhotoScheduleModel!.photoOfficeScheduleSlots == null) { return []; } for (var element in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) { if (!slotDates.contains(element.slotDate!)) { slotDates.add(element.slotDate!); vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), "")); } } return vehicleAdsSpecialServiceDates; } List populateScheduleDatesForAdCarCheckService() { List vehicleAdsSpecialServiceDates = []; List slotDates = []; if (ssCarCheckScheduleModel!.branchScheduleSlots == null) { return []; } for (var element in ssCarCheckScheduleModel!.branchScheduleSlots!) { if (!slotDates.contains(element.slotDate!)) { slotDates.add(element.slotDate!); vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), "")); } } return vehicleAdsSpecialServiceDates; } bool isVehicleDetailsValidated() { bool isValidated = true; if (vehicleTypeId.selectedId == -1) { vehicleTypeId.errorValue = "Please select vehicle type"; isValidated = false; notifyListeners(); return isValidated; } else { vehicleTypeId.errorValue = ""; } if (vehicleModelId.selectedId == -1) { vehicleModelId.errorValue = "Please select vehicle model"; isValidated = false; } else { vehicleModelId.errorValue = ""; } if (vehicleModelYearId.selectedId == -1) { vehicleModelYearId.errorValue = "Please select vehicle model year"; isValidated = false; } else { vehicleModelYearId.errorValue = ""; } if (vehicleColorId.selectedId == -1) { vehicleColorId.errorValue = "Please select vehicle color"; isValidated = false; } else { vehicleColorId.errorValue = ""; } if (vehicleConditionId.selectedId == -1) { vehicleConditionId.errorValue = "Please select vehicle condition"; isValidated = false; } else { vehicleConditionId.errorValue = ""; } if (vehicleCategoryId.selectedId == -1) { vehicleCategoryId.errorValue = "Please select vehicle category"; isValidated = false; } else { vehicleCategoryId.errorValue = ""; } if (vehicleMileageId.selectedId == -1) { vehicleMileageId.errorValue = "Please select vehicle Mileage"; isValidated = false; } else { vehicleMileageId.errorValue = ""; } if (vehicleTransmissionId.selectedId == -1) { vehicleTransmissionId.errorValue = "Please select vehicle transmission"; isValidated = false; } else { vehicleTransmissionId.errorValue = ""; } if (vehicleSellerTypeId.selectedId == -1) { vehicleSellerTypeId.errorValue = "Please select vehicle seller type"; isValidated = false; } else { vehicleSellerTypeId.errorValue = ""; } if (vehicleCountryId.selectedId == -1) { vehicleCountryId.errorValue = "Please select any"; isValidated = false; } else { vehicleCountryId.errorValue = ""; } if (vehicleCityId.selectedId != -1 && vehicleCityId.selectedId == -1) { vehicleCityId.errorValue = "Please select vehicle city"; isValidated = false; } else { vehicleCityId.errorValue = ""; } if (vehicleDemandAmount.isEmpty) { demandAmountError = GlobalConsts.demandAmountError; isValidated = false; } else { demandAmountError = ""; } if (vehicleVin.isEmpty) { vehicleVinError = GlobalConsts.vehicleVinError; isValidated = false; } else { vehicleVinError = ""; } if (vehicleTitle.isEmpty) { vehicleTitleError = GlobalConsts.vehicleTitleError; isValidated = false; } else { vehicleTitleError = ""; } if (warrantyDuration.isEmpty) { warrantyError = GlobalConsts.warrantyError; isValidated = false; } else { warrantyError = ""; } if (vehicleDescription.isEmpty) { vehicleDescError = GlobalConsts.vehicleDescError; isValidated = false; } else { vehicleDescError = ""; } if (pickedVehicleImages.isEmpty || pickedVehicleImages.length < 3) { vehicleImageError = GlobalConsts.attachImageError; isValidated = false; } else { vehicleImageError = ""; } notifyListeners(); return isValidated; } bool isDamagePartsValidated() { bool isValidated = true; for (var element in vehicleDamageCards) { if (element.partSelectedId!.selectedId == -1) { element.partSelectedId!.errorValue = "Please select vehicle part"; isValidated = false; } else { element.partSelectedId!.errorValue = ""; } } for (var element in vehicleDamageCards) { if (element.partImages == null || element.partImages!.isEmpty) { element.partImageErrorValue = GlobalConsts.attachDamagePartImage; isValidated = false; } else { element.partImageErrorValue = ""; } } // if (pickedDamageImages.isEmpty || pickedDamageImages.length < 3) { // vehicleDamageImageError = GlobalConsts.attachImageError; // isValidated = false; // } else { // vehicleDamageImageError = ""; // } notifyListeners(); return isValidated; } bool isAdDurationValidated() { bool isValidated = true; if (vehicleAdDurationId.selectedId == -1) { vehicleAdDurationId.errorValue = "Please select vehicle part"; isValidated = false; } else { vehicleAdDurationId.errorValue = ""; } if (selectionDurationStartDate.isEmpty) { adStartDateError = GlobalConsts.adDurationDateError; isValidated = false; } else { adStartDateError = ""; } if (isPhoneNumberShown && adPhoneNumber.isEmpty) { adPhoneNumberError = GlobalConsts.adDurationPhoneNumberError; isValidated = false; } else { adPhoneNumberError = ""; } // // if (vehicleAdReservableId.selectedId == -1) { // vehicleAdReservableId.errorValue = "Please select if the Ad is Reservable or not."; // isValidated = false; // } else { // vehicleAdReservableId.errorValue = ""; // } // // if (adReserveAmount.isEmpty) { // adReservePriceError = GlobalConsts.adReservablePriceErrorConst; // isValidated = false; // } else { // adStartDateError = ""; // } notifyListeners(); return isValidated; } void onBackButtonPressed(BuildContext context) { switch (currentProgressStep) { case AdCreationSteps.vehicleDetails: resetValues(); pop(context); break; case AdCreationSteps.damageParts: currentProgressStep = AdCreationSteps.vehicleDetails; notifyListeners(); break; case AdCreationSteps.adDuration: currentProgressStep = AdCreationSteps.damageParts; notifyListeners(); break; case AdCreationSteps.reviewAd: currentProgressStep = AdCreationSteps.adDuration; notifyListeners(); break; } } void updateCurrentStep(BuildContext context) async { switch (currentProgressStep) { case AdCreationSteps.vehicleDetails: if (isVehicleDetailsValidated()) { currentProgressStep = AdCreationSteps.damageParts; getVehicleDamagePartsList(); notifyListeners(); } break; case AdCreationSteps.damageParts: if (isDamagePartsValidated()) { currentProgressStep = AdCreationSteps.adDuration; getVehicleAdsDuration(); getVehicleAdsSpecialServices(); notifyListeners(); } break; case AdCreationSteps.adDuration: if (isAdDurationValidated()) { currentProgressStep = AdCreationSteps.reviewAd; notifyListeners(); } break; case AdCreationSteps.reviewAd: Utils.showLoading(context); try { int status = await createNewAd(); if (status != 1) { Utils.hideLoading(context); Utils.showToast("Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("A new ads has been created."); currentProgressStep = AdCreationSteps.vehicleDetails; resetValues(); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } catch (e) { Utils.hideLoading(context); Utils.showToast("Error: ${e.toString()}"); } break; } } bool financeAvailableStatus = false; void updateFinanceAvailableStatus(bool status) { financeAvailableStatus = status; notifyListeners(); } bool isPhoneNumberShown = false; void updateIsPhoneNumberShownStatus(bool status) { isPhoneNumberShown = status; notifyListeners(); } bool isNumberOnWhatsApp = false; void updateIsNumberOnWhatsAppStatus(bool status) { isNumberOnWhatsApp = status; notifyListeners(); } List pickedVehicleImages = []; void removeImageFromList(String filePath) { int index = pickedVehicleImages.indexWhere((element) => element.path == filePath); if (index == -1) { return; } pickedVehicleImages.removeAt(index); notifyListeners(); } void pickMultipleImages() async { List images = await commonServices.pickMultipleImages(); pickedVehicleImages.addAll(images); if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; notifyListeners(); } // sourceFlag for Camera = 0 // sourceFlag for Gallery = 1 void pickDamagePartImage(int index) async { List images = await commonServices.pickMultipleImages(); if (images.isNotEmpty) { if (vehicleDamageCards[index].partImages == null) { vehicleDamageCards[index].partImages = images; } else { vehicleDamageCards[index].partImages!.addAll(images); } vehicleDamageCards[index].partImageErrorValue = ""; notifyListeners(); } } List pickedDamageImages = []; void removeDamageImageFromList(String filePath) { int index = pickedDamageImages.indexWhere((element) => element.path == filePath); if (index == -1) { return; } pickedDamageImages.removeAt(index); notifyListeners(); } void removeDamagePartCard(int index) { String option = vehicleDamageCards.elementAt(index).partSelectedId!.selectedOption; for (var value in vehicleDamageParts) { if (value.partName == option) { value.isSelected = false; break; } } vehicleDamageCards.removeAt(index); notifyListeners(); } void removeDamageImageFromCard(int imageIndex, String filePath, int cardIndex) { VehicleDamageCard card = vehicleDamageCards.elementAt(cardIndex); if (card.partImages == null) return; int index = card.partImages!.indexWhere((element) => element.path == filePath); if (index == -1) { return; } vehicleDamageCards[cardIndex].partImages!.removeAt(index); notifyListeners(); } void pickMultipleDamageImages() async { List images = await commonServices.pickMultipleImages(); pickedDamageImages.addAll(images); if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = ""; notifyListeners(); } void resetValues() { pickedDamageImages.clear(); pickedVehicleImages.clear(); vehicleDamageCards.clear(); specialServiceCards.clear(); currentProgressStep = AdCreationSteps.vehicleDetails; vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleDemandAmount = ""; vehicleVin = ""; vehicleTitle = ""; warrantyDuration = ""; vehicleDescription = ""; selectionDurationStartDate = ""; updateFinanceAvailableStatus(false); notifyListeners(); } Future getVehicleDamagePartsList() async { vehicleDamageParts = await adsRepo.getVehicleDamageParts(); notifyListeners(); } resetSpecialServiceBottomSheet() { photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel(); selectedPhotoOfficeSlotDateTime = null; photoSSSchedulesByOffices = []; } SelectionModel photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updatePhotoOfficeSelectedId(SelectionModel id) { photoOfficeSelectedId = id; selectedPhotoSSSchedulesByOffice = photoSSSchedulesByOffices.elementAt(int.parse(id.itemPrice)); notifyListeners(); } updateSelectedPhotoOfficeAppointmentDate({required int dateIndex}) { for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) { element.date!.isSelected = false; for (var element in element.availableSlots!) { element.isSelected = false; } } selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.isSelected = true; selectedPhotoSSSchedulesByOffice.selectedDateIndex = dateIndex; final date = TimeSlotModel( date: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.date, slotId: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.slotId, isSelected: true, slot: "", ); selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date); notifyListeners(); } int? selectedPhotoOfficeSlotDateTime; updateSelectedAppointmentSlotByDate({required int slotIndex}) { for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) { for (var element in element.availableSlots!) { element.isSelected = false; } } int index = selectedPhotoSSSchedulesByOffice.selectedDateIndex!; selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true; selectedPhotoOfficeSlotDateTime = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].slotId; selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots!; notifyListeners(); } List photoSSSchedulesByOffices = []; SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel(); Future getPhotographyServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); try { photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude); if (isNeedToRebuild) setState(ViewState.idle); } catch (e) { if (isNeedToRebuild) setState(ViewState.idle); Utils.showToast("Error: ${e.toString()}"); } } // Future getCarCheckServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async { // if (isNeedToRebuild) setState(ViewState.busy); // // try { // photoSSSchedulesByOffices = await commonRepo.getCarCheckServiceScheduleDetails(lat: latitude, long: longitude); // if (isNeedToRebuild) setState(ViewState.idle); // } catch (e) { // if (isNeedToRebuild) setState(ViewState.idle); // Utils.showToast("Error: ${e.toString()}"); // } // } Future onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel, required int adsSpecialServiceID}) async { bool isValidated = false; if (selectedPhotoSSSchedulesByOffice.photoOfficeID == null) { isValidated = false; } else if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel == null || !selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.date!.isSelected) { isValidated = false; } else { if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots == null) { isValidated = false; } else { TimeSlotModel slot = selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected); if (slot.date.isNotEmpty) { isValidated = true; } } } if (!isValidated) { Utils.showToast("You must select appointment time the service."); return; } Utils.showLoading(context); try { GenericRespModel genericRespModel = await adsRepo.createAppointmentForAdSpecialService( adId: adDetailsModel.id ?? 0, photoOfficeID: photoOfficeSelectedId.selectedId, photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0, adsSpecialServiceID: adsSpecialServiceID, ); Utils.hideLoading(context); if (genericRespModel.messageStatus != 1) { Utils.showToast("Error: ${genericRespModel.message}"); } else { resetSpecialServiceBottomSheet(); navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads); } } catch (e) { Utils.hideLoading(context); Utils.showToast("Error: ${e.toString()}"); } } Future createNewAd() async { AppState appState = injector.get(); List adsSelectedServices = []; for (var value in specialServiceCards) { adsSelectedServices.add(value.serviceSelectedId!.selectedId); } Ads ads = Ads( adsDurationID: vehicleAdDurationId.selectedId, startDate: selectionDurationStartDate, countryId: vehicleCountryId.selectedId, specialServiceIDs: adsSelectedServices, ); List vehicleImages = []; for (var element in pickedVehicleImages) { vehicleImages.add(await convertFileToVehiclePostingImages(file: element)); } List vehicleDamageImages = []; for (var card in vehicleDamageCards) { if (card.partImages != null && card.partImages!.isNotEmpty) { for (var image in card.partImages!) { VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts( file: image, damagePartId: card.partSelectedId!.selectedId, ); vehicleDamageImages.add(stringImage); } } } VehiclePosting vehiclePosting = VehiclePosting( userID: appState.getUser.data!.userInfo!.userId, vehicleType: vehicleTypeId.selectedId, vehicleModelID: vehicleModelId.selectedId, vehicleModelYearID: vehicleModelYearId.selectedId, vehicleColorID: vehicleColorId.selectedId, vehicleCategoryID: vehicleCategoryId.selectedId, vehicleConditionID: vehicleConditionId.selectedId, vehicleMileageID: vehicleMileageId.selectedId, vehicleTransmissionID: vehicleTransmissionId.selectedId, vehicleSellerTypeID: vehicleSellerTypeId.selectedId, cityID: vehicleCityId.selectedId, price: int.parse(vehicleDemandAmount), vehicleVIN: vehicleVin, vehicleDescription: vehicleDescription, vehicleTitle: vehicleTitle, vehicleDescriptionN: vehicleDescription, isFinanceAvailable: financeAvailableStatus, warantyYears: int.parse(warrantyDuration), demandAmount: int.parse(vehicleDemandAmount), vehiclePostingImages: vehicleImages, vehiclePostingDamageParts: vehicleDamageImages, phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null, whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null, ); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); GenericRespModel respModel = await adsRepo.createNewAd(adsCreationPayloadModel: adsCreationPayloadModel); return Future.value(respModel.messageStatus); } Future convertFileToVehiclePostingImages({required File file}) async { List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); String fileName = file.path.split('/').last; VehiclePostingImages vehiclePostingImages = VehiclePostingImages( imageName: fileName, imageStr: image, imageUrl: file.path, ); return vehiclePostingImages; } Future convertFileToVehiclePostingDamageParts({required File file, required int damagePartId}) async { List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); VehiclePostingDamageParts vehiclePostingDamageParts = VehiclePostingDamageParts( vehicleImageBase64: image, vehicleDamagePartID: damagePartId, ); return vehiclePostingDamageParts; } // ************ ADS SEARCH VIEW **************** Future populateDataForAdFilter() async { if (vehicleBrands.isEmpty) { vehicleBrands = await adsRepo.getVehicleBrands(vehicleTypeId: -1); } if (vehicleModelYears.isEmpty) { vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: -1); } vehicleCities = await adsRepo.getVehicleCities(countryId: -1); // fetch all the cities } ifAlreadyExist({required List list, required DropValue value}) { int index = list.indexWhere((element) { return element.id == value.id; }); if (index != -1) { return true; } return false; } //BRANDS List vehicleBrandsAdSearchHistory = []; void removeVehicleBrandsAdSearchHistory({bool isClear = false, required int index}) { if (isClear) { vehicleBrandsAdSearchHistory.clear(); notifyListeners(); return; } vehicleBrandsAdSearchHistory.removeAt(index); notifyListeners(); } void addToVehicleBrandsAdSearchHistory({required DropValue value}) { vehicleBrandsAdSearchHistory.add(value); notifyListeners(); } // LOCATION List vehicleLocationAdSearchHistory = []; void removeVehicleLocationAdSearchHistory({bool isClear = false, required int index}) { if (isClear) { vehicleLocationAdSearchHistory.clear(); notifyListeners(); return; } vehicleLocationAdSearchHistory.removeAt(index); notifyListeners(); } void addToVehicleLocationAdSearchHistory({required DropValue value}) { vehicleLocationAdSearchHistory.add(value); notifyListeners(); } // OWNER List vehicleAdOwnerSearchHistory = []; void removeVehicleAdOwnerSearchHistory({bool isClear = false, required int index}) { if (isClear) { vehicleAdOwnerSearchHistory.clear(); notifyListeners(); return; } vehicleAdOwnerSearchHistory.removeAt(index); notifyListeners(); } void addToVehicleAdOwnerSearchHistory({required DropValue value}) { vehicleAdOwnerSearchHistory.add(value); notifyListeners(); } // YEAR List vehicleYearAdSearchHistory = []; void removeVehicleYearAdSearchHistory({bool isClear = false, required int index}) { if (isClear) { vehicleYearAdSearchHistory.clear(); notifyListeners(); return; } vehicleYearAdSearchHistory.removeAt(index); notifyListeners(); } void addToVehicleYearAdSearchHistory({required DropValue value}) { vehicleYearAdSearchHistory.add(value); notifyListeners(); } } class VehicleDamageCard { List? partImages; SelectionModel? partSelectedId; String partImageErrorValue; VehicleDamageCard({ this.partImages, this.partSelectedId, this.partImageErrorValue = "", }); } class SpecialServiceCard { SelectionModel? serviceSelectedId; String? serviceDate; String? serviceDateError; String? serviceTime; String? serviceTimeError; String? description; String? duration; String? address; SpecialServiceCard({ this.serviceSelectedId, this.serviceDate = "", this.serviceDateError = "", this.serviceTime = "", this.serviceTimeError = "", this.description = "", this.duration = "", this.address = "", }); }