import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_generic_model.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/widgets_models.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/services.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; class AdVM extends BaseVM { final CommonRepo commonRepo; final CommonServices commonServices; AdVM({required this.commonServices, required this.commonRepo}); AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails; VehicleDetailsModel? vehicleDetails; List vehicleTypes = []; List vehicleModels = []; List vehicleModelYears = []; List vehicleColors = []; List vehicleConditions = []; List vehicleCategories = []; List vehicleMileages = []; List vehicleTransmissions = []; List vehicleSellerTypes = []; List vehicleDamageParts = []; List vehicleCountries = []; List vehicleCities = []; List vehicleAdsDurations = []; List vehicleAdsSpecialServices = []; String demandAmountError = ""; String vehicleVinError = ""; String vehicleTitleError = ""; String warrantyError = ""; String vehicleDescError = ""; String vehicleImageError = ""; String vehicleDamageImageError = ""; String adStartDateError = ""; List allAds = []; List adsFilteredList = []; List myAds = []; List vehicleDamageCards = []; void addNewDamagePartCard({required VehicleDamageCard damageCard}) { vehicleDamageCards.add(damageCard); notifyListeners(); } void clearDamageCards() { vehicleDamageCards.clear(); } List specialServiceCards = []; void addNewSpecialServiceCard({required SpecialServiceCard specialServiceCard}) { int index = vehicleAdsSpecialServices.indexWhere((element) => element.name == specialServiceCard.serviceSelectedId!.selectedOption); if (index != -1) { vehicleAdsSpecialServices[index].isSelected = true; } specialServiceCards.add(specialServiceCard); vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); adSpecialServiceDate = ""; notifyListeners(); } void removeSpecialServiceCard(int index) { String option = specialServiceCards.elementAt(index).serviceSelectedId!.selectedOption; for (var value in vehicleAdsSpecialServices) { if (value.name == option) { value.isSelected = false; break; } } specialServiceCards.removeAt(index); notifyListeners(); } void clearSpecialServiceCard() { specialServiceCards.clear(); } bool isExploreAdsTapped = true; void updateIsExploreAds(bool value) async { isExploreAdsTapped = value; // if (value) { // await getAllAds(); // } notifyListeners(); } List adsFilterOptions = []; populateAdsFilterList() { adsFilterOptions.clear(); adsFilterOptions = [ FilterListModel(title: "All Ads", isSelected: true), FilterListModel(title: "Customer Ads", isSelected: false), FilterListModel(title: "Provider Ads", isSelected: false), FilterListModel(title: "Mowater Ads", isSelected: false), ]; notifyListeners(); } applyFilterOnAds({required int index}) { if (adsFilterOptions.isEmpty) return; for (var value in adsFilterOptions) { value.isSelected = false; } adsFilterOptions[index].isSelected = true; // TODO: --> here we will filter the allAds list // TODO: --> and get the updated list into this new list everytime filter changes adsFilteredList = allAds; notifyListeners(); } Future getMyAds() async { isFetchingLists = true; myAds = await commonRepo.getAllAds(isMyAds: true); isFetchingLists = true; notifyListeners(); } Future getAllAds() async { allAds = await commonRepo.getAllAds(isMyAds: false); notifyListeners(); } Future getVehicleTypes() async { vehicleTypes = await commonRepo.getVehicleTypes(); notifyListeners(); } Future getVehicleAdsDuration() async { vehicleAdsDurations = await commonRepo.getAdsDuration(); notifyListeners(); } Future getVehicleAdsSpecialServices() async { vehicleAdsSpecialServices = await commonRepo.getSpecialServices(); notifyListeners(); } bool isFetchingLists = false; bool isCountryFetching = false; Future getAllDataBasedOnVehicleTypeId() async { if (vehicleTypeId.selectedId == -1) { return; } isFetchingLists = true; notifyListeners(); vehicleModels = await commonRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId); vehicleModelYears = await commonRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId); vehicleColors = await commonRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId); vehicleConditions = await commonRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId); vehicleCategories = await commonRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId); vehicleMileages = await commonRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId); vehicleTransmissions = await commonRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId); vehicleCountries = await commonRepo.getVehicleCountries(); isFetchingLists = false; notifyListeners(); } Future getVehicleDetailsByVehicleId() async { if (vehicleTypeId.selectedId == -1) { return; } isFetchingLists = true; notifyListeners(); vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.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 adSpecialServiceDate = ""; void updateAdSpecialServiceDate(String date) { adSpecialServiceDate = date; if (adSpecialServiceDate.isNotEmpty) { adStartDateError = ""; } notifyListeners(); } SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleTypeId(SelectionModel id) async { vehicleTypeId = id; getVehicleDetailsByVehicleId(); notifyListeners(); } SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleModelId(SelectionModel id) { vehicleModelId = id; notifyListeners(); } SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleModelYearId(SelectionModel id) { vehicleModelYearId = id; notifyListeners(); } SelectionModel vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleColorId(SelectionModel id) { vehicleColorId = id; notifyListeners(); } SelectionModel vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleConditionId(SelectionModel id) { vehicleConditionId = id; notifyListeners(); } SelectionModel vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCategoryId(SelectionModel id) { vehicleCategoryId = id; notifyListeners(); } SelectionModel vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleMileageId(SelectionModel id) { vehicleMileageId = id; notifyListeners(); } String vehicleVin = ""; void updateVehicleVin(String vin) { vehicleVin = vin; } String warrantyDuration = ""; void updateVehicleWarrantyDuration(String warranty) { warrantyDuration = warranty; } String vehicleDemandAmount = ""; void updateVehicleDemandAmount(String amount) { vehicleDemandAmount = amount; } String vehicleTitle = ""; void updateVehicleTitle(String title) { vehicleTitle = title; } String vehicleDescription = ""; void updateVehicleDescription(String desc) { vehicleDescription = desc; } SelectionModel vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleTransmissionId(SelectionModel id) { vehicleTransmissionId = id; notifyListeners(); } SelectionModel vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleSellerTypeId(SelectionModel id) { vehicleSellerTypeId = id; notifyListeners(); } // SelectionModel vehicleDamagePartId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleDamagePartId(SelectionModel id, int index) { vehicleDamageCards[index].partSelectedId = id; int partIndex = vehicleDamageParts.indexWhere((element) => element.partName == id.selectedOption); if (partIndex != -1) { // vehicleDamageParts[partIndex].isSelected = true; } notifyListeners(); } SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCountryId(SelectionModel id) async { vehicleCountryId = id; isCountryFetching = true; notifyListeners(); vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId); isCountryFetching = false; notifyListeners(); } SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateSelectionVehicleCityId(SelectionModel id) { vehicleCityId = id; notifyListeners(); } SelectionModel vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdDurationId(SelectionModel id) { vehicleAdDurationId = id; notifyListeners(); } SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateVehicleAdsSpecialServicesId(SelectionModel id) { vehicleAdsSpecialServicesId = id; notifyListeners(); } bool isVehicleDetailsValidated() { bool isValidated = true; if (vehicleTypeId.selectedId == -1) { vehicleTypeId.errorValue = "Please select vehicle type"; isValidated = false; notifyListeners(); return isValidated; } else { vehicleTypeId.errorValue = ""; } if (vehicleModelId.selectedId == -1) { vehicleModelId.errorValue = "Please select vehicle model"; isValidated = false; } else { vehicleModelId.errorValue = ""; } if (vehicleModelYearId.selectedId == -1) { vehicleModelYearId.errorValue = "Please select vehicle model year"; isValidated = false; } else { vehicleModelYearId.errorValue = ""; } if (vehicleColorId.selectedId == -1) { vehicleColorId.errorValue = "Please select vehicle color"; isValidated = false; } else { vehicleColorId.errorValue = ""; } if (vehicleConditionId.selectedId == -1) { vehicleConditionId.errorValue = "Please select vehicle condition"; isValidated = false; } else { vehicleConditionId.errorValue = ""; } if (vehicleCategoryId.selectedId == -1) { vehicleCategoryId.errorValue = "Please select vehicle category"; isValidated = false; } else { vehicleCategoryId.errorValue = ""; } if (vehicleMileageId.selectedId == -1) { vehicleMileageId.errorValue = "Please select vehicle Mileage"; isValidated = false; } else { vehicleMileageId.errorValue = ""; } if (vehicleTransmissionId.selectedId == -1) { vehicleTransmissionId.errorValue = "Please select vehicle transmission"; isValidated = false; } else { vehicleTransmissionId.errorValue = ""; } if (vehicleSellerTypeId.selectedId == -1) { vehicleSellerTypeId.errorValue = "Please select vehicle seller type"; isValidated = false; } else { vehicleSellerTypeId.errorValue = ""; } if (vehicleCountryId.selectedId == -1) { vehicleCountryId.errorValue = "Please select any"; isValidated = false; } else { vehicleCountryId.errorValue = ""; } if (vehicleCityId.selectedId != -1 && vehicleCityId.selectedId == -1) { vehicleCityId.errorValue = "Please select vehicle city"; isValidated = false; } else { vehicleCityId.errorValue = ""; } if (vehicleDemandAmount.isEmpty) { demandAmountError = GlobalConsts.demandAmountError; isValidated = false; } else { demandAmountError = ""; } if (vehicleVin.isEmpty) { vehicleVinError = GlobalConsts.vehicleVinError; isValidated = false; } else { vehicleVinError = ""; } if (vehicleTitle.isEmpty) { vehicleTitleError = GlobalConsts.vehicleTitleError; isValidated = false; } else { vehicleTitleError = ""; } if (warrantyDuration.isEmpty) { warrantyError = GlobalConsts.warrantyError; isValidated = false; } else { warrantyError = ""; } if (vehicleDescription.isEmpty) { vehicleDescError = GlobalConsts.vehicleDescError; isValidated = false; } else { vehicleDescError = ""; } if (pickedVehicleImages.isEmpty || pickedVehicleImages.length < 3) { vehicleImageError = GlobalConsts.attachImageError; isValidated = false; } else { vehicleImageError = ""; } notifyListeners(); return isValidated; } bool isDamagePartsValidated() { bool isValidated = true; vehicleDamageCards.forEach((element) { if (element.partSelectedId!.selectedId == -1) { element.partSelectedId!.errorValue = "Please select vehicle part"; isValidated = false; } else { element.partSelectedId!.errorValue = ""; } }); vehicleDamageCards.forEach((element) { if (element.partImages == null || element.partImages!.isEmpty) { element.partImageErrorValue = GlobalConsts.attachDamagePartImage; isValidated = false; } else { element.partImageErrorValue = ""; } }); // if (pickedDamageImages.isEmpty || pickedDamageImages.length < 3) { // vehicleDamageImageError = GlobalConsts.attachImageError; // isValidated = false; // } else { // vehicleDamageImageError = ""; // } notifyListeners(); return isValidated; } bool isAdDurationValidated() { bool isValidated = true; if (vehicleAdDurationId.selectedId == -1) { vehicleAdDurationId.errorValue = "Please select vehicle part"; isValidated = false; } else { vehicleAdDurationId.errorValue = ""; } if (selectionDurationStartDate.isEmpty) { adStartDateError = GlobalConsts.adDurationDateError; isValidated = false; } else { adStartDateError = ""; } notifyListeners(); return isValidated; } void onBackButtonPressed(BuildContext context) { switch (currentProgressStep) { case AdCreationStepsEnum.vehicleDetails: resetValues(); pop(context); break; case AdCreationStepsEnum.damageParts: currentProgressStep = AdCreationStepsEnum.vehicleDetails; notifyListeners(); break; case AdCreationStepsEnum.adDuration: currentProgressStep = AdCreationStepsEnum.damageParts; notifyListeners(); break; case AdCreationStepsEnum.reviewAd: currentProgressStep = AdCreationStepsEnum.adDuration; notifyListeners(); break; } } void updateCurrentStep(BuildContext context) async { switch (currentProgressStep) { case AdCreationStepsEnum.vehicleDetails: if (isVehicleDetailsValidated()) { currentProgressStep = AdCreationStepsEnum.damageParts; getVehicleDamagePartsList(); notifyListeners(); } break; case AdCreationStepsEnum.damageParts: if (isDamagePartsValidated()) { currentProgressStep = AdCreationStepsEnum.adDuration; getVehicleAdsDuration(); getVehicleAdsSpecialServices(); notifyListeners(); } break; case AdCreationStepsEnum.adDuration: if (isAdDurationValidated()) { currentProgressStep = AdCreationStepsEnum.reviewAd; notifyListeners(); } break; case AdCreationStepsEnum.reviewAd: Utils.showLoading(context); try { int status = await createNewAd(); if (status != 1) { Utils.hideLoading(context); Utils.showToast("Something went wrong!"); return; } Utils.hideLoading(context); Utils.showToast("A new ads has been created."); currentProgressStep = AdCreationStepsEnum.vehicleDetails; resetValues(); navigateReplaceWithName(context, AppRoutes.dashboard); } catch (e) { Utils.hideLoading(context); Utils.showToast("Error: ${e.toString()}"); } break; } } bool financeAvailableStatus = false; void updateFinanceAvailableStatus(bool status) { financeAvailableStatus = status; notifyListeners(); } List pickedVehicleImages = []; void removeImageFromList(String filePath) { int index = pickedVehicleImages.indexWhere((element) => element.path == filePath); if (index == -1) { return; } pickedVehicleImages.removeAt(index); notifyListeners(); } void pickMultipleImages() async { List Images = await commonServices.pickMultipleImages(); pickedVehicleImages.addAll(Images); if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; notifyListeners(); } // sourceFlag for Camera = 0 // sourceFlag for Gallery = 1 void pickDamagePartImage(int index) async { List images = await commonServices.pickMultipleImages(); if (images.isNotEmpty) { if (vehicleDamageCards[index].partImages == null) { vehicleDamageCards[index].partImages = images; } else { vehicleDamageCards[index].partImages!.addAll(images); } vehicleDamageCards[index].partImageErrorValue = ""; notifyListeners(); } } List pickedDamageImages = []; void removeDamageImageFromList(String filePath) { int index = pickedDamageImages.indexWhere((element) => element.path == filePath); if (index == -1) { return; } pickedDamageImages.removeAt(index); notifyListeners(); } void removeDamagePartCard(int index) { String option = vehicleDamageCards.elementAt(index).partSelectedId!.selectedOption; for (var value in vehicleDamageParts) { if (value.partName == option) { value.isSelected = false; break; } } vehicleDamageCards.removeAt(index); notifyListeners(); } void removeDamageImageFromCard(int imageIndex, String filePath, int cardIndex) { VehicleDamageCard card = vehicleDamageCards.elementAt(cardIndex); if (card.partImages == null) return; int index = card.partImages!.indexWhere((element) => element.path == filePath); if (index == -1) { return; } vehicleDamageCards[cardIndex].partImages!.removeAt(index); notifyListeners(); } void pickMultipleDamageImages() async { List Images = await commonServices.pickMultipleImages(); pickedDamageImages.addAll(Images); if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = ""; notifyListeners(); } void resetValues() { pickedDamageImages.clear(); pickedVehicleImages.clear(); vehicleDamageCards.clear(); specialServiceCards.clear(); currentProgressStep = AdCreationStepsEnum.vehicleDetails; vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleDemandAmount = ""; vehicleVin = ""; vehicleTitle = ""; warrantyDuration = ""; vehicleDescription = ""; selectionDurationStartDate = ""; updateFinanceAvailableStatus(false); notifyListeners(); } Future getVehicleDamagePartsList() async { vehicleDamageParts = await commonRepo.getVehicleDamageParts(); notifyListeners(); } Future createNewAd() async { AppState appState = injector.get(); List adsSelectedServices = []; for (var value in specialServiceCards) { adsSelectedServices.add(value.serviceSelectedId!.selectedId); } Ads ads = Ads( adsDurationID: vehicleAdDurationId.selectedId, startDate: selectionDurationStartDate, countryId: vehicleCountryId.selectedId, specialServiceIDs: adsSelectedServices, ); List vehicleImages = []; pickedVehicleImages.forEach((element) async { vehicleImages.add(await convertFileToVehiclePostingImages(file: element)); }); List vehicleDamageImages = []; for (var card in vehicleDamageCards) { if (card.partImages != null && card.partImages!.length > 0) { for (var image in card.partImages!) { VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts( file: image, damagePartId: card.partSelectedId!.selectedId, ); vehicleDamageImages.add(stringImage); } } } VehiclePosting vehiclePosting = VehiclePosting( userID: appState.getUser.data!.userInfo!.userId, vehicleType: vehicleTypeId.selectedId, vehicleModelID: vehicleModelId.selectedId, vehicleModelYearID: vehicleModelYearId.selectedId, vehicleColorID: vehicleColorId.selectedId, vehicleCategoryID: vehicleCategoryId.selectedId, vehicleConditionID: vehicleConditionId.selectedId, vehicleMileageID: vehicleMileageId.selectedId, vehicleTransmissionID: vehicleTransmissionId.selectedId, vehicleSellerTypeID: vehicleSellerTypeId.selectedId, cityID: vehicleCityId.selectedId, price: int.parse(vehicleDemandAmount), vehicleVIN: vehicleVin, vehicleDescription: vehicleDescription, vehicleTitle: vehicleTitle, vehicleDescriptionN: vehicleDescription, isFinanceAvailable: financeAvailableStatus, warantyYears: int.parse(warrantyDuration), demandAmount: int.parse(vehicleDemandAmount), vehiclePostingImages: vehicleImages, vehiclePostingDamageParts: vehicleDamageImages, ); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); AdsGenericModel respModel = await commonRepo.createNewAd(adsCreationPayloadModel: adsCreationPayloadModel); return Future.value(respModel.messageStatus); } Future convertFileToVehiclePostingImages({required File file}) async { List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); String fileName = file.path.split('/').last; VehiclePostingImages vehiclePostingImages = VehiclePostingImages( imageName: fileName, imageStr: image, imageUrl: file.path, ); return vehiclePostingImages; } Future convertFileToVehiclePostingDamageParts({required File file, required int damagePartId}) async { List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); VehiclePostingDamageParts vehiclePostingDamageParts = VehiclePostingDamageParts( vehicleImageBase64: image, vehicleDamagePartID: damagePartId, ); return vehiclePostingDamageParts; } } class SelectionModel { String selectedOption; int selectedId; String errorValue; String itemPrice; SelectionModel({ this.selectedOption = "", this.errorValue = "", this.selectedId = 0, this.itemPrice = "", }); } class VehicleDamageCard { List? partImages; SelectionModel? partSelectedId; String partImageErrorValue; VehicleDamageCard({ this.partImages, this.partSelectedId, this.partImageErrorValue = "", }); } class SpecialServiceCard { SelectionModel? serviceSelectedId; String? serviceDate; String? serviceDateError; String? serviceTime; String? serviceTimeError; SpecialServiceCard({ this.serviceSelectedId, this.serviceDate = "", this.serviceDateError = "", this.serviceTime = "", this.serviceTimeError = "", }); }