Constraints are an inherent part of any scheduling workflow. From simple time restrictions to frequently changing rule matrices, rules can range in complexity. Validation rules allow you to codify these constraints, enabling end users to build and modify schedules with an understanding of the limitations and restrictions that define your organization’s operations.
Each validation rule is backed by a TypeScript function that evaluates whether the current state of a schedule object meets a certain condition as defined in the function logic.
Users are presented with the results of validation rules on the front-end of the Scheduling Gantt Chart widget in Workshop. Upon initial load, all rules are evaluated based on the current state of the Ontology. With each modification to the schedule, the rules are re-evaluated. This process empowers users with the knowledge of how their decisions comply with specific constraints and restrictions.
Below is an example of scheduling constraints within a Scheduling Gantt Chart widget. In the first image, the rule No Operator Overlaps is applied, as indicated with the toggle. This option ensures that only results abiding by this rule will be presented. The following image demonstrates the output. In this example, there is a conflict between the two rows, where the operators, Brad Evans and Ashley Brown, are overlapping.
In the Scheduling Gantt Chart widget in Workshop, the validation rules will be called each time a change is performed to validate the schedules.
1. Action "saveHandler" called on scenario
2. Validation rules called on updated scenario
3. Action "saveHandler" called on scenario
4. Validation rules called on updated scenario
etc ...
n. The user selects "Submit changes", and all Actions that have been applied to the scenario are applied to the Ontology
Rules are configured directly in the Scheduling Gantt Chart widget, allowing you to apply rules on a per use case basis. To add a rule to your Scheduling Gantt Chart widget:
The types below represent the necessary information to write a validation rule, which includes the status of the rule for each object.
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
type IFoORule = (scheduleObjectPrimaryKeys: string[]) => Array<IRuleResult> /* Rule result is interpreted as follows: true - Rule validated as passing false - Rule validated as not passing undefined - Rule is not relevant to the given schedule object */ interface IRuleResult { result: boolean | undefined; scheduleObjectPrimaryKey: string; details?: Array<IRuleResultDetails>; } /* By default the text on the pop-over card will display the rule name as configured in the rule object Optionally, you can explicitly define custom text based on the results of rule evaluation Additionally, you can provide a set of related puckIds to point users towards why a rule is passing or failing */ interface IRuleResultDetails { description: string; relatedPuckIds: string[]; }
The following is a basic example of a Function without the core logic of the validation:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
import { Function, Integer } from "@foundry/functions-api"; import { Objects, TaskOrSchedule, ObjectSet} from "@foundry/ontology-api"; // For type definitions, review our public documentation interface IRuleResultDetails { description: string; relatedPuckIds: string[]; } interface IRuleResult { result: boolean | undefined; scheduleObjectPrimaryKey: string; details?: Array<IRuleResultDetails>; } type IFoORule = (scheduleObjectPrimaryKeys: string[]) => Array<IRuleResult> export class MyFunctions { @Function() public async evaluateIfTaskOrScheduleIsValid(scheduleObjectPrimaryKeys: string[]): Promise<Array<IRuleResult>> { // Create the response data structure var arrayResponses : Array<IRuleResult> = []; scheduleObjectPrimaryKeys.forEach(pk => { // Get the primary key of each Schedule object const currentSchedulePK = scheduleObjectPrimaryKeys[i]; // Do something with the primary key; fetch objects, validate something, ... // Build the response const currentValidationDetails : Array<IRuleResultDetails> = []; currentValidationDetails.push( { description: "This is the description of the validation that passes or not", relatedPuckIds: [] }); const currentResponse : IRuleResult= { result: true, scheduleObjectPrimaryKey: currentSchedulePK, details: currentValidationDetails, }; arrayResponses.push(currentResponse); }); return arrayResponses; } }
More complex validation rules can be created. For example, rules can check the following: