onroute-policy-engine 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,5 +3,6 @@ export declare enum ValidationResultCode {
3
3
  FieldValidationError = "field-validation-error",
4
4
  ConfigurationInvalid = "configuration-invalid",
5
5
  GeneralResult = "general-result",
6
- CostValue = "cost-value"
6
+ CostValue = "cost-value",
7
+ IsLcvCarrier = "lcv-carrier"
7
8
  }
@@ -8,4 +8,5 @@ var ValidationResultCode;
8
8
  ValidationResultCode["ConfigurationInvalid"] = "configuration-invalid";
9
9
  ValidationResultCode["GeneralResult"] = "general-result";
10
10
  ValidationResultCode["CostValue"] = "cost-value";
11
+ ValidationResultCode["IsLcvCarrier"] = "lcv-carrier";
11
12
  })(ValidationResultCode || (exports.ValidationResultCode = ValidationResultCode = {}));
@@ -61,6 +61,28 @@ function addRuntimeFacts(engine, policy) {
61
61
  }
62
62
  return isValid;
63
63
  });
64
+ /**
65
+ * Add runtime fact to get the list of allowed vehicles taking into
66
+ * consideration a client special authorization lcv flag.
67
+ */
68
+ engine.addFact(enum_1.PolicyFacts.AllowedVehicles.toString(), async function (params, almanac) {
69
+ let allowedVehicles = [];
70
+ const permitTypeId = (await almanac.factValue(enum_1.PermitAppInfo.PermitType));
71
+ const permitType = policy.getPermitTypeDefinition(permitTypeId);
72
+ if (permitType) {
73
+ if (permitType.allowedVehicles &&
74
+ permitType.allowedVehicles.length > 0) {
75
+ allowedVehicles = permitType.allowedVehicles;
76
+ // Filter out long combination vehcles if necessary
77
+ if (!policy.specialAuthorizations ||
78
+ !policy.specialAuthorizations.isLcvAllowed) {
79
+ allowedVehicles =
80
+ policy.filterOutLongCombinationVehicles(allowedVehicles);
81
+ }
82
+ }
83
+ }
84
+ return allowedVehicles;
85
+ });
64
86
  /**
65
87
  * Add runtime fact for a fixed permit cost, the cost supplied
66
88
  * as a parameter.
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getRulesEngines = getRulesEngines;
4
4
  const json_rules_engine_1 = require("json-rules-engine");
5
5
  const custom_operators_1 = require("../rule-operator/custom-operators");
6
- const enum_1 = require("onroute-policy-engine/enum");
7
6
  /**
8
7
  * Gets a json-rules-engine with all onRouteBC custom operators added,
9
8
  * and all policy rules that apply to all permit types added.
@@ -60,16 +59,6 @@ function getRulesEngines(policy) {
60
59
  };
61
60
  engine.addRule(costRule);
62
61
  });
63
- let allowedVehicles;
64
- if (permitType.allowedVehicles && permitType.allowedVehicles.length > 0) {
65
- allowedVehicles = permitType.allowedVehicles;
66
- }
67
- else {
68
- // If no allowed vehicles are specified, none are permitted
69
- allowedVehicles = [];
70
- }
71
- // Each permit type should have a list of allowed vehicles configured.
72
- engine.addFact(enum_1.PolicyFacts.AllowedVehicles.toString(), allowedVehicles);
73
62
  engineMap.set(permitType.id, engine);
74
63
  });
75
64
  return engineMap;
@@ -0,0 +1,8 @@
1
+ import { VehicleTypes } from '../types';
2
+ /**
3
+ * Filters out all LCV vehicles from a supplied list of vehicle IDs.
4
+ * @param vehicleList List of vehicle IDs to filter
5
+ * @param vehicleTypes Configured vehicle types from policy configuration
6
+ * @returns
7
+ */
8
+ export declare function filterOutLcv(vehicleList: Array<string>, vehicleTypes: VehicleTypes): Array<string>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterOutLcv = filterOutLcv;
4
+ /**
5
+ * Filters out all LCV vehicles from a supplied list of vehicle IDs.
6
+ * @param vehicleList List of vehicle IDs to filter
7
+ * @param vehicleTypes Configured vehicle types from policy configuration
8
+ * @returns
9
+ */
10
+ function filterOutLcv(vehicleList, vehicleTypes) {
11
+ const allVehicleTypes = vehicleTypes.powerUnitTypes.concat(vehicleTypes.trailerTypes);
12
+ const filteredList = vehicleList.filter((v) => {
13
+ const vType = allVehicleTypes.find((vt) => vt.id === v);
14
+ if (vType) {
15
+ if (vType.isLcv) {
16
+ return false;
17
+ }
18
+ else {
19
+ return true;
20
+ }
21
+ }
22
+ else {
23
+ console.log(`No configured vehicle type matching '${v}'`);
24
+ return false;
25
+ }
26
+ });
27
+ return filteredList;
28
+ }
@@ -1,10 +1,16 @@
1
1
  import { PolicyDefinition, PermitType, Commodity, SizeDimension, AxleConfiguration, BridgeCalculationResult } from 'onroute-policy-engine/types';
