This is a migrated thread and some comments may be shown as answers.

Drop occurrence as exception

12 Answers 105 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Pim Kerkhof
Top achievements
Rank 1
Pim Kerkhof asked on 31 May 2013, 07:01 AM
Hello,
We use Scheduleview to display appointments in selected rooms.
We allow users to make recurrent appointments.
When there is a conflict, the conflicting occurrence is placed in a listbox and is registred in the recurrencerule as an exception, so the occurrence is no longer visible in Scheduleview.

I need a method to drag a conflicting occurrence from the listbox, drop it into Scheduleview and register it as an exception from the original appointment.

Does anybody have a sample how to achieve this?

Kind regards,
Pim

12 Answers, 1 is accepted

Sort by
0
Vladi
Telerik team
answered on 05 Jun 2013, 01:24 PM
Hello,

Currently we do not have an sample project that shows the described scenario.

You could check our Drag-Drop between RadListBox and RadScheduleView article for more details on the drag and drop functionality between the controls, Also you could check the help articles about Recurrence that describes the recurrence process in the ScheduleView control. Hope this is helpful.

I would suggest you to open a support thread and send us a sample project with the specific issues you are facing when implementing the described scenario.

Regards,
Vladi
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Pim Kerkhof
Top achievements
Rank 1
answered on 22 Aug 2013, 11:05 AM
OK Vladi, let me try to describe my problem.

In my ScheduleView i have a couple of rooms.
One room has appointments on August 21 and 22 (Screen2.jpg).
The next step is to make a recurrent appointment on August 19 with a 5 days daily recurrence (Screen3.jpg).

When there is a overlap with other appointments (e.g. 21 and 22) those overlaps must by placed in a list (Screen4.jpg, this works fine) AND must not appear in the ScheduleView (on my ToDo, I want to use RecurrenceRule.AddException for this function).

 

 

 

.
Then, when the overlapping occurrences from the list are dropped in the ScheduleView , they must be handled as a exception from the original appointment (from Screen3.jpg).

Can you provide an example how to fix this challenge?

Kind regards,
Pim

0
Vladi
Telerik team
answered on 27 Aug 2013, 11:17 AM
Hello,

Unfortunately we do not have an example that we can share with you that shows how to achieve the desired behavior when dragging and dropping items from outside of the ScheduleView control. You can take a look at our DragDropWithScheduleView example in our online SDK repository that shows how to achieve a simple drag drop functionality between the two control. A possible approach could be to:
  • In that example you should handled the creation of the exceptions in the CustomScheduleViewDragDropBehavior that is fired when an item from the ListBox is dropped in the ScheduleView control. In that behavior you should create the new exception appointment and add it to the desired RecurrenceRule with the use of the AddExceptio() method.

Hope this is helpful. You can download the entire repository from this link.

Regards,
Vladi
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Pim Kerkhof
Top achievements
Rank 1
answered on 22 Oct 2013, 09:53 AM
Hi,

I've added this code to the ScheduleViewDragDropBehavior.
The database is updated correctly, but de Scheduleview does not display the dropped exception (only when I close the app and restart it). What am I missing here?

public override void Drop(Telerik.Windows.Controls.DragDropState state)
{
    var newApp = (state.Appointment as SqlExceptionAppointment);

    // Get occurence from conflictlist
    Occurrence occ = current.ConflictenLijst.Where(o => o.Start == newApp.Start && o.End == newApp.End).First();
    // Get time slot where shift was dropped
    Slot droppedAtSlot = state.DestinationSlots.First();
    // Calculate offset between default shift start and actual dropped at start
    TimeSpan offset = droppedAtSlot.Start - newApp.Start;
     // Set time of creation and creator
    newApp.INGEVOERD_DOOR = WebContext.Current.Authentication.User.Identity.Name;
    newApp.INVOER_DATUM = DateTime.Now;
    // Set new times based on dropped time
    newApp.Start = newApp.Start.Add(offset);
    newApp.End = newApp.End.Add(offset);

    if (occ.Master.RecurrenceRule != null)
    {
         //Get Master from dropped occurence
        SqlAppointment CurrentApp = current.model.Appointments.Where(a => a.Start == occ.Master.Start).First();

        //Search for right exception based on datetime from dropped occ.
        //Exception is saved earlier when conflictlist was filled..
        SqlExceptionOccurrence ExcOcc = CurrentApp.SqlExceptionOccurrences.Where(e => e.ExceptionDate == occ.Start).First();
         if (ExcOcc != null)
         {
             //Set ExceptionId of SqlExceptionAppointment
             newApp.ExceptionId = ExcOcc.ExceptionId;

             //Create SqlExceptionResource
             SqlExceptionResource ExResource = new SqlExceptionResource();
             ExResource.SqlResource = droppedAtSlot.Resources[0] as SqlResource;
             ExResource.SqlExceptionAppointments_ExceptionId = ExcOcc.ExceptionId;
             (CurrentApp as IAppointment).BeginEdit();
              //Add SqlExceptionAppointment to SqlExceptionOccurence
             CurrentApp.SqlExceptionOccurrences.Where(e => e.ExceptionDate == occ.Start).First().SqlExceptionAppointment = newApp;
              //Add SqlExceptionResource to SqlExceptionAppointment
              CurrentApp.SqlExceptionOccurrences.Where(e => e.ExceptionDate ==             Occ.Start).First().SqlExceptionAppointment.SqlExceptionResources.Add(ExResource);
             (CurrentApp as IAppointment).EndEdit();

              //Set current exception
             current.model.CurrentExceptionAppointment = newApp;

             //Reset Appointmentsource to force scheduleview to refresh
             ScheduleViewRepository.CurrentReservering.scheduleview.AppointmentsSource = null;
             ScheduleViewRepository.CurrentReservering.scheduleview.AppointmentsSource = current.model.Appointments;
             ScheduleViewRepository.SaveData();
            }
     }
}
0
Konstantina
Telerik team
answered on 24 Oct 2013, 11:49 AM
Hello Pim,

