Skip to content

Commit 7c02311

Browse files
authored
Merge pull request #190 from fleetbase/dev-v0.6.26
release: v0.6.26, fixed Kanban card
2 parents 91f84ef + 67e0341 commit 7c02311

50 files changed

Lines changed: 3313 additions & 443 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

DRIVER_SCHEDULING.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# FleetOps Driver Scheduling Module
2+
3+
This module implements driver scheduling with Hours of Service (HOS) compliance for FleetOps.
4+
5+
## Features
6+
7+
- **Fleet-Wide Scheduler**: Manage all drivers' schedules in a single calendar view
8+
- **Driver Schedule Management**: Create, edit, and manage driver shifts
9+
- **HOS Compliance**: Real-time validation against FMCSA regulations
10+
- **Calendar View**: Visual schedule management with drag-and-drop
11+
- **Resource Timeline**: View multiple drivers' schedules simultaneously
12+
- **Individual Driver Schedules**: Dedicated schedule view on driver detail pages
13+
- **Availability Management**: Track driver availability and time-off requests
14+
- **Conflict Detection**: Automatic detection of scheduling conflicts
15+
- **Dual View Modes**: Toggle between order scheduling and driver scheduling
16+
17+
## Components
18+
19+
### Operations/Scheduler (Fleet-Wide View)
20+
21+
The main scheduler view at `operations/scheduler` now supports both order scheduling and driver scheduling.
22+
23+
**Location**: `addon/controllers/operations/scheduler/index.js`
24+
25+
**Features**:
26+
- **View Mode Toggle**: Switch between "Orders" and "Driver Schedules" modes
27+
- **Resource Timeline**: In driver mode, shows all drivers as resources with their shifts
28+
- **Drag-and-Drop**: Drag shifts between drivers or reschedule by dragging
29+
- **Add Shift**: Quick action button to create new driver shifts
30+
- **Real-Time Updates**: Calendar updates automatically when shifts are modified
31+
- **Status Colors**: Visual indicators for shift status (pending, confirmed, etc.)
32+
33+
**View Modes**:
34+
1. **Orders Mode** (default):
35+
- Month calendar view
36+
- Drag unscheduled orders to calendar
37+
- Manage order scheduling
38+
39+
2. **Driver Schedules Mode**:
40+
- Resource timeline view (week view with drivers as resources)
41+
- View all drivers' shifts simultaneously
42+
- Drag shifts between drivers
43+
- Reschedule shifts by dragging
44+
- Click shifts to view/edit details
45+
46+
**Usage**:
47+
Navigate to Operations → Scheduler, then toggle between "Orders" and "Driver Schedules" using the header buttons.
48+
49+
### Driver::Schedule
50+
51+
Displays and manages a driver's schedule from their detail page.
52+
53+
**Location**: `addon/components/driver/schedule.js`
54+
55+
**Features**:
56+
- HOS compliance dashboard with visual indicators
57+
- Weekly calendar view of driver shifts
58+
- Upcoming shifts list (next 5 shifts)
59+
- Availability and time-off management
60+
- Quick actions for adding shifts and requesting time off
61+
62+
**Usage**:
63+
```handlebars
64+
<Driver::Schedule @driver={{@model}} />
65+
```
66+
67+
**Integration**: Add a "Schedule" tab to the driver detail page.
68+
69+
## Backend Components
70+
71+
### HOSConstraint
72+
73+
Validates schedule items against FMCSA Hours of Service regulations.
74+
75+
**Location**: `server/src/Constraints/HOSConstraint.php`
76+
77+
**Regulations Enforced**:
78+
1. **11-Hour Driving Limit**: Maximum 11 hours driving after 10 consecutive hours off duty
79+
2. **14-Hour Duty Window**: Cannot drive beyond 14th hour after coming on duty
80+
3. **60/70-Hour Weekly Limit**: Cannot drive after 60/70 hours in 7/8 consecutive days
81+
4. **30-Minute Break**: Required after 8 cumulative hours of driving
82+
83+
**Violation Severity**:
84+
- `critical`: Immediate compliance issue, shift cannot be scheduled
85+
- `warning`: Approaching limit, requires attention
86+
87+
**Registration**:
88+
```php
89+
// In FleetOps ServiceProvider boot() method
90+
$constraintService = app(\Fleetbase\Services\Scheduling\ConstraintService::class);
91+
$constraintService->register('driver', \Fleetbase\FleetOps\Constraints\HOSConstraint::class);
92+
```
93+
94+
## HOS Compliance Dashboard
95+
96+
The HOS dashboard displays:
97+
- **Daily Driving Hours**: X/11 hours with circular progress indicator
98+
- **Weekly Hours**: X/70 hours with circular progress indicator
99+
- **Compliance Status**: Badge indicating compliance level
100+
- Green: Compliant
101+
- Yellow: Approaching Limit
102+
- Red: At Limit
103+
104+
## API Endpoints
105+
106+
FleetOps extends the core scheduling endpoints with driver-specific functionality:
107+
108+
- `GET /drivers/{id}/hos-status` - Get HOS compliance status for a driver
109+
- `GET /drivers/{id}/schedule` - Get schedule items for a driver
110+
- `POST /drivers/{id}/schedule` - Create a new shift for a driver
111+
- `PUT /schedule-items/{id}` - Update a shift (with HOS validation)
112+
- `DELETE /schedule-items/{id}` - Delete a shift
113+
114+
## Workflow
115+
116+
### Creating a Driver Shift
117+
118+
1. User clicks "Add Shift" button
119+
2. Modal opens with shift form
120+
3. User selects date, time, vehicle, and other details
121+
4. System validates against HOS constraints
122+
5. If violations found, display warnings/errors
123+
6. If valid, create schedule item
124+
7. Update driver schedule view and HOS dashboard
125+
126+
### HOS Validation
127+
128+
1. When a schedule item is created/updated
129+
2. `HOSConstraint::validate()` is called
130+
3. Checks all four HOS regulations
131+
4. Returns violations array if any
132+
5. Frontend displays violations to user
133+
6. User can adjust shift or override (with proper permissions)
134+
135+
## Integration with Core Scheduling
136+
137+
FleetOps uses the core scheduling module with driver-specific customizations:
138+
139+
**Core Components Used**:
140+
- `Schedule` model (subject_type: 'fleet', subject_uuid: fleet.id)
141+
- `ScheduleItem` model (assignee_type: 'driver', assignee_uuid: driver.id)
142+
- `ScheduleAvailability` model (subject_type: 'driver')
143+
- `ScheduleConstraint` model (subject_type: 'driver')
144+
145+
**FleetOps Extensions**:
146+
- `HOSConstraint` for compliance validation
147+
- `Driver::Schedule` component for driver-specific UI
148+
- HOS status API endpoint
149+
- Driver-specific scheduling logic
150+
151+
## Future Enhancements
152+
153+
- **Automatic Schedule Generation**: AI-powered schedule optimization
154+
- **ELD Integration**: Sync with Electronic Logging Devices
155+
- **Predictive HOS**: Forecast HOS availability for future dates
156+
- **Mobile App**: Driver-facing mobile app for schedule viewing
157+
- **Notifications**: Real-time alerts for schedule changes and HOS warnings
158+
- **Reporting**: HOS compliance reports and analytics
159+
160+
## Testing
161+
162+
### HOS Constraint Tests
163+
164+
Test cases should cover:
165+
- 11-hour driving limit enforcement
166+
- 14-hour duty window enforcement
167+
- 60/70-hour weekly limit enforcement
168+
- 30-minute break requirement
169+
- Edge cases (consecutive shifts, split shifts, etc.)
170+
171+
### Integration Tests
172+
173+
- Create driver shift via API
174+
- Validate HOS constraints are enforced
175+
- Update shift and verify re-validation
176+
- Delete shift and verify HOS recalculation
177+
- Test driver schedule view rendering
178+
179+
## Compliance Notes
180+
181+
This implementation follows FMCSA Hours of Service regulations as of 2025. Regulations may vary by:
182+
- Jurisdiction (US Federal, state-specific, Canada, etc.)
183+
- Vehicle type (property-carrying vs. passenger-carrying)
184+
- Industry (short-haul vs. long-haul)
185+
186+
**Important**: This is a software implementation and should not be the sole method of HOS compliance. Proper driver training, ELD integration, and regular audits are essential for full compliance.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<div class="driver-schedule-container" ...attributes>
2+
<ContentPanel @title="Hours of Service Status" @open={{true}} @isLoading={{this.loadHOSStatus.isRunning}} @wrapperClass="bordered-top">
3+
{{#if this.hosStatus}}
4+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
5+
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded">
6+
<div>
7+
<div class="text-sm text-gray-500 dark:text-gray-400">Daily Driving Hours</div>
8+
<div class="text-2xl font-bold">{{this.hosStatus.daily_hours}}/11</div>
9+
</div>
10+
<div class="w-16 h-16">
11+
<CircularProgress @value={{this.hosStatus.daily_hours}} @max={{11}} />
12+
</div>
13+
</div>
14+
15+
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded">
16+
<div>
17+
<div class="text-sm text-gray-500 dark:text-gray-400">Weekly Hours</div>
18+
<div class="text-2xl font-bold">{{this.hosStatus.weekly_hours}}/70</div>
19+
</div>
20+
<div class="w-16 h-16">
21+
<CircularProgress @value={{this.hosStatus.weekly_hours}} @max={{70}} />
22+
</div>
23+
</div>
24+
25+
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded">
26+
<div>
27+
<div class="text-sm text-gray-500 dark:text-gray-400">Compliance Status</div>
28+
<span
29+
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-{{this.hosComplianceBadge.color}}-100 text-{{this.hosComplianceBadge.color}}-800"
30+
>
31+
{{this.hosComplianceBadge.text}}
32+
</span>
33+
</div>
34+
</div>
35+
</div>
36+
{{/if}}
37+
</ContentPanel>
38+
<ContentPanel @title="Schedule Calendar" @open={{true}} @isLoading={{this.loadDriverSchedule.isRunning}} @actionButtons={{this.scheduleActionButtons}} @wrapperClass="bordered-top">
39+
<ScheduleCalendar @items={{this.scheduleItems}} @view="timeGridWeek" @onItemClick={{this.handleItemClick}}>
40+
<:item as |ctx|>
41+
<div class="schedule-item-content">
42+
<div class="font-medium">{{ctx.item.title}}</div>
43+
<div class="text-xs">{{ctx.item.duration}} min</div>
44+
</div>
45+
</:item>
46+
</ScheduleCalendar>
47+
</ContentPanel>
48+
49+
<ContentPanel @title="Upcoming Shifts" @open={{true}} @actionButtons={{this.shiftActionButtons}} @wrapperClass="bordered-top">
50+
{{#if this.upcomingShifts.length}}
51+
<div class="space-y-2">
52+
{{#each this.upcomingShifts as |shift|}}
53+
<ScheduleItemCard @item={{shift}} @onClick={{this.handleItemClick}}>
54+
<:actions>
55+
<button type="button" class="text-blue-600 hover:text-blue-800 text-sm" {{on "click" (fn this.editScheduleItem shift)}}>
56+
Edit
57+
</button>
58+
</:actions>
59+
</ScheduleItemCard>
60+
{{/each}}
61+
</div>
62+
{{else}}
63+
<div class="text-center py-4 text-gray-500 dark:text-gray-400">
64+
No upcoming shifts scheduled
65+
</div>
66+
{{/if}}
67+
</ContentPanel>
68+
69+
<ContentPanel @title="Availability & Time Off" @open={{true}} @actionButtons={{this.availabilityActionButtons}} @wrapperClass="bordered-top">
70+
{{#if this.availability.length}}
71+
<div class="space-y-2">
72+
{{#each this.availability as |avail|}}
73+
<div class="flex items-center justify-between p-2 bg-gray-50 dark:bg-gray-700 rounded">
74+
<div>
75+
<div class="font-medium">
76+
{{#if avail.is_available}}
77+
<span class="text-green-600">Available</span>
78+
{{else}}
79+
<span class="text-red-600">Unavailable</span>
80+
{{/if}}
81+
</div>
82+
<div class="text-sm text-gray-500">
83+
{{format-date-fns avail.start_at "MMM DD, YYYY"}}
84+
-
85+
{{format-date-fns avail.end_at "MMM DD, YYYY"}}
86+
</div>
87+
{{#if avail.reason}}
88+
<div class="text-xs text-gray-400">{{avail.reason}}</div>
89+
{{/if}}
90+
</div>
91+
</div>
92+
{{/each}}
93+
</div>
94+
{{else}}
95+
<div class="text-center py-4 text-gray-500 dark:text-gray-400">
96+
No availability restrictions set
97+
</div>
98+
{{/if}}
99+
</ContentPanel>
100+
</div>

0 commit comments

Comments
 (0)