2
2
  import { Engine } from 'json-rules-engine';
3
3
  import { ValidationResults } from './validation-results';
4
+ import { SpecialAuthorizations } from './types/special-authorizations';
4
5
  /** Class representing commercial vehicle policy. */
5
6
  export declare class Policy {
6
7
  /** Object representation of policy definition and rules. */
7
8
  policyDefinition: PolicyDefinition;
9
+ /**
10
+ * Special authorizations granted to a client, used
11
+ * to adjust validations and allowed vehicles for permit types.
12
+ */
13
+ specialAuthorizations?: SpecialAuthorizations | null;
8
14
  /**
9
15
  * Map of json-rules-engine instances, one for each
10
16
  * permit type defined in the permit definition. Keyed
@@ -15,7 +21,13 @@ export declare class Policy {
15
21
  * Creates a new Policy object.
16
22
  * @param definition Policy definition to validate permits against
17
23
  */
18
- constructor(definition: PolicyDefinition);
24
+ constructor(definition: PolicyDefinition, authorizations?: SpecialAuthorizations);
25
+ /**
26
+ * Sets a client's special authorizations to modify the policy validations
27
+ * and permittable vehicles for permit types.
28
+ * @param authorizations Special authorizations for a client
29
+ */
30
+ setSpecialAuthorizations(authorizations: SpecialAuthorizations | null): void;
19
31
  /**
20
32
  * Validates a permit application against the policy definition.
21
33
  * @param permit The permit application to validate against policy
@@ -32,6 +44,13 @@ export declare class Policy {
32
44
  * @returns Map of geographic region IDs to region names.
33
45
  */
34
46
  getGeographicRegions(): Map<string, string>;
47
+ /**
48
+ * Filters out all long combination vehicles from the list of supplied
49
+ * vehicle IDs, based on policy configuration.
50
+ * @param vehicleList List of vehicles to filter
51
+ * @returns Filtered list of vehicles without LCVs
52
+ */
53
+ filterOutLongCombinationVehicles(vehicleList: Array<string>): Array<string>;
35
54
  /**
36
55
  * Gets a list of all configured commodities in the policy definition.
37
56
  * @param permitTypeId Return only commodities valid for this permit type.
@@ -15,13 +15,14 @@ const version_1 = require("./version");
15
15
  const valid_1 = __importDefault(require("semver/functions/valid"));
16
16
  const lt_1 = __importDefault(require("semver/functions/lt"));
17
17
  const major_1 = __importDefault(require("semver/functions/major"));
18
+ const vehicles_helper_1 = require("./helper/vehicles.helper");
18
19
  /** Class representing commercial vehicle policy. */
19
20
  class Policy {
20
21
  /**
21
22
  * Creates a new Policy object.
22
23
  * @param definition Policy definition to validate permits against
23
24
  */
24
- constructor(definition) {
25
+ constructor(definition, authorizations) {
25
26
  // Check compatibility of the policy engine with the policy config
26
27
  if (!(0, valid_1.default)(version_1.version)) {
27
28
  throw new Error(`Cannot determine the version of the policy engine for compatibility: invalid semver: ${version_1.version}`);
@@ -36,14 +37,24 @@ class Policy {
36
37
  throw new Error(`Current policy config minimum version is at least one major version behind policy engine: major(${definition.minPEVersion}) < major(${version_1.version}))`);
37
38
  }
38
39
  this.policyDefinition = definition;
40
+ this.specialAuthorizations = authorizations;
39
41
  this.rulesEngines = (0, rules_engine_helper_1.getRulesEngines)(this);
40
42
  }
43
+ /**
44
+ * Sets a client's special authorizations to modify the policy validations
45
+ * and permittable vehicles for permit types.
46
+ * @param authorizations Special authorizations for a client
47
+ */
48
+ setSpecialAuthorizations(authorizations) {
49
+ this.specialAuthorizations = authorizations;
50
+ }
41
51
  /**
42
52
  * Validates a permit application against the policy definition.
43
53
  * @param permit The permit application to validate against policy
44
54
  * @returns Results of the validation of the permit application
45
55
  */
46
56
  async validate(permit) {
57
+ var _a;
47
58
  const engine = this.rulesEngines.get(permit.permitType);
48
59
  if (!engine) {
49
60
  // If the permit type being validated has no configuration in the
@@ -60,7 +71,12 @@ class Policy {
60
71
  // Run the json-rules-engine against the permit facts
61
72
  const engineResult = await engine.run(permit);
62
73
  // Wrap the json-rules-engine result in a ValidationResult object
63
- return new validation_results_1.ValidationResults(engineResult);
74
+ const validationResults = new validation_results_1.ValidationResults(engineResult);
75
+ // Include an informational message if the client is an LCV carrier
76
+ if ((_a = this.specialAuthorizations) === null || _a === void 0 ? void 0 : _a.isLcvAllowed) {
77
+ validationResults.information.push(new validation_result_1.ValidationResult(enum_1.ValidationResultType.Information, enum_1.ValidationResultCode.IsLcvCarrier, `Policy validation allowing long combination vahicle permitting for client '${this.specialAuthorizations.companyId}'`));
78
+ }
79
+ return validationResults;
64
80
  }
65
81
  }
66
82
  /**
@@ -79,6 +95,15 @@ class Policy {
79
95
  const geographicRegions = (0, lists_helper_1.extractIdentifiedObjects)(this.policyDefinition.geographicRegions);
80
96
  return geographicRegions;
81
97
  }
98
+ /**
99
+ * Filters out all long combination vehicles from the list of supplied
100
+ * vehicle IDs, based on policy configuration.
101
+ * @param vehicleList List of vehicles to filter
102
+ * @returns Filtered list of vehicles without LCVs
103
+ */
104
+ filterOutLongCombinationVehicles(vehicleList) {
105
+ return (0, vehicles_helper_1.filterOutLcv)(vehicleList, this.policyDefinition.vehicleTypes);
106
+ }
82
107
  /**
83
108
  * Gets a list of all configured commodities in the policy definition.
84
109
  * @param permitTypeId Return only commodities valid for this permit type.
@@ -143,7 +168,7 @@ class Policy {
143
168
  * vehicle, and a string common name for the vehicle.
144
169
  */
145
170
  getPermittableVehicleTypes(permitTypeId, commodityId) {
146
- var _a, _b, _c, _d;
171
+ var _a, _b, _c, _d, _e;
147
172
  if (!permitTypeId || !commodityId) {
148
173
  throw new Error('Missing permitTypeId and/or commodityId');
149
174
  }
@@ -170,16 +195,31 @@ class Policy {
170
195
  if (!commodity) {
171
196
  throw new Error(`Commodity id '${commodityId}' is not correctly configured in the policy definition`);
172
197
  }
173
- const puTypeIdsOS = (_b = (_a = commodity.size) === null || _a === void 0 ? void 0 : _a.powerUnits) === null || _b === void 0 ? void 0 : _b.map((p) => p.type);
174
- const trTypeIdsOS = [];
198
+ let puTypeIdsOS = (_b = (_a = commodity.size) === null || _a === void 0 ? void 0 : _a.powerUnits) === null || _b === void 0 ? void 0 : _b.map((p) => p.type);
199
+ let trTypeIdsOS = [];
175
200
  (_d = (_c = commodity.size) === null || _c === void 0 ? void 0 : _c.powerUnits) === null || _d === void 0 ? void 0 : _d.forEach((pu) => {
176
201
  const trForPu = pu.trailers.map((t) => t.type);
177
202
  if (trForPu)
178
- trTypeIdsOS.concat(trForPu);
203
+ trTypeIdsOS === null || trTypeIdsOS === void 0 ? void 0 : trTypeIdsOS.concat(trForPu);
179
204
  });
180
205
  // TODO: implement along with overweight permits. Stub for now.
181
- const puTypeIdsOW = [];
182
- const trTypeIdsOW = [];
206
+ let puTypeIdsOW = [];
207
+ let trTypeIdsOW = [];
208
+ // Remove long combination vehicles if needed
209
+ if (!((_e = this.specialAuthorizations) === null || _e === void 0 ? void 0 : _e.isLcvAllowed)) {
210
+ if (puTypeIdsOS) {
211
+ puTypeIdsOS = this.filterOutLongCombinationVehicles(puTypeIdsOS);
212
+ }
213
+ if (trTypeIdsOS) {
214
+ trTypeIdsOS = this.filterOutLongCombinationVehicles(trTypeIdsOS);
215
+ }
216
+ if (puTypeIdsOW) {
217
+ puTypeIdsOW = this.filterOutLongCombinationVehicles(puTypeIdsOW);
218
+ }
219
+ if (trTypeIdsOW) {
220
+ trTypeIdsOW = this.filterOutLongCombinationVehicles(trTypeIdsOW);
221
+ }
222
+ }
183
223
  const puTypesOS = (0, lists_helper_1.extractIdentifiedObjects)(this.policyDefinition.vehicleTypes.powerUnitTypes, puTypeIdsOS);
184
224
  const trTypesOS = (0, lists_helper_1.extractIdentifiedObjects)(this.policyDefinition.vehicleTypes.trailerTypes, trTypeIdsOS);
185
225
  const puTypesOW = (0, lists_helper_1.extractIdentifiedObjects)(this.policyDefinition.vehicleTypes.powerUnitTypes, puTypeIdsOW);
@@ -237,7 +277,7 @@ class Policy {
237
277
  * trailers in a single return value (if applicable).
238
278
  */
239
279
  getNextPermittableVehicles(permitTypeId, commodityId, currentConfiguration) {
240
- var _a, _b, _c, _d;
280
+ var _a, _b, _c, _d, _e;
241
281
  if (!permitTypeId || !commodityId || !currentConfiguration) {
242
282
  throw new Error('Missing permitTypeId and/or commodityId and/or currentConfiguration');
243
283
  }
@@ -305,6 +345,12 @@ class Policy {
305
345
  }
306
346
  }
307
347
  }
348
+ // Remove long combination vehicles if required
349
+ if (!((_e = this.specialAuthorizations) === null || _e === void 0 ? void 0 : _e.isLcvAllowed)) {
350
+ if (vehicleTypeIds) {
351
+ vehicleTypeIds = this.filterOutLongCombinationVehicles(vehicleTypeIds);
352
+ }
353
+ }
308
354
  vehicleTypes = (0, lists_helper_1.extractIdentifiedObjects)(allVehicles, vehicleTypeIds);
309
355
  return vehicleTypes;
310
356
  }
@@ -347,6 +393,16 @@ class Policy {
347
393
  // invalid as a complete configuration.
348
394
  return validatePartial;
349
395
  }
396
+ if (!this.specialAuthorizations ||
397
+ !this.specialAuthorizations.isLcvAllowed) {
398
+ // No provision for allowing long combination vehicles
399
+ const filteredConfiguration = this.filterOutLongCombinationVehicles(currentConfiguration);
400
+ if (filteredConfiguration.length !== currentConfiguration.length) {
401
+ // There is an LCV in the configuration, but we are not allowing
402
+ // LCV permitting. Return false.
403
+ return false;
404
+ }
405
+ }
350
406
  const powerUnit = (_b = (_a = commodity.size) === null || _a === void 0 ? void 0 : _a.powerUnits) === null || _b === void 0 ? void 0 : _b.find((p) => p.type == currentConfiguration[0]);
351
407
  if (!powerUnit) {
352
408
  // The power unit is not allowed for the commodity
@@ -13,6 +13,7 @@ export { Matrix, RangeMatrix } from './range-matrix';
13
13
  export { RegionSizeOverride } from './region-size-override';
14
14
  export { SelfIssuable } from './self-issuable';
15
15
  export { SizeDimension } from './size-dimension';
16
+ export { SpecialAuthorizations } from './special-authorizations';
16
17
  export { VehicleCategory, PowerUnitCategory, TrailerCategory, VehicleCategories, } from './vehicle-category';
17
18
  export { VehicleType, PowerUnitType, TrailerType, VehicleTypes, } from './vehicle-type';
18
19
  export { Vehicle, VehicleSizeConfiguration, TrailerSize, PowerUnitWeight, TrailerWeight, } from './vehicle';
@@ -0,0 +1,5 @@
1
+ export type SpecialAuthorizations = {
2
+ companyId: number;
3
+ isLcvAllowed?: boolean;
4
+ noFeeType?: string;
5
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -3,6 +3,7 @@ export type VehicleType = IdentifiedObject & {
3
3
  category: string;
4
4
  defaultSizeDimensions?: SizeDimension;
5
5
  ignoreForSizeDimensions?: boolean;
6
+ isLcv?: boolean;
6
7
  };
7
8
  export type PowerUnitType = VehicleType & {
8
9
  defaultWeightDimensions?: Array<PowerUnitWeightDimension>;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "v1.0.0";
1
+ export declare const version = "v1.2.0";
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // Generated by genversion.
5
- exports.version = 'v1.0.0';
5
+ exports.version = 'v1.2.0';
package/package.json CHANGED
@@ -89,5 +89,5 @@
89
89
  ],
90
90
  "testEnvironment": "node"
91
91
  },
92
- "version": "v1.0.0"
92
+ "version": "v1.2.0"
93
93
  }