onroute-policy-engine 2.1.0 → 2.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.
Files changed (80) hide show
  1. package/.github/workflows/pipeline.yml +25 -6
  2. package/dist/enum/custom-operator.d.ts +6 -0
  3. package/dist/enum/custom-operator.js +10 -0
  4. package/dist/enum/facts.d.ts +8 -4
  5. package/dist/enum/facts.js +8 -4
  6. package/dist/enum/index.d.ts +2 -0
  7. package/dist/enum/index.js +6 -1
  8. package/dist/enum/permit-app-info.d.ts +8 -5
  9. package/dist/enum/permit-app-info.js +8 -5
  10. package/dist/enum/policy-check.d.ts +11 -0
  11. package/dist/enum/policy-check.js +16 -0
  12. package/dist/enum/validation-result-code.d.ts +1 -0
  13. package/dist/enum/validation-result-code.js +1 -0
  14. package/dist/helper/dimensions.helper.js +7 -3
  15. package/dist/helper/display-code-helper.d.ts +42 -0
  16. package/dist/helper/display-code-helper.js +73 -1
  17. package/dist/helper/facts.helper.js +64 -0
  18. package/dist/helper/policy-check.helper.d.ts +183 -0
  19. package/dist/helper/policy-check.helper.js +337 -0
  20. package/dist/helper/vehicles.helper.d.ts +45 -1
  21. package/dist/helper/vehicles.helper.js +61 -0
  22. package/dist/policy-engine.d.ts +95 -1
  23. package/dist/policy-engine.js +103 -0
  24. package/dist/rule-operator/custom-operators.d.ts +7 -0
  25. package/dist/rule-operator/custom-operators.js +57 -3
  26. package/dist/types/axle-calculation-results.d.ts +49 -0
  27. package/dist/types/axle-calculation-results.js +8 -0
  28. package/dist/types/axle-configuration.d.ts +12 -0
  29. package/dist/types/axle-configuration.js +6 -0
  30. package/dist/types/bridge-calculation-constants.d.ts +8 -0
  31. package/dist/types/bridge-calculation-result.d.ts +11 -0
  32. package/dist/types/commodity.d.ts +10 -0
  33. package/dist/types/commodity.js +6 -0
  34. package/dist/types/cost-rule.d.ts +8 -0
  35. package/dist/types/cost-rule.js +6 -0
  36. package/dist/types/dimension-modifier.d.ts +27 -0
  37. package/dist/types/dimension-modifier.js +6 -0
  38. package/dist/types/display-code-defaults.d.ts +22 -0
  39. package/dist/types/display-code-defaults.js +6 -0
  40. package/dist/types/facts.d.ts +14 -0
  41. package/dist/types/facts.js +6 -0
  42. package/dist/types/geographic-region.d.ts +10 -0
  43. package/dist/types/geographic-region.js +6 -0
  44. package/dist/types/identified-object.d.ts +8 -0
  45. package/dist/types/identified-object.js +6 -0
  46. package/dist/types/index.d.ts +1 -0
  47. package/dist/types/permit-application.d.ts +109 -0
  48. package/dist/types/permit-application.js +6 -0
  49. package/dist/types/permit-condition.d.ts +18 -0
  50. package/dist/types/permit-condition.js +6 -0
  51. package/dist/types/permit-type.d.ts +18 -0
  52. package/dist/types/permit-type.js +6 -0
  53. package/dist/types/policy-definition.d.ts +24 -0
  54. package/dist/types/policy-definition.js +7 -0
  55. package/dist/types/range-matrix.d.ts +17 -0
  56. package/dist/types/range-matrix.js +6 -0
  57. package/dist/types/region-size-override.d.ts +10 -0
  58. package/dist/types/region-size-override.js +6 -0
  59. package/dist/types/self-issuable.d.ts +7 -0
  60. package/dist/types/self-issuable.js +6 -0
  61. package/dist/types/size-dimension.d.ts +17 -0
  62. package/dist/types/size-dimension.js +6 -0
  63. package/dist/types/special-authorizations.d.ts +9 -0
  64. package/dist/types/special-authorizations.js +6 -0
  65. package/dist/types/standard-tire-size.d.ts +8 -0
  66. package/dist/types/standard-tire-size.js +6 -0
  67. package/dist/types/vehicle-category.d.ts +27 -0
  68. package/dist/types/vehicle-category.js +6 -0
  69. package/dist/types/vehicle-type.d.ts +36 -0
  70. package/dist/types/vehicle-type.js +6 -0
  71. package/dist/types/vehicle.d.ts +27 -0
  72. package/dist/types/vehicle.js +6 -0
  73. package/dist/types/weight-dimension.d.ts +34 -0
  74. package/dist/types/weight-dimension.js +6 -0
  75. package/dist/validation-result.d.ts +1 -0
  76. package/dist/validation-results.js +2 -1
  77. package/dist/version.d.ts +1 -1
  78. package/dist/version.js +1 -1
  79. package/eslint.config.mjs +1 -1
  80. package/package.json +2 -1
