@burdenoff/microfe-movethewheels 2026.1016.2 → 2026.1016.3
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.
- package/dist/components/freight-cost/FreightCommercialEditor.js +217 -0
- package/dist/components/freight-cost/FreightCommercialFactEditor.js +217 -0
- package/dist/components/freight-cost/FreightCommercialHistory.js +115 -0
- package/dist/components/freight-cost/FreightDraftForm.js +106 -91
- package/dist/components/freight-cost/FreightHistory.js +42 -40
- package/dist/generated/freight-cost-operations.d.ts +959 -0
- package/dist/hooks/useFreightRecoveryAction.js +20 -20
- package/dist/movethewheels/components/freight-cost/FreightCommercialEditor.d.ts +8 -0
- package/dist/movethewheels/components/freight-cost/FreightCommercialFactEditor.d.ts +8 -0
- package/dist/movethewheels/components/freight-cost/FreightCommercialHistory.d.ts +4 -0
- package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +4 -2
- package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +2 -2
- package/dist/movethewheels/utils/freightCommercial.d.ts +44 -0
- package/dist/pages/FreightEstimatePage.js +96 -92
- package/dist/src/generated/freight-cost-operations.js +495 -6
- package/dist/utils/freightAcknowledgement.js +6 -5
- package/dist/utils/freightCommercial.js +194 -0
- package/dist/utils/freightRecovery.js +22 -22
- package/package.json +4 -3
- package/src/generated/freight-cost-operations.ts +831 -1
- package/src/movethewheels/components/freight-cost/FreightCommercialEditor.tsx +236 -0
- package/src/movethewheels/components/freight-cost/FreightCommercialFactEditor.tsx +258 -0
- package/src/movethewheels/components/freight-cost/FreightCommercialHistory.tsx +90 -0
- package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +33 -4
- package/src/movethewheels/components/freight-cost/FreightHistory.tsx +4 -2
- package/src/movethewheels/hooks/useFreightRecoveryAction.ts +2 -1
- package/src/movethewheels/pages/FreightEstimatePage.tsx +14 -7
- package/src/movethewheels/utils/freightAcknowledgement.ts +3 -1
- package/src/movethewheels/utils/freightCommercial.ts +388 -0
- package/src/movethewheels/utils/freightRecovery.ts +6 -2
- package/src/operations/freight-cost/commercial.graphql +483 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
//#region src/movethewheels/utils/freightCommercial.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"origin",
|
|
4
|
+
"destination",
|
|
5
|
+
"carrier",
|
|
6
|
+
"service",
|
|
7
|
+
"cargo",
|
|
8
|
+
"weight",
|
|
9
|
+
"volume",
|
|
10
|
+
"equipment"
|
|
11
|
+
], t = "Not recorded for this cost version";
|
|
12
|
+
function n() {
|
|
13
|
+
return {
|
|
14
|
+
facts: i(),
|
|
15
|
+
selectedLegs: [],
|
|
16
|
+
reviewed: null
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function r(e = "UNKNOWN") {
|
|
20
|
+
return {
|
|
21
|
+
status: e,
|
|
22
|
+
reason: e === "UNKNOWN" ? t : "",
|
|
23
|
+
label: "",
|
|
24
|
+
reference: "",
|
|
25
|
+
description: "",
|
|
26
|
+
kind: "",
|
|
27
|
+
jurisdiction: "",
|
|
28
|
+
amount: "",
|
|
29
|
+
unit: "",
|
|
30
|
+
zeroReason: "",
|
|
31
|
+
count: "",
|
|
32
|
+
sourceReference: "",
|
|
33
|
+
sourceRevision: "",
|
|
34
|
+
observedAt: "",
|
|
35
|
+
evidenceLinks: []
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function i() {
|
|
39
|
+
return {
|
|
40
|
+
origin: r(),
|
|
41
|
+
destination: r(),
|
|
42
|
+
carrier: r(),
|
|
43
|
+
service: r(),
|
|
44
|
+
cargo: r(),
|
|
45
|
+
weight: r(),
|
|
46
|
+
volume: r(),
|
|
47
|
+
equipment: r()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function a(e, t, n) {
|
|
51
|
+
let r = e.trim();
|
|
52
|
+
if (!r || r.length > t) throw Error(`${n}: enter 1–${t} characters.`);
|
|
53
|
+
return r;
|
|
54
|
+
}
|
|
55
|
+
function o(e) {
|
|
56
|
+
if (!/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(e) || new Date(e).toISOString() !== e || Date.parse(e) > Date.now()) throw Error("Use a valid observed time no later than now.");
|
|
57
|
+
return e;
|
|
58
|
+
}
|
|
59
|
+
function s(e, t) {
|
|
60
|
+
if (!/^(0|[1-9][0-9]{0,17})(\.[0-9]{0,5}[1-9])?$/.test(e)) throw Error("Use a canonical nonnegative decimal: up to 18 integer and 6 fractional digits, no exponent or trailing fractional zero.");
|
|
61
|
+
if (e === "0") return a(t, 255, "Recorded zero reason");
|
|
62
|
+
if (t.trim()) throw Error("A zero reason belongs only to an amount of zero.");
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function c(e, t) {
|
|
66
|
+
let n = e.evidenceLinks;
|
|
67
|
+
if (n.length < 1 || n.length > 2 || new Set(n.map((e) => JSON.stringify([e.fileId, e.versionId]))).size !== n.length || n.some((e) => !t.some((t) => t.fileId === e.fileId && t.versionId === e.versionId))) throw Error("Choose 1–2 distinct exact evidence versions already selected for this cost record.");
|
|
68
|
+
return {
|
|
69
|
+
sourceReference: a(e.sourceReference, 255, "Fact source"),
|
|
70
|
+
sourceRevision: a(e.sourceRevision, 255, "Fact source revision"),
|
|
71
|
+
observedAt: e.observedAt ? o(e.observedAt) : null,
|
|
72
|
+
evidenceLinks: [...n].sort((e, t) => JSON.stringify([e.fileId, e.versionId]) < JSON.stringify([t.fileId, t.versionId]) ? -1 : +(JSON.stringify([e.fileId, e.versionId]) > JSON.stringify([t.fileId, t.versionId]))).map((e) => ({ ...e }))
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function l(e, t, n) {
|
|
76
|
+
let r = (t) => {
|
|
77
|
+
let r = e[t];
|
|
78
|
+
if (r.status === "UNKNOWN") return {
|
|
79
|
+
status: r.status,
|
|
80
|
+
value: null,
|
|
81
|
+
reason: a(r.reason, 255, t),
|
|
82
|
+
provenance: null
|
|
83
|
+
};
|
|
84
|
+
if (r.status !== "SOURCED" && r.status !== "NOT_APPLICABLE") throw Error("Choose a supported commercial fact status.");
|
|
85
|
+
return {
|
|
86
|
+
status: r.status,
|
|
87
|
+
value: null,
|
|
88
|
+
reason: r.status === "NOT_APPLICABLE" ? a(r.reason, 255, t) : null,
|
|
89
|
+
provenance: c(r, n)
|
|
90
|
+
};
|
|
91
|
+
}, i = (t) => {
|
|
92
|
+
let n = r(t), i = e[t];
|
|
93
|
+
if (n.status !== "SOURCED") return n;
|
|
94
|
+
if (i.kind !== "ADDRESS_LABEL" && i.kind !== "PORT_LABEL" && i.kind !== "TERMINAL_LABEL" && i.kind !== "POSTCODE_LABEL" && i.kind !== "CUSTOM_LABEL") throw Error("Choose a location label kind.");
|
|
95
|
+
return {
|
|
96
|
+
...n,
|
|
97
|
+
value: {
|
|
98
|
+
kind: i.kind,
|
|
99
|
+
label: a(i.label, 255, t),
|
|
100
|
+
jurisdictionLabel: i.jurisdiction.trim() ? a(i.jurisdiction, 120, "Jurisdiction label") : null
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}, o = r("weight"), l = r("volume"), u = r("carrier"), d = r("service"), f = r("cargo"), p = r("equipment"), m = e.weight, h = e.volume;
|
|
104
|
+
if (m.status === "SOURCED" && m.unit !== "KG" && m.unit !== "TONNE" && m.unit !== "LB") throw Error("Choose a recorded weight unit.");
|
|
105
|
+
if (h.status === "SOURCED" && h.unit !== "M3" && h.unit !== "FT3") throw Error("Choose a recorded volume unit.");
|
|
106
|
+
if (e.equipment.status === "SOURCED" && (!/^[1-9][0-9]{0,5}$/.test(e.equipment.count) || Number(e.equipment.count) > 1e5)) throw Error("Equipment count must be an integer from 1 to 100000.");
|
|
107
|
+
if (t.length > 16 || new Set(t.map((e) => e.id)).size !== t.length) throw Error("Select at most 16 distinct reviewed legs.");
|
|
108
|
+
let g = {
|
|
109
|
+
schemaVersion: 1,
|
|
110
|
+
selectedLegs: t.map((e) => ({
|
|
111
|
+
id: a(e.id, 200, "Leg ID"),
|
|
112
|
+
expectedUpdatedAt: e.expectedUpdatedAt
|
|
113
|
+
})).sort((e, t) => e.id < t.id ? -1 : +(e.id > t.id)),
|
|
114
|
+
origin: i("origin"),
|
|
115
|
+
destination: i("destination"),
|
|
116
|
+
carrier: u.status === "SOURCED" ? {
|
|
117
|
+
...u,
|
|
118
|
+
value: {
|
|
119
|
+
reference: a(e.carrier.reference, 120, "Carrier reference"),
|
|
120
|
+
label: a(e.carrier.label, 255, "Carrier label")
|
|
121
|
+
}
|
|
122
|
+
} : u,
|
|
123
|
+
service: d.status === "SOURCED" ? {
|
|
124
|
+
...d,
|
|
125
|
+
value: a(e.service.label, 120, "Service")
|
|
126
|
+
} : d,
|
|
127
|
+
cargo: f.status === "SOURCED" ? {
|
|
128
|
+
...f,
|
|
129
|
+
value: {
|
|
130
|
+
classificationLabel: a(e.cargo.label, 120, "Cargo classification"),
|
|
131
|
+
description: a(e.cargo.description, 500, "Cargo description")
|
|
132
|
+
}
|
|
133
|
+
} : f,
|
|
134
|
+
weight: o.status === "SOURCED" ? {
|
|
135
|
+
...o,
|
|
136
|
+
value: {
|
|
137
|
+
amount: m.amount,
|
|
138
|
+
unit: m.unit === "KG" ? "KG" : m.unit === "TONNE" ? "TONNE" : "LB",
|
|
139
|
+
zeroReason: s(m.amount, m.zeroReason)
|
|
140
|
+
}
|
|
141
|
+
} : o,
|
|
142
|
+
volume: l.status === "SOURCED" ? {
|
|
143
|
+
...l,
|
|
144
|
+
value: {
|
|
145
|
+
amount: h.amount,
|
|
146
|
+
unit: h.unit === "M3" ? "M3" : "FT3",
|
|
147
|
+
zeroReason: s(h.amount, h.zeroReason)
|
|
148
|
+
}
|
|
149
|
+
} : l,
|
|
150
|
+
equipment: p.status === "SOURCED" ? {
|
|
151
|
+
...p,
|
|
152
|
+
value: {
|
|
153
|
+
typeLabel: a(e.equipment.label, 120, "Equipment type"),
|
|
154
|
+
count: Number(e.equipment.count)
|
|
155
|
+
}
|
|
156
|
+
} : p
|
|
157
|
+
};
|
|
158
|
+
if (new TextEncoder().encode(JSON.stringify(g)).byteLength > 32768) throw Error("Commercial capture exceeds 32768 bytes. Shorten facts before saving.");
|
|
159
|
+
return g;
|
|
160
|
+
}
|
|
161
|
+
function u(e) {
|
|
162
|
+
function t(e) {
|
|
163
|
+
return Array.isArray(e) ? e.map(t) : e && typeof e == "object" ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "__typename").sort(([e], [t]) => e.localeCompare(t)).map(([e, n]) => [e, t(n)])) : e;
|
|
164
|
+
}
|
|
165
|
+
return JSON.stringify(t(e));
|
|
166
|
+
}
|
|
167
|
+
function d(e, t) {
|
|
168
|
+
if (!e || typeof e != "object" || !("commercialCapture" in e) || !e.commercialCapture || typeof e.commercialCapture != "object") return !1;
|
|
169
|
+
let n = e.commercialCapture;
|
|
170
|
+
if (!t.commercialCapture || typeof t.commercialCapture != "object" || !("selectedLegs" in t.commercialCapture) || !Array.isArray(t.commercialCapture.selectedLegs) || !("ownerShipment" in n) || !n.ownerShipment || typeof n.ownerShipment != "object" || !("shipmentId" in n.ownerShipment) || n.ownerShipment.shipmentId !== t.shipmentId || !("updatedAt" in n.ownerShipment) || n.ownerShipment.updatedAt !== t.expectedShipmentUpdatedAt || !("primaryMode" in n.ownerShipment) || typeof n.ownerShipment.primaryMode != "string" || ![
|
|
171
|
+
"AIR",
|
|
172
|
+
"OCEAN",
|
|
173
|
+
"RAIL",
|
|
174
|
+
"ROAD"
|
|
175
|
+
].includes(n.ownerShipment.primaryMode) || !("ownerLegs" in n) || !Array.isArray(n.ownerLegs) || u(Object.fromEntries(Object.entries(n).filter(([e]) => e !== "ownerShipment" && e !== "ownerLegs"))) !== u(t.commercialCapture)) return !1;
|
|
176
|
+
let r = t.commercialCapture.selectedLegs, i = n.ownerLegs;
|
|
177
|
+
return i.length === r.length && r.every((e) => e && typeof e == "object" && "id" in e && "expectedUpdatedAt" in e && i.some((t) => t && typeof t == "object" && "id" in t && t.id === e.id && "updatedAt" in t && t.updatedAt === e.expectedUpdatedAt && "legNumber" in t && typeof t.legNumber == "number" && Number.isInteger(t.legNumber) && t.legNumber > 0 && "mode" in t && typeof t.mode == "string" && [
|
|
178
|
+
"AIR",
|
|
179
|
+
"OCEAN",
|
|
180
|
+
"RAIL",
|
|
181
|
+
"ROAD"
|
|
182
|
+
].includes(t.mode) && ["carrierId", "carrierName"].every((e) => e in t && (Reflect.get(t, e) === null || typeof Reflect.get(t, e) == "string")) && [
|
|
183
|
+
"weightKg",
|
|
184
|
+
"volumeCbm",
|
|
185
|
+
"containerCount"
|
|
186
|
+
].every((e) => e in t && (Reflect.get(t, e) === null || typeof Reflect.get(t, e) == "number" && Number.isFinite(Reflect.get(t, e)))) && "containerType" in t && (t.containerType === null || typeof t.containerType == "string" && [
|
|
187
|
+
"FCL_20FT",
|
|
188
|
+
"FCL_40FT",
|
|
189
|
+
"FCL_40FT_HC",
|
|
190
|
+
"LCL"
|
|
191
|
+
].includes(t.containerType))));
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
export { u as commercialCanonical, l as commercialCaptureInput, e as commercialSlots, d as matchesCommercialCapture, n as newCommercialEditor, r as newCommercialFact };
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { print as
|
|
1
|
+
import { SaveFreightCommercialCostsDocument as e, SaveFreightCostsDocument as t } from "../src/generated/freight-cost-operations.js";
|
|
2
|
+
import { print as n } from "graphql";
|
|
3
3
|
//#region src/movethewheels/utils/freightRecovery.ts
|
|
4
|
-
var
|
|
5
|
-
function r
|
|
6
|
-
if (!
|
|
4
|
+
var r = "movethewheels.freight.unresolved.v1";
|
|
5
|
+
function i(r) {
|
|
6
|
+
if (!r || new TextEncoder().encode(r).byteLength > 2e5) return null;
|
|
7
7
|
try {
|
|
8
|
-
let
|
|
9
|
-
if (typeof
|
|
10
|
-
let
|
|
11
|
-
return !("actorId" in
|
|
8
|
+
let i = JSON.parse(r);
|
|
9
|
+
if (typeof i != "object" || !i || !("version" in i) || i.version !== 1 || !("scope" in i) || !("input" in i) || !("operation" in i) || i.operation !== n(t) && i.operation !== n(e) || !("key" in i) || typeof i.key != "string" || !i.key || i.key.length > 200 || !("success" in i) || typeof i.success != "string" || i.success.length > 500 || typeof i.input != "object" || i.input === null || Array.isArray(i.input) || typeof i.scope != "object" || i.scope === null) return null;
|
|
10
|
+
let a = i.scope;
|
|
11
|
+
return !("actorId" in a) || typeof a.actorId != "string" || !a.actorId || !("workspaceId" in a) || typeof a.workspaceId != "string" || !a.workspaceId || !("tenantId" in a) || typeof a.tenantId != "string" || !("organizationId" in a) || typeof a.organizationId != "string" || !a.organizationId || !("gateway" in a) || typeof a.gateway != "string" || !("projectId" in a) || a.projectId !== null && typeof a.projectId != "string" ? null : {
|
|
12
12
|
version: 1,
|
|
13
13
|
scope: {
|
|
14
|
-
actorId:
|
|
15
|
-
workspaceId:
|
|
16
|
-
tenantId:
|
|
17
|
-
organizationId:
|
|
18
|
-
gateway:
|
|
19
|
-
projectId:
|
|
14
|
+
actorId: a.actorId,
|
|
15
|
+
workspaceId: a.workspaceId,
|
|
16
|
+
tenantId: a.tenantId,
|
|
17
|
+
organizationId: a.organizationId,
|
|
18
|
+
gateway: a.gateway,
|
|
19
|
+
projectId: a.projectId
|
|
20
20
|
},
|
|
21
|
-
operation:
|
|
22
|
-
input: structuredClone(
|
|
23
|
-
key:
|
|
24
|
-
success:
|
|
21
|
+
operation: i.operation,
|
|
22
|
+
input: structuredClone(i.input),
|
|
23
|
+
key: i.key,
|
|
24
|
+
success: i.success
|
|
25
25
|
};
|
|
26
26
|
} catch {
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function a(e) {
|
|
31
31
|
let t = JSON.stringify(e);
|
|
32
|
-
if (!
|
|
32
|
+
if (!i(t)) throw Error("Cannot safely retain this freight request. Nothing was sent.");
|
|
33
33
|
return t;
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
|
-
export {
|
|
36
|
+
export { r as FREIGHT_RECOVERY_STORAGE, i as decodeFreightRecovery, a as encodeFreightRecovery };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-movethewheels",
|
|
3
|
-
"version": "2026.1016.
|
|
3
|
+
"version": "2026.1016.3",
|
|
4
4
|
"description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
37
37
|
"type:check": "bash scripts/build-limits.sh tsc --noEmit",
|
|
38
38
|
"validate:schema-drift": "graphql-schema-drift",
|
|
39
|
-
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:pick-review-ack && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:workspace-predispatch && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:free-time-permissions && bun run verify:braces-depth && bun run build && bun run build-storybook'",
|
|
39
|
+
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:pick-review-ack && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:freight-commercial && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:workspace-predispatch && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:free-time-permissions && bun run verify:braces-depth && bun run build && bun run build-storybook'",
|
|
40
40
|
"storybook": "storybook dev -p 6006",
|
|
41
41
|
"build-storybook": "storybook build",
|
|
42
42
|
"test:storybook": "test-storybook",
|
|
@@ -66,7 +66,8 @@
|
|
|
66
66
|
"verify:tracking-quality-outcomes": "bun test scripts/verify-tracking-quality-outcomes.test.ts",
|
|
67
67
|
"verify:braces-depth": "bun test scripts/braces-depth-patch.test.ts",
|
|
68
68
|
"verify:shipment-status-authority": "bun scripts/verify-shipment-status-command.mjs",
|
|
69
|
-
"verify:free-time-permissions": "bun scripts/verify-free-time-permission-gates.mjs"
|
|
69
|
+
"verify:free-time-permissions": "bun scripts/verify-free-time-permission-gates.mjs",
|
|
70
|
+
"verify:freight-commercial": "bun scripts/verify-freight-commercial.mjs && bun scripts/verify-freight-commercial-recovery.mjs && bun scripts/verify-freight-commercial-mounted.mjs"
|
|
70
71
|
},
|
|
71
72
|
"dependencies": {
|
|
72
73
|
"@apollo/client": "^4.0.11",
|