You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These methods encapsulate shift-related logic within the domain model, making constraints more readable and maintainable. They're particularly important for date-boundary calculations (e.g., a shift spanning midnight).
335
+
These methods encapsulate shift-related logic within the domain model, making constraints more readable and maintainable.
336
+
337
+
> **Implementation Note:** For datetime overlap calculations in constraint penalty lambdas, the codebase uses inline calculations with explicit `time(0, 0, 0)` and `time(23, 59, 59)` rather than calling domain methods. This avoids transpilation issues with `datetime.min.time()` and `datetime.max.time()` in the constraint stream API.
2.`.join(Employee, ...)`: Join with the assigned employee
492
491
3.`.flatten_last(lambda employee: employee.unavailable_dates)`: Expand each employee's unavailable_dates set
493
492
4.`.filter(...)`: Keep only when shift overlaps the unavailable date
494
-
5.`.penalize(...)`: Penalize by overlapping duration in minutes
493
+
5.`.penalize(...)`: Penalize by overlapping duration in minutes (calculated inline)
494
+
495
+
**Optimization concept:** The `flatten_last` operation demonstrates **constraint streaming with collections**. We iterate over each date in the employee's unavailable set, creating (shift, date) pairs to check.
495
496
496
-
**Optimization concept:** The `flatten_last` operation demonstrates **constraint streaming with collections**. We iterate over each date in the employee's unavailable set, creating (shift, date) pairs to check. The `shift.is_overlapping_with_date()`and `shift.get_overlapping_duration_in_minutes()`methods are defined on the Shift domain model class.
497
+
> **Why inline calculation?** The penalty lambda uses explicit `time(0, 0, 0)` and `time(23, 59, 59)` rather than `datetime.min.time()`or calling domain methods. This is required because certain datetime methods don't transpile correctly to the constraint stream engine.
Analyze a schedule without solving to understand constraint violations:
797
+
798
+
**Request body:** Same format as demo-data response
799
+
800
+
**Response:**
801
+
```json
802
+
{
803
+
"constraints": [
804
+
{
805
+
"name": "Required skill",
806
+
"weight": "1hard",
807
+
"score": "-2hard",
808
+
"matches": [
809
+
{
810
+
"name": "Required skill",
811
+
"score": "-1hard",
812
+
"justification": "Shift(id=5) assigned to Employee(Amy Cole)"
813
+
}
814
+
]
815
+
}
816
+
]
817
+
}
760
818
```
761
819
762
820
### Web UI Flow
@@ -780,15 +838,15 @@ The `static/app.js` implements this polling workflow:
780
838
781
839
## Making Your First Customization
782
840
783
-
The quickstart includes a cardinality constraint that demonstrates a common pattern. Let's understand how it works and then learn how to create similar constraints.
841
+
The quickstart includes an optional cardinality constraint that demonstrates a common pattern. Let's understand how it works and then learn how to create similar constraints.
784
842
785
843
### Understanding the Max Shifts Constraint
786
844
787
-
The codebase includes `max_shifts_per_employee` which limits workload imbalance:
845
+
The codebase includes `max_shifts_per_employee` which limits workload imbalance. This constraint is **disabled by default** (commented out in `define_constraints()`) but serves as a useful example:
788
846
789
847
**Business rule:** "No employee can work more than 12 shifts in the schedule period."
790
848
791
-
This is a **hard constraint** (must be satisfied).
849
+
This is a **hard constraint** (must be satisfied when enabled).
0 commit comments