@@ -12,10 +12,11 @@ jobs:
12
12
  packages: write
13
13
  steps:
14
14
  - uses: actions/checkout@v4
15
- deploy:
15
+ semver:
16
16
  runs-on: ubuntu-24.04
17
+ outputs:
18
+ next-version: ${{ steps.semver.outputs.next }}
17
19
  permissions:
18
- id-token: write # needed for provenance data generation
19
20
  contents: write
20
21
  packages: write
21
22
 
@@ -29,10 +30,28 @@ jobs:
29
30
  with:
30
31
  token: ${{ github.token }}
31
32
  branch: main
32
-
33
+ noNewCommitBehavior: warn
34
+ noVersionBumpBehavior: warn
35
+
36
+ - name: Log if No Version Bump
37
+ if: ${{ !steps.semver.outputs.next }}
38
+ run: echo "No version bump detected. Skipping deploy."
39
+ deploy:
40
+ needs: semver
41
+ if: ${{ needs.semver.outputs.next-version }}
42
+ runs-on: ubuntu-24.04
43
+ permissions:
44
+ id-token: write # needed for provenance data generation
45
+ contents: write
46
+ packages: write
47
+
48
+ steps:
49
+ - name: Checkout Code
50
+ uses: actions/checkout@v4
51
+
33
52
  - name: Injecting Semver Into Package.json
34
53
  run: |
35
- cat package.json | jq '. + { "version": "${{ steps.semver.outputs.next }}" }' | tee package.json
54
+ cat package.json | jq '. + { "version": "${{ needs.semver.outputs.next-version }}" }' | tee package.json
36
55
 
37
56
  - uses: actions/setup-node@v4
38
57
  with:
@@ -54,7 +73,7 @@ jobs:
54
73
  env:
55
74
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56
75
  run: |
57
- gh release create "${{ steps.semver.outputs.next }}" \
76
+ gh release create "${{ needs.semver.outputs.next-version }}" \
58
77
  --repo="${{ github.repository }}" \
59
- --title="${{ steps.semver.outputs.next }}" \
78
+ --title="${{ needs.semver.outputs.next-version }}" \
60
79
  --generate-notes