Does it get displayed when you change the visible range?
The appointments are loaded in the GenerateAppointment() method which is called when the visible range is changed, not when the appointment's source is edited. So, in order to make it work, you will have to call this method when you need to reload the appointments in any other case.

Does this resolve your issue?

Regards,
Konstantina
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Pim Kerkhof
Top achievements
Rank 1
answered on 24 Oct 2013, 02:19 PM
Hello Konstantina,

No it doesn't get displayed when the visible range is changed, but the Model.Appointments ObservableCollection does gets updated however.
So:
The SqlExceptionAppointment which is added to the SqlExceptionOccurrence from an SqlAppointment in the Viewmodel is saved correctly
to the SQLDatabase, is present in the ViewModel, but does NOT show up in the scheduleview even after calling a GenerateAppointments().

OK I've found a difference between Model.Appointments BEFORE and AFTER a close and reload from the App
BEFORE (incorrect display):
Appointment.exceptionAppointments Count = 0
Appointment.exceptionOccurrences Count = 1

AFTER reload (correct display):
Appointment.exceptionAppointments Count = null
Appointment.exceptionOccurrences Count = null

Any suggestions?
Regards,
Pim

0
Konstantina
Telerik team
answered on 28 Oct 2013, 02:54 PM
Hello Pim,

Seems like the AppointmetnSource collection is not updating synchronously with the DB. I am not quite sure what the problem is. Could you please open a support ticket and send us your project, so that we could run it here locally and debug it. In that way we will be able to track down the source of the problem in a timely manner.

Thank you for your cooperation.

Regards,
Konstantina
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Pim Kerkhof
Top achievements
Rank 1
answered on 30 Oct 2013, 08:38 AM
Hello Konstantina,

My project is very complex so uploading a sampleproject is not an option i'am afraid.

The code which contains my problem is listed below:


I've created a webservice to check for conflicting appointments (RuimtebeheerGetConflictingApps)

void client_RuimtebeheerGetConflictingAppsCompleted(object sender, F2WishServiceReference.RuimtebeheerGetConflictingAppsCompletedEventArgs e)
        {
            List<SimpleAppointment> ConflictingAppsList = e.Result.ToList();
            current.ConflictenLijst.Clear();
            foreach (SimpleAppointment app in ConflictingAppsList)
            {
                foreach (Occurrence occ in model.CurrentAppointment.GetOccurrences(model.CurrentAppointment.Start, new DateTime(2099, 12, 31)))
                {
                    if (occ.Start.Date == app.Start.Date)
                    {
                        current.ConflictenLijst.Add(occ);
                        if (model.CurrentAppointment.RecurrenceRule != null)
//Here i add an exception to the current appointment so the conflicting occurrence is not visible in the scheduleview
 model.CurrentAppointment.RecurrenceRule.AddException(occ.Start);
                        else
                        {
                            model.Appointments.Remove(model.CurrentAppointment);
                            if (ScheduleViewRepository.Context.SqlAppointments.Contains(model.CurrentAppointment))
                                ScheduleViewRepository.Context.SqlAppointments.Remove(model.CurrentAppointment);
                            model.CurrentAppointment = null;
                        }
                        //occ.Master.RecurrenceRule.AddException(occ.Start);
                    }
                }
            }
            if (current.ConflictenLijst.Count > 0)
            {
                ConflictenListBox.ItemsSource = current.ConflictenLijst;
                ConflictenListBox.Visibility = Visibility.Visible;
                RedefineScheduleView();
            }
            else ConflictenListBox.Visibility = Visibility.Collapsed;

            //poging om de view te refreshen
            SqlResourceType newType = this.model.ResourceTypes.First();
            this.model.ResourceTypes.Remove(newType);
            this.model.ResourceTypes.Add(newType);
        }

