Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
75
XamScheduler Weekly View Invalid Operation Exception : "Sequence contains no elements"
posted

Hello,

I have a view where I have 3 different XamSchedulers, each with his own view mode. I toggle the visibility of each one based on a selection of dropdown. Agenda and Monthly views are working fine, but when I select the Weekly View is causing the application to crash with an Invalid Operation Exception : "Sequence contains no elements".

View

...
<Grid>
                    
                    <!--#region Monthly View -->
                    
                    <ig:XamScheduler x:Name="MonthlyScheduler"
                        ViewMode="MonthView" 
                        IsVisible="{Binding IsMonthlyVisible}"
                        ViewSplitOrientation="Vertical" 
                        MonthViewAgendaVisibility="Visible"  
                        MonthViewNameVisibility="Visible"
                        MonthViewNameFontSize="20"       
                        MonthViewDayFontSize="12"      
                        MonthViewDayOfWeekHeaderVisibility="Visible"
                        MonthViewDayOfWeekHeaderFontSize="12"
                        MonthViewLeadingDayVisibility="Visible"
                        MonthViewLeadingDayFontSize="12"
                        MonthViewTrailingDayVisibility="Visible"
                        MonthViewTrailingDayFontSize="12"       
                        MonthViewWeekNumberVisibility="Visible"
                        MonthViewWeekNumberFontSize="12"
                        MonthViewScrollDirection="Horizontal"
                        SelectedDate="{Binding SelectedDate, Mode=TwoWay}"
                        SelectedAppointment="{Binding SelectedAppointment, Mode=TwoWay}"
                        SelectedDateChanged="MonthlyScheduler_SelectedDateChanged">

                        <ig:XamScheduler.DataSource>
                            <ig:ScheduleListDataSource AppointmentItemsSource="{Binding Appointments, Mode=TwoWay}"
                                                   ResourceItemsSource="{Binding Resources, Mode=TwoWay}" />
                        </ig:XamScheduler.DataSource>
                    </ig:XamScheduler>
                    
                    <!--#endregion-->

                    <!--#region Weekly View -->

                    <ig:XamScheduler x:Name="WeekScheduler"
                        ViewMode="WeekView"
                        IsVisible="{Binding IsWeeklyVisible}"
                        WorkingHoursDisplayMode="WorkingHoursOnly"
                        AppointmentSelected="WeekScheduler_AppointmentSelected"
                        SelectedDate="{Binding SelectedDate, Mode=TwoWay}"
                        SelectedAppointment="{Binding SelectedAppointment, Mode=TwoWay}">
                        <ig:XamScheduler.DataSource>
                            <ig:ScheduleListDataSource AppointmentItemsSource="{Binding Appointments, Mode=TwoWay}"
                                ResourceItemsSource="{Binding Resources, Mode=TwoWay}" />
                        </ig:XamScheduler.DataSource>
                    </ig:XamScheduler>

                    <!--#endregion-->

                    <!--#region Agenda View -->
                    
                    <ig:XamScheduler x:Name="AgendaScheduler"
                        ViewMode="AgendaView"
                        AgendaViewMinimumDate="{Binding MinimumDate}"
                        AgendaViewMaximumDate="{Binding MaximumDate}"
                        SelectedDate="{Binding SelectedDate, Mode=TwoWay}"
                        SelectedAppointment="{Binding SelectedAppointment, Mode=TwoWay}"
                        IsVisible="{Binding IsAgendaVisible}"
                        SelectedDateChanged="AgendaScheduler_SelectedDateChanged">
                        <ig:XamScheduler.DataSource>
                            <ig:ScheduleListDataSource AppointmentItemsSource="{Binding Appointments, Mode=TwoWay}"
                                ResourceItemsSource="{Binding Resources, Mode=TwoWay}" />
                        </ig:XamScheduler.DataSource>
                    </ig:XamScheduler>
                    
                    <!--#endregion-->

</Grid>
...

View Code

