You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
car_common_app/lib/view_models/ad_view_model.dart

3215 lines
114 KiB
Dart

import 'dart:convert';
import 'dart:developer';
import 'dart:io';
2 years ago
import 'package:easy_localization/easy_localization.dart';
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/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
2 years ago
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.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/pdf_receipt_model.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/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart';
import 'package:mc_common_app/models/chat_models/chat_message_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
3 years ago
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';
4 months ago
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart';
4 months ago
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.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/view_models/chat_view_model.dart';
4 months ago
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:provider/provider.dart';
class AdVM extends BaseVM {
final CommonRepo commonRepo;
3 years ago
final AdsRepo adsRepo;
final CommonAppServices commonServices;
AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo});
AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails;
VehicleDetailsModel? vehicleDetails;
List<VehicleTypeModel> vehicleTypes = [];
List<VehicleBrandsModel> vehicleBrands = [];
List<VehicleModel> vehicleModels = [];
List<VehicleYearModel> vehicleModelYears = [];
List<VehicleColorModel> vehicleColors = [];
List<VehicleConditionModel> vehicleConditions = [];
List<VehicleCategoryModel> vehicleCategories = [];
List<VehicleMileageModel> vehicleMileages = [];
List<VehicleTransmissionModel> vehicleTransmissions = [];
List<VehicleSellerTypeModel> vehicleSellerTypes = [];
List<VehiclePartModel> vehicleDamageParts = [];
List<VehiclePartModel> vehiclePartsSearchResults = [];
List<VehicleCountryModel> vehicleCountries = [];
List<VehicleCityModel> vehicleCities = [];
List<AdsDurationModel> vehicleAdsDurations = [];
List<SpecialServiceModel> 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 = "";
2 months ago
String accidentFreeError = "";
// Edit Variables Amir
2 years ago
bool isExtendAdEditEnabled = false;
bool isAdEditEnabled = false;
2 years ago
bool isDraftEditEnabled = false;
AdDetailsModel? previousAdDetails;
2 years ago
List<AdDetailsModel> myDraftAds = [];
4 months ago
List<AdDetailsModel> favouriteAds = [];
List<AdDetailsModel> exploreAds = [];
List<AdDetailsModel> exploreAdsFilteredList = [];
List<AdDetailsModel> myAdsFilteredList = [];
List<AdDetailsModel> myAds = [];
List<AdDetailsModel> myReservedAds = [];
List<AdDetailsModel> myActiveAdsForHome = [];
List<VehicleDamageCard> vehicleDamageCards = [];
void addNewDamagePartCard({required VehicleDamageCard damageCard}) {
vehicleDamageCards.add(damageCard);
notifyListeners();
}
void clearDamageCards() {
vehicleDamageCards.clear();
}
List<SpecialServiceCard> 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);
2 years ago
selectedVehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
adSpecialServiceDate = "";
notifyListeners();
}
void removeSpecialServiceCard(int index) {
2 years ago
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) {
3 years ago
// await getExploreAds();
// }
notifyListeners();
}
List<EnumsModel> myAdsStatusEnums = [];
List<VehicleBrandsModel> vehicleBrandsForFilters = [];
List<FilterListModel> exploreAdsFilterOptions = [];
List<FilterListModel> myAdsFilterOptions = [];
populateAdsFilterList() async {
if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) {
2 years ago
return;
}
if (myAdsStatusEnums.isEmpty) {
myAdsStatusEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.myAdsFilterEnumId);
}
2 years ago
if (vehicleBrandsForFilters.isEmpty) {
vehicleBrandsForFilters = await commonRepo.getVehicleBrands(vehicleTypeId: -1); // to get all the brands
}
exploreAdsFilterOptions.clear();
myAdsFilterOptions.clear();
for (int i = 0; i < myAdsStatusEnums.length; i++) {
1 month ago
myAdsFilterOptions.add(FilterListModel(title: myAdsStatusEnums[i].enumValueStr, titleN: myAdsStatusEnums[i].enumValueStrN, isSelected: false, id: myAdsStatusEnums[i].enumValue));
}
3 months ago
myAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", titleN: "جميع الاعلانات", isSelected: true, id: 0));
for (int i = 0; i < vehicleBrandsForFilters.length; i++) {
exploreAdsFilterOptions.add(FilterListModel(
id: vehicleBrandsForFilters[i].id!,
title: "${vehicleBrandsForFilters[i].vehicleBrandDescription}",
3 months ago
titleN: "${vehicleBrandsForFilters[i].vehicleBrandDescriptionN}",
2 years ago
iconUrl: vehicleBrandsForFilters[i].imageUrl ?? "",
isSelected: false,
));
}
1 month ago
exploreAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", titleN: "جميع الاعلانات", isSelected: true, id: 0));
notifyListeners();
}
applyFilterOnExploreAds({required int vehicleBrandId}) async {
pageIndexForExploreAds = 1;
hasMoreDataForExploreAds = true;
if (exploreAdsFilterOptions.isEmpty) return;
int index = exploreAdsFilterOptions.indexWhere((element) => element.id == vehicleBrandId);
for (var value in exploreAdsFilterOptions) {
value.isSelected = false;
}
exploreAdsFilterOptions[index].isSelected = true;
if (vehicleBrandId == 0) {
// all ads
getExploreAds();
3 years ago
return;
}
setState(ViewState.busy);
exploreAdsFilteredList = await getAdsByFilter(vehicleBrandId: vehicleBrandId, isMyAds: false);
setState(ViewState.idle);
notifyListeners();
}
int pageIndexForExploreAds = 1;
int pageIndexForMyAds = 1;
bool hasMoreDataForExploreAds = true;
bool hasMoreDataForMyAds = true;
2 years ago
bool isLoadingMore = false;
bool isLoadingAdsDuration = false;
2 years ago
Future<void> fetchMoreExploreAds() async {
if (isLoadingMore) return;
isLoadingMore = true;
hasMoreDataForExploreAds = true;
notifyListeners();
try {
final List<AdDetailsModel> newAds = await getAdsBasedOnFilters(pageIndex: pageIndexForExploreAds, isFromLazyLoad: true);
if (newAds.isEmpty) {
hasMoreDataForExploreAds = false;
} else {
exploreAdsFilteredList.addAll(newAds);
pageIndexForExploreAds++;
if (exploreAdsFilteredList.length < exploreAdsFilteredList.last.totalItemsCount!) {
hasMoreDataForExploreAds = true;
} else {
hasMoreDataForExploreAds = false;
}
}
} catch (error) {
isLoadingMore = false;
Utils.showToast(error.toString());
}
isLoadingMore = false;
notifyListeners();
}
Future<void> fetchMoreMyAds({required AdPostStatus adsStatus}) async {
if (isLoadingMore) return;
hasMoreDataForMyAds = true;
isLoadingMore = true;
notifyListeners();
try {
final List<AdDetailsModel> newAds = await adsRepo.getAllAds(page: pageIndexForMyAds, isMyAds: true, adPostStatus: adsStatus);
if (newAds.isEmpty) {
hasMoreDataForMyAds = false;
} else {
myAdsFilteredList.addAll(newAds);
pageIndexForMyAds++;
if (myAdsFilteredList.length < myAdsFilteredList.last.totalItemsCount!) {
hasMoreDataForMyAds = true;
} else {
hasMoreDataForMyAds = false;
}
}
} catch (error) {
isLoadingMore = false;
Utils.showToast(error.toString());
}
isLoadingMore = false;
notifyListeners();
}
2 years ago
Future<List<AdDetailsModel>> getAdsByFilter({AdPostStatus? adPostStatus, required bool isMyAds, CreatedByRoleEnum? createdByRoleEnum, int? vehicleBrandId}) async {
return await adsRepo.getAllAds(isMyAds: isMyAds, adPostStatus: adPostStatus, createdByRoleEnum: createdByRoleEnum, vehicleBrandId: vehicleBrandId);
2 years ago
}
/// Check if the "Reserved" filter is currently selected in My Ads
bool get isReservedFilterSelected {
if (myAdsFilterOptions.isEmpty) return false;
var selectedFilter = myAdsFilterOptions.firstWhere(
(element) => element.isSelected,
orElse: () => FilterListModel(id: 0, title: "All Ads", isSelected: true),
);
return selectedFilter.id.toAdPostEnum() == AdPostStatus.reserved;
}
2 years ago
applyFilterOnMyAds({required AdPostStatus adPostStatusEnum}) async {
pageIndexForMyAds = 1;
hasMoreDataForMyAds = true;
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) {
getMyAds();
return;
}
3 years ago
// this means if the filter is reserved ads
if (adPostStatusEnum == AdPostStatus.reserved) {
// Fetch reserved ads when filter is tapped (lazy loading for consistency)
setState(ViewState.busy);
await getMyReservedAds();
setState(ViewState.idle);
log("📊 Reserved ads count: ${myReservedAds.length}");
myAdsFilteredList = myReservedAds;
for (var ad in myAdsFilteredList) {
ad.isReservedByMe = true;
}
3 years ago
notifyListeners();
return;
}
2 years ago
setState(ViewState.busy);
myAdsFilteredList = await getAdsByFilter(adPostStatus: adPostStatusEnum, isMyAds: true);
setState(ViewState.idle);
notifyListeners();
}
Future<bool> createReserveAd({required int adId, required BuildContext context}) async {
Utils.showLoading(context);
GenericRespModel genericRespModel = await adsRepo.createReserveAd(adId: adId);
if (genericRespModel.messageStatus == null) {
Utils.hideLoading(context);
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
return false;
}
Utils.hideLoading(context);
return true;
}
4 months ago
Future<bool> toggleAdFavorite({required int adsID, required bool isFavorite}) async {
try {
GenericRespModel genericRespModel = await adsRepo.toggleAdFavorite(adsID: adsID, isFavorite: isFavorite);
if (genericRespModel.messageStatus == 1) {
if (genericRespModel.message != null && genericRespModel.message!.isNotEmpty) {
Utils.showToast(genericRespModel.message!);
}
return true;
} else {
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
return false;
}
} catch (e) {
logger.e(e.toString());
Utils.showToast(LocaleKeys.somethingWrong.tr());
return false;
}
}
3 weeks ago
Future<AdDetailsModel?> getAdDetailsById(int adId) async {
try {
return await adsRepo.getAdDetailsById(adId: adId);
} catch (e) {
logger.e(e.toString());
return null;
}
}
Future<void> getExploreAds() async {
pageIndexForExploreAds = 1;
hasMoreDataForExploreAds = true;
setState(ViewState.busy);
3 years ago
exploreAds = await adsRepo.getAllAds(isMyAds: false);
3 years ago
exploreAdsFilteredList = exploreAds;
2 years ago
notifyListeners();
setState(ViewState.idle);
}
2 years ago
bool hasMoreDataForMyDraftsAds = false;
int pageIndexForMyDrafts = 1;
Future<void> getMyDraftAds() async {
2 years ago
try {
pageIndexForMyAds = 1;
hasMoreDataForMyAds = true;
setState(ViewState.busy);
myDraftAds = await adsRepo.getMyDraftAds();
notifyListeners();
setState(ViewState.idle);
} catch (e) {
setState(ViewState.idle);
logger.e(e.toString());
}
2 years ago
}
Future<void> getFavouriteAds({
AdPostStatus? adPostStatus,
CreatedByRoleEnum? createdByRoleEnum,
int? vehicleBrandId,
}) async {
4 months ago
try {
setState(ViewState.busy);
favouriteAds = await adsRepo.getFavouriteAds(
adPostStatus: adPostStatus,
createdByRoleEnum: createdByRoleEnum,
vehicleBrandId: vehicleBrandId,
);
4 months ago
notifyListeners();
setState(ViewState.idle);
} catch (e) {
setState(ViewState.idle);
logger.e(e.toString());
}
}
2 years ago
Future<void> fetchMoreDraftAds() async {
2 years ago
if (isLoadingMore) return;
hasMoreDataForMyDraftsAds = true;
isLoadingMore = true;
notifyListeners();
try {
final List<AdDetailsModel> newAds = await adsRepo.getMyDraftAds(page: pageIndexForMyDrafts);
if (newAds.isEmpty) {
hasMoreDataForMyDraftsAds = false;
} else {
myDraftAds.addAll(newAds);
pageIndexForMyDrafts++;
if (myDraftAds.length < myDraftAds.last.totalItemsCount!) {
hasMoreDataForMyDraftsAds = true;
} else {
hasMoreDataForMyDraftsAds = false;
}
}
} catch (error) {
isLoadingMore = false;
Utils.showToast(error.toString());
}
isLoadingMore = false;
notifyListeners();
}
Future<void> getMyAds() async {
pageIndexForMyAds = 1;
hasMoreDataForMyAds = true;
setState(ViewState.busy);
2 years ago
if (!AppState().getIsViewOnly) {
myAds = await adsRepo.getAllAds(isMyAds: true);
}
myAdsFilteredList = myAds;
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
// Removed: await getMyReservedAds();
// Now lazy loads when "Reserved" filter is tapped (see applyFilterOnMyAds)
notifyListeners();
setState(ViewState.idle);
}
Future<List<AdDetailsModel>> getMyReservedAds() async {
try {
setState(ViewState.busy);
myReservedAds = await adsRepo.getMyReservedAds();
setState(ViewState.idle);
notifyListeners(); // Notify UI of data changes
return myReservedAds;
} catch (e) {
logger.e("Error fetching reserved ads: ${e.toString()}");
setState(ViewState.idle);
myReservedAds = []; // Explicitly set to empty list on error
notifyListeners(); // Notify UI of error state
// Show user-friendly error message
String errorMessage = e.toString().replaceAll('Exception: ', '');
Utils.showToast(errorMessage);
return [];
}
}
Future<void> getVehicleTypes() async {
vehicleTypes = await commonRepo.getVehicleTypes();
notifyListeners();
}
Future<void> getVehicleAdsDuration() async {
isLoadingAdsDuration = true;
notifyListeners();
try {
final countryId = AppState().getUser.data!.userInfo!.countryId;
vehicleAdsDurations = await adsRepo.getAdsDuration(countryId: countryId);
isLoadingAdsDuration = false;
notifyListeners();
} catch (e) {
isLoadingAdsDuration = false;
notifyListeners();
rethrow;
}
}
2 years ago
Future<void> getVehicleAdsSpecialServices({required int cityId, required int countryId, required int specialServiceType}) async {
2 years ago
log("cityId: $cityId");
2 years ago
vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceType: specialServiceType, countryId: countryId, cityId: cityId);
2 years ago
vehicleAdsSpecialServices = vehicleAdsSpecialServices.where((ad) {
bool matchesCityInDetails = ad.details?.any((detail) => detail.fromcity == cityId || detail.tocity == cityId) ?? false;
bool matchesCityInOffice = ad.office?.any((office) => office.cityID == cityId) ?? false;
return matchesCityInDetails || matchesCityInOffice;
}).toList();
notifyListeners();
}
AdsBankDetailsModel? adsBankDetailsModel;
Future<void> getAdBankingAccountInfo({required int adId}) async {
setState(ViewState.busy);
try {
adsBankDetailsModel = await adsRepo.getAdBankingAccountInfo(adId: adId);
setState(ViewState.idle);
} catch (e) {
setState(ViewState.idle);
Utils.showToast(e.toString());
}
}
Future<void> 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 ?? LocaleKeys.somethingWrong.tr());
return;
}
Utils.hideLoading(context);
Utils.showToast(respModel.message ?? LocaleKeys.adMarkedAsSold.tr());
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.sold); //pending for review
2 years ago
navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
}
Future<void> 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 ?? LocaleKeys.somethingWrong.tr());
return;
}
Utils.hideLoading(context);
2 years ago
Utils.showToast(LocaleKeys.adDeletedSuccessfully.tr());
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
2 years ago
navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
}
Future<void> cancelMyAdReservation(BuildContext context, {required int adId, required int adsReserveId, required String reason}) async {
Utils.showLoading(context);
GenericRespModel respModel = await adsRepo.cancelMyAdReservation(adId: adId, adsReserveId: adsReserveId, adsReserveStatus: 2, reason: reason); // 2 for AdsReserveStatus is to Cancel Reservation
if (respModel.messageStatus != 1) {
Utils.hideLoading(context);
Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
return;
}
// Reset the cancel reason text field
reservationCancelReason = "";
reservationCancelError = "";
Utils.hideLoading(context);
2 years ago
Utils.showToast(LocaleKeys.yourReservationCancelled.tr());
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
2 years ago
navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
}
Future<void> deactivateTheAd(BuildContext context, {required int adId, String? comment}) async {
Utils.showLoading(context);
GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.cancelled, comment: comment);
if (respModel.messageStatus != 1) {
Utils.hideLoading(context);
Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
return;
}
Utils.hideLoading(context);
2 years ago
Utils.showToast(LocaleKeys.adDeactivatedSuccessfully.tr());
updateDeactivateAdReasonDescription('');
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.cancelled); //Cacncelled
2 years ago
navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
}
bool isFetchingLists = false;
bool isCountryFetching = false;
// Future<void> 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();
// }
Future<void> getVehicleBrandsByVehicleTypeId({int vehicleIdForEditAd = -1}) async {
// if (vehicleTypeId.selectedId == -1 || vehicleBrands.isNotEmpty) {
// return;
// }
isFetchingLists = true;
notifyListeners();
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId);
isFetchingLists = false;
notifyListeners();
}
Future<void> getVehicleDetailsByVehicleBrandId() async {
// if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) {
// return;
// }
isFetchingLists = true;
notifyListeners();
vehicleDetails = await commonRepo.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: "");
2 years ago
void updateSelectionVehicleTypeId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) {
VehicleTypeModel vehicleTypeModel = vehicleTypesForFilters.firstWhere((element) => element.id == id.selectedId);
DropValue vehicleTypeVValue = DropValue(vehicleTypeModel.id ?? 0, vehicleTypeModel.vehicleTypeName ?? "", "");
if (!ifAlreadyExist(list: vehicleTypesAdSearchHistory, value: vehicleTypeVValue)) {
addToVehicleTypesAdSearchHistory(value: vehicleTypeVValue);
}
notifyListeners();
return;
}
vehicleTypeId = id;
await getVehicleBrandsByVehicleTypeId();
notifyListeners();
}
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
Future<void> updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) {
2 years ago
VehicleBrandsModel brand = vehicleBrandsForFilters.firstWhere((element) => element.id == id.selectedId);
DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", "");
if (!ifAlreadyExist(list: vehicleBrandsAdSearchHistory, value: brandValue)) {
addToVehicleBrandsAdSearchHistory(value: brandValue);
}
3 weeks ago
pruneVehicleModelsAdSearchHistoryForRemovedBrands();
notifyListeners();
return;
}
vehicleBrandId = id;
2 years ago
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
await getVehicleDetailsByVehicleBrandId();
notifyListeners();
}
SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
3 weeks ago
void updateSelectionVehicleModelId(SelectionModel id, {bool isForSearch = false}) {
if (isForSearch) {
VehicleModel model = vehicleModelsForSelectedBrandsFilter.firstWhere((element) => element.id == id.selectedId);
DropValue modelValue = DropValue(model.id ?? 0, model.model ?? "", "");
if (!ifAlreadyExist(list: vehicleModelsAdSearchHistory, value: modelValue)) {
addToVehicleModelsAdSearchHistory(value: modelValue);
}
notifyListeners();
return;
}
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);
}
notifyListeners();
return;
}
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, {bool showSelectionInDropdown = true, bool isForSearch = false}) {
if (isForSearch) {
EnumsModel owner = vehicleConditionsEnum.firstWhere((element) => element.enumValue == id.selectedId);
DropValue ownerValue = DropValue(owner.enumValue, owner.enumValueStr, "");
if (!ifAlreadyExist(list: vehicleAdConditionSearchHistory, value: ownerValue)) {
addToVehicleAdConditionSearchHistory(value: ownerValue);
}
}
if (showSelectionInDropdown) {
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;
}
6 months ago
String odometer = "";
void updateOdometer(String value) {
odometer = value;
notifyListeners();
}
2 months ago
int? isInUsed; // null = not set, 0 = No, 1 = Yes
String isInUsedError = "";
6 months ago
void updateIsInUsed(int value) {
isInUsed = value;
2 months ago
isInUsedError = ""; // Clear error when user makes a selection
6 months ago
notifyListeners();
}
bool isAccidentFree = false;
bool isAccidentFreeSet = false;
void updateIsAccidentFree(bool value) {
isAccidentFree = value;
isAccidentFreeSet = true;
2 months ago
accidentFreeError = ""; // Clear error when user makes a selection
6 months ago
notifyListeners();
}
String reservationCancelReason = "";
String reservationCancelError = "";
void updateReservationCancelReason(String value) {
if (value.isNotEmpty) {
reservationCancelError = "";
}
reservationCancelReason = value;
}
List<OfferRequestCommentModel> deActivateAdModelList = [
OfferRequestCommentModel(
index: 0,
isSelected: true,
title: LocaleKeys.vehicleDealOutsideApp.tr(),
),
OfferRequestCommentModel(
index: 1,
isSelected: false,
title: LocaleKeys.changedDesireToSell.tr(),
),
OfferRequestCommentModel(
index: 2,
isSelected: false,
title: LocaleKeys.otherVar.tr(),
),
];
OfferRequestCommentModel selectedDeActivateAdCommentModel = OfferRequestCommentModel(
index: 0,
isSelected: true,
title: LocaleKeys.changedMind.tr(),
);
void updateSelectionInDeActivateAdModelList(int index) {
for (var value in deActivateAdModelList) {
value.isSelected = false;
}
selectedDeActivateAdCommentModel = deActivateAdModelList[index];
log("selectedDeActivateAdCommentModel: ${selectedDeActivateAdCommentModel.index}");
deActivateAdModelList[index].isSelected = true;
notifyListeners();
}
String deactivateAdReasonDescription = "";
String deactivateAdReasonDescriptionError = "";
void updateDeactivateAdReasonDescription(String value) {
deactivateAdReasonDescription = value;
if (value.isNotEmpty) {
deactivateAdReasonDescriptionError = "";
}
}
bool isDeActivateReasonSubmitValidated() {
if (selectedDeActivateAdCommentModel.index != deActivateAdModelList.length - 1) {
return true;
}
bool isValidated = true;
if (deactivateAdReasonDescription.isEmpty) {
deactivateAdReasonDescriptionError = GlobalConsts.descriptionError;
isValidated = false;
} else {
deactivateAdReasonDescriptionError = "";
}
notifyListeners();
return isValidated;
}
String completeDealNotesForAdmin = "";
void updateCompleteDealNotesForAdmin(String value) {
completeDealNotesForAdmin = value;
}
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, {bool needRefresh = true}) {
vehicleSellerTypeId = id;
if (needRefresh) {
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 commonRepo.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);
}
notifyListeners();
return;
}
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();
}
2 years ago
SelectionModel selectedVehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
2 years ago
void updateSelectedVehicleAdsSpecialServicesId(SelectionModel id) async {
selectedVehicleAdsSpecialServicesId = 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<TimeSlotModel> 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<DropValue> populateScheduleDatesForAdPhotoService() {
List<DropValue> vehicleAdsSpecialServiceDates = [];
List<String> 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<DropValue> populateScheduleDatesForAdCarCheckService() {
List<DropValue> vehicleAdsSpecialServiceDates = [];
List<String> 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) {
2 years ago
vehicleTypeId.errorValue = LocaleKeys.vehicle_selectVehicleType.tr();
isValidated = false;
notifyListeners();
return isValidated;
} else {
vehicleTypeId.errorValue = "";
}
if (vehicleModelId.selectedId == -1) {
2 years ago
vehicleModelId.errorValue = LocaleKeys.vehicle_selectVehicleModel.tr();
isValidated = false;
} else {
vehicleModelId.errorValue = "";
}
if (vehicleModelYearId.selectedId == -1) {
vehicleModelYearId.errorValue = LocaleKeys.vehicle_selectVehicleModelYear.tr();
isValidated = false;
} else {
vehicleModelYearId.errorValue = "";
}
if (vehicleColorId.selectedId == -1) {
2 years ago
vehicleColorId.errorValue = LocaleKeys.vehicle_selectVehicleColor.tr();
isValidated = false;
} else {
vehicleColorId.errorValue = "";
}
if (vehicleConditionId.selectedId == -1) {
2 years ago
vehicleConditionId.errorValue = LocaleKeys.vehicle_vehicleCondition.tr();
isValidated = false;
} else {
vehicleConditionId.errorValue = "";
}
if (vehicleCategoryId.selectedId == -1) {
2 years ago
vehicleCategoryId.errorValue = LocaleKeys.vehicle_vehicleCategory.tr();
isValidated = false;
} else {
vehicleCategoryId.errorValue = "";
}
if (vehicleMileageId.selectedId == -1) {
2 years ago
vehicleMileageId.errorValue = LocaleKeys.vehicle_vehicleMileage.tr();
isValidated = false;
} else {
vehicleMileageId.errorValue = "";
}
if (vehicleTransmissionId.selectedId == -1) {
vehicleTransmissionId.errorValue = LocaleKeys.vehicle_vehicleTransmission.tr();
isValidated = false;
} else {
vehicleTransmissionId.errorValue = "";
}
// if (vehicleSellerTypeId.selectedId == -1) {
// vehicleSellerTypeId.errorValue = LocaleKeys.vehicle_vehicleSellerType.tr();
// isValidated = false;
// } else {
// vehicleSellerTypeId.errorValue = "";
// }
if (vehicleCountryId.selectedId == -1) {
2 years ago
vehicleCountryId.errorValue = LocaleKeys.vehicle_selectAny.tr();
isValidated = false;
} else {
vehicleCountryId.errorValue = "";
}
if (vehicleCityId.selectedId != -1 && vehicleCityId.selectedId == -1) {
2 years ago
vehicleCityId.errorValue = LocaleKeys.vehicle_vehicleCity.tr();
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 = "";
}
1 month ago
2 months ago
// Validate Accident Free field (mandatory)
if (!isAccidentFreeSet) {
accidentFreeError = LocaleKeys.pleaseSelectAccidentFree.tr();
isValidated = false;
} else {
accidentFreeError = "";
}
1 month ago
2 months ago
// Validate Is In Used field (mandatory)
if (isInUsed == null) {
isInUsedError = LocaleKeys.pleaseSelectMileageIncrease.tr();
isValidated = false;
} else {
isInUsedError = "";
}
1 month ago
3 weeks ago
if (pickedPostingImages.isEmpty || (pickedPostingImages.length < 3 && !isAdEditEnabled)) {
vehicleImageError = GlobalConsts.attachImageError;
isValidated = false;
} else {
vehicleImageError = "";
}
notifyListeners();
return isValidated;
}
bool validateReservationCancelReason() {
bool isValidated = true;
if (reservationCancelReason.isEmpty) {
reservationCancelError = GlobalConsts.reservationCancelError;
isValidated = false;
notifyListeners();
}
return isValidated;
}
bool isDamagePartsValidated() {
bool isValidated = true;
for (var element in vehicleDamageCards) {
if (element.partSelectedId!.selectedId == -1) {
element.partSelectedId!.errorValue = LocaleKeys.vehicle_vehiclePart.tr();
isValidated = false;
} else {
element.partSelectedId!.errorValue = "";
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 (AppState().userType != UserType.providerDealer && vehicleAdDurationId.selectedId == -1) {
2 years ago
vehicleAdDurationId.errorValue = LocaleKeys.vehicle_vehiclePart.tr();
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 AdCreationStepsEnum.vehicleDetails:
4 months ago
// Check if user has entered any data
bool hasData = vehicleTypeId.selectedId != -1 ||
vehicleBrandId.selectedId != -1 ||
vehicleModelId.selectedId != -1 ||
vehicleModelYearId.selectedId != -1 ||
vehicleColorId.selectedId != -1 ||
vehicleCategoryId.selectedId != -1 ||
vehicleConditionId.selectedId != -1 ||
vehicleMileageId.selectedId != -1 ||
vehicleTransmissionId.selectedId != -1 ||
vehicleCountryId.selectedId != -1 ||
vehicleCityId.selectedId != -1 ||
vehicleDemandAmount.isNotEmpty ||
vehicleVin.isNotEmpty ||
vehicleTitle.isNotEmpty ||
warrantyDuration.isNotEmpty ||
vehicleDescription.isNotEmpty ||
pickedPostingImages.isNotEmpty;
if (hasData) {
1 month ago
// Skip save confirmation when extending ad
if (isExtendAdEditEnabled) {
isAdEditEnabled = false;
isDraftEditEnabled = false;
isExtendAdEditEnabled = false;
previousAdDetails = null;
resetValues();
pop(context);
return;
}
4 months ago
// Show confirmation dialog if user has entered data
showSaveAsDraftConfirmationDialog(
context,
onYes: () async {
Navigator.pop(context);
await saveAdAsDraft(context: context, stepNoEnum: AdCreationStepsEnum.vehicleDetails, bypassValidation: true);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
isAdEditEnabled = false;
isDraftEditEnabled = false;
resetValues();
pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
},
onNo: () {
Navigator.pop(context);
isAdEditEnabled = false;
isDraftEditEnabled = false;
1 month ago
previousAdDetails = null; // Clear when user cancels without saving
4 months ago
resetValues();
pop(context);
},
);
} else {
// No data entered, go back directly
isAdEditEnabled = false;
isDraftEditEnabled = false;
1 month ago
previousAdDetails = null; // Clear when going back without data
4 months ago
resetValues();
pop(context);
}
break;
case AdCreationStepsEnum.damageParts:
1 month ago
// Skip save confirmation when extending ad
if (isExtendAdEditEnabled) {
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
notifyListeners();
return;
}
4 months ago
showSaveAsDraftConfirmationDialog(
context,
onYes: () async {
Navigator.pop(context);
await saveAdAsDraft(context: context, stepNoEnum: AdCreationStepsEnum.damageParts, bypassValidation: true);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
isAdEditEnabled = false;
isDraftEditEnabled = false;
resetValues();
pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
},
onNo: () {
Navigator.pop(context);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
notifyListeners();
},
);
break;
case AdCreationStepsEnum.adDuration:
1 month ago
// Skip save confirmation when extending ad
if (isExtendAdEditEnabled) {
currentProgressStep = AdCreationStepsEnum.damageParts;
notifyListeners();
return;
}
4 months ago
showSaveAsDraftConfirmationDialog(
context,
onYes: () async {
Navigator.pop(context);
await saveAdAsDraft(context: context, stepNoEnum: AdCreationStepsEnum.adDuration, bypassValidation: true);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
isAdEditEnabled = false;
isDraftEditEnabled = false;
resetValues();
pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
},
onNo: () {
Navigator.pop(context);
currentProgressStep = AdCreationStepsEnum.damageParts;
notifyListeners();
},
);
break;
case AdCreationStepsEnum.reviewAd:
1 month ago
// Skip save confirmation when extending ad
if (isExtendAdEditEnabled) {
currentProgressStep = AdCreationStepsEnum.adDuration;
notifyListeners();
return;
}
4 months ago
showSaveAsDraftConfirmationDialog(
context,
onYes: () async {
Navigator.pop(context);
await saveAdAsDraft(context: context, stepNoEnum: AdCreationStepsEnum.reviewAd, bypassValidation: true);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
isAdEditEnabled = false;
isDraftEditEnabled = false;
resetValues();
pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
},
onNo: () {
Navigator.pop(context);
currentProgressStep = AdCreationStepsEnum.adDuration;
notifyListeners();
},
);
break;
}
}
4 months ago
void showSaveAsDraftConfirmationDialog(BuildContext context, {required VoidCallback onYes, required VoidCallback onNo}) {
final isArabic = AppState().isArabic(context);
4 months ago
actionConfirmationBottomSheet(
context: context,
title:( isArabic ? "حفظ كمسودة" : "Save As Draft").toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: isArabic
? "سيتم حفظ إعلانك كمسودة، ويمكنك المتابعة لاحقًا من حيث توقفت. هل تريد الحفظ والرجوع؟"
: "Your ad will be saved as draft and you can continue later from where you left off. Do you want to save and go back?",
4 months ago
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: onYes,
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: LocaleKeys.no.tr(),
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: onNo,
),
),
);
}
Future<int> saveAdVehicleDetailsDraft({required bool isNew, required BuildContext context, required AdCreationStepsEnum stepNoEnum}) async {
AppState appState = injector.get<AppState>();
2 years ago
log("selectionDurationStartDate: $selectionDurationStartDate");
log("specialServiceCards: ${specialServiceCards.length}");
List<int> adsSelectedServices = [];
for (var value in specialServiceCards) {
adsSelectedServices.add(value.serviceSelectedId!.selectedId);
}
Utils.showLoading(context);
try {
Ads ads = Ads(
id: !isNew ? previousAdDetails!.id : 0,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
2 years ago
startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId,
2 years ago
specialServiceIDs: adsSelectedServices,
showContactDetail: isPhoneNumberShown,
isOnWhatsApp: isNumberOnWhatsApp,
);
List<VehiclePostingImages> vehicleImages = [];
for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
}
2 years ago
List<VehiclePostingDamageParts> vehicleDamageImages = [];
for (var card in vehicleDamageCards) {
if (card.partImages != null && card.partImages!.isNotEmpty) {
for (var image in card.partImages!) {
VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
imageModel: image,
damagePartId: card.partSelectedId!.selectedId,
commentParam: card.damagePartDescription ?? "",
);
vehicleDamageImages.add(stringImage);
}
}
}
VehiclePosting vehiclePosting = VehiclePosting(
id: !isNew ? previousAdDetails!.vehiclePostingID : null,
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 == -1 ? 1 : 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,
2 years ago
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
6 months ago
odometer: odometer.isNotEmpty ? int.tryParse(odometer) : 0,
isInUsed: isInUsed,
isAccidentFree: isAccidentFree,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
GenericRespModel respModel = await adsRepo.createOrUpdateDraftAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: isNew,
stepNo: stepNoEnum,
);
Utils.hideLoading(context);
return Future.value(respModel.messageStatus == 1 ? respModel.data : -1);
} catch (e) {
Utils.hideLoading(context);
logger.e(e.toString());
return -1;
}
}
4 months ago
Future<void> saveAdAsDraft({required BuildContext context, required AdCreationStepsEnum stepNoEnum, bool bypassValidation = false}) async {
AppState appState = injector.get<AppState>();
List<int> adsSelectedServices = [];
for (var value in specialServiceCards) {
adsSelectedServices.add(value.serviceSelectedId!.selectedId);
}
Utils.showLoading(context);
try {
Ads ads = Ads(
id: (previousAdDetails != null && previousAdDetails!.id != null) ? previousAdDetails!.id : 0,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate.isNotEmpty ? selectionDurationStartDate : null,
countryId: vehicleCountryId.selectedId != -1 ? vehicleCountryId.selectedId : null,
specialServiceIDs: adsSelectedServices,
showContactDetail: isPhoneNumberShown,
isOnWhatsApp: isNumberOnWhatsApp,
);
List<VehiclePostingImages> vehicleImages = [];
for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
}
List<VehiclePostingDamageParts> vehicleDamageImages = [];
for (var card in vehicleDamageCards) {
if (card.partImages != null && card.partImages!.isNotEmpty) {
for (var image in card.partImages!) {
VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
imageModel: image,
damagePartId: card.partSelectedId!.selectedId,
commentParam: card.damagePartDescription ?? "",
);
vehicleDamageImages.add(stringImage);
}
}
}
VehiclePosting vehiclePosting = VehiclePosting(
id: (previousAdDetails != null && previousAdDetails!.vehiclePostingID != null) ? previousAdDetails!.vehiclePostingID : null,
userID: appState.getUser.data!.userInfo!.userId,
vehicleType: vehicleTypeId.selectedId != -1 ? vehicleTypeId.selectedId : null,
vehicleModelID: vehicleModelId.selectedId != -1 ? vehicleModelId.selectedId : null,
vehicleModelYearID: vehicleModelYearId.selectedId != -1 ? vehicleModelYearId.selectedId : null,
vehicleColorID: vehicleColorId.selectedId != -1 ? vehicleColorId.selectedId : null,
vehicleCategoryID: vehicleCategoryId.selectedId != -1 ? vehicleCategoryId.selectedId : null,
vehicleConditionID: vehicleConditionId.selectedId != -1 ? vehicleConditionId.selectedId : null,
vehicleMileageID: vehicleMileageId.selectedId != -1 ? vehicleMileageId.selectedId : null,
vehicleTransmissionID: vehicleTransmissionId.selectedId != -1 ? vehicleTransmissionId.selectedId : null,
vehicleSellerTypeID: vehicleSellerTypeId.selectedId == -1 ? 1 : vehicleSellerTypeId.selectedId,
cityID: vehicleCityId.selectedId != -1 ? vehicleCityId.selectedId : null,
price: vehicleDemandAmount.isNotEmpty ? int.tryParse(vehicleDemandAmount) : null,
vehicleVIN: vehicleVin.isNotEmpty ? vehicleVin : null,
vehicleDescription: vehicleDescription.isNotEmpty ? vehicleDescription : null,
vehicleTitle: vehicleTitle.isNotEmpty ? vehicleTitle : null,
vehicleDescriptionN: vehicleDescription.isNotEmpty ? vehicleDescription : null,
isFinanceAvailable: financeAvailableStatus,
warantyYears: warrantyDuration.isNotEmpty ? int.tryParse(warrantyDuration) : null,
demandAmount: vehicleDemandAmount.isNotEmpty ? int.tryParse(vehicleDemandAmount) : null,
vehiclePostingImages: vehicleImages,
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: (isPhoneNumberShown && adPhoneNumber.isNotEmpty) ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp && adPhoneNumber.isNotEmpty) ? adPhoneNumberDialCode + adPhoneNumber : null,
odometer: odometer.isNotEmpty ? int.tryParse(odometer) : 0,
isInUsed: isInUsed,
isAccidentFree: isAccidentFree,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
1 month ago
log("adsCreationPayloadModel Ads: ${adsCreationPayloadModel.ads.toString()}");
log("adsCreationPayloadModel Posting: ${adsCreationPayloadModel.vehiclePosting.toString()}");
4 months ago
GenericRespModel respModel = await adsRepo.createOrUpdateDraftAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: previousAdDetails == null || previousAdDetails!.id == null,
stepNo: stepNoEnum,
);
Utils.hideLoading(context);
if (respModel.messageStatus == 1) {
Utils.showToast('Saved as Draft');
getMyDraftAds();
} else {
Utils.showToast(respModel.message ?? "Failed to save draft");
}
} catch (e) {
Utils.hideLoading(context);
logger.e(e.toString());
Utils.showToast("Error saving draft: ${e.toString()}");
}
}
Future saveAdDamagePartDetailsDraft() async {}
Future saveAdDurationsDraft() async {}
void updateCurrentStep(BuildContext context) async {
switch (currentProgressStep) {
case AdCreationStepsEnum.vehicleDetails:
if (isVehicleDetailsValidated()) {
1 month ago
// Skip draft saving when extending ad - ad is already approved
if (!isExtendAdEditEnabled) {
int adID = await saveAdVehicleDetailsDraft(isNew: previousAdDetails == null || previousAdDetails!.id == null, context: context, stepNoEnum: AdCreationStepsEnum.vehicleDetails);
previousAdDetails ??= AdDetailsModel();
if (previousAdDetails!.id == null) {
previousAdDetails!.id = adID;
}
}
currentProgressStep = AdCreationStepsEnum.damageParts;
getVehicleDamagePartsList();
notifyListeners();
}
break;
case AdCreationStepsEnum.damageParts:
if (isDamagePartsValidated()) {
1 month ago
// Skip draft saving when extending ad - ad is already approved
if (!isExtendAdEditEnabled) {
await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.damageParts);
}
currentProgressStep = AdCreationStepsEnum.adDuration;
if (vehicleAdsDurations.isEmpty) {
getVehicleAdsDuration();
}
2 years ago
getVehicleAdsSpecialServices(countryId: vehicleCountryId.selectedId, cityId: vehicleCityId.selectedId, specialServiceType: 1);
notifyListeners();
}
break;
case AdCreationStepsEnum.adDuration:
// log("state: ${AppState().getUser.data!.accessToken}");
if (isAdDurationValidated()) {
1 month ago
// Skip draft saving when extending ad - ad is already approved
if (!isExtendAdEditEnabled) {
await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.adDuration);
}
currentProgressStep = AdCreationStepsEnum.reviewAd;
notifyListeners();
}
break;
case AdCreationStepsEnum.reviewAd:
Utils.showLoading(context);
try {
bool status = await createNewAd();
if (!status) {
Utils.hideLoading(context);
return;
}
isAdEditEnabled = false;
2 years ago
isDraftEditEnabled = false;
2 years ago
isExtendAdEditEnabled = false;
1 month ago
previousAdDetails = null; // Clear after successful ad creation
Utils.hideLoading(context);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
resetValues();
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
2 years ago
navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
} 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<ImageModel> pickedPostingImages = [];
void removeImageFromList(String filePath) {
int index = pickedPostingImages.indexWhere((element) => element.filePath == filePath);
if (index == -1) {
return;
}
pickedPostingImages.removeAt(index);
notifyListeners();
}
void pickMultipleImages() async {
List<ImageModel> imageModels = [];
List<File> images = await commonServices.pickMultipleImages();
for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
2 years ago
pickedPostingImages.addAll(imageModels);
2 years ago
// Added By Aamir
if (pickedPostingImages.length > GlobalConsts.maxFileCount) {
pickedPostingImages = pickedPostingImages.sublist(0, GlobalConsts.maxFileCount);
6 months ago
Utils.showToast(LocaleKeys.maxFileSelection.tr());
2 years ago
}
if (pickedPostingImages.isNotEmpty) vehicleImageError = "";
notifyListeners();
}
// Single receipt file for Complete Deal flow
ImageModel? pickedReceiptFile;
String receiptFileError = "";
void removeReceiptFile() {
pickedReceiptFile = null;
notifyListeners();
}
void pickReceiptFile(BuildContext context) async {
List<File>? files = await commonServices.pickMultipleFiles(context, allowMultiple: false);
if (files == null || files.isEmpty) return;
pickedReceiptFile = ImageModel(filePath: files.first.path, isFromNetwork: false);
if (pickedReceiptFile != null) receiptFileError = "";
notifyListeners();
}
// Upload bank receipt for Complete Deal
Future<void> uploadBankReceipt(BuildContext context, {required int adId}) async {
if (pickedReceiptFile == null) {
receiptFileError = LocaleKeys.selectAttachment.tr();
notifyListeners();
return;
}
try {
Utils.showLoading(context);
// Convert file to base64
File file = File(pickedReceiptFile!.filePath!);
List<int> fileBytes = await file.readAsBytes();
String base64File = base64Encode(fileBytes);
String fileName = file.path.split('/').last;
// Create PdfReceiptModel for API
PdfReceiptModel pdfReceipt = PdfReceiptModel(
id: 0,
pdfName: fileName,
pdfString: base64File,
);
// Call repository method
GenericRespModel response = await adsRepo.uploadBankReceiptsOnReserveDealDone(
adId: adId,
detailNote: completeDealNotesForAdmin,
pdfReceiptsList: [pdfReceipt],
);
Utils.hideLoading(context);
if (response.messageStatus == 1) {
Utils.showToast(response.message ?? "Receipt uploaded successfully");
// Reset values
pickedReceiptFile = null;
completeDealNotesForAdmin = "";
receiptFileError = "";
notifyListeners();
// Close bottom sheet
if (context.mounted) {
Navigator.of(context).pop();
}
} else {
Utils.showToast(response.message ?? "Failed to upload receipt");
}
} catch (e) {
Utils.hideLoading(context);
Utils.showToast("Error uploading receipt: $e");
log("Error in uploadBankReceipt: $e");
}
}
// sourceFlag for Camera = 0
// sourceFlag for Gallery = 1
void pickDamagePartImage(int index) async {
List<ImageModel> imageModels = [];
List<File> images = await commonServices.pickMultipleImages();
for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
if (images.isNotEmpty) {
if (vehicleDamageCards[index].partImages == null) {
vehicleDamageCards[index].partImages = imageModels;
} else {
vehicleDamageCards[index].partImages!.addAll(imageModels);
2 years ago
// Added By Aamir
if (vehicleDamageCards[index].partImages!.length > GlobalConsts.maxFileCount) {
vehicleDamageCards[index].partImages = vehicleDamageCards[index].partImages!.sublist(0, GlobalConsts.maxFileCount);
6 months ago
Utils.showToast(LocaleKeys.maxFileSelection.tr());
2 years ago
}
}
2 years ago
vehicleDamageCards[index].partImageErrorValue = "";
notifyListeners();
}
}
List<File> 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) {
2 years ago
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 updateDamagePartDescription(int index, String value) {
vehicleDamageCards[index].damagePartDescription = value;
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.filePath == filePath);
if (index == -1) {
return;
}
vehicleDamageCards[cardIndex].partImages!.removeAt(index);
notifyListeners();
}
void pickMultipleDamageImages() async {
List<File> images = await commonServices.pickMultipleImages();
pickedDamageImages.addAll(images);
2 years ago
if (pickedDamageImages.length > GlobalConsts.maxFileCount) {
pickedDamageImages = pickedDamageImages.sublist(0, GlobalConsts.maxFileCount);
6 months ago
Utils.showToast(LocaleKeys.maxFileSelection.tr());
2 years ago
}
if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = "";
notifyListeners();
}
void resetValues() {
pickedDamageImages.clear();
pickedPostingImages.clear();
vehicleDamageCards.clear();
specialServiceCards.clear();
vehicleAdsSpecialServices.clear();
pickedReceiptFile = null;
completeDealNotesForAdmin = "";
receiptFileError = "";
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
2 years ago
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
// vehicleAdDurationId = 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: "");
vehicleDemandAmount = "";
vehicleVin = "";
vehicleTitle = "";
warrantyDuration = "";
vehicleDescription = "";
selectionDurationStartDate = "";
2 years ago
isPhoneNumberShown = false;
isNumberOnWhatsApp = false;
adPhoneNumberDialCode = "";
adPhoneNumber = "";
6 months ago
odometer = "";
2 months ago
isInUsed = null;
isInUsedError = "";
6 months ago
isAccidentFree = false;
isAccidentFreeSet = false;
2 months ago
accidentFreeError = "";
clearSpecialServiceCard();
updateFinanceAvailableStatus(false);
notifyListeners();
}
Future<void> getVehicleDamagePartsList() async {
vehicleDamageParts = await commonRepo.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<SSPhotoOfficeScheduleModel> photoSSSchedulesByOffices = [];
SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();
2 years ago
Future<void> getPhotographyServiceScheduleListByOffices({required int cityId, required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
2 years ago
photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude, cityID: cityId);
if (isNeedToRebuild) setState(ViewState.idle);
} catch (e) {
if (isNeedToRebuild) setState(ViewState.idle);
Utils.showToast("Error: ${e.toString()}");
}
}
// Future<void> 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()}");
// }
// }
2 years ago
Future<void> onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel}) async {
bool isValidated = false;
2 years ago
int specialSServideId = 1;
if (adDetailsModel.specialservice != null && adDetailsModel.specialservice!.isNotEmpty) {
specialSServideId = adDetailsModel.specialservice!.first.specialServiceID ?? 1;
}
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) {
2 years ago
Utils.showToast(LocaleKeys.selectAppointmentTimeService.tr());
return;
}
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await adsRepo.createAppointmentForAdSpecialService(
adId: adDetailsModel.id ?? 0,
photoOfficeID: photoOfficeSelectedId.selectedId,
photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0,
2 years ago
adsSpecialServiceID: specialSServideId,
);
Utils.hideLoading(context);
if (genericRespModel.messageStatus != 1) {
Utils.showToast("${LocaleKeys.error.tr()}: ${genericRespModel.message}");
} else {
resetSpecialServiceBottomSheet();
2 years ago
pop(context);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads);
}
} catch (e) {
Utils.hideLoading(context);
Utils.showToast("${LocaleKeys.error.tr()}: ${e.toString()}");
}
}
Future<bool> createNewAd() async {
AppState appState = injector.get<AppState>();
List<int> adsSelectedServices = [];
for (var value in specialServiceCards) {
adsSelectedServices.add(value.serviceSelectedId!.selectedId);
}
2 years ago
log("selectionDurationStartDate: $selectionDurationStartDate");
2 years ago
if (selectionDurationStartDate.isNotEmpty) {
// Define the format of the input string
2 years ago
DateTime startDate = DateHelper.parseStringToDate(selectionDurationStartDate);
2 years ago
DateTime currentDate = DateTime.now();
if (startDate.isBefore(currentDate)) {
selectionDurationStartDate = DateHelper.formatAsYearMonthDay(currentDate);
}
}
2 years ago
log("selectionDurationStartDate: $selectionDurationStartDate");
Ads ads = Ads(
2 years ago
id: isDraftEditEnabled
? null
: isAdEditEnabled
? previousAdDetails!.id
: null,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId,
specialServiceIDs: adsSelectedServices,
2 years ago
showContactDetail: isPhoneNumberShown,
isOnWhatsApp: isNumberOnWhatsApp,
);
List<VehiclePostingImages> vehicleImages = [];
for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
}
List<VehiclePostingDamageParts> vehicleDamageImages = [];
for (var card in vehicleDamageCards) {
if (card.partImages != null && card.partImages!.isNotEmpty) {
for (var image in card.partImages!) {
VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
imageModel: image,
damagePartId: card.partSelectedId!.selectedId,
commentParam: card.damagePartDescription ?? "",
);
vehicleDamageImages.add(stringImage);
}
}
}
1 month ago
log("Creating VehiclePosting - isAdEditEnabled: $isAdEditEnabled, isExtendAdEditEnabled: $isExtendAdEditEnabled");
log("Creating VehiclePosting - previousAdDetails?.vehiclePostingID: ${previousAdDetails?.vehiclePostingID}");
VehiclePosting vehiclePosting = VehiclePosting(
1 month ago
id: (isAdEditEnabled || isExtendAdEditEnabled) && previousAdDetails != null && previousAdDetails!.vehiclePostingID != null ? previousAdDetails!.vehiclePostingID : null,
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 == -1 ? 1 : 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,
6 months ago
odometer: odometer.isNotEmpty ? int.tryParse(odometer) : 0,
isInUsed: isInUsed,
isAccidentFree: isAccidentFree,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
2 years ago
2 years ago
GenericRespModel respModel = await adsRepo.createOrUpdateAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: isDraftEditEnabled ? true : !isAdEditEnabled,
isExtendAdEditEnabled: isExtendAdEditEnabled,
);
Utils.showToast(respModel.message.toString());
return Future.value(respModel.messageStatus == 1);
}
Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async {
VehiclePostingImages vehiclePostingImages;
if (imageModel.isFromNetwork ?? false) {
vehiclePostingImages = VehiclePostingImages(
id: imageModel.id,
imageUrl: imageModel.filePath,
);
} else {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
2 years ago
String fileName = file.path.split('/').last;
vehiclePostingImages = VehiclePostingImages(
imageName: fileName,
imageStr: image,
imageUrl: file.path,
vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
);
}
return vehiclePostingImages;
}
Future<VehiclePostingDamageParts> convertFileToVehiclePostingDamageParts({required ImageModel imageModel, required int damagePartId, required String commentParam}) async {
VehiclePostingDamageParts vehiclePostingDamageParts;
if (imageModel.isFromNetwork ?? false) {
vehiclePostingDamageParts = VehiclePostingDamageParts(
id: imageModel.id,
vehicleDamagePartID: damagePartId,
imageUrl: imageModel.filePath,
comment: commentParam,
vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
);
} else {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
vehiclePostingDamageParts = VehiclePostingDamageParts(vehicleImageBase64: image, vehicleDamagePartID: damagePartId, imageUrl: file.path, comment: commentParam);
}
return vehiclePostingDamageParts;
}
// ************ ADS SEARCH VIEW ****************
List<EnumsModel> vehicleConditionsEnum = [];
List<EnumsModel> adOwnerEnumsFilter = [];
2 years ago
List<VehicleTypeModel> vehicleTypesForFilters = [];
3 weeks ago
List<VehicleModel> vehicleModelsForFilters = [];
// Cascading list: only models belonging to the brand(s) currently selected in vehicleBrandsAdSearchHistory.
List<VehicleModel> get vehicleModelsForSelectedBrandsFilter {
if (vehicleBrandsAdSearchHistory.isEmpty) return [];
Set<int> selectedBrandIds = vehicleBrandsAdSearchHistory.map((e) => e.id).toSet();
return vehicleModelsForFilters.where((model) => selectedBrandIds.contains(model.vehicleBrandID)).toList();
}
Future<void> populateDataForAdFilter() async {
setState(ViewState.busy);
pageIndexForExploreAds = 1;
pageIndexForMyAds = 1;
hasMoreDataForExploreAds = true;
hasMoreDataForMyAds = true;
isLoadingMore = false;
if (adOwnerEnumsFilter.isEmpty) {
adOwnerEnumsFilter = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.adOwnersFilterEnumId);
}
if (vehicleConditionsEnum.isEmpty) {
vehicleConditionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.conditionEnumId);
}
2 years ago
if (vehicleTypesForFilters.isEmpty) {
vehicleTypesForFilters = await commonRepo.getVehicleTypes();
}
if (vehicleBrandsForFilters.isEmpty) {
vehicleBrandsForFilters = await commonRepo.getVehicleBrands(vehicleTypeId: -1); // to get all the brands
}
if (vehicleModelYears.isEmpty) {
vehicleModelYears = await commonRepo.getVehicleModelYears(vehicleTypeId: -1);
}
3 weeks ago
if (vehicleModelsForFilters.isEmpty) {
vehicleModelsForFilters = await commonRepo.getVehicleModels(vehicleTypeId: -1); // to get all the models
}
vehicleCities = await commonRepo.getVehicleCities(countryId: -1); // fetch all the cities
setState(ViewState.idle);
}
ifAlreadyExist({required List<DropValue> list, required DropValue value}) {
int index = list.indexWhere((element) {
return element.id == value.id;
});
if (index != -1) {
return true;
}
return false;
}
2 years ago
ifAlreadyExistForStringValue({required List<String> list, required String value}) {
int index = list.indexWhere((element) {
return element == value;
});
if (index != -1) {
return true;
}
return false;
}
//Ad Demand Price
String adFilterDemandStartPrice = "";
void updateAdFilterDemandStartPrice(String title) {
adFilterDemandStartPrice = title;
}
String adFilterDemandEndPrice = "";
void updateAdFilterDemandEndPrice(String title) {
adFilterDemandEndPrice = title;
}
// Ads Mobile Number Filter
String currentAdMobilePhoneFilter = '';
void onCurrentAdMobilePhoneFilterChanged(var value) {
currentAdMobilePhoneFilter = value;
notifyListeners();
}
List<String> adFilterMobilePhoneSearchHistory = [];
void removeAdFilterMobilePhoneSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
adFilterMobilePhoneSearchHistory.clear();
notifyListeners();
return;
}
adFilterMobilePhoneSearchHistory.removeAt(index);
if (adFilterMobilePhoneSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addAdFilterMobilePhoneSearchHistory({required String value}) {
if (adFilterMobilePhoneSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
if (!ifAlreadyExistForStringValue(list: adFilterMobilePhoneSearchHistory, value: value)) {
adFilterMobilePhoneSearchHistory.add(value);
currentAdMobilePhoneFilter = "";
}
notifyListeners();
}
// Ad ID
List<String> adsFilterAdIDSearchHistory = [];
String currentAdIDFilter = '';
void onCurrentAdIDFilterChanged(var value) {
currentAdIDFilter = value;
notifyListeners();
}
void removeAdFilterAdIDSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
adsFilterAdIDSearchHistory.clear();
notifyListeners();
return;
}
adsFilterAdIDSearchHistory.removeAt(index);
if (adsFilterAdIDSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addAdFilterAdIDSearchHistory({required String value}) {
if (adsFilterAdIDSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
if (!ifAlreadyExistForStringValue(list: adsFilterAdIDSearchHistory, value: value)) {
adsFilterAdIDSearchHistory.add(value);
currentAdIDFilter = "";
}
notifyListeners();
}
//TYPES
List<DropValue> vehicleTypesAdSearchHistory = [];
void removeVehicleTypesAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleTypesAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleTypesAdSearchHistory.removeAt(index);
if (vehicleTypesAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleTypesAdSearchHistory({required DropValue value}) {
if (vehicleTypesAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleTypesAdSearchHistory.add(value);
notifyListeners();
}
//BRANDS
List<DropValue> vehicleBrandsAdSearchHistory = [];
void removeVehicleBrandsAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleBrandsAdSearchHistory.clear();
3 weeks ago
pruneVehicleModelsAdSearchHistoryForRemovedBrands();
notifyListeners();
return;
}
vehicleBrandsAdSearchHistory.removeAt(index);
if (vehicleBrandsAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
3 weeks ago
pruneVehicleModelsAdSearchHistoryForRemovedBrands();
notifyListeners();
}
void addToVehicleBrandsAdSearchHistory({required DropValue value}) {
if (vehicleBrandsAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleBrandsAdSearchHistory.add(value);
notifyListeners();
}
3 weeks ago
// MODELS (cascades from vehicleBrandsAdSearchHistory)
List<DropValue> vehicleModelsAdSearchHistory = [];
void removeVehicleModelsAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleModelsAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleModelsAdSearchHistory.removeAt(index);
if (vehicleModelsAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleModelsAdSearchHistory({required DropValue value}) {
if (vehicleModelsAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleModelsAdSearchHistory.add(value);
notifyListeners();
}
// Removes any previously selected models whose brand is no longer present in vehicleBrandsAdSearchHistory,
// keeping the Model filter consistent whenever the Brand selection changes (add or remove).
void pruneVehicleModelsAdSearchHistoryForRemovedBrands() {
if (vehicleModelsAdSearchHistory.isEmpty) return;
Set<int> validModelIds = vehicleModelsForSelectedBrandsFilter.map((e) => e.id ?? -1).toSet();
int previousLength = vehicleModelsAdSearchHistory.length;
vehicleModelsAdSearchHistory.removeWhere((element) => !validModelIds.contains(element.id));
if (vehicleModelsAdSearchHistory.isEmpty && previousLength > 0) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
}
// LOCATION
List<DropValue> vehicleLocationAdSearchHistory = [];
void removeVehicleLocationAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleLocationAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleLocationAdSearchHistory.removeAt(index);
if (vehicleLocationAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleLocationAdSearchHistory({required DropValue value}) {
if (vehicleLocationAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleLocationAdSearchHistory.add(value);
notifyListeners();
}
// OWNER
SelectionModel vehicleOwnerId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleAdOwnerId(SelectionModel id, {bool showSelectionInDropdown = true, bool isForSearch = false}) {
if (isForSearch) {
EnumsModel owner = adOwnerEnumsFilter.firstWhere((element) => element.enumValue == id.selectedId);
DropValue ownerValue = DropValue(owner.enumValue, "${owner.enumValueStr} Ads", "");
if (!ifAlreadyExist(list: vehicleAdOwnerSearchHistory, value: ownerValue)) {
addToVehicleAdOwnerSearchHistory(value: ownerValue);
}
notifyListeners();
return;
}
if (showSelectionInDropdown) {
vehicleOwnerId = id;
}
notifyListeners();
}
List<DropValue> vehicleAdOwnerSearchHistory = [];
void removeVehicleAdOwnerSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdOwnerSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdOwnerSearchHistory.removeAt(index);
if (vehicleAdOwnerSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleAdOwnerSearchHistory({required DropValue value}) {
if (vehicleAdOwnerSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleAdOwnerSearchHistory.add(value);
notifyListeners();
}
// YEAR
List<DropValue> vehicleYearAdSearchHistory = [];
void removeVehicleYearAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleYearAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleYearAdSearchHistory.removeAt(index);
if (vehicleYearAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleYearAdSearchHistory({required DropValue value}) {
if (vehicleYearAdSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleYearAdSearchHistory.add(value);
notifyListeners();
}
// Created Date
List<DropValue> vehicleAdCreatedDateSearchHistory = [];
void removeVehicleAdCreatedDateSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdCreatedDateSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdCreatedDateSearchHistory.removeAt(index);
if (vehicleAdCreatedDateSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleAdCreatedDateSearchHistory({required DropValue value}) {
if (vehicleAdCreatedDateSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
2 years ago
vehicleAdCreatedDateSearchHistory.add(value);
// if (vehicleAdCreatedDateSearchHistory.isEmpty) {
// vehicleAdCreatedDateSearchHistory.add(value);
// } else {
// vehicleAdCreatedDateSearchHistory.first = value;
// }
2 years ago
notifyListeners();
}
2 years ago
// Ad Condition
List<DropValue> vehicleAdConditionSearchHistory = [];
void removeVehicleAdConditionSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdConditionSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdConditionSearchHistory.removeAt(index);
if (vehicleAdConditionSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleAdConditionSearchHistory({required DropValue value}) {
if (vehicleAdConditionSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleAdConditionSearchHistory.add(value);
notifyListeners();
}
int adsFiltersCounter = 0;
updateAdsFiltersCounter(int value) {
adsFiltersCounter = value;
notifyListeners();
}
void clearAdsFilters() {
2 years ago
adsFilterAdIDSearchHistory.clear();
vehicleTypesAdSearchHistory.clear();
vehicleAdOwnerSearchHistory.clear();
vehicleLocationAdSearchHistory.clear();
vehicleYearAdSearchHistory.clear();
vehicleAdCreatedDateSearchHistory.clear();
vehicleAdConditionSearchHistory.clear();
2 years ago
adFilterMobilePhoneSearchHistory.clear();
1 month ago
vehicleBrandsAdSearchHistory.clear();
3 weeks ago
vehicleModelsAdSearchHistory.clear();
2 years ago
adFilterDemandStartPrice = '';
adFilterDemandEndPrice = '';
1 month ago
clearAdFilterSelections(); // Clear dropdown selections
adsFiltersCounter = 0;
getExploreAds();
notifyListeners();
}
void clearAdFilterSelections() {
vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleOwnerId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
1 month ago
vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
Future<List<AdDetailsModel>> getAdsBasedOnFilters({
required int pageIndex,
required bool isFromLazyLoad,
}) async {
if (!isFromLazyLoad) {
exploreAdsFilteredList.clear();
setState(ViewState.busy);
}
2 years ago
1 month ago
// Auto-add current typed Ad ID to history if not empty and not already in list
if (currentAdIDFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adsFilterAdIDSearchHistory, value: currentAdIDFilter)) {
addAdFilterAdIDSearchHistory(value: currentAdIDFilter);
}
2 years ago
List<String> adIdsList = [];
if (adsFilterAdIDSearchHistory.isNotEmpty) {
for (var element in adsFilterAdIDSearchHistory) {
adIdsList.add(element.toString());
}
}
List<String> cityIdsList = [];
if (vehicleLocationAdSearchHistory.isNotEmpty) {
for (var element in vehicleLocationAdSearchHistory) {
cityIdsList.add(element.id.toString());
}
}
2 years ago
List<String> typesIdsList = [];
if (vehicleTypesAdSearchHistory.isNotEmpty) {
for (var element in vehicleTypesAdSearchHistory) {
typesIdsList.add(element.id.toString());
}
}
List<String> brandsIdsList = [];
if (vehicleBrandsAdSearchHistory.isNotEmpty) {
for (var element in vehicleBrandsAdSearchHistory) {
brandsIdsList.add(element.id.toString());
}
}
3 weeks ago
List<String> modelsIdsList = [];
if (vehicleModelsAdSearchHistory.isNotEmpty) {
for (var element in vehicleModelsAdSearchHistory) {
modelsIdsList.add(element.id.toString());
}
}
List<String> vehicleYearIdsList = [];
if (vehicleYearAdSearchHistory.isNotEmpty) {
for (var element in vehicleYearAdSearchHistory) {
vehicleYearIdsList.add(element.id.toString());
}
}
List<String> adOwnerIdsList = [];
if (vehicleAdOwnerSearchHistory.isNotEmpty) {
for (var element in vehicleAdOwnerSearchHistory) {
adOwnerIdsList.add(element.id.toString());
}
}
List<String> conditionsIdsList = [];
if (vehicleAdConditionSearchHistory.isNotEmpty) {
for (var element in vehicleAdConditionSearchHistory) {
conditionsIdsList.add(element.id.toString());
}
}
List<String> createdDatesList = [];
if (vehicleAdCreatedDateSearchHistory.isNotEmpty) {
for (var element in vehicleAdCreatedDateSearchHistory) {
createdDatesList.add(element.value.toString());
}
}
1 month ago
// Auto-add current typed phone number to history if not empty and not already in list
if (currentAdMobilePhoneFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adFilterMobilePhoneSearchHistory, value: currentAdMobilePhoneFilter)) {
addAdFilterMobilePhoneSearchHistory(value: currentAdMobilePhoneFilter);
}
2 years ago
List<String> phoneNumbersList = [];
if (adFilterMobilePhoneSearchHistory.isNotEmpty) {
for (var element in adFilterMobilePhoneSearchHistory) {
phoneNumbersList.add(element.toString());
}
}
int? startPriceDemand;
int? endPriceDemand;
if (adFilterDemandStartPrice.isNotEmpty) {
try {
startPriceDemand = int.parse(adFilterDemandStartPrice);
} catch (e) {
startPriceDemand = null;
}
}
if (adFilterDemandEndPrice.isNotEmpty) {
try {
endPriceDemand = int.parse(adFilterDemandEndPrice);
} catch (e) {
endPriceDemand = null;
}
}
List<AdDetailsModel> list = await adsRepo.getExploreAdsBasedOnFilters(
2 years ago
adIdsList: adIdsList,
cityIdsList: cityIdsList,
createdByRolesIdsList: adOwnerIdsList,
2 years ago
vehicleTypeIdsList: typesIdsList,
vehicleBrandIdsList: brandsIdsList,
3 weeks ago
vehicleModelIdsList: modelsIdsList,
vehicleModelYearIdsList: vehicleYearIdsList,
vehicleAdConditionIdsList: conditionsIdsList,
vehicleAdCreatedDateList: createdDatesList,
2 years ago
mobileNumbersList: phoneNumbersList,
startPriceDemand: startPriceDemand,
endPriceDemand: endPriceDemand,
page: pageIndex,
);
if (!isFromLazyLoad) {
exploreAdsFilteredList.clear();
exploreAdsFilteredList = list;
setState(ViewState.idle);
} else {
return list;
}
return [];
}
2 years ago
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) {
1 month ago
log("previousDetails: ${previousDetails.vehiclePostingID}");
log("previousDetails: ${previousDetails.vehicle?.id}");
isAdEditEnabled = true;
1 month ago
isDraftEditEnabled = isForDraft; // Only true if editing a draft
2 years ago
isExtendAdEditEnabled = isFromExtendAd;
previousAdDetails = previousDetails;
1 month ago
log("previousAdDetails: ${previousAdDetails?.vehicle?.id}");
autoFillSelectedVehicleType();
autoFillSelectedVehicleAdsDuration();
1 month ago
// if (isForDraft) {
autoFillSelectedVehicleAdsDetails(context);
// }
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd, previousDetails.id]);
}
2 years ago
Future<List<bool>> createAdExtensionOrder(BuildContext context, {required int adId, required int adsDurationId}) async {
// [0] Means API response [1] means isPaymentRequired
try {
Utils.showLoading(context);
GenericRespModel respModel = await adsRepo.createAdExtensionOrder(adID: adId, adsDurationId: adsDurationId, specialServiceIds: []);
2 years ago
if (respModel.messageStatus != 1 && respModel.data == null) {
Utils.hideLoading(context);
Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
2 years ago
return [false, false]; // api fail response
}
Utils.hideLoading(context);
2 years ago
final AdExtensionOrderResponseModel adExtensionOrderResponseModel = AdExtensionOrderResponseModel.fromJson(respModel.data);
return [true, adExtensionOrderResponseModel.isPaymentRequired];
} catch (e) {
Utils.hideLoading(context);
Utils.showToast(e.toString());
2 years ago
return [false, false]; // api fail response
}
}
void autoFillSelectedVehicleType() async {
if (vehicleTypes.isEmpty) {
await getVehicleTypes();
2 years ago
// return;
}
if (vehicleTypes.isNotEmpty) {
for (var vehicle in vehicleTypes) {
2 years ago
vehicle.isSelected = false;
if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) {
vehicle.isSelected = true;
2 years ago
log("Hi: ${vehicle.vehicleTypeName}");
break;
}
}
}
notifyListeners();
}
void autoFillSelectedVehicleAdsDuration() async {
if (vehicleAdsDurations.isEmpty) {
await getVehicleAdsDuration();
}
if (vehicleAdsDurations.isNotEmpty) {
// TODO: FOR THE PROVIDER, THIS CHECK WILL NOT WORK. BECAUSE IN CASE OF PROVIDER,THE PRICE WILL ALWAYS BE 0.0. Have to get ads duration ID from API in previousAd Details
int index = vehicleAdsDurations.indexWhere((element) => element.price == previousAdDetails!.adsDurationPrice!);
if (index != -1) {
updateVehicleAdDurationId(
SelectionModel(
selectedId: vehicleAdsDurations[index].id ?? 0,
selectedOption: "${vehicleAdsDurations[index].days} Days",
itemPrice: vehicleAdsDurations[index].price!.toString(),
currency: vehicleAdsDurations[index].currency!.toString(),
currencyN: vehicleAdsDurations[index].currencyN!.toString(),
),
);
}
}
notifyListeners();
}
List<VehiclePostingDamageParts> vehicleOldDamageImagesList = [];
void removeVehicleOldDamageImagesList(String imageUrl) {
int index = vehicleOldDamageImagesList.indexWhere((element) => element.imageUrl == imageUrl);
if (index == -1) {
return;
}
vehicleOldDamageImagesList.removeAt(index);
notifyListeners();
}
void autoFillSelectedVehicleAdsDetails(BuildContext context) async {
1 month ago
bool isArabic = AppState().isArabic(context);
2 years ago
if (vehicleBrands.isEmpty) {
await getVehicleBrandsByVehicleTypeId();
}
int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID);
2 years ago
if (index != -1) {
await updateSelectionVehicleBrandId(SelectionModel(selectedId: vehicleBrands[index].id!, selectedOption: vehicleBrands[index].vehicleBrandDescription ?? ""));
}
updateSelectionVehicleModelId(SelectionModel(selectedId: previousAdDetails!.vehicle!.model!.id!, selectedOption: previousAdDetails!.vehicle!.model!.label ?? ""));
updateSelectionVehicleModelYearId(SelectionModel(selectedId: previousAdDetails!.vehicle!.modelyear!.id!, selectedOption: previousAdDetails!.vehicle!.modelyear!.label ?? ""));
updateSelectionVehicleColorId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.color!.id!, selectedOption: isArabic ? previousAdDetails!.vehicle!.color!.labelN.toString() : previousAdDetails!.vehicle!.color!.label ?? ""));
updateSelectionVehicleConditionId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.condition!.id!,
selectedOption: isArabic ? previousAdDetails!.vehicle!.condition!.labelN.toString() : previousAdDetails!.vehicle!.condition!.label ?? ""));
updateSelectionVehicleCategoryId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: isArabic ? previousAdDetails!.vehicle!.category!.labelN.toString() : previousAdDetails!.vehicle!.category!.label ?? ""));
updateSelectionVehicleMileageId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.mileage!.id!,
selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}",
));
updateSelectionVehicleTransmissionId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.transmission!.id!,
selectedOption: isArabic ? previousAdDetails!.vehicle!.transmission!.labelN.toString() : previousAdDetails!.vehicle!.transmission!.label ?? ""));
updateSelectionVehicleSellerTypeId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.sellertype!.id!,
selectedOption: isArabic ? previousAdDetails!.vehicle!.sellertype!.labelN.toString() : previousAdDetails!.vehicle!.sellertype!.label ?? ""));
int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID);
if (indexCountry != -1) {
updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[indexCountry].id!, selectedOption: vehicleCountries[indexCountry].countryName ?? ""));
}
2 years ago
updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? ""));
1 month ago
vehicleDemandAmount = (previousAdDetails!.vehicle!.demandAmount == null || previousAdDetails!.vehicle!.demandAmount == 0)
? ""
: previousAdDetails!.vehicle!.demandAmount!.toInt().toString();
vehicleVin = previousAdDetails!.vehicle!.vehicleVIN ?? "";
vehicleTitle = previousAdDetails!.vehicle!.vehicleTitle ?? "";
vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription ?? "";
financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
1 month ago
odometer = (previousAdDetails!.vehicle!.odometer == null || previousAdDetails!.vehicle!.odometer == 0)
? ""
: previousAdDetails!.vehicle!.odometer.toString();
6 months ago
isInUsed = previousAdDetails!.vehicle!.isInUsed ?? 0;
isAccidentFree = previousAdDetails!.vehicle!.isAccidentFree ?? false;
isAccidentFreeSet = true;
pickedPostingImages.clear();
if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
for (var element in previousAdDetails!.vehicle!.image!) {
if (element.imageUrl != null) {
ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true);
2 years ago
log("running");
pickedPostingImages.add(imageModel);
}
}
}
if (previousAdDetails!.vehicle!.damagereport != null && previousAdDetails!.vehicle!.damagereport!.isNotEmpty) {
for (var element in previousAdDetails!.vehicle!.damagereport!) {
int index = -1;
if (vehicleDamageCards.isNotEmpty) {
index = ifDamagePartAlreadyThere(element.vehicleDamagePartID!);
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
vehicleDamageCards[index].partImages!.add(imageModel);
} else {
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
damagePartDescription: "",
partImages: [imageModel],
);
addNewDamagePartCard(damageCard: vehicleDamageCard);
}
}
}
if (previousAdDetails!.specialservice != null && previousAdDetails!.specialservice!.isNotEmpty) {
for (var element in previousAdDetails!.specialservice!) {
SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedId: element.specialServiceID!, selectedOption: element.name ?? "", itemPrice: element.price.toString());
SpecialServiceCard specialServiceCard = SpecialServiceCard(
serviceSelectedId: vehicleAdsSpecialServicesId,
description: element.description ?? "",
duration: "",
serviceDate: "",
serviceDateError: "",
serviceTimeError: "",
address: "",
serviceTime: "",
);
2 years ago
int index = ifSpecialServiceAlreadyThere(element.specialServiceID!);
log("Found at : $index");
if (index == -1) {
addNewSpecialServiceCard(specialServiceCard: specialServiceCard);
}
}
}
2 years ago
// selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
2 years ago
selectionDurationStartDate = ""; // You have to mention this each time
2 years ago
isPhoneNumberShown = previousAdDetails!.showContactDetail ?? false;
adPhoneNumber = previousAdDetails!.adOwnerDetails!.mobileNo ?? "";
isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null;
1 month ago
warrantyDuration = (previousAdDetails!.warrantyYears == null || previousAdDetails!.warrantyYears == "0")
? ""
: previousAdDetails!.warrantyYears!;
notifyListeners();
}
int ifDamagePartAlreadyThere(int partId) {
return vehicleDamageCards.indexWhere((element) => element.partSelectedId!.selectedId == partId);
}
int ifSpecialServiceAlreadyThere(int id) {
return specialServiceCards.indexWhere((element) => element.serviceSelectedId!.selectedId == id);
}
List<BuyersChatForAdsModel> buyersChatListForAds = [];
void onMessagesButtonPressed({required BuildContext context, required AdDetailsModel adDetailsModel}) async {
final myUserID = AppState().getUser.data!.userInfo!.userId;
if (adDetailsModel.isMyAd != null && adDetailsModel.isMyAd!) {
await getBuyerChatsByAds(adsID: adDetailsModel.id!, context: context);
navigateWithName(context, AppRoutes.adsBuyerChatsListView, arguments: buyersChatListForAds);
} else {
ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: adDetailsModel.userID, adsID: adDetailsModel.id);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd);
final chatVM = context.read<ChatVM>();
await chatVM
.getUsersChatMessagesForAd(
2 years ago
context: context,
isForBuyer: true,
adsChatBuyerId: 1,
adID: adDetailsModel.id,
userID: myUserID,
senderName: adDetailsModel.adOwnerName,
)
.whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
}
}
Future<void> getBuyerChatsByAds({required int adsID, required BuildContext context}) async {
try {
Utils.showLoading(context);
List<BuyersChatForAdsModel> buyersChatList = await adsRepo.getChatBuyersForAds(adsID: adsID);
Utils.hideLoading(context);
buyersChatListForAds.clear();
buyersChatListForAds = buyersChatList;
notifyListeners();
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
Utils.hideLoading(context);
}
}
}
class VehicleDamageCard {
List<ImageModel>? partImages;
SelectionModel? partSelectedId;
String? damagePartDescription;
String partImageErrorValue;
VehicleDamageCard({
this.partImages,
this.partSelectedId,
this.damagePartDescription,
this.partImageErrorValue = "",
});
@override
String toString() {
return 'VehicleDamageCard{partImages: $partImages, partSelectedId: $partSelectedId,damagePartDescription: $damagePartDescription, partImageErrorValue: $partImageErrorValue}';
}
}
class ImageModel {
int? id;
bool? isFromNetwork;
String? filePath;
ImageModel({this.id, this.filePath, this.isFromNetwork});
ImageModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
filePath = json['image'];
isFromNetwork = true;
}
@override
String toString() {
return 'ImageModel{id: $id, isFromNetwork: $isFromNetwork, filePath: $filePath}';
}
}
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 = "",
});
}