From d1fe3163f3faf2c90f353f608a7db3076543dcfc Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 27 Nov 2024 17:57:05 +0300 Subject: [PATCH] Dropped the JIRA Count to 23 --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 6 +- lib/generated/codegen_loader.g.dart | 12 ++- lib/generated/locale_keys.g.dart | 4 + .../service_schedule_model.dart | 8 +- lib/models/general_models/widgets_models.dart | 4 +- lib/models/services_models/service_model.dart | 35 ++++++-- lib/repositories/appointment_repo.dart | 4 + lib/repositories/branch_repo.dart | 11 ++- lib/view_models/ad_view_model.dart | 45 ++++++---- lib/view_models/appointments_view_model.dart | 90 ++++++++++++------- .../ad_duration_selection_sheet.dart | 1 + .../advertisement/select_ad_type_view.dart | 2 +- .../appointments/appointment_detail_view.dart | 2 +- .../book_appointment_services_view.dart | 6 +- .../appointments/review_appointment_view.dart | 69 ++++++++------ ...appointment_service_pick_bottom_sheet.dart | 28 +++--- lib/views/common_fragments/ads_fragment.dart | 1 + lib/widgets/tab/role_type_tab.dart | 8 +- 19 files changed, 228 insertions(+), 114 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index e5b4816..53f04a9 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -732,5 +732,9 @@ "pleaseEnterStartDateFirst": "من فضلك أدخل تاريخ البدء أولاً.", "endTimeAfterStartTime": "يجب أن يكون وقت الانتهاء بعد وقت البدء.", "pickedLocationNotice": "سيتم استخدام هذا الموقع لجميع الخدمات المنزلية في هذه الموعد", - "serviceNotProvided": "لسوء الحظ، هذه الخدمة غير متوفرة في الفرع الذي اخترته في هذا الموقع المحدد" + "serviceNotProvided": "لسوء الحظ، هذه الخدمة غير متوفرة في الفرع الذي اخترته في هذا الموقع المحدد", + "pleaseSelectService": "يرجى اختيار خدمة واحدة على الأقل", + "operationalIssue": "مشكلة تشغيلية", + "materialIssue": "مشكلة في المواد", + "selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء." } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index eae787f..8839c3c 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -730,5 +730,9 @@ "pleaseEnterStartDateFirst": "Please enter start date first.", "endTimeAfterStartTime": "End Time should be after start time.", "pickedLocationNotice": "This picked location will be used for all home-based services in this appointment", - "serviceNotProvided": "Unfortunately, this service is not provided by your selected branch in this picked location." + "serviceNotProvided": "Unfortunately, this service is not provided by your selected branch in this picked location.", + "pleaseSelectService": "Please select at least one service.", + "operationalIssue": "Operational Issue", + "materialIssue": "Material Issue", + "selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone." } \ No newline at end of file diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 1abcd67..17eaa37 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -748,7 +748,11 @@ class CodegenLoader extends AssetLoader{ "pleaseEnterStartDateFirst": "من فضلك أدخل تاريخ البدء أولاً.", "endTimeAfterStartTime": "يجب أن يكون وقت الانتهاء بعد وقت البدء.", "pickedLocationNotice": "سيتم استخدام هذا الموقع لجميع الخدمات المنزلية في هذه الموعد", - "serviceNotProvided": "لسوء الحظ، هذه الخدمة غير متوفرة في الفرع الذي اخترته في هذا الموقع المحدد" + "serviceNotProvided": "لسوء الحظ، هذه الخدمة غير متوفرة في الفرع الذي اخترته في هذا الموقع المحدد", + "pleaseSelectService": "يرجى اختيار خدمة واحدة على الأقل", + "operationalIssue": "مشكلة تشغيلية", + "materialIssue": "مشكلة في المواد", + "selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء." }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1482,7 +1486,11 @@ static const Map en_US = { "pleaseEnterStartDateFirst": "Please enter start date first.", "endTimeAfterStartTime": "End Time should be after start time.", "pickedLocationNotice": "This picked location will be used for all home-based services in this appointment", - "serviceNotProvided": "Unfortunately, this service is not provided by your selected branch in this picked location." + "serviceNotProvided": "Unfortunately, this service is not provided by your selected branch in this picked location.", + "pleaseSelectService": "Please select at least one service.", + "operationalIssue": "Operational Issue", + "materialIssue": "Material Issue", + "selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone." }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 5198393..201e3e6 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -712,5 +712,9 @@ abstract class LocaleKeys { static const endTimeAfterStartTime = 'endTimeAfterStartTime'; static const pickedLocationNotice = 'pickedLocationNotice'; static const serviceNotProvided = 'serviceNotProvided'; + static const pleaseSelectService = 'pleaseSelectService'; + static const operationalIssue = 'operationalIssue'; + static const materialIssue = 'materialIssue'; + static const selectReasonBeforeCancel = 'selectReasonBeforeCancel'; } diff --git a/lib/models/appointments_models/service_schedule_model.dart b/lib/models/appointments_models/service_schedule_model.dart index 3f07f73..87967b2 100644 --- a/lib/models/appointments_models/service_schedule_model.dart +++ b/lib/models/appointments_models/service_schedule_model.dart @@ -21,6 +21,8 @@ class ServiceAppointmentScheduleModel { double? amountTotal; double? amountRem; int? appointmentType; + double? totalLocationCharges; + CurrentLocationInfoModel? locationInfoModel; AppointmentTypeEnum? appointmentTypeEnum; ServiceAppointmentScheduleModel({ @@ -34,6 +36,8 @@ class ServiceAppointmentScheduleModel { this.amountTotal, this.amountRem, this.appointmentType, + this.totalLocationCharges, + this.locationInfoModel, this.appointmentTypeEnum, }); @@ -74,7 +78,7 @@ class ServiceAppointmentScheduleModel { .toList(); List slotTime = []; for (var element in slotTimeData) { - slotTime.add(TimeSlotModel(isSelected: false, slotId: element.id!, slot: element.startTime ?? "", date: element.slotDate!.toFormattedDateWithoutTime() ?? "")); + slotTime.add(TimeSlotModel(isSelected: false, slotId: element.id!, slot: element.startTime ?? "", date: element.slotDate!.toFormattedDateWithoutTime())); } return slotTime; @@ -112,6 +116,8 @@ class ServiceAppointmentScheduleModel { amountTotal = json['amountTotal']; amountRem = json['amountRem']; appointmentType = json['appointmentType']; + totalLocationCharges = 0.0; + locationInfoModel = CurrentLocationInfoModel(address: "", latitude: 0.0, longitude: 0.0, distanceToBranch: 0.0, homeChargesInCurrentService: 0.0); appointmentTypeEnum = json['appointmentType'] != null ? (json['appointmentType'] as int).toAppointmentTypeEnum() : AppointmentTypeEnum.workshop; } } diff --git a/lib/models/general_models/widgets_models.dart b/lib/models/general_models/widgets_models.dart index 9972299..d4271c9 100644 --- a/lib/models/general_models/widgets_models.dart +++ b/lib/models/general_models/widgets_models.dart @@ -11,17 +11,19 @@ class SelectionModel { int selectedId; String errorValue; String itemPrice; + String currency; SelectionModel({ this.selectedOption = "", this.errorValue = "", this.selectedId = 0, this.itemPrice = "", + this.currency = "", }); @override String toString() { - return 'SelectionModel{selectedOption: $selectedOption, selectedId: $selectedId, errorValue: $errorValue, itemPrice: $itemPrice}'; + return 'SelectionModel{selectedOption: $selectedOption, selectedId: $selectedId, errorValue: $errorValue, itemPrice: $itemPrice, currency: $currency}'; } } diff --git a/lib/models/services_models/service_model.dart b/lib/models/services_models/service_model.dart index 9128bd9..ea06c99 100644 --- a/lib/models/services_models/service_model.dart +++ b/lib/models/services_models/service_model.dart @@ -1,4 +1,5 @@ import 'package:mc_common_app/models/services_models/item_model.dart'; +import 'package:mc_common_app/view_models/appointments_view_model.dart'; class ServiceModel { final int? serviceProviderServiceId; @@ -13,16 +14,15 @@ class ServiceModel { final bool? isAllowAppointment; final bool? isAllowAppointmentHome; final int? customerLocationRange; - final String? rangePricePerKm; + String? rangePricePerKm; final int? itemsCount; List? serviceItems; bool isExpandedOrSelected; int providerServiceId; String providerServiceName; bool isHomeSelected; - String homeLocation; - double distanceToHomeInKms; double currentTotalServicePrice; + CurrentLocationInfoModel servicelocationInfo; ServiceModel({ this.serviceProviderServiceId, @@ -41,12 +41,11 @@ class ServiceModel { this.itemsCount, this.serviceItems, this.isHomeSelected = false, - this.homeLocation = "", - this.distanceToHomeInKms = 0.0, this.currentTotalServicePrice = 0.0, required this.isExpandedOrSelected, required this.providerServiceId, required this.providerServiceName, + required this.servicelocationInfo, }); factory ServiceModel.fromJson(Map json, {bool isForAppointment = false}) => ServiceModel( @@ -62,7 +61,7 @@ class ServiceModel { isAllowAppointment: json["isAllowAppointment"], isAllowAppointmentHome: json["isAllowAppointmentHome"], customerLocationRange: json["customerLocationRange"], - rangePricePerKm: json["rangePricePerKm"].toString(), + rangePricePerKm: json["rangePricePerKm"]?.toString(), itemsCount: json["itemsCount"], serviceItems: isForAppointment ? json["serviceItemList"] == null @@ -75,8 +74,7 @@ class ServiceModel { providerServiceId: 0, providerServiceName: "", isHomeSelected: false, - homeLocation: "", - distanceToHomeInKms: 0.0, + servicelocationInfo: CurrentLocationInfoModel(address: '', distanceToBranch: 0.0, homeChargesInCurrentService: 0.0, latitude: 0.0, longitude: 0.0), ); Map toJson() => { @@ -102,3 +100,24 @@ class ServiceModel { return 'ServiceModel{serviceProviderServiceId: $serviceProviderServiceId, providerServiceDescription: $providerServiceDescription, categoryId: $categoryId, categoryName: $categoryName, serviceId: $serviceId, serviceDescription: $serviceDescription, serviceDescriptionN: $serviceDescriptionN, serviceStatus: $serviceStatus, statusText: $statusText, isAllowAppointment: $isAllowAppointment, isAllowAppointmentHome: $isAllowAppointmentHome, customerLocationRange: $customerLocationRange, rangePricePerKm: $rangePricePerKm, itemsCount: $itemsCount, serviceItems: $serviceItems, isExpandedOrSelected: $isExpandedOrSelected}'; } } + +class CurrentLocationInfoModel { + String address; + double latitude; + double longitude; + double distanceToBranch; + double homeChargesInCurrentService; + + CurrentLocationInfoModel({ + required this.address, + required this.latitude, + required this.longitude, + required this.distanceToBranch, + required this.homeChargesInCurrentService, + }); + + @override + String toString() { + return 'CurrentLocationInfoModel{address: $address, latitude: $latitude, longitude: $longitude, distanceToBranch: $distanceToBranch, homeChargesInCurrentService: $homeChargesInCurrentService}'; + } +} diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index b5037ec..f13fb45 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -166,6 +166,10 @@ class AppointmentRepoImp implements AppointmentRepo { "serviceProviderID": serviceProviderID, "customerID": customerId, "serviceItemID": serviceItemIds, + "amountCustomerLocation": schedule.totalLocationCharges.toString(), + "customerLocLat": (schedule.locationInfoModel!.latitude).toString(), + "customerLocLong": (schedule.locationInfoModel!.longitude).toString(), + "customerLocAddress": (schedule.locationInfoModel!.address).toString(), }); } log("maplist: ${mapList.toString()}"); diff --git a/lib/repositories/branch_repo.dart b/lib/repositories/branch_repo.dart index 1809a7a..2cb2f77 100644 --- a/lib/repositories/branch_repo.dart +++ b/lib/repositories/branch_repo.dart @@ -191,7 +191,9 @@ class BranchRepoImp implements BranchRepo { }; String? token = AppState().getUser.data?.accessToken; debugPrint(token); - return await injector.get().getJsonForObject((json) => Document.fromJson(json), ApiConsts.fetProviderDocument, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? ""); + return await injector + .get() + .getJsonForObject((json) => Document.fromJson(json), ApiConsts.fetProviderDocument, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? ""); } @override @@ -438,10 +440,11 @@ class BranchRepoImp implements BranchRepo { }; if (latitude != null && longitude != null) { - postParams.addAll({"Longitude": "$latitude"}); - postParams.addAll({"Latitude": "$longitude"}); + postParams.addAll({"Longitude": "$longitude"}); + postParams.addAll({"Latitude": "$latitude"}); } - GenericRespModel adsGenericModel = await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.branchesAndServices, token: appState.getUser.data!.accessToken, queryParameters: postParams); + GenericRespModel adsGenericModel = + await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.branchesAndServices, token: appState.getUser.data!.accessToken, queryParameters: postParams); return ProviderProfileModel.fromJson(adsGenericModel.data); } diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 941170c..d46b5a4 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -114,7 +114,10 @@ class AdVM extends BaseVM { } void removeSpecialServiceCard(int index) { - String option = specialServiceCards.elementAt(index).serviceSelectedId!.selectedOption; + String option = specialServiceCards + .elementAt(index) + .serviceSelectedId! + .selectedOption; for (var value in vehicleAdsSpecialServices) { if (value.name == option) { @@ -284,11 +287,17 @@ class AdVM extends BaseVM { } Future> getMyReservedAds() async { - setState(ViewState.busy); - myReservedAds = await adsRepo.getMyReservedAds(); - isFetchingLists = false; - setState(ViewState.idle); - return myReservedAds; + try { + setState(ViewState.busy); + myReservedAds = await adsRepo.getMyReservedAds(); + isFetchingLists = false; + setState(ViewState.idle); + return myReservedAds; + } catch (e) { + logger.e(e.toString()); + setState(ViewState.idle); + return []; + } } Future getVehicleTypes() async { @@ -1240,7 +1249,10 @@ class AdVM extends BaseVM { } void removeDamagePartCard(int index) { - String option = vehicleDamageCards.elementAt(index).partSelectedId!.selectedOption; + String option = vehicleDamageCards + .elementAt(index) + .partSelectedId! + .selectedOption; for (var value in vehicleDamageParts) { if (value.partName == option) { @@ -1518,7 +1530,9 @@ class AdVM extends BaseVM { File file = File(imageModel.filePath!); List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); - String fileName = file.path.split('/').last; + String fileName = file.path + .split('/') + .last; vehiclePostingImages = VehiclePostingImages( imageName: fileName, imageStr: image, @@ -1810,6 +1824,7 @@ class AdVM extends BaseVM { selectedId: vehicleAdsDurations[index].id ?? 0, selectedOption: "${vehicleAdsDurations[index].days} Days", itemPrice: vehicleAdsDurations[index].price!.toString(), + currency: vehicleAdsDurations[index].currency!.toString(), ), ); } @@ -1938,13 +1953,13 @@ class AdVM extends BaseVM { final chatVM = context.read(); await chatVM .getUsersChatMessagesForAd( - context: context, - isForBuyer: true, - adsChatBuyerId: 1, - adID: adDetailsModel.id, - userID: myUserID, - senderName: adDetailsModel.adOwnerName, - ) + context: context, + isForBuyer: true, + adsChatBuyerId: 1, + adID: adDetailsModel.id, + userID: myUserID, + senderName: adDetailsModel.adOwnerName, + ) .whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments)); } } diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index 1e48f60..7547d28 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -138,7 +138,6 @@ class AppointmentsVM extends BaseVM { } else { isSuccess = false; Utils.showToast(element['message']); - return; } }); @@ -230,7 +229,7 @@ class AppointmentsVM extends BaseVM { Utils.showToast(genericRespModel.message.toString()); return; } - if (genericRespModel.messageStatus == 1) { + if (genericRespModel.messageStatus == 1 && AppState().currentAppType == AppType.customer) { context.read().onNavbarTapped(1); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled); Utils.showToast(genericRespModel.message.toString()); @@ -240,6 +239,7 @@ class AppointmentsVM extends BaseVM { navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } } catch (e) { + logger.e(e.toString()); Utils.showToast(e.toString()); } } @@ -282,19 +282,58 @@ class AppointmentsVM extends BaseVM { currentLocationInfoModel = value; pickHomeLocationError = ""; if (currentServiceSelection != null && value != null) { - currentServiceSelection!.homeLocation = value.address; + currentServiceSelection!.servicelocationInfo = value; + } + + if (value != null) { + for (var service in servicesInCurrentAppointment) { + service.servicelocationInfo.address = value.address; + service.servicelocationInfo.latitude = value.latitude; + service.servicelocationInfo.longitude = value.longitude; + service.servicelocationInfo.distanceToBranch = value.distanceToBranch; + service.servicelocationInfo.homeChargesInCurrentService = double.parse(service.rangePricePerKm ?? "0.0"); + } } + notifyListeners(); } void updateBranchServiceId(SelectionModel id) async { branchSelectedServiceId = id; currentServiceSelection = branchServices.firstWhere((element) => element.serviceProviderServiceId == id.selectedId); + if (currentServiceSelection == null) { + return; + } + + servicesInCurrentAppointment.forEach((i) { + log("hlo1: ${i.serviceDescription} ${i.servicelocationInfo.homeChargesInCurrentService}"); + }); + if (!(currentServiceSelection!.isAllowAppointmentHome ?? false)) { + updateIsHomeTapped(false); + return; + } if (currentLocationInfoModel != null) { currentLocationInfoModel!.homeChargesInCurrentService = double.parse(currentServiceSelection!.rangePricePerKm ?? "0.0"); + currentServiceSelection!.servicelocationInfo = CurrentLocationInfoModel( + address: currentLocationInfoModel!.address, + latitude: currentLocationInfoModel!.latitude, + longitude: currentLocationInfoModel!.longitude, + distanceToBranch: currentLocationInfoModel!.distanceToBranch, + homeChargesInCurrentService: double.parse(currentServiceSelection!.rangePricePerKm ?? "0.0"), + ); + + // for (var service in servicesInCurrentAppointment) { + // service.servicelocationInfo.address = currentLocationInfoModel!.address; + // service.servicelocationInfo.latitude = currentLocationInfoModel!.latitude; + // service.servicelocationInfo.longitude = currentLocationInfoModel!.longitude; + // service.servicelocationInfo.distanceToBranch = currentLocationInfoModel!.distanceToBranch; + // } } - log("currentServiceSelection isAllowAppointmentHome: ${currentServiceSelection!.isAllowAppointmentHome}"); - log("currentServiceSelection serviceDescription: ${currentServiceSelection!.serviceDescription}"); + + servicesInCurrentAppointment.forEach((i) { + log("hlo2: ${i.serviceDescription} ${i.servicelocationInfo.homeChargesInCurrentService}"); + }); + notifyListeners(); } @@ -565,7 +604,6 @@ class AppointmentsVM extends BaseVM { double amountToPayForAppointment = 0.0; double totalAmount = 0.0; - double totalLocationCharges = 0.0; List serviceItemsFromApi = []; @@ -697,7 +735,8 @@ class AppointmentsVM extends BaseVM { isScrollControlled: true, enableDrag: true, builder: (BuildContext context) { - double totalKms = double.parse(selectedService.distanceToHomeInKms.toStringAsFixed(2)); + double totalKms = double.parse(selectedService.servicelocationInfo.distanceToBranch.toStringAsFixed(2)); + double pricePerKm = double.parse(selectedService.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)); return InfoBottomSheet( title: LocaleKeys.chargesBreakdown.tr().toText(fontSize: 24, isBold: true), description: Column( @@ -729,14 +768,14 @@ class AppointmentsVM extends BaseVM { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ "${totalKms}km ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - "${selectedService.rangePricePerKm} x $totalKms".toText(fontSize: 12, isBold: true), + "$pricePerKm x $totalKms".toText(fontSize: 12, isBold: true), ], ), 8.height, Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - "${((double.parse(selectedService.rangePricePerKm!)) * totalKms).toStringAsFixed(2)} ${LocaleKeys.sar.tr()}".toText(fontSize: 16, isBold: true), + "${((pricePerKm) * totalKms).toStringAsFixed(2)} ${LocaleKeys.sar.tr()}".toText(fontSize: 16, isBold: true), ], ), ], @@ -748,9 +787,7 @@ class AppointmentsVM extends BaseVM { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - (selectedService.isHomeSelected - ? ((selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)).toStringAsFixed(2) - : "${selectedService.currentTotalServicePrice}") + (selectedService.isHomeSelected ? ((selectedService.currentTotalServicePrice) + (pricePerKm * totalKms)).toStringAsFixed(2) : "${selectedService.currentTotalServicePrice}") .toText(fontSize: 29, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), @@ -798,7 +835,7 @@ class AppointmentsVM extends BaseVM { void onServicesNextPressed(BuildContext context) async { if (allSelectedItemsInAppointments.isEmpty) { - Utils.showToast("Please select at least one service."); + Utils.showToast(LocaleKeys.pleaseSelectService.tr()); return; } Utils.showLoading(context); @@ -806,8 +843,6 @@ class AppointmentsVM extends BaseVM { List serviceItemIdsForHome = []; List serviceItemIdsForWorkshop = []; for (var serviceItem in allSelectedItemsInAppointments) { - log("homeselcted for : ${serviceItem.isHomeSelected}"); - if (serviceItem.isHomeSelected!) { serviceItemIdsForHome.add(serviceItem.id!.toString()); } else { @@ -826,7 +861,6 @@ class AppointmentsVM extends BaseVM { return; } totalAmount = 0.0; - totalLocationCharges = 0.0; amountToPayForAppointment = 0.0; for (var schedule in serviceAppointmentScheduleList) { amountToPayForAppointment = amountToPayForAppointment + (schedule.amountToPay ?? 0.0); @@ -835,8 +869,12 @@ class AppointmentsVM extends BaseVM { int index = servicesInCurrentAppointment.indexWhere((element) => element.serviceProviderServiceId == service.serviceProviderServiceId); if (index != -1) { if (servicesInCurrentAppointment[index].isHomeSelected) { - totalAmount = totalAmount + ((servicesInCurrentAppointment[index].distanceToHomeInKms) * double.parse(servicesInCurrentAppointment[index].rangePricePerKm!)); - totalLocationCharges = totalLocationCharges + (servicesInCurrentAppointment[index].distanceToHomeInKms * double.parse(servicesInCurrentAppointment[index].rangePricePerKm!)); + service.servicelocationInfo = servicesInCurrentAppointment[index].servicelocationInfo; + schedule.locationInfoModel = servicesInCurrentAppointment[index].servicelocationInfo; + totalAmount = + totalAmount + ((servicesInCurrentAppointment[index].servicelocationInfo.distanceToBranch) * servicesInCurrentAppointment[index].servicelocationInfo.homeChargesInCurrentService); + schedule.totalLocationCharges = schedule.totalLocationCharges! + + (servicesInCurrentAppointment[index].servicelocationInfo.distanceToBranch * servicesInCurrentAppointment[index].servicelocationInfo.homeChargesInCurrentService); } } } @@ -1748,19 +1786,3 @@ class AppointmentsVM extends BaseVM { // } } } - -class CurrentLocationInfoModel { - final String address; - final double latitude; - final double longitude; - final double distanceFromCurrent; - double homeChargesInCurrentService; - - CurrentLocationInfoModel({ - required this.address, - required this.latitude, - required this.longitude, - required this.distanceFromCurrent, - required this.homeChargesInCurrentService, - }); -} diff --git a/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart b/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart index 347f1bf..c4fe29b 100644 --- a/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart +++ b/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart @@ -102,6 +102,7 @@ class AdDurationSelectionSheet extends StatelessWidget { selectedId: adDuration.id ?? 0, selectedOption: ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"), itemPrice: adDuration.price!.toString(), + currency: adDuration.currency!.toString(), ), ); }); diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 9649132..07076c9 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -138,7 +138,7 @@ class SelectAdTypeView extends StatelessWidget { 2.width, Padding( padding: const EdgeInsets.only(bottom: 4), - child: LocaleKeys.sar.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + child: adVM.vehicleAdDurationId.currency.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), ), ], ), diff --git a/lib/views/appointments/appointment_detail_view.dart b/lib/views/appointments/appointment_detail_view.dart index 78d2e43..397d54a 100644 --- a/lib/views/appointments/appointment_detail_view.dart +++ b/lib/views/appointments/appointment_detail_view.dart @@ -26,7 +26,7 @@ import 'package:sizer/sizer.dart'; class AppointmentDetailView extends StatelessWidget { final AppointmentListModel appointmentListModel; - const AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key); + const AppointmentDetailView({super.key, required this.appointmentListModel}); Widget getBaseActionButtonWidget({required Color color, required String text, Color textColor = MyColors.white, required Function() onPressed}) { return Expanded( diff --git a/lib/views/appointments/book_appointment_services_view.dart b/lib/views/appointments/book_appointment_services_view.dart index 66103fe..eb9c4bc 100644 --- a/lib/views/appointments/book_appointment_services_view.dart +++ b/lib/views/appointments/book_appointment_services_view.dart @@ -66,8 +66,6 @@ class BookAppointmentServicesView extends StatelessWidget { Row( children: [ MyAssets.icEdit.buildSvg(height: 17, width: 17).onPress(() { - log("serviceId: ${serviceData.serviceProviderServiceId}"); - appointmentsVM.updateBranchServiceId( SelectionModel( selectedId: serviceData.serviceProviderServiceId!, @@ -103,7 +101,7 @@ class BookAppointmentServicesView extends StatelessWidget { children: [ (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor), 4.width, - (serviceData.isHomeSelected ? serviceData.homeLocation : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(), + (serviceData.isHomeSelected ? serviceData.servicelocationInfo.address : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(), ], ), 5.height, @@ -111,7 +109,7 @@ class BookAppointmentServicesView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ if (serviceData.isHomeSelected) ...[ - ((serviceData.currentTotalServicePrice + (serviceData.distanceToHomeInKms * double.parse(serviceData.rangePricePerKm!))).toStringAsFixed(2)) + ((serviceData.currentTotalServicePrice + (serviceData.servicelocationInfo.distanceToBranch * double.parse(serviceData.rangePricePerKm!))).toStringAsFixed(2)) .toText(fontSize: 32, isBold: true), ] else ...[ ((serviceData.currentTotalServicePrice).toString()).toText(fontSize: 32, isBold: true), diff --git a/lib/views/appointments/review_appointment_view.dart b/lib/views/appointments/review_appointment_view.dart index c896e37..3badab3 100644 --- a/lib/views/appointments/review_appointment_view.dart +++ b/lib/views/appointments/review_appointment_view.dart @@ -239,11 +239,18 @@ class ReviewAppointment extends StatelessWidget { children: List.generate(scheduleData.servicesListInAppointment!.length, (serviceIndex) { ServiceModel serviceData = scheduleData.servicesListInAppointment![serviceIndex]; return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "${serviceData.providerServiceDescription}".toText(fontSize: 16, isBold: true), + if (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ + "${LocaleKeys.chargesPerKM.tr()}: ${serviceData.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)} ${LocaleKeys.sar.tr()}/km".toText( + fontSize: 12, + color: MyColors.lightTextColor, + ), + ], ], ), Column( @@ -251,6 +258,7 @@ class ReviewAppointment extends StatelessWidget { ItemData itemData = serviceData.serviceItems![itemIndex]; return Column( children: [ + // Item Name and Price Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -258,13 +266,15 @@ class ReviewAppointment extends StatelessWidget { ("${itemData.name}: ${itemData.price} ${LocaleKeys.sar.tr()}").toText(fontSize: 13, color: MyColors.lightTextColor), ], ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ("${itemData.description}").toText(fontSize: 11, color: MyColors.lightTextColor), - ], - ), + + //Description + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // ("${itemData.description}").toText(fontSize: 11, color: MyColors.lightTextColor), + // ], + // ), ], ); }), @@ -286,26 +296,32 @@ class ReviewAppointment extends StatelessWidget { "${LocaleKeys.dateAndTime.tr()}: ".toText(fontSize: 12, color: MyColors.lightTextColor), "${scheduleData.selectedCustomTimeDateSlotModel!.date!.date} at $selectedTimeSlot".toText(fontSize: 12), ]), - Row(children: [ - ("${LocaleKeys.location.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), - (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.homeLocation.tr() : LocaleKeys.companyLocation.tr()).toText(fontSize: 12), - ]), + Row( + children: [ + ("${LocaleKeys.location.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.homeLocation.tr() : LocaleKeys.companyLocation.tr()).toText(fontSize: 12), + if (appointmentsVM.currentLocationInfoModel != null && scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ + " , ${appointmentsVM.currentLocationInfoModel!.distanceToBranch.toStringAsFixed(2)} KM".toText(fontSize: 12), + ], + ], + ), + if (appointmentsVM.currentLocationInfoModel != null && scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ("${LocaleKeys.address.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + Flexible(child: appointmentsVM.currentLocationInfoModel!.address.toText(fontSize: 12)), + ], + ), + ], ], ), ), 10.height, const Divider(thickness: 0.7), Builder(builder: (BuildContext context) { - double totalServicePrice = 0.0; - double totalKms = 0.0; - double rangePricePerKm = 0; - - if (appointmentsVM.currentLocationInfoModel != null) { - totalKms = appointmentsVM.currentLocationInfoModel!.distanceFromCurrent; - rangePricePerKm = appointmentsVM.currentLocationInfoModel!.homeChargesInCurrentService; - } - totalServicePrice = rangePricePerKm * totalKms; - + double totalServicePrice = scheduleData.totalLocationCharges ?? 0.0; + double totalKms = scheduleData.locationInfoModel!.distanceToBranch; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -321,8 +337,7 @@ class ReviewAppointment extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - ("${LocaleKeys.locationCharges.tr()} (${rangePricePerKm.toStringAsFixed(2)} x ${totalKms.toStringAsFixed(2)} )") - .toText(fontSize: 14, color: MyColors.lightTextColor), + Flexible(child: ("${LocaleKeys.locationCharges.tr()} (${totalKms.toStringAsFixed(2)}km away)").toText(fontSize: 14, color: MyColors.lightTextColor)), ("${totalServicePrice.toStringAsFixed(2)} ${LocaleKeys.sar.tr()}").toText(fontSize: 16, isBold: true), ], ), @@ -351,13 +366,13 @@ class ReviewAppointment extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Divider(thickness: 0.7, height: 3), + const Divider(thickness: 0.8, height: 2), 8.height, if (appointmentsVM.amountToPayForAppointment > 0) ...[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.payableNow.tr().toText(fontSize: 14, isBold: true), + LocaleKeys.payableNow.tr().toText(fontSize: 14), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -371,7 +386,7 @@ class ReviewAppointment extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.remainingAmount.tr().toText(fontSize: 14, isBold: true), + LocaleKeys.remainingAmount.tr().toText(fontSize: 14), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ diff --git a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart index 4012d56..29ed87d 100644 --- a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart +++ b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart @@ -2,13 +2,13 @@ import 'dart:developer'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; @@ -151,25 +151,31 @@ class AppointmentServicePickBottomSheet extends StatelessWidget { destLatitude: latitude, destLongitude: longitude, ); + log("distance: $distance"); + log("customerLocationRange : ${appointmentsVM.currentServiceSelection!.customerLocationRange}"); + if (distance > (appointmentsVM.currentServiceSelection!.customerLocationRange ?? 0)) { Utils.showToast(LocaleKeys.serviceNotProvided.tr()); + appointmentsVM.currentServiceSelection!.servicelocationInfo = CurrentLocationInfoModel( + address: '', + latitude: 0.0, + longitude: 0.0, + distanceToBranch: 0.0, + homeChargesInCurrentService: 0.0, + ); appointmentsVM.updateCurrentLocationInfoModel(null); return; } - log("distance: $distance"); - log("customerLocationRange : ${appointmentsVM.currentServiceSelection!.customerLocationRange}"); - - if (appointmentsVM.currentServiceSelection != null) { - appointmentsVM.currentServiceSelection!.distanceToHomeInKms = distance; - } CurrentLocationInfoModel temp = CurrentLocationInfoModel( address: address, latitude: latitude, longitude: longitude, - distanceFromCurrent: distance, + distanceToBranch: distance, homeChargesInCurrentService: double.parse(appointmentsVM.currentServiceSelection!.rangePricePerKm ?? "0.0"), ); + + log("appointmentsVM.currentServiceSelection!.rangePricePerKm : ${temp.toString()}"); appointmentsVM.updateCurrentLocationInfoModel(temp); }, ), @@ -206,13 +212,15 @@ class AppointmentServicePickBottomSheet extends StatelessWidget { appointmentsVM.currentServiceSelection!.rangePricePerKm.toString().toText(fontSize: 30, isBold: true), "${LocaleKeys.sar.tr()}/km".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), ] else ...[ - (appointmentsVM.currentLocationInfoModel!.homeChargesInCurrentService * appointmentsVM.currentLocationInfoModel!.distanceFromCurrent).toStringAsFixed(2).toText( + (appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService * appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch) + .toStringAsFixed(2) + .toText( fontSize: 30, isBold: true, ), LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), 10.width, - ("(${(appointmentsVM.currentLocationInfoModel!.homeChargesInCurrentService).toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentLocationInfoModel!.distanceFromCurrent.toStringAsFixed(2)} KMs )") + ("(${(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService).toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)} KMs )") .toText(fontSize: 13, color: MyColors.lightTextColor) .paddingOnly(bottom: 5), ], diff --git a/lib/views/common_fragments/ads_fragment.dart b/lib/views/common_fragments/ads_fragment.dart index 97c1116..4ae6c88 100644 --- a/lib/views/common_fragments/ads_fragment.dart +++ b/lib/views/common_fragments/ads_fragment.dart @@ -152,6 +152,7 @@ class AdsFragment extends StatelessWidget { selectedId: adVM.vehicleAdsDurations.first.id ?? 0, selectedOption: ("${adVM.vehicleAdsDurations.first.days} ${LocaleKeys.daysVar.tr()}"), itemPrice: adVM.vehicleAdsDurations.first.price!.toString(), + currency: adVM.vehicleAdsDurations.first.currency!.toString(), ); adVM.updateVehicleAdDurationId(selection); } diff --git a/lib/widgets/tab/role_type_tab.dart b/lib/widgets/tab/role_type_tab.dart index 689bbfb..458b546 100644 --- a/lib/widgets/tab/role_type_tab.dart +++ b/lib/widgets/tab/role_type_tab.dart @@ -7,11 +7,11 @@ import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; class RoleTypeTab extends StatefulWidget { int selectedIndex; - List dropList; - Function(DropValue value) onSelect; - double? width; + final List dropList; + final Function(DropValue value) onSelect; + final double? width; - RoleTypeTab(this.selectedIndex, this.dropList, {required this.onSelect, this.width}); + RoleTypeTab(this.selectedIndex, this.dropList, {super.key, required this.onSelect, this.width}); @override State createState() => _RoleTypeTabState();