First and foremost, thanks a lot for the help you've given me so far. Our project is looking pretty nice with Bryntum Gantt and the integration is smooth . I'm on the last stretch of dev and this might be the most critial part of it. We used to rely on a backend scheduling engine to get when a task should start and end based on resources and calendars and I figured I could give your engine a go. So I followed and understood the guide in the documentation which is a fair introduction, and then I went ahead and integrated it in our project, inspired by the data that drives the demos.
Our use case is fairly advanced but in simple terms, pretty much all tasks we have are effort driven and for any task we have, we may have multiple assignments for multiple resources on multiple schedules, and also every resource has its own leaves. For example, for a single task we might have those assignments:
- Employee A, 100% assigned, works on day schedule, has two leaves in the upcoming week
- Employee B, 75% assigned, works on night schedule, has no leaves planned
- Employee C, 100% assigned, works on night schedule, has one leave in two days
- Employee D, 100% assigned, works on weekend schedule, has no leaves.
But that does not quite work. Or I missed something? Apparently I must set a calendar on a task for the scheduling to work, right? The task begins depending on what calendar I choose and in the example above, there is no single good choice. I expect the task to start as early as possible (from the constraint) according to all the resources availabilities, and I expect its duration to take the employees leaves into account.
Here's a sample of test data. Notice the calendar structure: One main calendar per shift where intervals are working times (isWorking: true) and also global leaves (isWorking: false). The main calendars then have one child per resource where the intervals are all leaves (isWorking: false) (sick leaves for example)
{
"success": true,
"type": "load",
"project": {
"name": "Year 20XX",
"startDate": "2020-04-01 00:00:00"
},
"tasks": {
"rows": [{
"id": 77,
"name": "Eat all the potatoes!",
"startDate": "2020-04-02 00:00:00",
"endDate": "2020-04-03 12:00:00",
"duration": 1.333333333,
"constraintDate": "2020-04-02 00:00:00",
"manuallyScheduled": false,
"rollup": false,
"initiallyExpanded": true,
"effortDriven": true,
"constraintType": "startnoearlierthan",
"effortUnit": "hour",
"schedulingMode": "FixedUnits",
"expanded": true,
"effort": 72.0,
"percentDone": 0,
"children": []
}]
},
"resources": {
"rows": [{
"id": 15,
"name": "Doris Cole",
"calendar": "resource_15"
}, {
"id": 19,
"name": "Eli Lambert",
"calendar": "resource_19"
}, {
"id": 18,
"name": "Ernest Reed",
"calendar": "resource_18"
}]
},
"assignments": {
"rows": [{
"id": 133,
"resource": 15,
"event": 77,
"units": 100
}, {
"id": 134,
"resource": 19,
"event": 77,
"units": 100
}, {
"id": 135,
"resource": 18,
"event": 77,
"units": 100
}]
},
"calendars": {
"rows": [{
"id": 2,
"name": "Evening shift",
"hoursPerDay": 4.0,
"daysPerWeek": 5,
"daysPerMonth": 20,
"unspecifiedTimeIsWorking": false,
"intervals": [{
"recurrentStartDate": "on monday at 18:00",
"recurrentEndDate": "on monday at 22:00",
"isWorking": true
}, {
"recurrentStartDate": "on tuesday at 18:00",
"recurrentEndDate": "on tuesday at 22:00",
"isWorking": true
}, {
"recurrentStartDate": "on wednesday at 18:00",
"recurrentEndDate": "on wednesday at 22:00",
"isWorking": true
}, {
"recurrentStartDate": "on thursday at 18:00",
"recurrentEndDate": "on thursday at 22:00",
"isWorking": true
}, {
"recurrentStartDate": "on friday at 18:00",
"recurrentEndDate": "on friday at 22:00",
"isWorking": true
}],
"children": [{
"id": "resource_15",
"name": "Doris Cole",
"intervals": []
}]
}, {
"id": 1,
"name": "Standard 40 Hours/Week",
"hoursPerDay": 8.0,
"daysPerWeek": 5,
"daysPerMonth": 20,
"unspecifiedTimeIsWorking": false,
"intervals": [{
"recurrentStartDate": "on monday at 8:00",
"recurrentEndDate": "on monday at 12:00",
"isWorking": true
}, {
"recurrentStartDate": "on monday at 13:00",
"recurrentEndDate": "on monday at 17:00",
"isWorking": true
}, {
"recurrentStartDate": "on tuesday at 8:00",
"recurrentEndDate": "on tuesday at 12:00",
"isWorking": true
}, {
"recurrentStartDate": "on tuesday at 13:00",
"recurrentEndDate": "on tuesday at 17:00",
"isWorking": true
}, {
"recurrentStartDate": "on wednesday at 8:00",
"recurrentEndDate": "on wednesday at 12:00",
"isWorking": true
}, {
"recurrentStartDate": "on wednesday at 13:00",
"recurrentEndDate": "on wednesday at 17:00",
"isWorking": true
}, {
"recurrentStartDate": "on thursday at 8:00",
"recurrentEndDate": "on thursday at 12:00",
"isWorking": true
}, {
"recurrentStartDate": "on thursday at 13:00",
"recurrentEndDate": "on thursday at 17:00",
"isWorking": true
}, {
"recurrentStartDate": "on friday at 8:00",
"recurrentEndDate": "on friday at 12:00",
"isWorking": true
}, {
"recurrentStartDate": "on friday at 13:00",
"recurrentEndDate": "on friday at 17:00",
"isWorking": true
}, {
"startDate": "2020-05-03 00:00:00",
"endDate": "2020-05-04 00:00:00",
"isWorking": false
}],
"children": [{
"id": "resource_19",
"name": "Eli Lambert",
"intervals": []
}, {
"id": "resource_18",
"name": "Ernest Reed",
"intervals": [{
"startDate": "2020-04-02 00:00:00",
"endDate": "2020-04-04 00:00:00",
"isWorking": false
}]
}]
}]
}
}
Then I edit the task and for some reason I have to switch the scheduling mode to normal then back to Fixed Effort, and I have to set all the assignments to 100%. Then for the scheduling to work, I must set the calendar with the earliest interval ("standard 40hrs"). Then, when I change the effort to 12 hours, the result is this:
Start time is 8:00 AM, which is fine as the earliest an employee can start to work is 8:00 AM.
End time is 3:00 PM on the same day, which is wrong. This is 6 working hours later, which means the scheduler thinks there are two employees working from 8:00 AM, but one of the employee (Ernest Reed) has a leave that covers the first two days! The task should have ended at 10:00 PM during the evening shift!
So I'm a bit lost. I hope this is clear enough, if not I can try to work a better example. Any advice?
EDIT: the data was updated to set the task scheduling mode properly, and to include an evening schedule calendar.