@@ -0,0 +1,6 @@
1
+ export declare enum CustomOperator {
2
+ DateLessThan = "dateLessThan",
3
+ IsEmptyArray = "isEmptyArray",
4
+ Regex = "regex",
5
+ StringMinimumLength = "stringMinimumLength"
6
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomOperator = void 0;
4
+ var CustomOperator;
5
+ (function (CustomOperator) {
6
+ CustomOperator["DateLessThan"] = "dateLessThan";
7
+ CustomOperator["IsEmptyArray"] = "isEmptyArray";
8
+ CustomOperator["Regex"] = "regex";
9
+ CustomOperator["StringMinimumLength"] = "stringMinimumLength";
10
+ })(CustomOperator || (exports.CustomOperator = CustomOperator = {}));
@@ -1,15 +1,19 @@
1
1
  export declare enum PolicyFacts {
2
2
  AllowedVehicles = "allowedVehicles",
3
+ AxleCalcViolations = "axleCalcViolations",
4
+ ConfigurationIsValid = "configurationIsValid",
5
+ DaysBetween = "daysBetween",
3
6
  DaysInPermitYear = "daysInPermitYear",
4
7
  EndOfPermitQuarter = "endOfPermitQuarter",
8
+ GrossVehicleCombinationWeight = "gvcw",
9
+ PolicyCheckPassed = "policyCheckPassed",
5
10
  ValidationDate = "validationDate",
6
- ConfigurationIsValid = "configurationIsValid",
7
- DaysBetween = "daysBetween"
11
+ VehicleConfiguration = "vehicleConfiguration"
8
12
  }
9
13
  export declare enum CostFacts {
10
14
  ConditionalFixedCost = "conditionalFixedCost",
11
- FixedCost = "fixedCost",
12
- CostPerMonth = "costPerMonth",
13
15
  CostPerKilometre = "costPerKilometre",
16
+ CostPerMonth = "costPerMonth",
17
+ FixedCost = "fixedCost",
14
18
  RangeMatrixCostLookup = "rangeMatrixCostLookup"
15
19
  }
@@ -4,17 +4,21 @@ exports.CostFacts = exports.PolicyFacts = void 0;
4
4
  var PolicyFacts;
5
5
  (function (PolicyFacts) {
6
6
  PolicyFacts["AllowedVehicles"] = "allowedVehicles";
7
+ PolicyFacts["AxleCalcViolations"] = "axleCalcViolations";
8
+ PolicyFacts["ConfigurationIsValid"] = "configurationIsValid";
9
+ PolicyFacts["DaysBetween"] = "daysBetween";
7
10
  PolicyFacts["DaysInPermitYear"] = "daysInPermitYear";
8
11
  PolicyFacts["EndOfPermitQuarter"] = "endOfPermitQuarter";
12
+ PolicyFacts["GrossVehicleCombinationWeight"] = "gvcw";
13
+ PolicyFacts["PolicyCheckPassed"] = "policyCheckPassed";
9
14
  PolicyFacts["ValidationDate"] = "validationDate";
10
- PolicyFacts["ConfigurationIsValid"] = "configurationIsValid";
11
- PolicyFacts["DaysBetween"] = "daysBetween";
15
+ PolicyFacts["VehicleConfiguration"] = "vehicleConfiguration";
12
16
  })(PolicyFacts || (exports.PolicyFacts = PolicyFacts = {}));
13
17
  var CostFacts;
14
18
  (function (CostFacts) {
15
19
  CostFacts["ConditionalFixedCost"] = "conditionalFixedCost";
16
- CostFacts["FixedCost"] = "fixedCost";
17
- CostFacts["CostPerMonth"] = "costPerMonth";
18
20
  CostFacts["CostPerKilometre"] = "costPerKilometre";
21
+ CostFacts["CostPerMonth"] = "costPerMonth";
22
+ CostFacts["FixedCost"] = "fixedCost";
19
23
  CostFacts["RangeMatrixCostLookup"] = "rangeMatrixCostLookup";
20
24
  })(CostFacts || (exports.CostFacts = CostFacts = {}));
@@ -1,6 +1,8 @@
1
1
  export { AccessoryVehicleType } from './accessory-vehicle-type';
2
+ export { CustomOperator } from './custom-operator';
2
3
  export { PolicyFacts, CostFacts } from './facts';
3
4
  export { PermitAppInfo } from './permit-app-info';
5
+ export { PolicyCheckResultType, PolicyCheckId } from './policy-check';
4
6
  export { RelativePosition } from './relative-position';
5
7
  export { ValidationResultCode } from './validation-result-code';
6
8
  export { ValidationResultType } from './validation-result-type';
@@ -1,13 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VehicleTypes = exports.VehicleCategory = exports.ValidationResultType = exports.ValidationResultCode = exports.RelativePosition = exports.PermitAppInfo = exports.CostFacts = exports.PolicyFacts = exports.AccessoryVehicleType = void 0;
3
+ exports.VehicleTypes = exports.VehicleCategory = exports.ValidationResultType = exports.ValidationResultCode = exports.RelativePosition = exports.PolicyCheckId = exports.PolicyCheckResultType = exports.PermitAppInfo = exports.CostFacts = exports.PolicyFacts = exports.CustomOperator = exports.AccessoryVehicleType = void 0;
4
4
  var accessory_vehicle_type_1 = require("./accessory-vehicle-type");
5
5
  Object.defineProperty(exports, "AccessoryVehicleType", { enumerable: true, get: function () { return accessory_vehicle_type_1.AccessoryVehicleType; } });
6
+ var custom_operator_1 = require("./custom-operator");
7
+ Object.defineProperty(exports, "CustomOperator", { enumerable: true, get: function () { return custom_operator_1.CustomOperator; } });
6
8
  var facts_1 = require("./facts");
7
9
  Object.defineProperty(exports, "PolicyFacts", { enumerable: true, get: function () { return facts_1.PolicyFacts; } });
8
10
  Object.defineProperty(exports, "CostFacts", { enumerable: true, get: function () { return facts_1.CostFacts; } });
9
11
  var permit_app_info_1 = require("./permit-app-info");
10
12
  Object.defineProperty(exports, "PermitAppInfo", { enumerable: true, get: function () { return permit_app_info_1.PermitAppInfo; } });
13
+ var policy_check_1 = require("./policy-check");
14
+ Object.defineProperty(exports, "PolicyCheckResultType", { enumerable: true, get: function () { return policy_check_1.PolicyCheckResultType; } });
15
+ Object.defineProperty(exports, "PolicyCheckId", { enumerable: true, get: function () { return policy_check_1.PolicyCheckId; } });
11
16
  var relative_position_1 = require("./relative-position");
12
17
  Object.defineProperty(exports, "RelativePosition", { enumerable: true, get: function () { return relative_position_1.RelativePosition; } });
13
18
  var validation_result_code_1 = require("./validation-result-code");
@@ -4,14 +4,17 @@
4
4
  * referenced from within source code.
5
5
  */
6
6
  export declare enum PermitAppInfo {
7
- PermitType = "permitType",
7
+ AxleConfiguration = "$.vehicleConfiguration.axleConfiguration",
8
+ CompanyName = "$.companyName",
9
+ Commodity = "$.permittedCommodity.commodityType",
8
10
  PermitData = "permitData",
9
- PermitStartDate = "$.startDate",
10
11
  PermitDateFormat = "YYYY-MM-DD",
11
- CompanyName = "$.companyName",
12
12
  PermitDuration = "$.permitDuration",
13
+ PermitStartDate = "$.startDate",
14
+ PermitType = "permitType",
13
15
  PowerUnitType = "$.vehicleDetails.vehicleSubType",
16
+ TotalDistance = "$.permittedRoute.manualRoute.totalDistance",
14
17
  TrailerList = "$.vehicleConfiguration.trailers",
15
- Commodity = "$.permittedCommodity.commodityType",
16
- TotalDistance = "$.permittedRoute.manualRoute.totalDistance"
18
+ VehicleConfiguration = "$.vehicleConfiguration",
19
+ VehicleDetails = "$.vehicleDetails"
17
20
  }
@@ -8,14 +8,17 @@ exports.PermitAppInfo = void 0;
8
8
  */
9
9
  var PermitAppInfo;
10
10
  (function (PermitAppInfo) {
11
- PermitAppInfo["PermitType"] = "permitType";
11
+ PermitAppInfo["AxleConfiguration"] = "$.vehicleConfiguration.axleConfiguration";
12
+ PermitAppInfo["CompanyName"] = "$.companyName";
13
+ PermitAppInfo["Commodity"] = "$.permittedCommodity.commodityType";
12
14
  PermitAppInfo["PermitData"] = "permitData";
13
- PermitAppInfo["PermitStartDate"] = "$.startDate";
14
15
  PermitAppInfo["PermitDateFormat"] = "YYYY-MM-DD";
15
- PermitAppInfo["CompanyName"] = "$.companyName";
16
16
  PermitAppInfo["PermitDuration"] = "$.permitDuration";
17
+ PermitAppInfo["PermitStartDate"] = "$.startDate";
18
+ PermitAppInfo["PermitType"] = "permitType";
17
19
  PermitAppInfo["PowerUnitType"] = "$.vehicleDetails.vehicleSubType";
18
- PermitAppInfo["TrailerList"] = "$.vehicleConfiguration.trailers";
19
- PermitAppInfo["Commodity"] = "$.permittedCommodity.commodityType";
20
20
  PermitAppInfo["TotalDistance"] = "$.permittedRoute.manualRoute.totalDistance";
21
+ PermitAppInfo["TrailerList"] = "$.vehicleConfiguration.trailers";
22
+ PermitAppInfo["VehicleConfiguration"] = "$.vehicleConfiguration";
23
+ PermitAppInfo["VehicleDetails"] = "$.vehicleDetails";
21
24
  })(PermitAppInfo || (exports.PermitAppInfo = PermitAppInfo = {}));
@@ -0,0 +1,11 @@
1
+ export declare enum PolicyCheckResultType {
2
+ Pass = "pass",
3
+ Fail = "fail"
4
+ }
5
+ export declare enum PolicyCheckId {
6
+ BridgeFormula = "bridge-formula",
7
+ CheckPermittableWeight = "check-permittable-weight",
8
+ MinDriveAxleWeight = "minimum-drive-axle-weight",
9
+ MinSteerAxleWeight = "minimum-steer-axle-weight",
10
+ NumberOfWheelsPerAxle = "number-of-wheels"
11
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolicyCheckId = exports.PolicyCheckResultType = void 0;
4
+ var PolicyCheckResultType;
5
+ (function (PolicyCheckResultType) {
6
+ PolicyCheckResultType["Pass"] = "pass";
7
+ PolicyCheckResultType["Fail"] = "fail";
8
+ })(PolicyCheckResultType || (exports.PolicyCheckResultType = PolicyCheckResultType = {}));
9
+ var PolicyCheckId;
10
+ (function (PolicyCheckId) {
11
+ PolicyCheckId["BridgeFormula"] = "bridge-formula";
12
+ PolicyCheckId["CheckPermittableWeight"] = "check-permittable-weight";
13
+ PolicyCheckId["MinDriveAxleWeight"] = "minimum-drive-axle-weight";
14
+ PolicyCheckId["MinSteerAxleWeight"] = "minimum-steer-axle-weight";
15
+ PolicyCheckId["NumberOfWheelsPerAxle"] = "number-of-wheels";
16
+ })(PolicyCheckId || (exports.PolicyCheckId = PolicyCheckId = {}));
@@ -1,6 +1,7 @@
1
1
  export declare enum ValidationResultCode {
2
2
  PermitTypeUnknown = "permit-type-unknown",
3
3
  FieldValidationError = "field-validation-error",
4
+ PolicyValidationError = "policy-validation-error",
4
5
  ConfigurationInvalid = "configuration-invalid",
5
6
  GeneralResult = "general-result",
6
7
  CostValue = "cost-value",
@@ -5,6 +5,7 @@ var ValidationResultCode;
5
5
  (function (ValidationResultCode) {
6
6
  ValidationResultCode["PermitTypeUnknown"] = "permit-type-unknown";
7
7
  ValidationResultCode["FieldValidationError"] = "field-validation-error";
8
+ ValidationResultCode["PolicyValidationError"] = "policy-validation-error";
8
9
  ValidationResultCode["ConfigurationInvalid"] = "configuration-invalid";
9
10
  ValidationResultCode["GeneralResult"] = "general-result";
10
11
  ValidationResultCode["CostValue"] = "cost-value";
@@ -308,12 +308,16 @@ function selectCorrectWeightDimensionHelper(policy, weightDimensions, configurat
308
308
  if (!axleConfiguration || axleConfiguration.length === 0) {
309
309
  throw new Error('Missing axle configuration');
310
310
  }
311
- if (axleIndex > configuration.length) {
311
+ if (axleIndex >= axleConfiguration.length) {
312
312
  throw new Error('Invalid axle index value');
313
313
  }
314
- if (configuration.length !== axleConfiguration.length - 1) {
314
+ const realVehicleConfig = configuration.filter((v) => {
315
+ const vehicleDef = policy.getVehicleDefinition(v);
316
+ return !(vehicleDef === null || vehicleDef === void 0 ? void 0 : vehicleDef.ignoreForAxleCalculation);
317
+ });
318
+ if (realVehicleConfig.length !== axleConfiguration.length - 1) {
315
319
  // We expect the axle configuration array length to be one more
316
- // than the configuration length because the power unit has two
320
+ // than the real configuration length because the power unit has two
317
321
  // axle units.
318
322
  throw new Error('Wrong number of axles configured for vehicle configuration');
319
323
  }
@@ -1,4 +1,46 @@
1
1
  import { Policy } from 'onroute-policy-engine';
2
2
  import { AxleConfiguration } from 'onroute-policy-engine/types';
3
+ /**
4
+ * Helper function to generate a vehicle display code based on the vehicle configuration and axle configuration.
5
+ *
6
+ * This function determines whether to generate a standard display code (for known vehicle types with
7
+ * configured display codes) or a universal display code (for complex or unknown configurations).
8
+ *
9
+ * @param policy The Policy instance containing vehicle definitions and display code defaults.
10
+ * @param configuration Array of vehicle type identifiers representing the vehicle configuration.
11
+ * The first element should be a power unit type, followed by trailer types.
12
+ * @param axleConfiguration Array of axle configurations corresponding to each vehicle in the configuration.
13
+ * Each axle configuration contains details like number of axles, spacing, etc.
14
+ * @returns A string representing the vehicle display code, or an empty string if the configuration is empty.
15
+ *
16
+ * @throws {Error} If vehicleDisplayCodeDefaults is not configured in the policy definition.
17
+ */
3
18
  export declare function getVehicleDisplayCodeHelper(policy: Policy, configuration: Array<string>, axleConfiguration: Array<AxleConfiguration>): string;
19
+ /**
20
+ * Generates a universal display code for vehicle configurations that cannot use the standard display code format.
21
+ *
22
+ * Universal display codes are used when:
23
+ * - Vehicle types are unknown or don't have configured display codes
24
+ * - Axle configurations exceed the maximum standard axle count
25
+ * - Vehicle configuration doesn't match the expected pattern
26
+ *
27
+ * The universal format uses generic symbols and spacing indicators to represent the axle configuration
28
+ * in a standardized way that can handle complex or unusual vehicle setups.
29
+ *
30
+ * @param policy The Policy instance containing display code defaults configuration.
31
+ * @param axleConfiguration Array of axle configurations representing the vehicle's axle setup.
32
+ * Each configuration contains details like number of axles, spacing, etc.
33
+ * @returns A string representing the universal vehicle display code, or an empty string if the axle configuration is empty.
34
+ *
35
+ * @throws {Error} If vehicleDisplayCodeDefaults is not configured in the policy definition.
36
+ *
37
+ * @example
38
+ * // For a complex axle configuration
39
+ * const code = getUniversalDisplayCode(policy, [
40
+ * { numberOfAxles: 2, interaxleSpacing: 1.8, ... },
41
+ * { numberOfAxles: 3, interaxleSpacing: 4.2, ... },
42
+ * { numberOfAxles: 5, interaxleSpacing: 3.0, ... } // Exceeds standard threshold
43
+ * ]);
44
+ * // Returns something like "U2U1MU3U2MU5+U3" where U represents universal axle codes
45
+ */
4
46
  export declare function getUniversalDisplayCode(policy: Policy, axleConfiguration: Array<AxleConfiguration>): string;
@@ -2,6 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVehicleDisplayCodeHelper = getVehicleDisplayCodeHelper;
4
4
  exports.getUniversalDisplayCode = getUniversalDisplayCode;
5
+ /**
6
+ * Helper function to generate a vehicle display code based on the vehicle configuration and axle configuration.
7
+ *
8
+ * This function determines whether to generate a standard display code (for known vehicle types with
9
+ * configured display codes) or a universal display code (for complex or unknown configurations).
10
+ *
11
+ * @param policy The Policy instance containing vehicle definitions and display code defaults.
12
+ * @param configuration Array of vehicle type identifiers representing the vehicle configuration.
13
+ * The first element should be a power unit type, followed by trailer types.
14
+ * @param axleConfiguration Array of axle configurations corresponding to each vehicle in the configuration.
15
+ * Each axle configuration contains details like number of axles, spacing, etc.
16
+ * @returns A string representing the vehicle display code, or an empty string if the configuration is empty.
17
+ *
18
+ * @throws {Error} If vehicleDisplayCodeDefaults is not configured in the policy definition.
19
+ */
5
20
  function getVehicleDisplayCodeHelper(policy, configuration, axleConfiguration) {
6
21
  if (!policy.policyDefinition.vehicleDisplayCodeDefaults) {
7
22
  throw new Error('Unable to construct vehicle display code; missing vehicleDisplayCodeDefaults in policy configuration');
@@ -65,6 +80,33 @@ function getVehicleDisplayCodeHelper(policy, configuration, axleConfiguration) {
65
80
  return getUniversalDisplayCode(policy, axleConfiguration);
66
81
  }
67
82
  }
83
+ /**
84
+ * Generates a universal display code for vehicle configurations that cannot use the standard display code format.
85
+ *
86
+ * Universal display codes are used when:
87
+ * - Vehicle types are unknown or don't have configured display codes
88
+ * - Axle configurations exceed the maximum standard axle count
89
+ * - Vehicle configuration doesn't match the expected pattern
90
+ *
91
+ * The universal format uses generic symbols and spacing indicators to represent the axle configuration
92
+ * in a standardized way that can handle complex or unusual vehicle setups.
93
+ *
94
+ * @param policy The Policy instance containing display code defaults configuration.
95
+ * @param axleConfiguration Array of axle configurations representing the vehicle's axle setup.
96
+ * Each configuration contains details like number of axles, spacing, etc.
97
+ * @returns A string representing the universal vehicle display code, or an empty string if the axle configuration is empty.
98
+ *
99
+ * @throws {Error} If vehicleDisplayCodeDefaults is not configured in the policy definition.
100
+ *
101
+ * @example
102
+ * // For a complex axle configuration
103
+ * const code = getUniversalDisplayCode(policy, [
104
+ * { numberOfAxles: 2, interaxleSpacing: 1.8, ... },
105
+ * { numberOfAxles: 3, interaxleSpacing: 4.2, ... },
106
+ * { numberOfAxles: 5, interaxleSpacing: 3.0, ... } // Exceeds standard threshold
107
+ * ]);
108
+ * // Returns something like "U2U1MU3U2MU5+U3" where U represents universal axle codes
109
+ */
68
110
  function getUniversalDisplayCode(policy, axleConfiguration) {
69
111
  const defs = policy.policyDefinition.vehicleDisplayCodeDefaults;
70
112
  if (!defs) {
@@ -93,7 +135,7 @@ function getUniversalDisplayCode(policy, axleConfiguration) {
93
135
  displayCodeTokens.push(defs.spacingUniversalDefault);
94
136
  }
95
137
  }
96
- if (a.numberOfAxles >= defs.thresholdAxlesUniversal) {
138
+ if (a.numberOfAxles > defs.thresholdAxlesUniversal) {
97
139
  // The number of axles in this axle unit is above the threshold
98
140
  // for the number of axles that can be represented by the simple
99
141
  // universal formula
@@ -140,6 +182,36 @@ function getUniversalDisplayCode(policy, axleConfiguration) {
140
182
  });
141
183
  return displayCodeTokens.join('');
142
184
  }
185
+ /**
186
+ * Determines whether a standard display code can be generated for the given vehicle configuration.
187
+ *
188
+ * A standard display code can be created when:
189
+ * - All vehicle types are known and have configured display codes
190
+ * - The power unit has all required display code properties (prefix, steer axle, drive axle)
191
+ * - All trailers have display codes (unless they're marked to ignore for axle calculation)
192
+ * - No axle configuration exceeds the maximum standard axle count
193
+ * - The number of axle configurations matches the number of non-ignorable vehicles plus one
194
+ *
195
+ * @param policy The Policy instance containing vehicle definitions and display code defaults.
196
+ * @param configuration Array of vehicle type identifiers representing the vehicle configuration.
197
+ * The first element should be a power unit type, followed by trailer types.
198
+ * @param axleConfiguration Array of axle configurations corresponding to each vehicle in the configuration.
199
+ * Each axle configuration contains details like number of axles, spacing, etc.
200
+ * @returns True if a standard display code can be generated, false if a universal display code is required.
201
+ *
202
+ * @example
203
+ * // Returns true for a standard truck-tractor with semi-trailer
204
+ * canCreateStandardCode(policy, ['TRKTRAC', 'SEMI'], [
205
+ * { numberOfAxles: 2, ... }, // Steer axle
206
+ * { numberOfAxles: 3, ... }, // Drive axle
207
+ * { numberOfAxles: 3, ... } // Trailer axle
208
+ * ]);
209
+ *
210
+ * // Returns false for unknown vehicle types or complex configurations
211
+ * canCreateStandardCode(policy, ['UNKNOWN'], [
212
+ * { numberOfAxles: 10, ... } // Exceeds standard threshold
213
+ * ]);
214
+ */
143
215
  function canCreateStandardCode(policy, configuration, axleConfiguration) {
144
216
  var _a;
145
217
  // Check that all of the vehicle types are known,
@@ -7,6 +7,7 @@ exports.addRuntimeFacts = addRuntimeFacts;
7
7
  const dayjs_1 = __importDefault(require("dayjs"));
8
8
  const quarterOfYear_1 = __importDefault(require("dayjs/plugin/quarterOfYear"));
9
9
  const enum_1 = require("onroute-policy-engine/enum");
10
+ const policy_check_helper_1 = require("./policy-check.helper");
10
11
  dayjs_1.default.extend(quarterOfYear_1.default);
11
12
  /**
12
13
  * Adds runtime facts for the validation. For example, adds the
@@ -83,6 +84,69 @@ function addRuntimeFacts(engine, policy) {
83
84
  }
84
85
  return allowedVehicles;
85
86
  });
87
+ /**
88
+ * Add runtime fact to calculate the complete vehicle configuration
89
+ * by combining the power unit type with any attached trailers.
90
+ * Returns an array of vehicle types representing the full configuration.
91
+ */
92
+ engine.addFact(enum_1.PolicyFacts.VehicleConfiguration.toString(), async function (params, almanac) {
93
+ // Retrieve the vehicle details from permit data
94
+ const vehicleDetails = await almanac.factValue(enum_1.PermitAppInfo.PermitData, {}, enum_1.PermitAppInfo.VehicleDetails);
95
+ // Retrieve the vehicle configuration from permit data
96
+ const vehicleConfiguration = await almanac.factValue(enum_1.PermitAppInfo.PermitData, {}, enum_1.PermitAppInfo.VehicleConfiguration);
97
+ return policy.getSimplifiedVehicleConfiguration(vehicleDetails, vehicleConfiguration);
98
+ });
99
+ /**
100
+ * Add runtime fact to calculate the gross vehicle combination
101
+ * weight by summing the weights of the individual axle units.
102
+ */
103
+ engine.addFact(enum_1.PolicyFacts.GrossVehicleCombinationWeight, async function (params, almanac) {
104
+ // Retrieve the axle configuration from permit data
105
+ const axleConfiguration = await almanac.factValue(enum_1.PermitAppInfo.PermitData, {}, enum_1.PermitAppInfo.AxleConfiguration);
106
+ return axleConfiguration.reduce((w, curr) => w + curr.axleUnitWeight, 0);
107
+ });
108
+ /**
109
+ * Add runtime fact to evaluate whether a specific policy check passes
110
+ * based on the vehicle configuration and axle configuration.
111
+ * Returns true if all policy check results are 'pass', false otherwise.
112
+ */
113
+ engine.addFact(enum_1.PolicyFacts.PolicyCheckPassed.toString(), async function (params, almanac) {
114
+ // Retrieve the complete vehicle configuration (power unit + trailers)
115
+ const vehicleConfiguration = await almanac.factValue(enum_1.PolicyFacts.VehicleConfiguration);
116
+ // Retrieve the axle configuration from permit data
117
+ const axleConfiguration = await almanac.factValue(enum_1.PermitAppInfo.PermitData, {}, enum_1.PermitAppInfo.AxleConfiguration);
118
+ // Get the specific policy check ID from parameters
119
+ const policyCheckId = params.policyId;
120
+ // Look up the policy check function from the policy check map
121
+ const func = policy_check_helper_1.policyCheckMap.get(policyCheckId);
122
+ if (!func) {
123
+ return false;
124
+ }
125
+ // Execute the policy check function with vehicle and axle configurations
126
+ const policyCheckResults = func(policy, vehicleConfiguration, axleConfiguration);
127
+ if (!policyCheckResults || policyCheckResults.length === 0) {
128
+ // We did not get any policy check results returned which is an error
129
+ // condition - all policy checks must return at least one result
130
+ return false;
131
+ }
132
+ // Return true only if all policy check results are 'pass'
133
+ return policyCheckResults.every((r) => r.result === enum_1.PolicyCheckResultType.Pass);
134
+ });
135
+ /**
136
+ * Add runtime fact to return an array of all messages that result from
137
+ * all combined policy checks for axle calculation. This is used in
138
+ * permit validation, returned in the details param for that rule for
139
+ * overweight permit types.
140
+ */
141
+ engine.addFact(enum_1.PolicyFacts.AxleCalcViolations, async function (params, almanac) {
142
+ // Retrieve the complete vehicle configuration (power unit + trailers)
143
+ const vehicleConfiguration = await almanac.factValue(enum_1.PolicyFacts.VehicleConfiguration);
144
+ // Retrieve the axle configuration from permit data
145
+ const axleConfiguration = await almanac.factValue(enum_1.PermitAppInfo.PermitData, {}, enum_1.PermitAppInfo.AxleConfiguration);
146
+ const results = policy.runAxleCalculation(vehicleConfiguration, axleConfiguration);
147
+ const violations = results.results.filter((r) => r.result === enum_1.PolicyCheckResultType.Fail);
148
+ return violations.map((v) => v.message);
149
+ });
86
150
  /**
87
151
  * Add runtime fact to calculate the number of days between a from
88
152
  * and to date supplied in parameters. Will be positive for a dateTo