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

Schedular application: Schedular functionality and Implementation help required

2 Answers 157 Views
Scheduler and Reminder
This is a migrated thread and some comments may be shown as answers.
Ambisoft
Top achievements
Rank 2
Ambisoft asked on 21 Dec 2010, 06:26 PM

Hello all! I would like to discuss an application scenario so that I, later, will be able to properly identify issue I am facing. The reason I am doing this on a WinApp is that ASP.NET scheduler turned out to be restricted and could not cope with the huge list of Resource and massive number of appointments.

The scenario is as follows:

  • I require showing Jobs on a scheduler
  • A job has the following characteristics: It is only one day long
  • A resource (Locum (worker), in my case) can have a maximum of two jobs per day. A job has a ShiftType (Shift 1 and Shift 2). Therefore, a job’s StartTime can be (Date) + 8:00AM and EndTime be (Date) + 4:00PM. A field named JobShiftTypeID decided the shift. There are three values at current: None, Shift 1, and Shift 2. I’d like to custom paint (backgroung color/gradient) a job based upon this value
  • A job will never extend beyond 24 hours
  • Similarly, a job’s job date cannot be changed. Therefore, a job for 21-Dec-2010 will only move from one resource to another but cannot move from one date to another (Disable horizontal drag-drop). If a Job is dragged from Worker A to Worker B, then there first is required a few checks to see if the job can actually be allotted to Worker B. If not, there will be no change but a MessageBox will inform the user that the move is invalid. All this can be done through an event
  • A job can be of different types and LocumTypeID indicates the current. I’d like the job have a custom paint (an image) based upon this field’s value
  • A job has different states and JobStatusID indicates the current. Displaying an icon over the job is desired
  • Jobs are created through a well defined process and doesn’t require a scheduler. Once a job is ready for booking, the system takes each of the ready for booking job and goes through a heavy process of selecting most preferred work for it and places the result set in a temporary JobBooking table
  • Job and JobBooking has a one-to-one relation
  • The LINQ that shall feed the scheduler will fetch data through a query that’ll bring forth fields from both tables with the Job ID as the unique identifier
  • Since there is a certain amount of rules to go through upon performing and job switching, canceling, deletion etc, all operations to persists data to the DB need to hand-coded manually and the scheduler cannot be automatic in that regard
  • LINQ to SQL is used as the Data access Layer and there needs to be a way to bind the scheduler with LINQ data source or SchedularDataSource should be fed with LINQ
  • The field in JobBooking named LocumID is the common field between Locums (coming from Locum table as the primary resource) and will help place the job card against correct locum (resource)