public partial class SchedulesPage : ContentView
    {
        SchedulesPageVM viewModel;
        public SchedulesPage()
        {
            InitializeComponent();
            viewModel = new SchedulesPageVM(GlobalData.Cl, StartDatePicker, EndDatePicker);
            BindingContext = viewModel;

            WorkingHoursCollection shift = new WorkingHoursCollection();
            shift.Add(new TimeSpan(GlobalData.GeneralParameters.StartHour, 0, 0), new TimeSpan(GlobalData.GeneralParameters.EndHour, 0, 0));

            WeekScheduler.DaysOfWeekSettings = new Infragistics.Scheduler.ScheduleDaysOfWeekSettings()
            {
                Monday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = true,
                    WorkingHours = shift
                },
                Tuesday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = true,
                    WorkingHours = shift
                },
                Wednesday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = true,
                    WorkingHours = shift
                },
                Thursday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = true,
                    WorkingHours = shift
                },
                Friday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = true,
                    WorkingHours = shift
                },
                Saturday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = false,
                    WorkingHours = shift
                },
                Sunday = new ScheduleDayOfWeekSettings()
                {
                    IsWorkday = false,
                    WorkingHours = shift
                }

            };
        }

        private void GoToToday(object sender, EventArgs e)
        {
            viewModel.SelectedDate = DateTime.Now;
            if (viewModel.SelectedCalendar.Text == "Calendário")
            {
                MonthlyScheduler.EnsureDayVisibleInMonthView(DateTime.Now);
            }
            else if (viewModel.SelectedCalendar.Text == "Semanal")
            {
                WeekScheduler.EnsureDayVisibleInDayOrWeekView(DateTime.Now);
            }
            else
            {
                AgendaScheduler.EnsureDayVisibleInAgendaView(DateTime.Now);
            }
        }

        private void MonthlyScheduler_SelectedDateChanged(object sender, SelectedDateChangedEventArgs e)
        {
            MonthlyScheduler.EnsureDayVisibleInMonthView(viewModel.SelectedDate);
        }


    }

View Model