The conflicting occurrence is added to a list.
The user can drag and drop this occurrence to de scheduleview:

ScheduleViewDragDropBehavior:

                var newApp = (state.Appointment as SqlExceptionAppointment); 

                // Get occurence from conflictlist
                Occurrence occ = current.ConflictenLijst.Where(o => o.Start == newApp.Start && o.End == newApp.End).First();
                // Get time slot where shift was dropped
                Slot droppedAtSlot = state.DestinationSlots.First();
                // Calculate offset between default shift start and actual dropped at start
                TimeSpan offset = droppedAtSlot.Start - newApp.Start;
                // Set new times based on dropped time
                newApp.Start = newApp.Start.Add(offset);
                newApp.End = newApp.End.Add(offset);

                if (occ.Master.RecurrenceRule != null)
                {
                    //Get Master from dropped occurence
                    SqlAppointment CurrentApp = current.model.Appointments.Where(a => a.Start == occ.Master.Start && a.Resources == occ.Master.Resources).First();

                    //Search for right exception based on datetime from dropped occ.
                    //Exception is saved earlier when conflictlist was filled..
                    SqlExceptionOccurrence ExcOcc = CurrentApp.SqlExceptionOccurrences.Where(e => e.ExceptionDate == occ.Start).First();
                    if (ExcOcc != null)
                    {

                        //Set ExceptionId of SqlExceptionAppointment 
                        newApp.ExceptionId = ExcOcc.ExceptionId;

                        //Create SqlExceptionResource
                        SqlExceptionResource ExResource = new SqlExceptionResource();
                        ExResource.SqlResource = droppedAtSlot.Resources[0] as SqlResource;
                        ExResource.SqlExceptionAppointments_ExceptionId = ExcOcc.ExceptionId;
                        newApp.SqlExceptionResources.Add(ExResource);

//Here I remove the SqlOcurrenceException to prevent duplicate Exceptions:
                        CurrentApp.RecurrenceRule.Exceptions.Remove(ExcOcc);

                        ScheduleViewRepository.Context.SqlExceptionOccurrences.Remove(ExcOcc);

//Here I add the dropped occurrende as SqlExceptionAppointment to the current Appointment.
                        CurrentApp.RecurrenceRule.AddException(occ.Start, newApp);
                      
                        //Reset Appointmentsource to force scheduleview to refresh
                        ScheduleViewRepository.CurrentReservering.scheduleview.AppointmentsSource = null;
                        ScheduleViewRepository.CurrentReservering.scheduleview.AppointmentsSource = current.model.Appointments;
                        ScheduleViewRepository.SaveData();

                    }
                }

Can you please provide me with a working sample?

Kind regards,
Pim
0
Konstantina
Telerik team
answered on 01 Nov 2013, 02:11 PM
Hello,

We do not have example at the moment. We will do our best to prepare one next week.
I hope this is acceptable time-frame for you.

Regards,
Konstantina
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Pim Kerkhof
Top achievements
Rank 1
answered on 01 Nov 2013, 02:43 PM
Hello Konstantina,

Next week is acceptable. Thanks in advance.

Kind regards,
Pim
0
Kalin
Telerik team
answered on 08 Nov 2013, 04:12 PM
Hi Pim,

Please find attached a sample project which demonstrates drag/drop of SqlExceptionAppointments from the ListBox to the ScheduleView and refreshing the view as well. You can test it the following way: create a recurring appointment, make one of the appointments an exception, click the "Get the exceptions" button. The exceptions get displayed in the ListBox, afterwards simply drag/drop one of them into desired place. In our approach we are not removing and adding the exception, but just changing the its time firstly to non visible time in the future and setting the correct times when dropped.

Hope this works for you. 

Regards,
Kalin
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Pim Kerkhof
Top achievements
Rank 1
answered on 14 Nov 2013, 02:24 PM
Hi Kalin,

This works for me, many thanks for the sample!

Kind regards,
Pim
Tags
ScheduleView
Asked by
Pim Kerkhof
Top achievements
Rank 1
Answers by
Vladi
Telerik team
Pim Kerkhof
Top achievements
Rank 1
Konstantina
Telerik team
Kalin
Telerik team
Share this question
or