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/appointments_view_model.dart

2304 lines
81 KiB
Dart

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/classes/consts.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/main.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/appointments_models/appointment_slots.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_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';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_contact_info_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.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/dashboard_view_model_customer.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/views/appointments/book_appointment_schedules_view.dart';
import 'package:mc_common_app/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class AppointmentsVM extends BaseVM {
final CommonRepo commonRepo;
final CommonAppServices commonServices;
final BranchRepo branchRepo;
final AppointmentRepo appointmentRepo;
AppointmentsVM(
{required this.commonServices, required this.appointmentRepo, required this.commonRepo, required this.branchRepo});
bool isUpcomingEnabled = true;
bool isFetchingLists = false;
int selectedAppointmentIndex = 0;
int selectedAppointmentSubIndex = 0;
int selectedAppointmentId = 0;
int selectedBranchIdForAppointments = 0;
List<AppointmentListModel> myAppointments = [];
List<AppointmentListModel> myUpComingAppointments = [];
List<AppointmentListModel> myFilteredAppointmentsForCustomers = [];
List<FilterListModel> appointmentsFilterOptions = [];
List<AppointmentListModel> myFilteredAppointmentsForProvider = [];
bool isFetchingServices = false;
List<DropValue> branchCategories = [];
bool isHomeTapped = false;
bool isShowEmptyMessage = false;
List<ServiceAppointmentScheduleModel> serviceAppointmentScheduleList = [];
List<ItemData> allSelectedItemsInAppointments = [];
bool ifItemAlreadySelected(int id) {
int indexFound = allSelectedItemsInAppointments.indexWhere((
element) => element.id == id);
log("already selected at: $indexFound");
if (indexFound != -1) {
return true;
}
return false;
}
Future<void> onItemsSelectedInService() async {
if (currentServiceSelection != null) {
int index = servicesInCurrentAppointment.indexWhere((element) =>
element.serviceId == currentServiceSelection!.serviceId!);
if (index == -1) {
double totalPrice = 0.0;
for (var element in currentServiceSelection!.serviceItems!) {
totalPrice = totalPrice + double.parse(element.price ?? "0.0");
}
currentServiceSelection!.currentTotalServicePrice = totalPrice;
servicesInCurrentAppointment.insert(0, currentServiceSelection!);
}
resetCategorySelectionBottomSheet();
notifyListeners();
}
}
Future<void> onPayNowPressedForAppointment(
{required BuildContext context, required int appointmentID}) async {
context.read<PaymentVM>().updateAppointmentIdsForPayment(
ids: [appointmentID]);
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.partialAppointment);
}
Future<void> onBookAppointmentPressed(BuildContext context) async {
Utils.showLoading(context);
bool isSuccess = false;
List<int> appointmentIdsList = [];
try {
GenericRespModel genericRespModel = await appointmentRepo
.createServiceAppointment(
schedules: serviceAppointmentScheduleList,
serviceProviderID: selectedBranchModel!.serviceProviderId ?? 0,
);
if (genericRespModel.data.isEmpty) {
Utils.hideLoading(context);
Utils.showToast(genericRespModel.message.toString());
return;
}
if (genericRespModel.data != null && genericRespModel.data.isNotEmpty) {
genericRespModel.data.forEach((element) {
if (element['appointmentID'] != 0) {
appointmentIdsList.add(element['appointmentID']);
isSuccess = true;
} else {
isSuccess = false;
Utils.showToast(element['message']);
return;
}
});
}
context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVMForCustomers(
appointmentStatusEnum: AppointmentStatusEnum.booked);
Utils.hideLoading(context);
resetAfterBookingAppointment();
if (isSuccess) {
if (amountToPayForAppointment > 0) {
context.read<PaymentVM>().updateAppointmentIdsForPayment(
ids: appointmentIdsList);
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.appointment);
} else {
Utils.showToast(LocaleKeys.appointmentBookedSuccessfully.tr());
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
}
} catch (e) {
Utils.showToast(e.toString());
}
}
Future<void> onConfirmAppointmentPressed(
{required BuildContext context, required appointmentId}) async {
context.read<PaymentVM>().updateAppointmentIdsForPayment(
ids: [appointmentId]);
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.appointment);
}
OfferRequestCommentModel selectedCancelAppointmentReason = OfferRequestCommentModel(
index: 0,
isSelected: true,
title: LocaleKeys.changedMind.tr(),
);
List<OfferRequestCommentModel> cancelAppointmentReasonList = [
OfferRequestCommentModel(
index: 0,
isSelected: true,
title: LocaleKeys.wantToRescheduleAppointment.tr(),
),
OfferRequestCommentModel(
index: 1,
isSelected: false,
title: LocaleKeys.noNeedForService.tr(),
),
OfferRequestCommentModel(
index: 2,
isSelected: false,
title: LocaleKeys.testTheService.tr(),
),
OfferRequestCommentModel(
index: 3,
isSelected: false,
title: LocaleKeys.otherVar.tr(),
),
];
void updateSelectedCancelAppointmentReason(int index) {
for (var value in cancelAppointmentReasonList) {
value.isSelected = false;
}
selectedCancelAppointmentReason = cancelAppointmentReasonList[index];
cancelAppointmentReasonList[index].isSelected = true;
notifyListeners();
}
String cancelAppointmentDescription = "";
String cancelAppointmentDescriptionError = "";
void updateCancelAppointmentDescription(String value) {
cancelAppointmentDescription = value;
if (value.isNotEmpty) {
cancelAppointmentDescriptionError = "";
}
}
Future<void> onCancelAppointmentPressed(
{required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await appointmentRepo
.cancelOrRescheduleServiceAppointment(
serviceAppointmentID: appointmentListModel.id ?? 0,
serviceSlotID: appointmentListModel.serviceSlotID ?? 0,
appointmentScheduleAction: 2, // 1 for Reschedule and 2 for Cancel
);
if (genericRespModel.messageStatus == 2 ||
genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast(genericRespModel.message.toString());
return;
}
if (genericRespModel.messageStatus == 1 &&
AppState().currentAppType == AppType.customer) {
context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVMForCustomers(
appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast(genericRespModel.message.toString());
Utils.hideLoading(context);
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
} catch (e) {
logger.e(e.toString());
Utils.showToast(e.toString());
}
}
void updateIsHomeTapped(bool value) {
isHomeTapped = value;
if (currentServiceSelection != null) {
currentServiceSelection!.isHomeSelected = value;
}
notifyListeners();
}
SelectionModel branchSelectedCategoryId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateProviderCategoryId(SelectionModel id) {
branchSelectedCategoryId = id;
getBranchServices(categoryId: branchSelectedCategoryId.selectedId);
notifyListeners();
}
List<FilterListModel> branchesCategoriesFilterOptions = [];
List<ServiceModel> servicesInCurrentAppointment = [];
ServiceModel? currentServiceSelection;
CurrentLocationInfoModel? currentLocationInfoModel;
void updateCurrentLocationInfoModel(CurrentLocationInfoModel? value) {
currentLocationInfoModel = value;
pickHomeLocationError = "";
if (currentServiceSelection != null && value != null) {
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;
}
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"),
);
}
notifyListeners();
}
void removeServiceInCurrentAppointment(int index) {
int serviceId = servicesInCurrentAppointment
.elementAt(index)
.serviceProviderServiceId ?? -1;
allSelectedItemsInAppointments.removeWhere((element) =>
element.serviceProviderServiceId == serviceId);
servicesInCurrentAppointment[index].serviceItems!.clear();
servicesInCurrentAppointment.removeAt(index);
notifyListeners();
}
resetCategorySelectionBottomSheet() {
selectedSubServicesCounter = 0;
branchSelectedCategoryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
isHomeTapped = false;
branchSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
currentServiceSelection = null;
}
resetAfterBookingAppointment() {
allSelectedItemsInAppointments.clear();
currentServiceSelection = null;
for (var element in servicesInCurrentAppointment) {
if (element.serviceItems != null) {
element.serviceItems!.clear();
element.serviceItems = [];
}
}
servicesInCurrentAppointment.clear();
servicesInCurrentAppointment = [];
currentLocationInfoModel = null;
log("here servicesInCurrentAppointment: ${servicesInCurrentAppointment
.length}");
}
List<EnumsModel> myAppointmentsEnum = [];
Future<void> populateAppointmentsFilterList() async {
if (appointmentsFilterOptions.isNotEmpty) return;
myAppointmentsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums
.appointmentsFilterEnumId); // 13 is to get Appointments Filter Enums
for (int i = 0; i < myAppointmentsEnum.length; i++) {
appointmentsFilterOptions.add(FilterListModel(
title: myAppointmentsEnum[i].enumValueStr,
titleN: myAppointmentsEnum[i].enumValueStrN,
isSelected: false,
id: myAppointmentsEnum[i].enumValue));
}
appointmentsFilterOptions.insert(
0, FilterListModel(title: "All Appointments",titleN: "جميع الفروع", isSelected: true, id: 0));
notifyListeners();
}
bool isAppointmentLoading = false;
applyFilterOnAppointmentsVMForProviders(
{int? branchID, required AppointmentStatusEnum appointmentStatusEnum, bool isNeedCustomerFilter = false, bool shouldPopulateUpcoming = false}) async {
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
value.isSelected = false;
}
int index = appointmentsFilterOptions.indexWhere((element) =>
element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum());
appointmentsFilterOptions[index].isSelected = true;
isAppointmentLoading = true;
notifyListeners();
myFilteredAppointmentsForProvider =
await getAppointmentsBasedOnFiltersForProviders(
branchID: branchID ?? selectedBranchIdForAppointments,
appointmentStatus: appointmentStatusEnum);
isAppointmentLoading = false;
if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForProvider
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked ||
element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(
DateTime.now())))
.toList();
log("myUpComingAppointments: ${myUpComingAppointments.length}");
}
if (isNeedCustomerFilter) {
log(
"myFilteredAppointmentsForProvider: ${myFilteredAppointmentsForProvider
.length}");
myFilteredAppointmentsForProvider =
findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider);
}
notifyListeners();
}
applyFilterOnAppointmentsVMForCustomers(
{required AppointmentStatusEnum appointmentStatusEnum, bool shouldPopulateUpcoming = false}) async {
log("appointmentsFilterOptions: ${appointmentsFilterOptions.isEmpty}");
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
value.isSelected = false;
}
int index = appointmentsFilterOptions.indexWhere((element) =>
element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum());
appointmentsFilterOptions[index].isSelected = true;
isAppointmentLoading = true;
notifyListeners();
myFilteredAppointmentsForCustomers =
await getAppointmentsBasedOnFiltersForCustomer(
appointmentStatusEnum: appointmentStatusEnum);
isAppointmentLoading = false;
if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForCustomers
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked ||
element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(
DateTime.now())))
.toList();
}
notifyListeners();
}
List<AppointmentListModel> findAppointmentsBasedOnCustomers(
List<AppointmentListModel> appointments) {
Set<int> uniqueCustomerIDs = <int>{};
for (var item in appointments) {
uniqueCustomerIDs.add(item.customerID ?? 0);
}
List<AppointmentListModel> groupedList = uniqueCustomerIDs.map((id) {
List<AppointmentListModel> list = appointments.where((item) =>
item.customerID == id).toList();
list.sort((a, b) =>
DateHelper
.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!))
.millisecondsSinceEpoch
.compareTo(DateHelper
.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!))
.millisecondsSinceEpoch));
AppointmentListModel model = list.first;
model.customerAppointmentList = list;
return model;
}).toList();
return groupedList;
}
AppointmentSlots? appointmentSlots;
bool isSlotsLoading = true;
Future<void> getAppointmentSlotsInfo({required int branchID}) async {
isSlotsLoading = true;
notifyListeners();
try {
GenericRespModel genericRespModel = await appointmentRepo
.getAppointmentSlots(branchID: branchID,
fromDate: selectedDateForAppointments,
toDate: selectedDateForAppointments);
if (genericRespModel.messageStatus == 1) {
appointmentSlots = AppointmentSlots.fromJson(genericRespModel.data);
} else {
Utils.showToast(genericRespModel.message.toString());
}
isSlotsLoading = false;
notifyListeners();
} catch (e) {
isSlotsLoading = false;
notifyListeners();
Utils.showToast(e.toString());
}
}
Future<bool> updateAppointmentStatus(
{required int appointmentId, required AppointmentStatusEnum appointmentStatusEnum, bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
GenericRespModel genericRespModel = await appointmentRepo
.updateAppointmentStatus(appointmentId: appointmentId,
appointmentStatusEnum: appointmentStatusEnum);
if (genericRespModel.messageStatus == 1) {
Utils.showToast(LocaleKeys.appointmentStatusUpdated.tr());
return true;
} else {
Utils.showToast(genericRespModel.message.toString());
return false;
}
} catch (e) {
Utils.showToast(e.toString());
return false;
}
}
Future<bool> updateAppointmentPaymentStatus(Map<String, dynamic> map,
{bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
GenericRespModel genericRespModel = await appointmentRepo
.updateAppointmentPaymentStatus(map);
if (genericRespModel.messageStatus == 1) {
Utils.showToast(LocaleKeys.paymentStatusUpdated.tr());
return true;
} else {
Utils.showToast(genericRespModel.message.toString());
return false;
}
} catch (e) {
Utils.showToast(e.toString());
return false;
}
}
bool isShowMergeButton() {
if (myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList == null) {
return false;
}
return myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList!.every((appointment) =>
appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList!.length > 1;
}
Future<GenericRespModel> createMergeAppointment(Map<String, dynamic> map,
{bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
GenericRespModel genericRespModel = await appointmentRepo
.createMergeAppointment(map);
return genericRespModel;
}
bool inNeedToEnableMergeButton = false;
void updateCheckBoxInMergeRequest(int currentIndex) {
myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList![currentIndex].isSelected =
!(myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList?[currentIndex].isSelected ?? false);
int count = countSelected(
myFilteredAppointmentsForProvider[selectedAppointmentIndex]
.customerAppointmentList ?? []);
if (count > 1) {
inNeedToEnableMergeButton = true;
} else {
inNeedToEnableMergeButton = false;
}
notifyListeners();
}
int countSelected(List<AppointmentListModel> appointments) {
return appointments
.where((appointment) => appointment.isSelected == true)
.toList()
.length;
}
updateSelectedAppointmentDate(
{required int dateIndex, required int scheduleIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList!) {
element.date!.isSelected = false;
}
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex].date!.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex = dateIndex;
final date = TimeSlotModel(
date: serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex].date!.date,
slotId: serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex].date!.slotId,
isSelected: true,
slot: "",
);
serviceAppointmentScheduleList[scheduleIndex]
.selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date);
notifyListeners();
}
updateSelectedAppointmentSlotByDate(
{required int scheduleIndex, required int slotIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList!) {
for (var element in element.availableSlots!) {
element.isSelected = false;
}
}
int dateIndex = serviceAppointmentScheduleList[scheduleIndex]
.selectedDateIndex!;
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex].availableSlots![slotIndex]
.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex]
.selectedCustomTimeDateSlotModel!.availableSlots =
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex].availableSlots!;
notifyListeners();
}
double amountToPayForAppointment = 0.0;
double totalAmount = 0.0;
List<ItemData> serviceItemsFromApi = [];
ProviderProfileModel? providerProfileModel;
int selectedSubServicesCounter = 0;
void onItemUpdateOrSelected(int index, bool selected, int itemId) {
int serviceIndex = servicesInCurrentAppointment.indexWhere((
element) => element.serviceId == currentServiceSelection!.serviceId!);
serviceItemsFromApi[index].isUpdateOrSelected = selected;
serviceItemsFromApi[index].isHomeSelected = isHomeTapped;
log(" serviceIndex: $serviceIndex");
if (selected) {
selectedSubServicesCounter = selectedSubServicesCounter + 1;
selectSubServicesError = "";
if (!ifItemAlreadySelected(serviceItemsFromApi[index].id!)) {
currentServiceSelection!.serviceItems!.add(serviceItemsFromApi[index]);
allSelectedItemsInAppointments.add(serviceItemsFromApi[index]);
log("Here with: ${serviceItemsFromApi[index].description}");
if (serviceIndex != -1) {
// servicesInCurrentAppointment[serviceIndex].serviceItems!.add(serviceItemsFromApi[index]);
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex]
.currentTotalServicePrice +
double.parse((serviceItemsFromApi[index].price) ?? "0.0");
}
}
} else {
selectedSubServicesCounter = selectedSubServicesCounter - 1;
currentServiceSelection!.serviceItems!.removeWhere((element) =>
element.id == itemId);
allSelectedItemsInAppointments.removeWhere((element) =>
element.id == itemId);
if (serviceIndex != -1) {
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex]
.currentTotalServicePrice -
double.parse((serviceItemsFromApi[index].price) ?? "0.0");
if (servicesInCurrentAppointment[serviceIndex]
.currentTotalServicePrice < 0.0) {
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex]
.currentTotalServicePrice * -1;
}
// servicesInCurrentAppointment[serviceIndex].serviceItems!.removeWhere((element) => element.id == itemId);
}
}
notifyListeners();
}
Future<void> applyFilterOnBranches({required int index}) async {
if (branchesCategoriesFilterOptions.isEmpty) return;
for (var value in branchesCategoriesFilterOptions) {
value.isSelected = false;
}
branchesCategoriesFilterOptions[index].isSelected = true;
await getBranchesBasedOnCategoryFilters(
serviceId: branchesCategoriesFilterOptions[index].id);
notifyListeners();
}
Future<List<ItemData>> getServiceItems({required int serviceId}) async {
setState(ViewState.busy);
serviceItemsFromApi.clear();
serviceItemsFromApi =
await branchRepo.getServiceItems(serviceId: serviceId);
selectedSubServicesCounter = 0;
for (var item in serviceItemsFromApi) {
if (ifItemAlreadySelected(item.id!)) {
item.isUpdateOrSelected = true;
selectedSubServicesCounter++;
}
}
setState(ViewState.idle);
return serviceItemsFromApi;
}
String pickHomeLocationError = "";
String selectSubServicesError = "";
SelectionModel branchSelectedServiceId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updatePickHomeLocationError(String value) {
pickHomeLocationError = value;
// notifyListeners();
}
bool isServiceSelectionValidated() {
if (branchSelectedServiceId.selectedId == -1) {
return false;
}
if (isHomeTapped) {
if (currentLocationInfoModel == null ||
currentLocationInfoModel!.address == "") {
updatePickHomeLocationError(GlobalConsts.homeLocationEmptyError);
return false;
}
}
return true;
}
bool validateItemsSelection() {
for (var value in serviceItemsFromApi) {
if (value.isUpdateOrSelected!) {
return true;
}
}
selectSubServicesError = LocaleKeys.selectOneSubService.tr();
notifyListeners();
return false;
}
String getTotalPrice(List<ServiceModel> serviceItems) {
var totalPrice = 0.0;
for (var element in serviceItems) {
totalPrice = totalPrice + (element.currentTotalServicePrice);
}
return totalPrice.toString();
}
void openTheAddServiceBottomSheet(BuildContext context,
AppointmentsVM appointmentsVM) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return const AppointmentServicePickBottomSheet();
},
);
}
void priceBreakDownClicked(BuildContext context,
ServiceModel selectedService) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.services.tr().toText(fontSize: 16, isBold: true),
Column(
children: List.generate(
selectedService.serviceItems!.length,
(index) =>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}"
.toText(fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
"${selectedService.serviceItems![index]
.price} ${LocaleKeys.sar.tr()}".toText(
fontSize: 12, isBold: true),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
"${selectedService.currentTotalServicePrice} ${LocaleKeys
.sar.tr()}".toText(fontSize: 16, isBold: true),
],
),
if (selectedService.isHomeSelected) ...[
20.height,
LocaleKeys.homeLocation.tr().toText(
fontSize: 16, isBold: true),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${totalKms}km ".toText(fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
"$pricePerKm x $totalKms".toText(
fontSize: 12, isBold: true),
],
),
8.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
"${((pricePerKm) * totalKms).toStringAsFixed(
2)} ${LocaleKeys.sar.tr()}".toText(
fontSize: 16, isBold: true),
],
),
],
30.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.totalAmount.tr().toText(
fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
(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),
],
)
],
),
30.height,
],
));
});
}
void onReviewButtonPressed(BuildContext context) {
bool isValidated = false;
for (int i = 0; i < serviceAppointmentScheduleList.length; i++) {
final schedule = serviceAppointmentScheduleList[i];
if (schedule.selectedCustomTimeDateSlotModel == null) {
isValidated = false;
break;
}
if (schedule.selectedCustomTimeDateSlotModel!.date == null ||
!schedule.selectedCustomTimeDateSlotModel!.date!.isSelected) {
isValidated = false;
break;
} else {
if (schedule.selectedCustomTimeDateSlotModel!.availableSlots == null) {
isValidated = false;
break;
} else {
TimeSlotModel slot = schedule.selectedCustomTimeDateSlotModel!
.availableSlots!.firstWhere((element) => element.isSelected);
if (slot.date.isNotEmpty) {
isValidated = true;
break;
}
}
}
}
if (!isValidated) {
Utils.showToast(LocaleKeys.selectAppointmentTime.tr());
return;
}
navigateWithName(context, AppRoutes.reviewAppointmentView);
}
void onServicesNextPressed(BuildContext context) async {
if (allSelectedItemsInAppointments.isEmpty) {
Utils.showToast(LocaleKeys.pleaseSelectService.tr());
return;
}
Utils.showLoading(context);
List<String> serviceItemIdsForHome = [];
List<String> serviceItemIdsForWorkshop = [];
for (var serviceItem in allSelectedItemsInAppointments) {
if (serviceItem.isHomeSelected!) {
serviceItemIdsForHome.add(serviceItem.id!.toString());
} else {
serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
}
}
serviceAppointmentScheduleList =
await appointmentRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop,
);
if (serviceAppointmentScheduleList.isEmpty) {
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.noAppointmentAvailable.tr());
return;
}
totalAmount = 0.0;
amountToPayForAppointment = 0.0;
for (var schedule in serviceAppointmentScheduleList) {
amountToPayForAppointment =
amountToPayForAppointment + (schedule.amountToPay ?? 0.0);
totalAmount = totalAmount + (schedule.amountTotal ?? 0.0);
for (var service in schedule.servicesListInAppointment!) {
int index = servicesInCurrentAppointment.indexWhere((element) =>
element.serviceProviderServiceId == service.serviceProviderServiceId);
if (index != -1) {
if (servicesInCurrentAppointment[index].isHomeSelected) {
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);
}
}
}
}
Utils.hideLoading(context);
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView,
arguments: ScreenArgumentsForAppointmentDetailPage(
routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment
notifyListeners();
}
Future<void> onRescheduleAppointmentPressed(
{required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context);
List<String> serviceItemIdsForHome = [];
List<String> serviceItemIdsForWorkshop = [];
for (var service in appointmentListModel.appointmentServicesList!) {
for (var serviceItem in service.serviceItems!) {
serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// if (serviceItem.isHomeSelected ?? false) {
// serviceItemIdsForHome.add(serviceItem.id!.toString());
// } else {
// serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// }
}
}
serviceAppointmentScheduleList =
await appointmentRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop,
);
if (serviceAppointmentScheduleList.isEmpty) {
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.noAppointmentAvailable.tr());
return;
}
Utils.hideLoading(context);
navigateWithName(
context,
AppRoutes.bookAppointmenSchedulesView,
arguments: ScreenArgumentsForAppointmentDetailPage(
routeFlag: 2, appointmentId: appointmentListModel.id ?? 0),
); // 2 For Rescheduling an Appointment
notifyListeners();
}
Future<void> onRescheduleAppointmentConfirmPressed(
{required BuildContext context, required int appointmentId, required int selectedSlotId}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await appointmentRepo
.cancelOrRescheduleServiceAppointment(
serviceAppointmentID: appointmentId,
serviceSlotID: selectedSlotId,
appointmentScheduleAction: 1, // 1 for Reschedule and 2 for Cancel
);
if (genericRespModel.messageStatus == 2 ||
genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast(genericRespModel.message.toString());
return;
}
if (genericRespModel.messageStatus == 1) {
context.read<DashboardVmCustomer>().onNavbarTapped(1);
Utils.showToast(genericRespModel.message.toString());
applyFilterOnAppointmentsVMForCustomers(
appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.hideLoading(context);
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
} catch (e) {
Utils.showToast(e.toString());
}
}
// REPORT A COMPLAINT
String complaintDescription = "";
String complaintDescriptionError = "";
void updateComplaintDescription(String value) {
complaintDescription = value;
if (value.isNotEmpty) {
complaintDescriptionError = "";
}
}
Future buildComplaintBottomSheet(
{required int customerID, required int complainType, required String customerName, required BuildContext context}) {
return showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: LocaleKeys.reportComplaint.tr().toText(
fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery
.of(context)
.viewInsets
.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (customerName.isNotEmpty) ...[
("${LocaleKeys.customerName.tr()}: $customerName").toText(
fontSize: 15, color: MyColors.lightTextColor),
],
10.height,
TxtField(
maxLines: 5,
value: complaintDescription,
errorValue: complaintDescriptionError,
keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(),
onChanged: (v) => updateComplaintDescription(v),
),
25.height,
ShowFillButton(
title: LocaleKeys.submit.tr(),
onPressed: () async {
if (complaintDescription.isEmpty) {
Utils.showToast(LocaleKeys.descriptionCannotBeEmpty.tr());
return;
}
final status = await reportComplaintAgainstCustomer(
customerID: customerID,
comment: complaintDescription,
complaintType: complainType,
// 1 for Appointment and 2 for Requests
context: context,
);
if (status) {
updateComplaintDescription("");
pop(context);
}
},
maxWidth: double.infinity,
),
19.height,
],
),
),
);
},
);
}
Future<bool> reportComplaintAgainstCustomer(
{required int customerID, required String comment, required int complaintType, required BuildContext context}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await commonRepo
.createComplainFromProvider(customerId: customerID,
comment: comment,
complainType: complaintType);
Utils.showToast(genericRespModel.message.toString());
Utils.hideLoading(context);
return genericRespModel.messageStatus == 1;
} catch (e, s) {
logger.e(s);
Utils.hideLoading(context);
Utils.showToast(e.toString());
return false;
}
}
Future<ProviderContactInfoModel?> getProvidersContactInfo(
{required int providerId, required BuildContext context}) async {
Utils.showLoading(context);
try {
ProviderContactInfoModel contactInfoModel = await commonRepo
.getProvidersContactInfo(providerId: providerId);
Utils.hideLoading(context);
return contactInfoModel;
} catch (e, s) {
logger.e(s);
Utils.hideLoading(context);
Utils.showToast(e.toString());
return null;
}
}
// BRANCHES RELATED
List<BranchDetailModel> nearbyBranches = [];
List<BranchDetailModel> myRecentBranches = [];
BranchDetailModel? selectedBranchModel;
List<ServiceModel> branchServices = [];
Future<void> populateBranchesFilterList() async {
if (branchesCategoriesFilterOptions.isNotEmpty) return;
branchesCategoriesFilterOptions.clear();
setOnlyState(ViewState.busy);
Services services = await branchRepo.fetchServicesByCategoryId(
serviceCategoryId: -1);
services.data?.forEach((element) {
branchesCategoriesFilterOptions.add(FilterListModel(id: element.id ?? 0,
isSelected: false,
iconUrl: element.serviceIconUrl ?? "",
title: element.description ?? "",
titleN: element.descriptionN ?? "",));
});
branchesCategoriesFilterOptions.insert(
0, FilterListModel(id: 0, isSelected: true, title: "All Branches", titleN: "جميع الفروع"));
notifyListeners();
setState(ViewState.idle);
}
Future<void> getAllNearBranches(
{bool isNeedToRebuild = false, bool isFromRefresh = false}) async {
nearbyBranches.clear();
if (isNeedToRebuild) setState(ViewState.busy);
if (isFromRefresh) {
var selectedFilter = branchesCategoriesFilterOptions.firstWhere((
element) => element.isSelected);
log("selectedFilter: ${selectedFilter.id}");
if (selectedFilter.id == 0) {
nearbyBranches = await branchRepo.getAllNearBranchAndServices(
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
} else {
nearbyBranches = await branchRepo.getBranchesByFilters(
categoryIdsList: [selectedFilter.id],
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
}
setState(ViewState.idle);
return;
}
nearbyBranches = await branchRepo.getAllNearBranchAndServices(
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
setState(ViewState.idle);
}
Future<void> getMyRecentBranches({bool isNeedToRebuild = false}) async {
myRecentBranches.clear();
if (isNeedToRebuild) setState(ViewState.busy);
myRecentBranches = await branchRepo.getMyRecentBranchesWithServices();
setState(ViewState.idle);
}
void getBranchCategories() async {
for (var value in selectedBranchModel!.branchServices!) {
if (!isCategoryAlreadyPresent(value.categoryId!)) {
branchCategories.add(
DropValue(value.categoryId!, value.categoryName!, ""));
}
}
notifyListeners();
}
Future<void> getBranchServices({required int categoryId}) async {
branchSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
isHomeTapped = false;
pickHomeLocationError = "";
if (categoryId != -1) {
isFetchingServices = true;
branchServices = getFilteredBranchServices(categoryId: categoryId);
isFetchingServices = false;
notifyListeners();
}
}
List<ServiceModel> getFilteredBranchServices({required int categoryId}) {
List<ServiceModel> filteredServices = selectedBranchModel!.branchServices!
.where((element) => element.categoryId == categoryId).toList();
return filteredServices;
}
Future<void> getProviderProfileWithBranchesAndServices(int providerId) async {
double latitude = AppState().currentLocation.latitude;
double longitude = AppState().currentLocation.longitude;
setState(ViewState.busy);
try {
providerProfileModel = await branchRepo.getBranchAndServicesByProviderId(
providerId, latitude: latitude, longitude: longitude);
} catch (e, s) {
logger.e(s);
setState(ViewState.idle);
Utils.showToast(e.toString());
}
setState(ViewState.idle);
}
bool isCategoryAlreadyPresent(int id) {
final contain = branchCategories.where((element) => element.id == id);
if (contain.isEmpty) {
return false;
}
return true;
}
updateSelectedBranch(BranchDetailModel branchDetailModel) {
selectedBranchModel = branchDetailModel;
getBranchCategories();
notifyListeners();
}
int branchFiltersCounter = 0;
updateBranchFiltersCounter(int value) {
branchFiltersCounter = value;
notifyListeners();
}
double branchFilterCurrentDistance = 25.0;
updateBranchFilterCurrentDistance(double value) {
branchFilterCurrentDistance = value;
notifyListeners();
}
// Provider Filter
List<DropValue> branchFilterProviderSearchHistory = [];
void removeBranchFilterProviderSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
branchFilterProviderSearchHistory.clear();
notifyListeners();
return;
}
branchFilterProviderSearchHistory.removeAt(index);
if (branchFilterProviderSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
// branchFilterSelectedProviderId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addBranchFilterProviderSearchHistory({required DropValue value}) {
if (branchFilterProviderSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterProviderSearchHistory.add(value);
notifyListeners();
}
SelectionModel branchFilterSelectedProviderId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateBranchFilterSelectedProviderId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue providerDrop = providersDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: branchFilterProviderSearchHistory, value: providerDrop)) {
addBranchFilterProviderSearchHistory(value: providerDrop);
}
}
branchFilterSelectedProviderId = id;
notifyListeners();
}
// Category Filter
List<DropValue> branchFilterCategorySearchHistory = [];
void removeBranchFilterCategorySearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
branchFilterCategorySearchHistory.clear();
notifyListeners();
return;
}
branchFilterCategorySearchHistory.removeAt(index);
if (branchFilterCategorySearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
// branchFilterSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addBranchFilterCategorySearchHistory({required DropValue value}) {
if (branchFilterCategorySearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterCategorySearchHistory.add(value);
notifyListeners();
}
SelectionModel branchFilterSelectedCategoryId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateBranchFilterSelectedCategoryId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue categoryDrop = categoryDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: branchFilterCategorySearchHistory, value: categoryDrop)) {
addBranchFilterCategorySearchHistory(value: categoryDrop);
}
}
branchFilterSelectedCategoryId = id;
notifyListeners();
}
// Services Filter
List<DropValue> branchFilterServicesSearchHistory = [];
void removeBranchFilterServicesSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
branchFilterServicesSearchHistory.clear();
notifyListeners();
return;
}
branchFilterServicesSearchHistory.removeAt(index);
if (branchFilterServicesSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
// branchFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addBranchFilterServicesSearchHistory({required DropValue value}) {
if (branchFilterServicesSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterServicesSearchHistory.add(value);
notifyListeners();
}
SelectionModel branchFilterSelectedServiceId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateBranchFilterSelectedServiceId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue serviceDrop = servicesDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: branchFilterServicesSearchHistory, value: serviceDrop)) {
addBranchFilterServicesSearchHistory(value: serviceDrop);
}
notifyListeners();
return;
}
branchFilterSelectedServiceId = id;
notifyListeners();
}
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;
}
ifAlreadyExistForStringValue(
{required List<String> list, required String value}) {
int index = list.indexWhere((element) {
return element == value;
});
if (index != -1) {
return true;
}
return false;
}
// Rating filter
double branchFilterByRating = 4.0;
updateBranchFilterByRating(double value) {
branchFilterByRating = value;
notifyListeners();
}
List<DropValue> categoryDropList = [];
List<DropValue> providersDropList = [];
List<DropValue> servicesDropList = [];
List<DropValue> itemsDropList = [];
List<DropValue> serviceDeliveryTypesDropList = [];
Future<void> fetchAllProviders() async {
if (providersDropList.isNotEmpty) return;
providersDropList.clear();
setOnlyState(ViewState.busy);
List<ProviderBasicDataModel> providers = await branchRepo
.getAllProvidersWitheBasicData();
for (var element in providers) {
providersDropList.add(
DropValue(element.id ?? 0, element.providerName ?? "N/A", ""),
);
}
setState(ViewState.idle);
}
Future<void> fetchAllCategories() async {
if (categoryDropList.isNotEmpty) return;
categoryDropList.clear();
setOnlyState(ViewState.busy);
Category category = await branchRepo.fetchBranchCategory();
category.data?.forEach((element) {
categoryDropList.add(
DropValue(element.id ?? 0,
((element.categoryName!.isEmpty ? "N/A" : element.categoryName) ??
"N/A"), ""),
);
});
setState(ViewState.idle);
}
Future<void> fetchAllServices() async {
if (servicesDropList.isNotEmpty) return;
servicesDropList.clear();
setState(ViewState.busy);
Services services = await branchRepo.fetchServicesByCategoryId(
serviceCategoryId: -1); // to get all services
for (var element in services.data!) {
servicesDropList.add(
DropValue(
element.id ?? 0,
element.description ?? "N/A",
"",
),
);
}
setState(ViewState.idle);
}
Future<void> fetchAllItems() async {
if (itemsDropList.isNotEmpty) return;
itemsDropList.clear();
setState(ViewState.busy);
List<ItemData> itemsList = await branchRepo.getServiceItems(
serviceId: -1); // to get all services
for (ItemData element in itemsList) {
if (element.name != null && element.name!.isNotEmpty) {
itemsDropList.add(
DropValue(
element.id ?? 0,
element.name ?? "",
"",
),
);
}
}
setState(ViewState.idle);
}
Future<void> fetchAllServiceDeliveryTypes() async {
if (serviceDeliveryTypesDropList.isNotEmpty) return;
serviceDeliveryTypesDropList.clear();
setState(ViewState.busy);
List<EnumsModel> enums = await commonRepo.getEnumTypeValues(
enumTypeID: AppEnums.serviceDeliveryTypeEnumId);
for (EnumsModel element in enums) {
serviceDeliveryTypesDropList.add(
DropValue(
element.enumValue,
element.enumValueStr,
"",
),
);
}
setState(ViewState.idle);
}
Future<void> populateDataForBranchesFilter() async {
await fetchAllProviders();
await fetchAllCategories();
await fetchAllServices();
updateBranchFilterCurrentDistance(25.0);
}
void clearBranchFilters() {
branchFilterServicesSearchHistory.clear();
branchFilterCategorySearchHistory.clear();
branchFilterProviderSearchHistory.clear();
branchFilterByRating = 4.0;
branchFilterCurrentDistance = 25.0;
branchFiltersCounter = 0;
clearBranchFilterSelections();
notifyListeners();
}
void clearBranchFilterSelections() {
branchFilterSelectedProviderId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchFilterSelectedCategoryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchFilterSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
Future<void> getBranchesBasedOnFilters() async {
nearbyBranches.clear();
setState(ViewState.busy);
List<int> providersIdsList = [];
if (branchFilterProviderSearchHistory.isNotEmpty) {
for (var element in branchFilterProviderSearchHistory) {
providersIdsList.add(element.id);
}
}
List<int> categoryIdsList = [];
if (branchFilterCategorySearchHistory.isNotEmpty) {
for (var element in branchFilterCategorySearchHistory) {
categoryIdsList.add(element.id);
}
}
List<int> servicesIdsList = [];
if (branchFilterServicesSearchHistory.isNotEmpty) {
for (var element in branchFilterServicesSearchHistory) {
servicesIdsList.add(element.id);
}
}
nearbyBranches = await branchRepo.getBranchesByFilters(
providerIdsList: providersIdsList.isNotEmpty ? providersIdsList : null,
categoryIdsList: categoryIdsList.isNotEmpty ? categoryIdsList : null,
serviceIdsList: servicesIdsList.isNotEmpty ? servicesIdsList : null,
distanceKm: branchFilterCurrentDistance.toInt(),
rating: branchFilterByRating.toInt(),
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
setState(ViewState.idle);
}
Future<void> getBranchesBasedOnCategoryFilters(
{required int serviceId}) async {
setState(ViewState.busy);
if (serviceId == 0) {
await getAllNearBranches();
return;
}
nearbyBranches.clear();
nearbyBranches = await branchRepo.getBranchesByFilters(
serviceIdsList: [serviceId],
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
setState(ViewState.idle);
}
// Appointments Filter Screen
List<DropValue> branchesDropList = [];
Future<void> fetchAllBranchesBySelectedProviderId(
{required List<int> providersIdsList}) async {
branchesDropList.clear();
setOnlyState(ViewState.busy);
List<BranchDetailModel> providers = await branchRepo.getBranchesByFilters(
providerIdsList: providersIdsList,
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
);
for (var element in providers) {
branchesDropList.add(
DropValue(element.id ?? 0, element.branchName ?? "N/A", ""));
}
setState(ViewState.idle);
log("branchesDropList: ${branchesDropList.length}");
}
Future<void> populateDataForAppointmentsFilter() async {
await fetchAllProviders();
await fetchAllCategories();
await fetchAllServices();
await fetchAllItems();
await fetchAllServiceDeliveryTypes();
}
int appointmentFiltersCounter = 0;
updateAppointmentFiltersCounter(int value) {
appointmentFiltersCounter = value;
notifyListeners();
}
// Provider Filter For Appointments
List<DropValue> appointmentFilterProviderSearchHistory = [];
void removeAppointmentFilterProviderSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterProviderSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterProviderSearchHistory.removeAt(index);
if (appointmentFilterProviderSearchHistory.isNotEmpty) {
List<int> providerIdsSelected = [];
for (var element in appointmentFilterProviderSearchHistory) {
providerIdsSelected.add(element.id);
}
fetchAllBranchesBySelectedProviderId(
providersIdsList: providerIdsSelected);
}
if (appointmentFilterProviderSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedProviderId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterProviderSearchHistory({required DropValue value}) {
if (appointmentFilterProviderSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
List<int> providerIdsSelected = [];
for (var element in appointmentFilterProviderSearchHistory) {
providerIdsSelected.add(element.id);
}
fetchAllBranchesBySelectedProviderId(providersIdsList: providerIdsSelected);
appointmentFilterProviderSearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedProviderId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedProviderId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue providerDrop = providersDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: appointmentFilterProviderSearchHistory, value: providerDrop)) {
addAppointmentFilterProviderSearchHistory(value: providerDrop);
}
}
// appointmentFilterSelectedProviderId = id;
notifyListeners();
}
// Branches Filter For Appointments
List<DropValue> appointmentFilterBranchSearchHistory = [];
void removeAppointmentFilterBranchSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterBranchSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterBranchSearchHistory.removeAt(index);
if (appointmentFilterBranchSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedBranchId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterBranchSearchHistory({required DropValue value}) {
if (appointmentFilterBranchSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
appointmentFilterBranchSearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedBranchId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedBranchId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue branchesDrop = branchesDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: appointmentFilterBranchSearchHistory, value: branchesDrop)) {
addAppointmentFilterBranchSearchHistory(value: branchesDrop);
}
}
// appointmentFilterSelectedBranchId = id;
notifyListeners();
}
// Category Filter For Appointments
List<DropValue> appointmentFilterCategorySearchHistory = [];
void removeAppointmentFilterCategorySearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterCategorySearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterCategorySearchHistory.removeAt(index);
if (appointmentFilterCategorySearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterCategorySearchHistory({required DropValue value}) {
if (appointmentFilterCategorySearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
appointmentFilterCategorySearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedCategoryId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedCategoryId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue categoryDrop = categoryDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: appointmentFilterCategorySearchHistory, value: categoryDrop)) {
addAppointmentFilterCategorySearchHistory(value: categoryDrop);
}
}
// appointmentFilterSelectedCategoryId = id;
notifyListeners();
}
List<DropValue> appointmentFilterServicesSearchHistory = [];
void removeAppointmentFilterServicesSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterServicesSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterServicesSearchHistory.removeAt(index);
if (appointmentFilterServicesSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterServicesSearchHistory({required DropValue value}) {
if (appointmentFilterServicesSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
appointmentFilterServicesSearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedServiceId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedServiceId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue servicesDrop = servicesDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: appointmentFilterServicesSearchHistory, value: servicesDrop)) {
addAppointmentFilterServicesSearchHistory(value: servicesDrop);
}
}
// appointmentFilterSelectedServiceId = id;
notifyListeners();
}
List<DropValue> appointmentFilterItemsSearchHistory = [];
void removeAppointmentFilterItemsSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterItemsSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterItemsSearchHistory.removeAt(index);
if (appointmentFilterItemsSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterItemsSearchHistory({required DropValue value}) {
if (appointmentFilterItemsSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
appointmentFilterItemsSearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedItemId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedItemId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue itemsDrop = itemsDropList.firstWhere((element) =>
element.id == id.selectedId);
if (!ifAlreadyExist(
list: appointmentFilterItemsSearchHistory, value: itemsDrop)) {
addAppointmentFilterItemsSearchHistory(value: itemsDrop);
}
}
// appointmentFilterSelectedServiceId = id;
notifyListeners();
}
// Customer Name Filter for PROVIDER ONLY
List<String> appointmentFilterCustomerNameSearchHistory = [];
String currentCustomerNameFilter = '';
void onCurrentCustomerNameFilterChanged(var value) {
currentCustomerNameFilter = value;
notifyListeners();
}
void removeAppointmentFilterCustomerNameSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterCustomerNameSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterCustomerNameSearchHistory.removeAt(index);
if (appointmentFilterCustomerNameSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterCustomerNameSearchHistory({required String value}) {
if (appointmentFilterCustomerNameSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
if (!ifAlreadyExistForStringValue(
list: appointmentFilterCustomerNameSearchHistory, value: value)) {
appointmentFilterCustomerNameSearchHistory.add(value);
currentCustomerNameFilter = "";
}
notifyListeners();
}
// MOBILE PHONE Filter for PROVIDER ONLY
String currentMobilePhoneFilter = '';
void onCurrentMobilePhoneFilterChanged(var value) {
currentMobilePhoneFilter = value;
notifyListeners();
}
List<String> appointmentFilterMobilePhoneSearchHistory = [];
void removeAppointmentFilterMobilePhoneSearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterMobilePhoneSearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterMobilePhoneSearchHistory.removeAt(index);
if (appointmentFilterMobilePhoneSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterMobilePhoneSearchHistory({required String value}) {
if (appointmentFilterMobilePhoneSearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
if (!ifAlreadyExistForStringValue(
list: appointmentFilterMobilePhoneSearchHistory, value: value)) {
appointmentFilterMobilePhoneSearchHistory.add(value);
currentMobilePhoneFilter = "";
}
notifyListeners();
}
// Service Delivery Types For PROVIDER ONLY
List<DropValue> appointmentFilterServiceDeliverySearchHistory = [];
void removeAppointmentFilterServiceDeliverySearchHistory(
{bool isClear = false, required int index}) {
if (isClear) {
appointmentFilterServiceDeliverySearchHistory.clear();
notifyListeners();
return;
}
appointmentFilterServiceDeliverySearchHistory.removeAt(index);
if (appointmentFilterServiceDeliverySearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter - 1);
// appointmentFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
notifyListeners();
}
void addAppointmentFilterServiceDeliverySearchHistory(
{required DropValue value}) {
if (appointmentFilterServiceDeliverySearchHistory.isEmpty) {
updateAppointmentFiltersCounter(appointmentFiltersCounter + 1);
}
appointmentFilterServiceDeliverySearchHistory.add(value);
notifyListeners();
}
SelectionModel appointmentFilterSelectedServiceDeliveryId = SelectionModel(
selectedOption: "", selectedId: -1, errorValue: "");
void updateAppointmentFilterSelectedServiceDeliveryId(SelectionModel id,
{bool isForSearch = false}) async {
if (isForSearch) {
DropValue itemsDrop = serviceDeliveryTypesDropList.firstWhere((
element) => element.id == id.selectedId);
if (!ifAlreadyExist(list: appointmentFilterServiceDeliverySearchHistory,
value: itemsDrop)) {
addAppointmentFilterServiceDeliverySearchHistory(value: itemsDrop);
}
}
// appointmentFilterSelectedServiceId = id;
notifyListeners();
}
void clearAppointmentFilterSelections() {
appointmentFilterSelectedProviderId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
appointmentFilterSelectedCategoryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
appointmentFilterSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
appointmentFilterSelectedItemId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
appointmentFilterSelectedServiceDeliveryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
appointmentFilterSelectedBranchId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
void clearAppointmentFilters() {
appointmentFilterServiceDeliverySearchHistory.clear();
appointmentFilterCustomerNameSearchHistory.clear();
appointmentFilterMobilePhoneSearchHistory.clear();
appointmentFilterItemsSearchHistory.clear();
appointmentFilterServicesSearchHistory.clear();
appointmentFilterCategorySearchHistory.clear();
appointmentFilterProviderSearchHistory.clear();
appointmentFilterBranchSearchHistory.clear();
appointmentFiltersCounter = 0;
clearAppointmentFilterSelections();
if (AppState().currentAppType == AppType.provider) {
applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true);
} else {
applyFilterOnAppointmentsVMForCustomers(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
}
notifyListeners();
}
Future<List<AppointmentListModel>> getAppointmentsBasedOnFiltersForCustomer(
{required AppointmentStatusEnum appointmentStatusEnum}) async {
try {
setState(ViewState.busy);
List<String> providersIdsList = [];
if (appointmentFilterProviderSearchHistory.isNotEmpty) {
for (var element in appointmentFilterProviderSearchHistory) {
providersIdsList.add(element.id.toString());
}
}
List<String> categoryIdsList = [];
if (appointmentFilterCategorySearchHistory.isNotEmpty) {
for (var element in appointmentFilterCategorySearchHistory) {
categoryIdsList.add(element.id.toString());
}
}
List<String> servicesIdsList = [];
if (appointmentFilterServicesSearchHistory.isNotEmpty) {
for (var element in appointmentFilterServicesSearchHistory) {
servicesIdsList.add(element.id.toString());
}
}
List<String> itemIdsList = [];
if (appointmentFilterItemsSearchHistory.isNotEmpty) {
for (var element in appointmentFilterItemsSearchHistory) {
itemIdsList.add(element.id.toString());
}
}
List<String> branchesIdsList = [];
if (appointmentFilterBranchSearchHistory.isNotEmpty) {
for (var element in appointmentFilterBranchSearchHistory) {
branchesIdsList.add(element.id.toString());
}
}
List<AppointmentListModel> myAppointments = await appointmentRepo
.getMyAppointmentsForCustomersByFilters(
providerIdsList: providersIdsList,
categoryIdsList: categoryIdsList,
serviceIdsList: servicesIdsList,
itemIdsList: itemIdsList,
branchIdsList: branchesIdsList,
appointmentStatusEnum: appointmentStatusEnum,
);
setState(ViewState.idle);
return myAppointments;
} catch (e) {
logger.e(e);
setState(ViewState.idle);
Utils.showToast(e.toString());
return [];
}
}
String selectedDateForAppointments = "";
Future<List<AppointmentListModel>> getAppointmentsBasedOnFiltersForProviders(
{required int branchID, AppointmentStatusEnum? appointmentStatus}) async {
try {
setState(ViewState.busy);
List<String> servicesIdsList = [];
if (appointmentFilterServicesSearchHistory.isNotEmpty) {
for (var element in appointmentFilterServicesSearchHistory) {
servicesIdsList.add(element.id.toString());
}
}
List<String> customerNamesList = [];
if (appointmentFilterCustomerNameSearchHistory.isNotEmpty) {
for (var element in appointmentFilterCustomerNameSearchHistory) {
customerNamesList.add(element.toString());
}
}
List<String> customerPhonesList = [];
if (appointmentFilterMobilePhoneSearchHistory.isNotEmpty) {
for (var element in appointmentFilterMobilePhoneSearchHistory) {
customerPhonesList.add(element.toString());
}
}
List<String> customerDeliveryTypesList = [];
if (appointmentFilterServiceDeliverySearchHistory.isNotEmpty) {
for (var element in appointmentFilterServiceDeliverySearchHistory) {
customerDeliveryTypesList.add(element.id.toString());
}
}
log("customerNamesList: $customerNamesList");
log("customerPhonesList: $customerPhonesList");
log("customerDeliveryTypesList: $customerDeliveryTypesList");
log("servicesIdsList: $servicesIdsList");
List<AppointmentListModel> myAppointments = await appointmentRepo
.getMyAppointmentsForProvidersByFilters(
branchID: branchID,
customerNamesList: customerNamesList,
customerPhonesList: customerPhonesList,
deliveryTypeIdsList: customerDeliveryTypesList,
serviceProviderServiceIdsList: servicesIdsList,
appointmentStatusEnum: appointmentStatus,
fromDate: '',
toDate: '');
setState(ViewState.idle);
return myAppointments ?? [];
} catch (e) {
logger.e(e);
setState(ViewState.idle);
Utils.showToast(e.toString());
return [];
}
}
Future<bool> addProviderToFavorite(
{required int serviceProviderID, required BuildContext context}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await branchRepo
.addProviderToFavourite(providerID: serviceProviderID);
Utils.showToast(genericRespModel.message.toString());
Utils.hideLoading(context);
return genericRespModel.messageStatus == 1;
} catch (e, s) {
logger.e(s);
Utils.hideLoading(context);
Utils.showToast(e.toString());
return false;
}
}
Future<bool> removeProviderFromFavorite(
{required int serviceProviderID, required BuildContext context}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await branchRepo
.removeProviderFromFavourite(providerID: serviceProviderID);
Utils.hideLoading(context);
Utils.showToast(genericRespModel.message.toString());
return genericRespModel.messageStatus == 1;
} catch (e, s) {
logger.e(s);
Utils.hideLoading(context);
Utils.showToast(e.toString());
return false;
}
}
List<ProviderProfileModel> myFavProvidersList = [];
Future<void> getMyFavoriteProviders() async {
myFavProvidersList.clear();
setState(ViewState.busy);
try {
myFavProvidersList = await branchRepo.getMyFavoriteProviders();
setState(ViewState.idle);
} catch (e, s) {
logger.e(s);
setState(ViewState.idle);
Utils.showToast(e.toString());
}
}
List<BranchRatingModel> currentBranchReviews = [];
bool isReadMoreEnabled = false;
void resetCurrentBranchRatings() {
currentBranchReviews.clear();
isReadMoreEnabled = false;
}
updateIsReadMoreEnabled(var value) {
isReadMoreEnabled = value;
notifyListeners();
}
Future<void> getReviewsByBranchId(
{required int serviceProviderBranchID}) async {
setState(ViewState.busy);
try {
currentBranchReviews = await branchRepo.getBranchRatings(
serviceProviderBranchID: serviceProviderBranchID);
} catch (e, s) {
logger.e(s);
setState(ViewState.idle);
Utils.showToast(e.toString());
}
setState(ViewState.idle);
}
// Chat Related
Future<void> getGeneralChatsListForProvider(
{required BuildContext context}) async {
try {
// Utils.showLoading(context);
// List<BuyersChatForAdzsModel> buyersChatList = await appointmentRepo.getChatBuyersForAds(adsID: adsID);
// Utils.hideLoading(context);
// buyersChatListForAds.clear();
// buyersChatListForAds = buyersChatList;
notifyListeners();
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
Utils.hideLoading(context);
}
}
void onGeneralChatMessagesButtonPressed(
{required BuildContext context}) async {
final myUserID = AppState().getUser.data!.userInfo!.userId;
// if (adDetailsModel.isMyAd != null && adDetailsModel.isMyAd!) {
// await getGeneralChatsListForProvider(context: context);
// // navigateWithName(context, AppRoutes.generalChatsListForProvider, 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(
// context: context,
// isForBuyer: true,
// adsChatBuyerId: 1,
// adID: adDetailsModel.id,
// userID: myUserID,
// senderName: adDetailsModel.adOwnerName,
// )
// .whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
// }
}
}