public class SchedulesPageVM : BaseViewModel, INotifyPropertyChanged
    {
        #region State

        private DateTime selectedDate;

        private DateTime minimumDate;

        private DateTime maximumDate;

        private string searchText;

        private SearchScheduleModel searchSchedule;

        private ObservableCollection<Appointment> appointments = new ObservableCollection<Appointment>();

        private ObservableCollection<ScheduleResource> resources = new ObservableCollection<ScheduleResource>();

        private ObservableCollection<ScheduleModel> schedules = new ObservableCollection<ScheduleModel>();

        private Appointment selectedAppointment;

        private ObservableCollection<MiniModel> calendarOptions = new ObservableCollection<MiniModel>();

        private MiniModel selectedCalendar;

        private List<string> listCalendarOptions = new List<string>();

        private bool isWeeklyVisible;

        private bool isMonthlyVisible;

        private bool isAgendaVisible;

        #endregion

        #region Notify Property Changed

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Components, Properties, Images & Commands

        #region Components

        public DatePicker StartDatePicker { get; set; }

        public DatePicker EndDatePicker { get; set; }

        #endregion

        #region Properties

        public Preferencias Preferences { get; set; }

        public parapda Parapda { get; set; }

        public Cl CurrentEntity { get; set; }

        public DateTime SelectedDate
        {
            get { return selectedDate; }
            set
            {
                selectedDate = value;
                OnPropertyChanged("SelectedDate");
                if (SelectedAppointment != null)
                    SelectedAppointment = null;
            }
        }

        public DateTime MinimumDate
        {
            get { return minimumDate; }
            set
            {
                minimumDate = value;
                OnPropertyChanged("MinimumDate");
                SearchSchedule = new SearchScheduleModel()
                {
                    BeginDate = this.MinimumDate,
                    EndDate = this.MaximumDate,
                    SearchText = this.SearchText
                };

                if (MaximumDate.Subtract(MinimumDate).TotalDays > 186)
                {
                    UiInterfaceHelper.AlertNotification(LangSchedules.ExceededTimeWarningMessage);
                }
            }
        }

        public DateTime MaximumDate
        {
            get { return maximumDate; }
            set
            {
                maximumDate = value;
                OnPropertyChanged("MaximumDate");
                SearchSchedule = new SearchScheduleModel()
                {
                    BeginDate = this.MinimumDate,
                    EndDate = this.MaximumDate,
                    SearchText = this.SearchText
                };

                if (MaximumDate.Subtract(MinimumDate).TotalDays > 186)
                {
                    UiInterfaceHelper.AlertNotification(LangSchedules.ExceededTimeWarningMessage);
                }
            }
        }

        public string SearchText
        {
            get { return searchText; }
            set
            {
                searchText = value;
                OnPropertyChanged("SearchText");
                SearchSchedule = new SearchScheduleModel()
                {
                    BeginDate = this.MinimumDate,
                    EndDate = this.MaximumDate,
                    SearchText = this.SearchText
                };
            }
        }

        public SearchScheduleModel SearchSchedule
        {
            get { return searchSchedule; }
            set
            {
                searchSchedule = value;
                OnPropertyChanged("SearchSchedule");
            }
        }

        public ObservableCollection<Appointment> Appointments
        {
            get { return appointments; }
            set
            {
                appointments = value;
                OnPropertyChanged("Appointments");
            }
        }

        public ObservableCollection<ScheduleResource> Resources
        {
            get { return resources; }
            set
            {
                resources = value;
                OnPropertyChanged("Resources");
            }
        }

        public ObservableCollection<ScheduleModel> Schedules
        {
            get { return schedules; }
            set
            {
                schedules = value;
                OnPropertyChanged("Schedules");
            }
        }

        public Appointment SelectedAppointment
        {
            get { return selectedAppointment; }
            set
            {
                selectedAppointment = value;
                OnPropertyChanged("SelectedAppointment");
                if (selectedAppointment != null && GlobalData.CanExecute)
                {
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        await OpenUpdateScheduleFrame();
                    });
                }
            }
        }

        public ObservableCollection<MiniModel> CalendarOptions
        {
            get { return calendarOptions; }
            set
            {
                calendarOptions = value;
                OnPropertyChanged("CalendarOptions");
            }
        }
        public MiniModel SelectedCalendar
        {
            get { return selectedCalendar; }
            set
            {
                selectedCalendar = value;
                OnPropertyChanged("SelectedCalendar");
            }
        }

        public List<string> ListCalendarOptions
        {
            get { return listCalendarOptions; }
            set
            {
                listCalendarOptions = value;
                OnPropertyChanged("ListCalendarOptions");
            }
        }

        public bool IsWeeklyVisible
        {
            get { return isWeeklyVisible; }
            set
            {
                isWeeklyVisible = value;
                OnPropertyChanged("IsWeeklyVisible");
            }
        }

        public bool IsMonthlyVisible
        {
            get { return isMonthlyVisible; }
            set
            {
                isMonthlyVisible = value;
                OnPropertyChanged("IsMonthlyVisible");
            }
        }

        public bool IsAgendaVisible
        {
            get { return isAgendaVisible; }
            set
            {
                isAgendaVisible = value;
                OnPropertyChanged("IsAgendaVisible");
            }
        }

        #endregion

        #region Images

        public ImageSource CalendarIcon
        {
            get { return ImageSource.FromResource("WaveTradeX.Assets.Icons.ic_calendar.png"); }
        }

        #endregion

        #region Commands

        public ICommand TriggerDatePickerCommand => new Command<string>((parameter) => TriggerDatePicker(parameter));

        public ICommand OpenSheduleFrameCommand
        {
            get
            {
                return new Command<View>(async (v) => await
                 OpenSheduleFrame(), (v) => GlobalData.CanExecute && !IsNotConnected);
            }
        }

        public ICommand ActionCommand => new Command<MaterialMenuResult>((s) => RefreshAgenda(s));

        public SearchScheduleCommand SearchSchedulerCommand { get; set; }

        #endregion

        #endregion

        #region Constructor

        public SchedulesPageVM(Cl currentEntity, DatePicker startDatePicker, DatePicker endDatePicker)
        {
            try
            {
                _ = FileUtils.WriteLogAsync(LogMessageType.ViewModel, "SchedulesPageVM", "SchedulesPageVM");
                CurrentEntity = currentEntity;
                Preferences = GlobalData.Preferencia;
                Parapda = GlobalData.Parapda;
                StartDatePicker = startDatePicker;
                EndDatePicker = endDatePicker;
                SearchSchedulerCommand = new SearchScheduleCommand(this);
                CalendarOptions = ScheduleActionsHelper.GetCalendarOptions();
                ListCalendarOptions = CalendarOptions.Select(actions => actions.Text).ToList();
                SelectedCalendar = string.IsNullOrEmpty(Preferences.AgendaModeSelected) ? CalendarOptions[0] : CalendarOptions.Where(item => item.Description.Equals(Preferences.AgendaModeSelected)).FirstOrDefault();
                SwitchScheduler(SelectedCalendar.Text);
                // Update Preferences
                Preferences.AgendaModeSelected = SelectedCalendar.Description;
                PreferenciasHelper.UpdatePreferencia(Preferences);
                Appointments = new ObservableCollection<Appointment>();
                Resources = new ObservableCollection<ScheduleResource>();
                SelectedDate = DateTime.Now;
                MinimumDate = DateTime.Now.AddMonths(-3);
                MaximumDate = DateTime.Now.AddMonths(3);

                if (GlobalData.IsMain)
                    HomePage.viewModel.EventRefreshSchedules += async (sender, e) => await GetAllSchedulesAsync();
                else
                {
                    if(CurrentEntity.IsLead)
                        LeadDetailsPage.viewModel.EventGetAllSchedules += async (sender, e) => await GetAllSchedulesAsync();
                    else ClientDetailsPage.viewModel.EventGetAllSchedules += async (sender, e) => await GetAllSchedulesAsync();
                }
                
            }
            catch (Exception ex)
            {
                _ = FileUtils.WriteLogAsync(LogMessageType.Error, "SchedulesPageVM", string.Format("SchedulesPageVM : {0}", ex.Message));
            }
        }

        #endregion

        #region Methods

        #region Trigger Date Picker

        private void TriggerDatePicker(string parameter)
        {
            switch (parameter)
            {
                case "Start":
                    StartDatePicker.Focus();
                    break;

                case "End":
                    EndDatePicker.Focus();
                    break;
            }
        }

        #endregion

        #region Change Refresh

        public bool ChangeRefresh(int index)
        {
            bool result = false;
            string strSelected = ListCalendarOptions[index];

            if (strSelected != SelectedCalendar.Text)
            {
                SelectedCalendar = CalendarOptions.Where(item => item.Text.Equals(strSelected)).FirstOrDefault();
                Preferences.AgendaModeSelected = SelectedCalendar.Description;
                PreferenciasHelper.UpdatePreferencia(Preferences);
                SwitchScheduler(strSelected);
                result = true;
            }

            return result;
        }

        public void SwitchScheduler(string strScheduleType)
        {
            switch (strScheduleType)
            {
                case "Calendário":
                    IsMonthlyVisible = true;
                    IsWeeklyVisible = false;
                    IsAgendaVisible = false;
                    break;

                case "Agenda":
                    IsMonthlyVisible = false;
                    IsWeeklyVisible = false;
                    IsAgendaVisible = true;
                    break;

                case "Semanal":
                    IsMonthlyVisible = false;
                    IsWeeklyVisible = true;
                    IsAgendaVisible = false;
                    break;
            }
        }

        #endregion

        #region Refresh Agenda

        public async Task RefreshAgenda(MaterialMenuResult selected)
        {

            if (ChangeRefresh(selected.Index))
            {
                var config = new ProgressDialogConfig()
                            .SetTitle("")
                            .SetIsDeterministic(false)
                            .SetMaskType(MaskType.Gradient);

                using (UserDialogs.Instance.Progress(config))
                {
                    try
                    {
                        await Task.Delay(100);
                        await GetAllSchedulesAsync();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        _ = FileUtils.WriteLogAsync(LogMessageType.Error, "SchedulesPageVM", "RefreshAgenda()" + ex.Message);
                    }
                }
            }
        }

        #endregion

        #region Search For Schedule

        public void SearchForSchedules(SearchScheduleModel searchSchedule)
        {
            GetAllSchedulesAsync(searchSchedule);
        }

        #endregion

        #region Get All Schedules

        /// <summary>
        /// Get all schedules 
        /// </summary>
        private async Task GetAllSchedulesAsync(SearchScheduleModel search = null)
        {
            try
            {
                if (!IsNotConnected)
                {
                    bool serverStatus = false;

                    using (await MaterialDialog.Instance.LoadingDialogAsync(LangSync.ServerStatus))
                    {
                        serverStatus = await StatusRequestHelper.CheckWSStatus();
                    }

                    if (serverStatus)
                    {
                        var config = new ProgressDialogConfig()
                            .SetTitle("")
                            .SetIsDeterministic(false)
                            .SetMaskType(maskType: MaskType.Gradient);

                        using (UserDialogs.Instance.Progress(config))
                        {
                            bool IsSearch = false;
                            bool IsDescriptiveSearch = false;

                            ScheduleFormRequest form = new ScheduleFormRequest()
                            {
                                SellerNumber = Parapda.Vendedor,
                            };

                            // If its a search
                            if (search != null)
                            {
                                IsSearch = true;
                                // Check if dates not empty
                                if (search.BeginDate != null && search.EndDate != null)
                                {
                                    form.BeginDate = search.BeginDate;
                                    form.EndDate = search.EndDate;
                                }
                                // If search text is not empty
                                if (!string.IsNullOrEmpty(search.SearchText))
                                {
                                    IsDescriptiveSearch = true;
                                    form.SearchText = search.SearchText;
                                }
                            }
                            // Not being searched, set interval between 6 months
                            else
                            {
                                form.BeginDate = DateTime.Now.AddMonths(-3);
                                form.EndDate = DateTime.Now.AddMonths(3);
                            }
                            Schedules = new ObservableCollection<ScheduleModel>(await ScheduleServiceHelper.GetAllSchedules(form));
                            foreach (ScheduleModel schedule in Schedules)
                            {
                                schedule.DateStart = schedule.DateStart; //  + DateTimeOffset.Now.Offset;
                                schedule.DateEnd = schedule.DateEnd; //  + DateTimeOffset.Now.Offset;
                            }
                            Appointments = GenerateAppointments(Schedules);
                            Resources = GenerateResource();

                            if (IsSearch)
                            {
                                if (schedules.Count != 0)
                                {
                                    if (IsDescriptiveSearch)
                                    {

                                        SearchScheduleResultsPopup page = new SearchScheduleResultsPopup(Schedules, GetSearchSelection);
                                        await PopupNavigation.Instance.PushAsync(page);
                                    }
                                    else
                                    {
                                        ChangeRefresh(0);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        await UiInterfaceHelper.ShowSnackbar("blueBerryColor", LangGeneral.ServerUnreachable, LangGeneral.Close, 3000);
                    }
                }
                else
                    await UiInterfaceHelper.ShowSnackbar("blueBerryColor", LangGeneral.NoConnection, LangGeneral.Close, 3000);
            }
            catch (Exception ex)
            {
                _ = FileUtils.WriteLogAsync(LogMessageType.Error, "SchedulesPageVM", string.Format("GetAllSchedulesAsync() : {0}", ex.Message));
            }
        }

        #endregion

        #region Generate Appointments 

        /// <summary>
        /// Generate a list of all the appointments to be displayed on the view
        /// based on what is in the DB
        /// </summary>
        /// <param name="schedules"></param>
        /// <returns></returns>
        private ObservableCollection<Appointment> GenerateAppointments(ObservableCollection<ScheduleModel> schedules)
        {
            Random generator = new Random();
            var items = new ObservableCollection<Appointment>();
            foreach (ScheduleModel schedule in schedules)
            {
                string strOwner = string.Empty;
                string strLocal = string.Empty;

                bool bOwnerAssigned = false;
                bool bAssocLocal = false;

                if (!string.IsNullOrEmpty(schedule.CuName) && !string.IsNullOrEmpty(schedule.CuNumber))
                {
                    strOwner = schedule.CuName;
                    bOwnerAssigned = true;
                }
                else if (!string.IsNullOrEmpty(schedule.PoName) && !string.IsNullOrEmpty(schedule.PoNumber))
                {
                    strOwner = schedule.PoName;
                    bOwnerAssigned = true;
                }

                if (!string.IsNullOrEmpty(schedule.Address))
                {
                    strLocal = schedule.Address;
                    bAssocLocal = true;
                }

                items.Add(new Appointment()
                {
                    Start = schedule.DateStart,
                    End = schedule.DateEnd,
                    Subject = schedule.Description,
                    Location = bOwnerAssigned ? strOwner : (bAssocLocal ? strLocal : "Indefinido"),
                    ResourceId = "Resource-" + generator.Next(0, 20),
                    Id = schedule.Stamp.ToString()
                });
            }

            return items;
        }

        #endregion

        #region Generate Appointment

        private Appointment GenerateAppoiment(ScheduleModel scheduleModel)
        {
            Random generator = new Random();
            return new Appointment()
            {
                Start = scheduleModel.DateStart,
                End = scheduleModel.DateEnd,
                Subject = scheduleModel.Description,
                Location = scheduleModel.Address,
                ResourceId = "Resource-" + generator.Next(0, 20),
                Id = scheduleModel.Stamp.ToString()
            };
        }

        #endregion

        #region Generate Color Schemes

        /// <summary>
        /// Generates Color Schemes
        /// </summary>
        /// <returns></returns>
        public ObservableCollection<ScheduleResource> GenerateResource()
        {
            var resources = new ObservableCollection<ScheduleResource>();

            var schemes = Enum.GetValues(typeof(ScheduleResourceColorScheme));
            var schemesList = schemes.Cast<ScheduleResourceColorScheme>().ToList();

            for (int i = 0; i < 20; i++)
            {
                var schemeId = "Resource-" + i;
                var schemeColor = schemesList[i % schemesList.Count];
                resources.Add(new ScheduleResource(schemeId) { ColorScheme = schemeColor });
            }
            return resources;
        }

        #endregion

        #region Open Schedule Frame

        private async Task OpenSheduleFrame()
        {
            if (GlobalData.CanExecute)
            {
                GlobalData.CanExecute = false;
                using (await MaterialDialog.Instance.LoadingDialogAsync(LangGeneral.Loading))
                {
                    await Task.Delay(500);
                    
                    ScheduleModel newSchedule = new ScheduleModel();

                    DateTime nowDateTime = DateTime.Now;
                    bool hourExtension = false;
                    if (!ValidateDateSelection(selectedDate, nowDateTime, ref hourExtension))
                    {
                        // Show warning
                        if (!await UiInterfaceHelper.WarningDialog(LangSchedules.DateInvalidTitle, LangSchedules.DateInvalidMessage))
                        {
                            GlobalData.CanExecute = true;
                            return;
                        }
                    }
                    if (CurrentEntity != null)
                        newSchedule.Address = CurrentEntity.Address;
                    else newSchedule.Address = string.Empty;
                    // If its the same day but its past 09:00, set it to the next current hour
                    if (hourExtension)
                    {
                        newSchedule.DateStart = new DateTime(SelectedDate.Year, SelectedDate.Month, SelectedDate.Day, nowDateTime.Hour + 1, 00, 00);
                        newSchedule.DateEnd = new DateTime(SelectedDate.Year, SelectedDate.Month, SelectedDate.Day, nowDateTime.Hour + 2, 00, 00);
                    }
                    else
                    {
                        newSchedule.DateStart = new DateTime(SelectedDate.Year, SelectedDate.Month, SelectedDate.Day, 9, 00, 00);
                        newSchedule.DateEnd = new DateTime(SelectedDate.Year, SelectedDate.Month, SelectedDate.Day, 10, 00, 00);
                    }

                    // OpSchedulePopup page = new OpSchedulePopup(cl, 0, false, "Main", CreateOrUpdateSchedule);
                    // SchedulePopup page = new SchedulePopup(Cl, newSchedule, false, "Main", CreateOrUpdateSchedule);
                    ScheduleAuxData.SelectedSchedule = newSchedule;
                    // NewSchedulePopup page = new NewSchedulePopup("Main", CreateOrUpdateSchedule);
                    string strOrigin = CurrentEntity != null ? "Client" : "Main";
                    NewSchedulePopup page = new NewSchedulePopup(CurrentEntity, newSchedule, false, strOrigin, CreateOrUpdateSchedule);
                    await PopupNavigation.Instance.PushAsync(page);
                    GlobalData.PopupOpened = true;
                }
                GlobalData.CanExecute = true;
            }
        }

        #endregion

        #region Open Update Schedule Frame

        private async Task OpenUpdateScheduleFrame()
        {
            if (GlobalData.CanExecute)
            {
                GlobalData.CanExecute = false;
                using (await MaterialDialog.Instance.LoadingDialogAsync(LangGeneral.Loading))
                {
                    await Task.Delay(500);
                    
                    if (SelectedAppointment != null)
                    {

                        ScheduleModel selectedSchedule = Schedules.Where(item => item.Stamp.ToString().Contains(SelectedAppointment.Id)).FirstOrDefault();
                        string strOrigin = CurrentEntity != null ? "Client" : "Main";
                        NewSchedulePopup page = new NewSchedulePopup(CurrentEntity, selectedSchedule, true, strOrigin, CreateOrUpdateSchedule);
                        await PopupNavigation.Instance.PushAsync(page);
                        GlobalData.PopupOpened = true;
                    }
                }
                GlobalData.CanExecute = true;
            }

        }

        #endregion

        #region Validate Date Selection

        private bool ValidateDateSelection(DateTime selectedDate, DateTime currentTime, ref bool needsHourExtension)
        {
            bool result = true;
            // Convert Dates to string, isolating year, month and date
            string strSelectedDate = selectedDate.ToString("yyyy-MM-dd");
            string strCurrentTime = currentTime.ToString("yyyy-MM-dd");

            DateTime dateSelectedParsed = DateTime.Parse(strSelectedDate, CultureInfo.InvariantCulture);
            DateTime dateCurrentParsed = DateTime.Parse(strCurrentTime, CultureInfo.InvariantCulture);
            // if the selected date is previously to the current datetime
            if (dateSelectedParsed < dateCurrentParsed)
            {
                result = false;
            }
            // Date is the same, check the hour
            else if (dateSelectedParsed == dateCurrentParsed)
            {
                if (currentTime.Hour < 9) needsHourExtension = false;
                else needsHourExtension = true;
            }
            else needsHourExtension = false;

            return result;
        }

        #endregion

        #region Create or Update Schedule

        private void CreateOrUpdateSchedule(SchedulerEventArgs args)
        {
            if (args.IsConfirm)
            {
                var config = new ProgressDialogConfig()
                                .SetTitle("")
                                .SetIsDeterministic(false)
                                .SetMaskType(maskType: MaskType.Gradient);

                using (UserDialogs.Instance.Progress(config))
                {
                    switch (args.Option)
                    {
                        case "created":
                            Appointments.Add(GenerateAppoiment(args.Scheduler));
                            Schedules.Add(args.Scheduler);
                            break;
                        case "updated":
                            ScheduleModel editSchdule = Schedules.First(schedule => schedule.Stamp.Equals(args.Scheduler.Stamp));
                            if (editSchdule != null)
                            {
                                Schedules.Remove(editSchdule);
                                Schedules.Add(args.Scheduler);
                            }
                            Appointment editAppoiment = Appointments.First(appoiment => appoiment.Id.Equals(args.Scheduler.Stamp.ToString()));
                            if (editAppoiment != null)
                                Appointments = GenerateAppointments(Schedules);
                            break;
                        case "deleted":
                            ScheduleModel deleteSchdule = Schedules.First(schedule => schedule.Stamp.Equals(args.Scheduler.Stamp));
                            if (deleteSchdule != null)
                                Schedules.Remove(deleteSchdule);
                            if (deleteSchdule != null)
                                Appointments = GenerateAppointments(Schedules);
                            break;
                    }
                }
            }
        }

        #endregion

        #region Get Search Selection

        private void GetSearchSelection(SchedulerEventArgs args)
        {
            if (args.IsConfirm)
            {
                var config = new ProgressDialogConfig()
                                .SetTitle("")
                                .SetIsDeterministic(false)
                                .SetMaskType(maskType: MaskType.Gradient);

                using (UserDialogs.Instance.Progress(config))
                {
                    switch (args.Option)
                    {
                        case "selected":
                            SelectedDate = args.Scheduler.DateStart;
                            break;
                    }
                }
            }
        }

        #endregion

        #endregion
    }