onroute-policy-engine 2.27.0 → 2.28.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.
@@ -2,6 +2,7 @@ export { AccessoryVehicleType } from './accessory-vehicle-type';
2
2
  export { CustomOperator } from './custom-operator';
3
3
  export { PolicyFacts, CostFacts } from './facts';
4
4
  export { PermitAppInfo } from './permit-app-info';
5
+ export { OverloadCalculationDetailKind } from './overload-calculation-detail-kind';
5
6
  export { PolicyCheckResultType, PolicyCheckId } from './policy-check';
6
7
  export { RelativePosition } from './relative-position';
7
8
  export { ValidationResultCode } from './validation-result-code';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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;
3
+ exports.VehicleTypes = exports.VehicleCategory = exports.ValidationResultType = exports.ValidationResultCode = exports.RelativePosition = exports.PolicyCheckId = exports.PolicyCheckResultType = exports.OverloadCalculationDetailKind = 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
6
  var custom_operator_1 = require("./custom-operator");
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "PolicyFacts", { enumerable: true, get: function
10
10
  Object.defineProperty(exports, "CostFacts", { enumerable: true, get: function () { return facts_1.CostFacts; } });
11
11
  var permit_app_info_1 = require("./permit-app-info");
12
12
  Object.defineProperty(exports, "PermitAppInfo", { enumerable: true, get: function () { return permit_app_info_1.PermitAppInfo; } });
13
+ var overload_calculation_detail_kind_1 = require("./overload-calculation-detail-kind");
14
+ Object.defineProperty(exports, "OverloadCalculationDetailKind", { enumerable: true, get: function () { return overload_calculation_detail_kind_1.OverloadCalculationDetailKind; } });
13
15
  var policy_check_1 = require("./policy-check");
14
16
  Object.defineProperty(exports, "PolicyCheckResultType", { enumerable: true, get: function () { return policy_check_1.PolicyCheckResultType; } });
15
17
  Object.defineProperty(exports, "PolicyCheckId", { enumerable: true, get: function () { return policy_check_1.PolicyCheckId; } });
@@ -0,0 +1,4 @@
1
+ export declare enum OverloadCalculationDetailKind {
2
+ AxleWeight = "axle-weight",
3
+ LicensedGvw = "licensed-gvw"
4
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverloadCalculationDetailKind = void 0;
4
+ var OverloadCalculationDetailKind;
5
+ (function (OverloadCalculationDetailKind) {
6
+ OverloadCalculationDetailKind["AxleWeight"] = "axle-weight";
7
+ OverloadCalculationDetailKind["LicensedGvw"] = "licensed-gvw";
8
+ })(OverloadCalculationDetailKind || (exports.OverloadCalculationDetailKind = OverloadCalculationDetailKind = {}));
@@ -0,0 +1,5 @@
1
+ import { AxleGroupPolicyCheckResult, OverloadCalculationDetail } from '../types';
2
+ export declare const calculateOverload: (results: Array<AxleGroupPolicyCheckResult>, totalGCVW: number, licensedGVW: number, axleUnitCount: number) => {
3
+ overload: number;
4
+ overloadDetails: Array<OverloadCalculationDetail>;
5
+ };
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateOverload = void 0;
4
+ const enum_1 = require("../enum");
5
+ const EMPTY_SELECTION = {
6
+ details: [],
7
+ overload: 0,
8
+ individualCount: 0,
9
+ };
10
+ const compareSelections = (first, second) => {
11
+ if (first.overload !== second.overload) {
12
+ return first.overload > second.overload ? first : second;
13
+ }
14
+ if (first.individualCount !== second.individualCount) {
15
+ return first.individualCount > second.individualCount ? first : second;
16
+ }
17
+ // Keep output deterministic when equivalent policy checks are reordered.
18
+ const firstKey = first.details
19
+ .map(({ startAxleUnit, endAxleUnit }) => `${startAxleUnit}:${endAxleUnit}`)
20
+ .join('|');
21
+ const secondKey = second.details
22
+ .map(({ startAxleUnit, endAxleUnit }) => `${startAxleUnit}:${endAxleUnit}`)
23
+ .join('|');
24
+ return firstKey <= secondKey ? first : second;
25
+ };
26
+ const getAxleOverloadCandidates = (results) => results
27
+ .filter(({ id, result, actualWeight, thresholdWeight }) => ((id === enum_1.PolicyCheckId.LegalWeight &&
28
+ result === enum_1.PolicyCheckResultType.Warning) ||
29
+ (id === enum_1.PolicyCheckId.AxleGroupMaximumLegalWeightThreshold &&
30
+ result === enum_1.PolicyCheckResultType.Fail)) &&
31
+ Number.isFinite(actualWeight) &&
32
+ Number.isFinite(thresholdWeight) &&
33
+ thresholdWeight > 0 &&
34
+ actualWeight > thresholdWeight)
35
+ .map(({ startAxleUnit, endAxleUnit, actualWeight, thresholdWeight }) => ({
36
+ kind: enum_1.OverloadCalculationDetailKind.AxleWeight,
37
+ startAxleUnit,
38
+ endAxleUnit,
39
+ actualWeight: actualWeight,
40
+ legalMaxWeight: thresholdWeight,
41
+ overload: actualWeight - thresholdWeight,
42
+ }))
43
+ .sort((first, second) => first.endAxleUnit - second.endAxleUnit ||
44
+ first.startAxleUnit - second.startAxleUnit);
45
+ const selectAxleOverloadDetails = (candidates) => {
46
+ const bestThroughCandidate = new Array(candidates.length + 1);
47
+ bestThroughCandidate[0] = EMPTY_SELECTION;
48
+ candidates.forEach((candidate, candidateIndex) => {
49
+ let predecessorIndex = candidateIndex - 1;
50
+ while (predecessorIndex >= 0 &&
51
+ candidates[predecessorIndex].endAxleUnit >= candidate.startAxleUnit) {
52
+ predecessorIndex--;
53
+ }
54
+ const predecessor = bestThroughCandidate[predecessorIndex + 1];
55
+ const withCandidate = {
56
+ details: [...predecessor.details, candidate],
57
+ overload: predecessor.overload + candidate.overload,
58
+ individualCount: predecessor.individualCount +
59
+ Number(candidate.startAxleUnit === candidate.endAxleUnit),
60
+ };
61
+ bestThroughCandidate[candidateIndex + 1] = compareSelections(bestThroughCandidate[candidateIndex], withCandidate);
62
+ });
63
+ return bestThroughCandidate[candidates.length];
64
+ };
65
+ const calculateOverload = (results, totalGCVW, licensedGVW, axleUnitCount) => {
66
+ const axleSelection = selectAxleOverloadDetails(getAxleOverloadCandidates(results));
67
+ const licensedGvwOverload = Math.max(0, totalGCVW - licensedGVW);
68
+ // Licensed GVW intentionally wins an exact tie with the axle calculation. We have
69
+ // to pick one, so this one made sense.
70
+ if (licensedGvwOverload > 0 && licensedGvwOverload >= axleSelection.overload) {
71
+ return {
72
+ overload: licensedGvwOverload,
73
+ overloadDetails: [
74
+ {
75
+ kind: enum_1.OverloadCalculationDetailKind.LicensedGvw,
76
+ startAxleUnit: 1,
77
+ endAxleUnit: axleUnitCount,
78
+ licensedGVW,
79
+ totalGCVW,
80
+ overload: licensedGvwOverload,
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ return {
86
+ overload: axleSelection.overload,
87
+ overloadDetails: axleSelection.details,
88
+ };
89
+ };
90
+ exports.calculateOverload = calculateOverload;
@@ -141,7 +141,12 @@ function CheckLegalWeight(policy, vehicleConfiguration, axleConfiguration) {
141
141
  return {
142
142
  id: policyId,
143
143
  message: `Weight for axle unit ${axleUnitNumber} ${result ? 'is legal' : `must not exceed ${legalWeight} kgs`}`,
144
- result: result ? enum_1.PolicyCheckResultType.Pass : enum_1.PolicyCheckResultType.Fail,
144
+ // We intentionally only return Pass/Warning, as we should never
145
+ // show an error for being above legal amount, only permitable
146
+ // amount. But it's still useful info for things like OCD table.
147
+ result: result
148
+ ? enum_1.PolicyCheckResultType.Pass
149
+ : enum_1.PolicyCheckResultType.Warning,
145
150
  axleUnit: axleUnitNumber,
146
151
  actualWeight: axleUnit.axleUnitWeight,
147
152
  thresholdWeight: legalWeight,
@@ -953,8 +958,10 @@ function CheckMaxTireLoad(_policy, _vehicleConfiguration, axleConfiguration) {
953
958
  return;
954
959
  }
955
960
  // ORV2-5903 keeps this exact configuration as a grandfathered TPS case.
961
+ // The application stores the 279.4 mm option as 279 to match f
962
+ const hasGrandfatheredTpsTireSize = tireSize === 279.4 || tireSize === 279;
956
963
  const hasGrandfatheredTpsTireLimit = ac.numberOfAxles === 2 &&
957
- tireSize === 279.4 &&
964
+ hasGrandfatheredTpsTireSize &&
958
965
  numberOfTires === 8 &&
959
966
  axleWeight <= 23000;
960
967
  if (hasGrandfatheredTpsTireLimit) {
@@ -22,6 +22,7 @@ const dimensions_helper_2 = require("./helper/dimensions.helper");
22
22
  const display_code_helper_1 = require("./helper/display-code-helper");
23
23
  const policy_check_helper_1 = require("./helper/policy-check.helper");
24
24
  const cost_1 = require("./constants/cost");
25
+ const overload_helper_1 = require("./helper/overload.helper");
25
26
  /** Class representing commercial vehicle policy. */
26
27
  class Policy {
27
28
  /**
@@ -717,8 +718,14 @@ class Policy {
717
718
  const axleCalcResults = {
718
719
  results: [],
719
720
  overload: 0,
721
+ overloadDetails: [],
720
722
  totalGCVW: 0,
721
723
  };
724
+ const updateOverloadCalculation = () => {
725
+ const { overload, overloadDetails } = (0, overload_helper_1.calculateOverload)(axleCalcResults.results, axleCalcResults.totalGCVW, licensedGVW, axleConfiguration.length);
726
+ axleCalcResults.overload = overload;
727
+ axleCalcResults.overloadDetails = overloadDetails;
728
+ };
722
729
  // This is a little helper closure that just converts any PolicyCheckResult into an AxleGroupPolicyCheckResult,
723
730
  // basically giving us startAxleUnit and endAxleUnit, which can help with frontend form highlighting.
724
731
  const toAxleGroupPolicyCheckResult = (result) => {
@@ -731,11 +738,11 @@ class Policy {
731
738
  return Object.assign(Object.assign({}, result), { startAxleUnit: 1, endAxleUnit: axleConfiguration.length });
732
739
  };
733
740
  const gvcw = axleConfiguration.reduce((w, curr) => w + curr.axleUnitWeight, 0);
734
- axleCalcResults.overload = Math.max(axleCalcResults.overload, gvcw - licensedGVW);
735
741
  axleCalcResults.totalGCVW = gvcw;
736
742
  const axleCountResults = (0, policy_check_helper_1.CheckNumberOfAxles)(this, vehicleConfiguration, axleConfiguration);
737
743
  axleCalcResults.results.push(...axleCountResults.map(toAxleGroupPolicyCheckResult));
738
744
  if (axleCountResults.some((r) => r.result === enum_1.PolicyCheckResultType.Fail)) {
745
+ updateOverloadCalculation();
739
746
  return axleCalcResults;
740
747
  }
741
748
  for (const [policyCheckId, policyCheck] of policy_check_helper_1.policyCheckMap) {
@@ -744,6 +751,7 @@ class Policy {
744
751
  }
745
752
  axleCalcResults.results.push(...policyCheck(this, vehicleConfiguration, axleConfiguration).map(toAxleGroupPolicyCheckResult));
746
753
  }
754
+ updateOverloadCalculation();
747
755
  return axleCalcResults;
748
756
  }
749
757
  /**
@@ -4,7 +4,7 @@
4
4
  * These types define the structure for axle calculation results and policy check outcomes.
5
5
  * Used for validating vehicle configurations against weight and axle requirements.
6
6
  */
7
- import { PolicyCheckId, PolicyCheckResultType } from 'onroute-policy-engine/enum';
7
+ import { OverloadCalculationDetailKind, PolicyCheckId, PolicyCheckResultType } from 'onroute-policy-engine/enum';
8
8
  /**
9
9
  * Complete results from axle calculations including all policy checks and total overload
10
10
  */
@@ -13,9 +13,30 @@ export type AxleCalcResults = {
13
13
  results: Array<AxleGroupPolicyCheckResult>;
14
14
  /** Total weight overload across all axles in kilograms */
15
15
  overload: number;
16
+ /** Details for only the selected overload calculation */
17
+ overloadDetails: Array<OverloadCalculationDetail>;
16
18
  /** Total Gross Combined Vehicle Weight across all axles in kilograms */
17
19
  totalGCVW: number;
18
20
  };
21
+ /** Licensed-GVW overload selected across the complete axle configuration. */
22
+ export type LicensedGvwOverloadCalculationDetail = {
23
+ kind: OverloadCalculationDetailKind.LicensedGvw;
24
+ startAxleUnit: number;
25
+ endAxleUnit: number;
26
+ licensedGVW: number;
27
+ totalGCVW: number;
28
+ overload: number;
29
+ };
30
+ /** Legal-weight overload selected for an axle unit or axle-unit group. */
31
+ export type AxleWeightOverloadCalculationDetail = {
32
+ kind: OverloadCalculationDetailKind.AxleWeight;
33
+ startAxleUnit: number;
34
+ endAxleUnit: number;
35
+ actualWeight: number;
36
+ legalMaxWeight: number;
37
+ overload: number;
38
+ };
39
+ export type OverloadCalculationDetail = LicensedGvwOverloadCalculationDetail | AxleWeightOverloadCalculationDetail;
19
40
  /**
20
41
  * Individual policy check result for a specific validation rule
21
42
  */
@@ -1,4 +1,4 @@
1
- export type { AxleCalcResults, PolicyCheckResult, AxleUnitPolicyCheckResult, AxleGroupPolicyCheckResult, } from './axle-calculation-results';
1
+ export type { AxleCalcResults, PolicyCheckResult, AxleUnitPolicyCheckResult, AxleGroupPolicyCheckResult, OverloadCalculationDetail, LicensedGvwOverloadCalculationDetail, AxleWeightOverloadCalculationDetail, } from './axle-calculation-results';
2
2
  export type { AxleConfiguration, IndexedAxleConfiguration, } from './axle-configuration';
3
3
  export type { BridgeCalculationConstants } from './bridge-calculation-constants';
4
4
  export type { BridgeCalculationResult } from './bridge-calculation-result';
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "v2.27.0";
1
+ export declare const version = "v2.28.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 = 'v2.27.0';
5
+ exports.version = 'v2.28.0';
package/package.json CHANGED
@@ -91,5 +91,5 @@
91
91
  ],
92
92
  "testEnvironment": "node"
93
93
  },
94
- "version": "v2.27.0"
94
+ "version": "v2.28.0"
95
95
  }