views:

308

answers:

7

I am writing a C# program to handle scheduling. Now each employee needs the ability have limitations on their schedule for ex:

Sally can only work Monday, Wednesday, Friday from 9am-3pm

Billy can only work Tuesday, Thursday, Sunday from 5pm-9pm

Sally can only work Monday, Wednesday, Friday from 9am-3pm until so and so date and then she can work a different set of times and days.

These are some examples of limitations that I need to apply to each employee object. What I wanted were some suggestions on how to architect this as efficiently and generically as as possible. Obviously I am going to have to be able to access this data and be able to apply these limitations. For example when the manger is trying to make the schedule he needs to able to see that when he schedules Sally on Tuesday at 4 their is an issue. Also how should I store this data of each employee?

A: 

I would suggest giving the ability to store 'time off' as specific dates with time ranges or as a pattern. I have worked on a couple of scheduling systems that had very complex ways of dealing with union rules and employee availablity and this is how we handled it.

Either employee says I want day X from y to z off which is easy to check against or they could define patterns that they wanted or didn't want (eg. I dont want to work fridays) and then when scheduling you could check to see if applying them to a specific shift broke a set rule (day off) or did/didn't match a specific pattern.

Also how should I store this data of each employee?

Have a table for storing employee's specific exceptions. I want day X from y to z off. You have an employee a date and a time span. Pretty simple.

As for the patterns you will need to come up with some type of schema. And have types or something.

So you could have a type like 'weekly off pattern' that would store full days off for a week which could be stored as a simple string representing the days off: 1000001. Assuming the first bit is sunday, this would represent wanting weekends off. You could then store the pattern as string or something and then based on the defined type you would know how to deal with the string.

It can be a very complex or simple problem, it just depends how much customization you need to allow for. Hopefully this gives you enough ideas to get you started.

Automatic schedule generation is A LOT more complicated depending on the exceptions/rules you need to support.

Kelsey
Basically a good design - but - I would invert this so that "time on" is what you store. This is after all what you are really interested in. Bit maps look attrative but can end up being a real pain. I would probably store this in a db as emp,available_from, avalable_to. This would give a manager the ability to query "whos in on Satautday Afternoon'. Also bitmaps can only give you a here or not here data. Storing in a db gives you much richer options shuch as schedualed, avaialble , available only in emergency.
James Anderson
The example I have was any pattern. You could store anything. Considering time on is more common than time off, I haven't seen any scheduling systems that store that for availability data. The point is to use patterns when not dealing with absolute data.
Kelsey
A: 

"architect this as efficiently and generically as as possible"

These aren't mutually exclusive, per-se, however efficient and generic is really hard to pull off, especially on a scheduling system. Scheduling is a non-trivial problem.

Your question would probably better be stated as "What books should I read to get started on this?" and/or make this a community wiki.

Russell Steen
A: 

This is analogous to a graph-matching problem, and can also be modeled as a Constraint Satisfaction Problem. You may find NSolver helpful, or Cassowary.Net

JasonTrue
A: 

I've done something similar to this and what i've done is created a common interface and then created separate implementations for different scenarios. The interface might have a check IsInSchedule(dateTime). Then you can create different implementations as needed.

Josh
+1  A: 

something like this:

public class Employee
{
    public string Name { get; set; }
    // other important info

    private List<WorkTime> _availability = new List<WorkTime>();
    public List<WorkTime> Availability
    {
        get { return _availability; }
        internal set { _availability = value; }
    }
}

public class WorkTime
{
    public DayOfWeek Day { get; private set; }
    public int StartHour { get; private set; }
    public int EndHour { get; private set; }

    public WorkTime(DayOfWeek day, int startHour, int endHour)
    {
        // validation here (e.g. day and time range during store hours, start<end, etc.)

        Day = day;
        StartHour = startHour;
        EndHour = endHour;
    }
}

and use LINQ (or foreach) to query across an employee collection, and into each employee's Availability to find someone with hours to meet some shift.

Might also be useful to create some utility function (extensions) for comparing WorkTime objects based on your business rules (e.g. IsAvailable compares two WorkTime objects and returns true if it's the same DoW and at least 4 hours overlap)

and you'll likely be storing this in a database, so model the tables with fields like the properties in the classes.

Mike Jacobs
A: 

I would go with Rules using the strategy pattern.

public interface Rule
{
    bool Satisfies(Employee employee);
}

public class ScheduleRule : Rule
{
    ScheduleRule(Schedule schedule)
    { ... }

    bool Satisfies(Employee employee)
    {
        // Ensure the employee is available
    }
}

public class HolidayRule : Rule
{
    HolidayRule(Datetime date)
    { ... }

    bool Satisfies(Employee employee)
    {
        // Checks if the employee as volunteered for this holiday
    }
}

This pattern allows for easy extensibility and maintainability.

The availibility information (and other rule-related information) can be kept with the employee (see Mike Jacob's answer). It can however be stored with the employee or in a seperate table.

You can also keep this availability information apart from the employee if you expect a large amount of information related to rules. In this case, Rules could target another class:

...
bool Satisfies(RuleInfo info)
...
Bryan Menard
A: 

Martin Fowler has an interesting article on recurring calendar events and the various approaches you can take; I found it very useful when I was writing something similar:

http://martinfowler.com/apsupp/recurring.pdf

Mark Simpson