Job table structure is as follow:
CREATE TABLE [dbo].[Job]
  (
   [OID] [bigint] IDENTITY(1, 1) NOT NULL,
   [BatchID] [varchar](250) NOT NULL,
   [PharmacyID] [bigint] NOT NULL,
   [BranchID] [bigint] NOT NULL,
   [PharmacyCoordinatorID] [bigint] NOT NULL,
   [LocumTypeID] [int] NOT NULL,
   [JobShiftTypeID] [int] NOT NULL,
   [JobDate] [smalldatetime] NOT NULL,
   [Rate] [money] NOT NULL,
   [RatePlus] [money] NOT NULL,
   [StartTime] [smalldatetime] NOT NULL,
   [EndTime] [smalldatetime] NOT NULL,
   [PriorityID] [tinyint] NOT NULL,
   [JobCode] [varchar](100) NOT NULL,
   [JobStatusID] [int] NOT NULL,
   [UserID] [bigint] NOT NULL,
   [RegisteredDate] [smalldatetime] NOT NULL,
   [LastModifiedAt] [timestamp] NOT NULL,
   CONSTRAINT [PK__Jobs__056690C222951AFD] PRIMARY KEY CLUSTERED ([OID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  )
ON
  [PRIMARY]

Job Booking Table structure:
CREATE TABLE [dbo].[JobBooking](
    [OID] [bigint] IDENTITY(1,1) NOT NULL,
    [LocumID] [bigint] NOT NULL,
    [JobID] [bigint] NOT NULL,
    [BookingTime] [smalldatetime] NOT NULL,
    [LastModifiedAt] [timestamp] NOT NULL,
 CONSTRAINT [PK__Bookings__73951AED4AA30C57] PRIMARY KEY CLUSTERED
(
    [OID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO

Job Supporting Tables structure:
CREATE TABLE [dbo].[JobShiftType]
  (
   [OID] [int] IDENTITY(1, 1) NOT NULL,
   [Name] [varchar](50) NOT NULL,
   [LastModifiedAt] [timestamp] NOT NULL,
   CONSTRAINT [PK_Shift] PRIMARY KEY CLUSTERED ([OID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  )
ON
  [PRIMARY]
GO
 
SET IDENTITY_INSERT [dbo].[JobShiftType] ON
INSERT [dbo].[JobShiftType] ([OID], [Name]) VALUES (1, N'None')
INSERT [dbo].[JobShiftType] ([OID], [Name]) VALUES (2, N'Shift 1')
INSERT [dbo].[JobShiftType] ([OID], [Name]) VALUES (3, N'Shift 2')
SET IDENTITY_INSERT [dbo].[JobShiftType] OFF
 
CREATE TABLE [dbo].[LocumType]
  (
   [OID] [int] IDENTITY(1, 1) NOT NULL,
   [Name] [varchar](100) NOT NULL,
   [Code] [varchar](4) NOT NULL,
   [PictureID] [int] NOT NULL,
   [LastModifiedAt] [timestamp] NOT NULL,
   CONSTRAINT [PK__LocumTyp__3776C388173876EA] PRIMARY KEY CLUSTERED ([OID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  )
ON
  [PRIMARY]
GO
 
SET IDENTITY_INSERT [dbo].[LocumType] ON
INSERT [dbo].[LocumType] ([OID], [Name], [Code], [PictureID]) VALUES (1, N'Type A', N'P   ', 1)
INSERT [dbo].[LocumType] ([OID], [Name], [Code], [PictureID]) VALUES (2, N'Type B', N'D   ', 2)
INSERT [dbo].[LocumType] ([OID], [Name], [Code], [PictureID]) VALUES (3, N'Type C', N'ACT ', 3)
SET IDENTITY_INSERT [dbo].[LocumType] OFF
 
CREATE TABLE [dbo].[JobStatus]
  (
   [OID] [int] IDENTITY(1, 1) NOT NULL,
   [Name] [varchar](100) NOT NULL,
   [Code] [varchar](5) NOT NULL,
   [PictureID] [int] NOT NULL,
   [LastModifiedAt] [timestamp] NOT NULL,
   CONSTRAINT [PK_JobStatuses] PRIMARY KEY CLUSTERED ([OID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  )
ON
  [PRIMARY]
GO
 
SET IDENTITY_INSERT [dbo].[JobStatus] ON
INSERT [dbo].[JobStatus] ([OID], [Name], [Code], [PictureID]) VALUES (1, N'Ready to book', N'J_RTB', 13)
INSERT [dbo].[JobStatus] ([OID], [Name], [Code], [PictureID]) VALUES (2, N'Pending', N'J_P', 14) INSERT  [dbo].[JobStatus] ([OID], [Name], [Code], [PictureID]) VALUES (3, N'Booked', N'J_B', 15)
INSERT [dbo].[JobStatus] ([OID], [Name], [Code], [PictureID]) VALUES (4, N'Cancelled', N'J_CAN', 16)
INSERT [dbo].[JobStatus] ([OID], [Name], [Code], [PictureID]) VALUES (6, N'CallBack', N'J_CAL', 17)
SET IDENTITY_INSERT [dbo].[JobStatus] OFF

Here are the actions that are required:

  • Be able to limit the scheduler (From 01-Jan-2009 to any specified date)
  • The date format needs to be dd-MMM-yyyy everywhere
  • The culture required is System.Globalization.CultureInfo("en-GB") everywhere
  • User be able to drag a job (appointment) only vertically
  • User be able to drag multiple-selected jobs (appointment) only vertically
  • A job cannot be stretched in any direction
  • For a Locum (resource), there can be a maximum of two jobs per day
  • Double clicking a job needs to show a custom dialog as user need not modify different aspects of a job except it’s resource (Locum)
  • The scheduler is only limited to TimeLine view grouped by Resource (Locums)
  • The jobs never have any kind of recurrence
  • Need to customize the context menu displayed on jobs and empty time slots
  • Need to control the number of day-slots displayed in the timeline view
  • Need to show a tooltip with a lot of job related info. The tooltip will show job related stuff like rates and job location and the coordinator to hail. I suppose that these fields, though not related to the scheduler, will still be available in the array of data items. I do know the appointment  class is customizable
I'd like a detailed solution for this scenario. I'd like to know what requirements are achievable and what would the best practices. I have already consulted a magnitude of different posts and blogs and was able to get some help but they were all generic.

Waiting for a response.

Thanks.

2 Answers, 1 is accepted

Sort by
0
DoomerDGR8
Top achievements
Rank 2
Iron
Iron
Iron
answered on 22 Dec 2010, 02:11 PM
Waiting for any sort of input...
0
Dobry Zranchev
Telerik team
answered on 27 Dec 2010, 12:18 PM
Hello Terry Abbas,

Thank you for writing.

Find the answers to your questions bellow:

1. You can use Backgrounds collection in order to represent different jobs. You can add custom backgrounds which will help you to visualize the different jobs.

2. You should manually check whether the locum is already added in appointments as a resource for specific date.

3. You have to create custom appointment class that inherits from the Appointment class and add in it a field that represents JobStatusID. In order to show different icon according to this field you have to subscribe for the AppointmentFormatting of the RadScheduler and set its icon according to the JobStatusID. Please check our online documentation for more information here.

4. The AppointmentTitleFormat property can format the date in the AppointmentElement. Find the related documentation here.

5. Find the related documentation for the localization here.

6. Subscribe for the AppointmentMoving event of the DragDropBehavior which is the property of the SchedulerElement. After this you should prevent moving in the different cells using the following code snippet.

this.radScheduler1.SchedulerElement.DragDropBehavior.AppointmentMoving += new EventHandler<AppointmentMovingEventArgs>(DragDropBehavior_AppointmentMoving);
 
void DragDropBehavior_AppointmentMoving(object sender, AppointmentMovingEventArgs e)
{
    Point point = this.radScheduler1.PointToClient(Cursor.Position);
    DayViewAppointmentsTable table = (this.radScheduler1.SchedulerElement.ViewElement as SchedulerDayViewElement).DataAreaElement.Table;
    SchedulerCellElement cell = SchedulerUIHelper.GetCellAtPoint(point, table.Children);
 
    if (cell.Date.Add(e.Appointment.Duration).Day != e.Appointment.Start.Day)
    {
        e.Cancel = true;
    }
}

7. We do not provide multiple selections of the appointments.

8. To prevent resizing of the appointments you should set the property AllowAppointmentResize of the RadScheduler to false.

9. You should check manually whether a job is related only with two resources.

10. When you want to edit only Resources through the EditAppointmentDialog, you have to inherit this dialog and disable all controls that you won’t to be edit. The following help article demonstrates how to inherit the EditAppointmentDialog. 

11. By default RadScheduler opens in day view mode, however you can change this.

12. You can disable button Recurrence in the custom EditAppointmentDialog.

13. You can find the available documentation for the customization of the context menu here.

14. Each time scale has a property DisplayedCellsCount which represents the number of the slots.

15. You can set specific tooltip for every appointment in the scheduler.

16. Please check the following help article which describes the data binding process in RadScheduler.

For further assistance do not hesitate to write back.

Greetings,
Dobry Zranchev
the Telerik team
Check out the Q1 2011 Roadmap for Telerik Controls for Windows Forms.
Tags
Scheduler and Reminder
Asked by
Ambisoft
Top achievements
Rank 2
Answers by
DoomerDGR8
Top achievements
Rank 2
Iron
Iron
Iron
Dobry Zranchev
Telerik team
Share this question
or