import ' package:flutter/material.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/models/appointments_models/appointment_list_model.dart ' ;
import ' package:mc_common_app/models/general/enums_model.dart ' ;
import ' package:mc_common_app/models/general/generic_resp_model.dart ' ;
import ' package:mc_common_app/models/provider_branches_models/branch_detail_model.dart ' ;
import ' package:mc_common_app/models/provider_branches_models/provider_profile_model.dart ' ;
import ' package:mc_common_app/models/appointments_models/service_schedule_model.dart ' ;
import ' package:mc_common_app/models/services/item_model.dart ' ;
import ' package:mc_common_app/models/services/service_model.dart ' ;
import ' package:mc_common_app/models/general/widgets_models.dart ' ;
import ' package:mc_common_app/repositories/appointment_repo.dart ' ;
import ' package:mc_common_app/repositories/common_repo.dart ' ;
import ' package:mc_common_app/repositories/provider_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/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/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:provider/provider.dart ' ;
class AppointmentsVM extends BaseVM {
final CommonRepo commonRepo ;
final CommonAppServices commonServices ;
final ProviderRepo providerRepo ;
final AppointmentRepo scheduleRepo ;
AppointmentsVM ( { required this . commonServices , required this . scheduleRepo , required this . providerRepo , required this . commonRepo } ) ;
bool isFetchingLists = false ;
List < AppointmentListModel > myAppointments = [ ] ;
List < AppointmentListModel > myUpComingAppointments = [ ] ;
List < AppointmentListModel > myFilteredAppointments = [ ] ;
List < FilterListModel > appointmentsFilterOptions = [ ] ;
// List<ScheduleData> availableSchedules = [];
bool isFetchingServices = false ;
List < DropValue > branchCategories = [ ] ;
bool isHomeTapped = false ;
List < ServiceAppointmentScheduleModel > serviceAppointmentScheduleList = [ ] ;
bool ifItemAlreadySelected ( int id ) {
int indexFound = allSelectedItemsInAppointments . indexWhere ( ( element ) = > element . id = = id ) ;
if ( indexFound ! = - 1 ) {
return true ;
}
return false ;
}
List < ItemData > allSelectedItemsInAppointments = [ ] ;
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 > onBookAppointmentPressed ( BuildContext context ) async {
Utils . showLoading ( context ) ;
bool isSuccess = false ;
List < int > appointmentIdsList = [ ] ;
try {
GenericRespModel genericRespModel = await scheduleRepo . createServiceAppointment (
schedules: serviceAppointmentScheduleList ,
serviceProviderID: selectedBranchModel ! . serviceProviderId ? ? 0 ,
) ;
if ( genericRespModel . messageStatus = = 2 | | genericRespModel . data = = null ) {
Utils . hideLoading ( context ) ;
Utils . showToast ( " ${ genericRespModel . message . toString ( ) } " ) ;
return ;
}
if ( genericRespModel . data ! = null ) {
genericRespModel . data . forEach ( ( element ) {
if ( element [ ' appointmentID ' ] ! = 0 ) {
appointmentIdsList . add ( element [ ' appointmentID ' ] ) ;
isSuccess = true ;
} else {
isSuccess = false ;
return ;
}
} ) ;
}
context . read < DashboardVmCustomer > ( ) . onNavbarTapped ( 1 ) ;
applyFilterOnAppointmentsVM ( 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 ( " Your appointment has been booked successfully! " ) ;
getMyAppointments ( ) ;
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 ) ;
}
Future < void > onCancelAppointmentPressed ( { required BuildContext context , required AppointmentListModel appointmentListModel } ) async {
Utils . showLoading ( context ) ;
try {
GenericRespModel genericRespModel = await scheduleRepo . 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 . data = = 1 ) {
context . read < DashboardVmCustomer > ( ) . onNavbarTapped ( 1 ) ;
applyFilterOnAppointmentsVM ( appointmentStatusEnum: AppointmentStatusEnum . cancelled ) ;
Utils . showToast ( " ${ genericRespModel . message . toString ( ) } " ) ;
await getMyAppointments ( ) ;
Utils . hideLoading ( context ) ;
getMyAppointments ( ) ;
navigateReplaceWithNameUntilRoute ( context , AppRoutes . dashboard ) ;
}
} catch ( e ) {
Utils . showToast ( " ${ e . toString ( ) } " ) ;
}
}
void updateIsHomeTapped ( bool value ) {
isHomeTapped = value ;
if ( currentServiceSelection ! = null ) {
currentServiceSelection ! . isHomeSelected = value ;
}
notifyListeners ( ) ;
}
String pickedHomeLocation = " " ;
void updatePickedHomeLocation ( String value ) {
pickedHomeLocation = value ;
pickHomeLocationError = " " ;
if ( currentServiceSelection ! = null ) {
currentServiceSelection ! . homeLocation = value ;
}
notifyListeners ( ) ;
}
SelectionModel branchSelectedCategoryId = SelectionModel ( selectedOption: " " , selectedId: - 1 , errorValue: " " ) ;
void updateProviderCategoryId ( SelectionModel id ) {
branchSelectedCategoryId = id ;
getBranchServices ( categoryId: branchSelectedCategoryId . selectedId ) ;
notifyListeners ( ) ;
}
List < FilterListModel > providersFilterOptions = [ ] ;
List < BranchDetailModel > nearbyBranches = [ ] ;
BranchDetailModel ? selectedBranchModel ;
List < ServiceModel > branchServices = [ ] ;
List < ServiceModel > servicesInCurrentAppointment = [ ] ;
ServiceModel ? currentServiceSelection ;
void updateBranchServiceId ( SelectionModel id ) async {
branchSelectedServiceId = id ;
currentServiceSelection = branchServices . firstWhere ( ( element ) = > element . serviceProviderServiceId = = id . selectedId ) ;
notifyListeners ( ) ;
}
void removeServiceInCurrentAppointment ( int index ) {
int serviceId = servicesInCurrentAppointment . elementAt ( index ) . serviceProviderServiceId ? ? - 1 ;
allSelectedItemsInAppointments . removeWhere ( ( element ) = > element . serviceProviderServiceId = = serviceId ) ;
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 ( ) ;
// servicesInCurrentAppointment.clear();
serviceAppointmentScheduleList . clear ( ) ;
}
List < EnumsModel > myAppointmentsEnum = [ ] ;
populateAppointmentsFilterList ( ) async {
appointmentsFilterOptions . clear ( ) ;
myAppointmentsEnum = await commonRepo . getEnumTypeValues ( enumTypeID: 13 ) ; //TODO: 13 is to get Appointments Filter Enums
for ( int i = 0 ; i < myAppointmentsEnum . length ; i + + ) {
appointmentsFilterOptions . add ( FilterListModel ( title: myAppointmentsEnum [ i ] . enumValueStr , isSelected: false , id: myAppointmentsEnum [ i ] . enumValue ) ) ;
}
appointmentsFilterOptions . insert ( 0 , FilterListModel ( title: " All Appointments " , isSelected: true , id: 0 ) ) ;
notifyListeners ( ) ;
}
applyFilterOnAppointmentsVM ( { required AppointmentStatusEnum appointmentStatusEnum } ) {
if ( appointmentsFilterOptions . isEmpty ) return ;
for ( var value in appointmentsFilterOptions ) {
value . isSelected = false ;
}
appointmentsFilterOptions [ appointmentStatusEnum . getIdFromAppointmentStatusEnum ( ) ] . isSelected = true ;
if ( appointmentStatusEnum . getIdFromAppointmentStatusEnum ( ) = = 0 ) {
myFilteredAppointments = myAppointments ;
notifyListeners ( ) ;
return ;
}
myFilteredAppointments = myAppointments . where ( ( element ) = > element . appointmentStatusID ! = = appointmentStatusEnum . getIdFromAppointmentStatusEnum ( ) ) . toList ( ) ;
notifyListeners ( ) ;
}
Future < void > getMyAppointments ( { bool isNeedToRebuild = false } ) async {
if ( isNeedToRebuild ) setState ( ViewState . busy ) ;
myAppointments = await commonRepo . getMyAppointments ( ) ;
myFilteredAppointments = myAppointments ;
myUpComingAppointments = myAppointments . where ( ( element ) = > element . appointmentStatusEnum = = AppointmentStatusEnum . booked ) . toList ( ) ;
setState ( ViewState . idle ) ;
// applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
notifyListeners ( ) ;
}
updateSelectedBranch ( BranchDetailModel branchDetailModel ) {
selectedBranchModel = branchDetailModel ;
getBranchCategories ( ) ;
notifyListeners ( ) ;
}
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 index = serviceAppointmentScheduleList [ scheduleIndex ] . selectedDateIndex ! ;
serviceAppointmentScheduleList [ scheduleIndex ] . customTimeDateSlotList ! [ index ] . availableSlots ! [ slotIndex ] . isSelected = true ;
serviceAppointmentScheduleList [ scheduleIndex ] . selectedCustomTimeDateSlotModel ! . availableSlots = serviceAppointmentScheduleList [ scheduleIndex ] . customTimeDateSlotList ! [ index ] . availableSlots ! ;
notifyListeners ( ) ;
}
double amountToPayForAppointment = 0.0 ;
double totalAmount = 0.0 ;
List < ItemData > serviceItemsFromApi = [ ] ;
ProviderProfileModel ? providerProfileModel ;
int selectedSubServicesCounter = 0 ;
onItemUpdateOrSelected ( int index , bool selected , int itemId ) {
int serviceIndex = servicesInCurrentAppointment . indexWhere ( ( element ) = > element . serviceId = = currentServiceSelection ! . serviceId ! ) ;
// print("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}");
// if (serviceIndex == -1) {
// return;
// }
serviceItemsFromApi [ index ] . isUpdateOrSelected = selected ;
serviceItemsFromApi [ index ] . isHomeSelected = isHomeTapped ;
if ( selected ) {
selectedSubServicesCounter = selectedSubServicesCounter + 1 ;
selectSubServicesError = " " ;
currentServiceSelection ! . serviceItems ! . add ( serviceItemsFromApi [ index ] ) ;
allSelectedItemsInAppointments . add ( serviceItemsFromApi [ index ] ) ;
for ( var element in allSelectedItemsInAppointments ) {
if ( ! ifItemAlreadySelected ( element . id ! ) ) {
servicesInCurrentAppointment [ serviceIndex ] . serviceItems ! . add ( serviceItemsFromApi [ index ] ) ;
servicesInCurrentAppointment [ serviceIndex ] . currentTotalServicePrice =
servicesInCurrentAppointment [ serviceIndex ] . currentTotalServicePrice + double . parse ( ( serviceItemsFromApi [ index ] . price ) ? ? " 0.0 " ) ;
}
}
}
if ( ! selected ) {
selectedSubServicesCounter = selectedSubServicesCounter - 1 ;
currentServiceSelection ! . serviceItems ! . removeWhere ( ( element ) = > element . id = = itemId ) ;
allSelectedItemsInAppointments . removeWhere ( ( element ) = > element . id = = itemId ) ;
servicesInCurrentAppointment [ serviceIndex ] . currentTotalServicePrice =
servicesInCurrentAppointment [ serviceIndex ] . currentTotalServicePrice - double . parse ( ( serviceItemsFromApi [ index ] . price ) ? ? " 0.0 " ) ;
servicesInCurrentAppointment [ serviceIndex ] . serviceItems ! . removeWhere ( ( element ) = > element . id = = itemId ) ;
}
notifyListeners ( ) ;
}
populateBranchesFilterList ( ) {
providersFilterOptions . clear ( ) ;
providersFilterOptions = [
FilterListModel ( title: " All Providers " , isSelected: true , id: 0 ) ,
FilterListModel ( title: " Maintenance " , isSelected: false , id: 1 ) ,
FilterListModel ( title: " Oil Service " , isSelected: false , id: 2 ) ,
FilterListModel ( title: " Accessories " , isSelected: false , id: 3 ) ,
FilterListModel ( title: " Tire Service " , isSelected: false , id: 4 ) ,
FilterListModel ( title: " Dent and Paint " , isSelected: false , id: 5 ) ,
] ;
notifyListeners ( ) ;
}
applyFilterOnProviders ( { required int index } ) {
if ( providersFilterOptions . isEmpty ) return ;
for ( var value in providersFilterOptions ) {
value . isSelected = false ;
}
providersFilterOptions [ index ] . isSelected = true ;
notifyListeners ( ) ;
}
getAllNearBranches ( { bool isNeedToRebuild = false } ) async {
//TODO: needs to lat,long into API
nearbyBranches . clear ( ) ;
if ( isNeedToRebuild ) setState ( ViewState . busy ) ;
nearbyBranches = await providerRepo . getAllNearBranchAndServices ( ) ;
setState ( ViewState . idle ) ;
}
Future < List < ItemData > > getServiceItems ( int serviceId ) async {
serviceItemsFromApi . clear ( ) ;
serviceItemsFromApi = await providerRepo . getServiceItems ( serviceId ) ;
for ( var item in serviceItemsFromApi ) {
if ( ifItemAlreadySelected ( item . id ! ) ) {
item . isUpdateOrSelected = true ;
}
}
setState ( ViewState . idle ) ;
return serviceItemsFromApi ;
}
getBranchAndServices ( int providerId ) async {
providerProfileModel = null ;
providerProfileModel = await providerRepo . getBranchAndServices ( providerId ) ;
setState ( ViewState . idle ) ;
}
String pickHomeLocationError = " " ;
String selectSubServicesError = " " ;
SelectionModel branchSelectedServiceId = SelectionModel ( selectedOption: " " , selectedId: - 1 , errorValue: " " ) ;
bool isCategoryAlreadyPresent ( int id ) {
final contain = branchCategories . where ( ( element ) = > element . id = = id ) ;
if ( contain . isEmpty ) {
return false ;
}
return true ;
}
void getBranchCategories ( ) async {
for ( var value in selectedBranchModel ! . branchServices ! ) {
if ( ! isCategoryAlreadyPresent ( value . categoryId ! ) ) {
branchCategories . add ( DropValue ( value . categoryId ! , value . categoryName ! , " " ) ) ;
}
}
notifyListeners ( ) ;
}
getBranchServices ( { required int categoryId } ) async {
branchSelectedServiceId = SelectionModel ( selectedOption: " " , selectedId: - 1 , errorValue: " " ) ;
isHomeTapped = false ;
pickedHomeLocation = " " ;
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 ;
}
void updatePickHomeLocationError ( String value ) {
pickHomeLocationError = value ;
// notifyListeners();
}
bool isServiceSelectionValidated ( ) {
if ( branchSelectedServiceId . selectedId = = - 1 ) {
return false ;
}
if ( isHomeTapped ) {
if ( pickedHomeLocation = = " " ) {
updatePickHomeLocationError ( GlobalConsts . homeLocationEmptyError ) ;
return false ;
}
}
return true ;
}
bool validateItemsSelection ( ) {
for ( var value in serviceItemsFromApi ) {
if ( value . isUpdateOrSelected ! ) {
return true ;
}
}
selectSubServicesError = " Please select at least one sub service " ;
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 AppointmentServicePickBottomSheet ( ) ;
} ,
) ;
}
void priceBreakDownClicked ( BuildContext context , ServiceModel selectedService ) {
showModalBottomSheet (
context: context ,
isScrollControlled: true ,
enableDrag: true ,
builder: ( BuildContext context ) {
double totalKms = 15.3 ;
return InfoBottomSheet (
title: " Charges Breakdown " . toText ( fontSize: 24 , isBold: true ) ,
description: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
" Services " . 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 } SAR " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
) ,
) ,
Row (
mainAxisAlignment: MainAxisAlignment . end ,
children: [
" ${ selectedService . currentTotalServicePrice } SAR " . toText ( fontSize: 16 , isBold: true ) ,
] ,
) ,
if ( selectedService . isHomeSelected ) . . . [
20. height ,
" Home Location " . toText ( fontSize: 16 , isBold: true ) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" ${ totalKms } km " . toText ( fontSize: 12 , color: MyColors . lightTextColor , isBold: true ) ,
" ${ selectedService . rangePricePerKm } x $ totalKms " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
8. height ,
Row (
mainAxisAlignment: MainAxisAlignment . end ,
children: [
" ${ selectedService . rangePricePerKm ? ? 0 * totalKms } SAR " . toText ( fontSize: 16 , isBold: true ) ,
] ,
) ,
] ,
30. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Total Amount " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
( selectedService . isHomeSelected
? " ${ ( selectedService . currentTotalServicePrice ) + ( double . parse ( ( selectedService . rangePricePerKm ? ? " 0.0 " ) ) * totalKms ) } "
: " ${ selectedService . currentTotalServicePrice } " )
. toText ( fontSize: 29 , isBold: true ) ,
2. width ,
" SAR " . 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 ( " You must select appointment time for each schedule's appointment. " ) ;
return ;
}
navigateWithName ( context , AppRoutes . reviewAppointmentView ) ;
}
void onServicesNextPressed ( BuildContext context ) async {
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 scheduleRepo . mergeServiceIntoAvailableSchedules (
serviceItemIdsForHome: serviceItemIdsForHome ,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop ,
) ;
if ( serviceAppointmentScheduleList . isEmpty ) {
Utils . hideLoading ( context ) ;
Utils . showToast ( " There are no available appointments for selected Items. " ) ;
return ;
}
totalAmount = 0.0 ;
amountToPayForAppointment = 0.0 ;
for ( var schedule in serviceAppointmentScheduleList ) {
amountToPayForAppointment = amountToPayForAppointment + ( schedule . amountToPay ? ? 0.0 ) ;
totalAmount = totalAmount + ( schedule . amountTotal ? ? 0.0 ) ;
}
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 scheduleRepo . mergeServiceIntoAvailableSchedules (
serviceItemIdsForHome: serviceItemIdsForHome ,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop ,
) ;
if ( serviceAppointmentScheduleList . isEmpty ) {
Utils . hideLoading ( context ) ;
Utils . showToast ( " There are no available appointments for selected Items. " ) ;
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 scheduleRepo . 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 . data = = 1 ) {
context . read < DashboardVmCustomer > ( ) . onNavbarTapped ( 1 ) ;
applyFilterOnAppointmentsVM ( appointmentStatusEnum: AppointmentStatusEnum . cancelled ) ;
Utils . showToast ( " ${ genericRespModel . message . toString ( ) } " ) ;
getMyAppointments ( ) ;
Utils . hideLoading ( context ) ;
navigateReplaceWithNameUntilRoute ( context , AppRoutes . dashboard ) ;
}
} catch ( e ) {
Utils . showToast ( " ${ e . toString ( ) } " ) ;
}
}
}