@flowselections/floriday-afhandeling-module 1.0.50 → 1.0.54

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 (47) hide show
  1. package/dist-lib/components/afhandeling/ControlePage.js +1 -1
  2. package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
  3. package/dist-lib/components/afhandeling/DagDetailDialog.js +255 -89
  4. package/dist-lib/components/afhandeling/NuVersturenButton.d.ts +2 -2
  5. package/dist-lib/components/afhandeling/NuVersturenButton.d.ts.map +1 -1
  6. package/dist-lib/components/afhandeling/NuVersturenButton.js +22 -4
  7. package/dist-lib/components/afhandeling/ScanControleView.js +1 -1
  8. package/dist-lib/components/afhandeling/VervoerdersPage.js +1 -1
  9. package/dist-lib/components/afhandeling/VerzetOrderDialog.js +1 -1
  10. package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
  11. package/dist-lib/components/afhandeling/WeekAgendaView.js +4 -3
  12. package/dist-lib/components/afhandeling/WerkplekWaarschuwing.d.ts +9 -9
  13. package/dist-lib/components/afhandeling/WerkplekWaarschuwing.js +28 -28
  14. package/dist-lib/components/ui/responsive-dialog.js +1 -1
  15. package/dist-lib/hooks/useKnownOrders.d.ts +1 -0
  16. package/dist-lib/hooks/useKnownOrders.d.ts.map +1 -1
  17. package/dist-lib/hooks/useKnownOrders.js +20 -1
  18. package/dist-lib/hooks/useOrderBuffers.d.ts +6 -0
  19. package/dist-lib/hooks/useOrderBuffers.d.ts.map +1 -1
  20. package/dist-lib/hooks/useOrderBuffers.js +21 -0
  21. package/dist-lib/hooks/usePickAgenda.d.ts.map +1 -1
  22. package/dist-lib/hooks/usePickAgenda.js +7 -3
  23. package/dist-lib/hooks/usePickMode.d.ts +1 -1
  24. package/dist-lib/index.d.ts +0 -2
  25. package/dist-lib/index.d.ts.map +1 -1
  26. package/dist-lib/index.js +0 -2
  27. package/dist-lib/integrations/supabase/client.server.js +1 -1
  28. package/dist-lib/integrations/supabase/types.d.ts +14 -0
  29. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  30. package/dist-lib/lib/authGateway.server.d.ts.map +1 -1
  31. package/dist-lib/lib/authGateway.server.js +3 -2
  32. package/dist-lib/lib/cartAssignments.functions.d.ts +48 -0
  33. package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
  34. package/dist-lib/lib/cartAssignments.functions.js +111 -0
  35. package/dist-lib/lib/deliveryNotePrint.d.ts +33 -33
  36. package/dist-lib/lib/deliveryNotePrint.js +219 -219
  37. package/dist-lib/lib/floridayFulfillmentSend.server.d.ts +6 -1
  38. package/dist-lib/lib/floridayFulfillmentSend.server.d.ts.map +1 -1
  39. package/dist-lib/lib/floridayFulfillmentSend.server.js +23 -6
  40. package/dist-lib/lib/floridayLoading.functions.d.ts +2 -0
  41. package/dist-lib/lib/floridayLoading.functions.d.ts.map +1 -1
  42. package/dist-lib/lib/floridayLoading.functions.js +52 -24
  43. package/dist-lib/lib/logisticsEngine/capacity.js +1 -1
  44. package/dist-lib/lib/logisticsEngine/staffPlanning.js +1 -1
  45. package/dist-lib/lib/orderFulfilment.functions.d.ts.map +1 -1
  46. package/dist-lib/lib/orderFulfilment.functions.js +17 -0
  47. package/package.json +1 -1
@@ -1,219 +1,219 @@
1
- // Client-side helpers voor het ophalen en printen van Floriday-afleverbrieven
2
- // via de gateway-endpoints van de Authenticatie-module.
3
- // De Authenticatie-module accepteert een Supabase Bearer-token en stuurt
4
- // CORS-headers, dus we bellen direct cross-origin — geen eigen proxy nodig.
5
- import { printPdfBase64 } from "../components/pickstation/printDocuments";
6
- import { supabase } from "../integrations/supabase/moduleClient";
7
- import { resolveGatewayBaseClient } from "./gatewayBase";
8
- let floridayEnvironmentPromise = null;
9
- async function getFloridayEnvironment() {
10
- floridayEnvironmentPromise ?? (floridayEnvironmentPromise = Promise.resolve(supabase.from("floriday_settings").select("active_environment").eq("id", 1).maybeSingle()).then(({ data, error }) => {
11
- if (error) {
12
- console.warn("[delivery-note-print] active Floriday environment ophalen mislukt", error);
13
- }
14
- return data?.active_environment ?? "live";
15
- }));
16
- return floridayEnvironmentPromise;
17
- }
18
- async function getAccessToken() {
19
- const { data } = await supabase.auth.getSession();
20
- const token = data.session?.access_token;
21
- if (!token) {
22
- throw new Error("Niet ingelogd — kan afleverbrief niet ophalen.");
23
- }
24
- return token;
25
- }
26
- async function postJson(path, body) {
27
- const token = await getAccessToken();
28
- const base = resolveGatewayBaseClient();
29
- const res = await fetch(`${base}${path}`, {
30
- method: "POST",
31
- headers: {
32
- "Content-Type": "application/json",
33
- Authorization: `Bearer ${token}`,
34
- },
35
- body: JSON.stringify(body),
36
- });
37
- const ct = res.headers.get("content-type") ?? "";
38
- if (!ct.includes("application/json")) {
39
- throw new Error(`Gateway onbereikbaar (HTTP ${res.status}) — ontving ${ct || "onbekend content-type"}.`);
40
- }
41
- const text = await res.text();
42
- let data = null;
43
- try {
44
- data = text ? JSON.parse(text) : null;
45
- }
46
- catch {
47
- data = { ok: false, error: text };
48
- }
49
- return { status: res.status, data: data };
50
- }
51
- /**
52
- * Zoekt delivery-order IDs in de lokale cache voor een gegeven sales-order.
53
- * De gateway kan een delivery-note alleen genereren als er een delivery-order bestaat;
54
- * door hier eerst zelf te resolven omzeilen we de "Geen delivery-order beschikbaar" fout
55
- * wanneer de gateway de koppeling nog niet ziet.
56
- */
57
- async function resolveDeliveryOrderIds(salesOrderId) {
58
- const { data, error } = await supabase
59
- .from("floriday_delivery_orders_cache")
60
- .select("floriday_id, data")
61
- .contains("data", { fulfillmentRequests: [{ salesOrderId }] });
62
- if (error) {
63
- console.warn("[delivery-note-print] delivery-order lookup mislukt", error);
64
- return [];
65
- }
66
- const ids = new Set();
67
- for (const row of (data ?? [])) {
68
- const d = row.data;
69
- if (d?.isDeleted)
70
- continue;
71
- if (d?.fulfillmentRequests?.some((f) => f.salesOrderId === salesOrderId)) {
72
- ids.add(row.floriday_id);
73
- }
74
- }
75
- return [...ids];
76
- }
77
- /** Haalt de signed URL van een enkele afleverbrief op. */
78
- export async function fetchDeliveryNoteUrl(salesOrderId) {
79
- const environment = await getFloridayEnvironment();
80
- const deliveryOrderIds = await resolveDeliveryOrderIds(salesOrderId);
81
- if (deliveryOrderIds.length > 1) {
82
- throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
83
- }
84
- const payload = {
85
- environment,
86
- kind: "delivery-note",
87
- salesOrderId,
88
- };
89
- if (deliveryOrderIds[0])
90
- payload.deliveryOrderId = deliveryOrderIds[0];
91
- const { status, data } = await postJson("/api/public/gateway/pdf", payload);
92
- if (status === 409) {
93
- throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
94
- }
95
- if (!data?.ok || !data.url) {
96
- throw new Error(data?.error ?? `Afleverbrief ophalen mislukt (HTTP ${status})`);
97
- }
98
- return data.url;
99
- }
100
- /** Print een PDF vanaf een (signed) URL via de printwachtrij. */
101
- export async function printPdfFromUrl(url, opties) {
102
- const res = await fetch(url);
103
- if (!res.ok)
104
- throw new Error(`PDF download mislukt (HTTP ${res.status})`);
105
- const buf = new Uint8Array(await res.arrayBuffer());
106
- let binary = "";
107
- const chunk = 0x8000;
108
- for (let i = 0; i < buf.length; i += chunk) {
109
- binary += String.fromCharCode(...buf.subarray(i, i + chunk));
110
- }
111
- const base64 = btoa(binary);
112
- await printPdfBase64(base64, {
113
- documenttype: "afleverbrief",
114
- documentnaam: opties.documentnaam,
115
- isHerprint: opties.isHerprint,
116
- papierformaat: "A4",
117
- });
118
- }
119
- /** Haal en print één afleverbrief. */
120
- export async function printDeliveryNote(salesOrderId, opties) {
121
- const url = await fetchDeliveryNoteUrl(salesOrderId);
122
- await printPdfFromUrl(url, {
123
- documentnaam: opties?.documentnaam ?? `AFL-${salesOrderId}`,
124
- isHerprint: opties?.isHerprint,
125
- });
126
- }
127
- /** Maximaal aantal afleverbrieven in één samengevoegde printopdracht. */
128
- const CHUNK_SIZE = 25;
129
- /** Boven deze payloadgrootte (bytes) wordt de chunk gehalveerd. */
130
- const MAX_PAYLOAD_BYTES = 5 * 1024 * 1024;
131
- function base64Bytes(b64) {
132
- return Math.floor((b64.length * 3) / 4);
133
- }
134
- function vandaagIso() {
135
- return new Date().toISOString().slice(0, 10);
136
- }
137
- /**
138
- * Print meerdere afleverbrieven als samengevoegde PDF's van maximaal 25 stuks.
139
- * Te grote opdrachten worden automatisch verder opgeknipt.
140
- */
141
- export async function printDeliveryNotesMerged(items, opties) {
142
- const valid = items.filter((i) => i.salesOrderId || i.deliveryOrderId || i.fulfillmentOrderId);
143
- const summary = { total: valid.length, success: 0, failed: [] };
144
- if (valid.length === 0)
145
- return summary;
146
- const environment = await getFloridayEnvironment();
147
- // Verrijk items met deliveryOrderId uit de lokale cache waar mogelijk,
148
- // zodat de gateway niet meer op salesOrderId hoeft te zoeken.
149
- const enriched = [];
150
- for (const it of valid) {
151
- if (it.deliveryOrderId || it.fulfillmentOrderId || !it.salesOrderId) {
152
- enriched.push(it);
153
- continue;
154
- }
155
- const ids = await resolveDeliveryOrderIds(it.salesOrderId);
156
- if (ids.length === 0) {
157
- enriched.push(it);
158
- }
159
- else {
160
- for (const doId of ids)
161
- enriched.push({ ...it, deliveryOrderId: doId });
162
- }
163
- }
164
- const dag = vandaagIso();
165
- let deel = 0;
166
- const printChunk = async (chunk) => {
167
- if (chunk.length === 0)
168
- return;
169
- const { status, data } = await postJson("/api/public/gateway/pdf/bulk-merged", {
170
- environment,
171
- items: chunk.map((it) => ({
172
- id: it.id,
173
- ...(it.salesOrderId ? { salesOrderId: it.salesOrderId } : {}),
174
- ...(it.deliveryOrderId ? { deliveryOrderId: it.deliveryOrderId } : {}),
175
- ...(it.fulfillmentOrderId ? { fulfillmentOrderId: it.fulfillmentOrderId } : {}),
176
- })),
177
- });
178
- if (!data?.ok || !data.pdfBase64) {
179
- const err = data?.error ?? `HTTP ${status}`;
180
- for (const it of chunk)
181
- summary.failed.push({ id: it.id, error: err });
182
- return;
183
- }
184
- // Te grote samengevoegde PDF: halveren en opnieuw opvragen.
185
- if (chunk.length > 1 && base64Bytes(data.pdfBase64) > MAX_PAYLOAD_BYTES) {
186
- const half = Math.ceil(chunk.length / 2);
187
- await printChunk(chunk.slice(0, half));
188
- await printChunk(chunk.slice(half));
189
- return;
190
- }
191
- deel += 1;
192
- const documentnaam = chunk.length === 1
193
- ? `AFL-${chunk[0].salesOrderId ?? chunk[0].deliveryOrderId ?? chunk[0].id}`
194
- : `AFL-${dag}-deel-${deel}`;
195
- try {
196
- await printPdfBase64(data.pdfBase64, {
197
- documenttype: "afleverbrief",
198
- documentnaam,
199
- isHerprint: opties?.isHerprint,
200
- papierformaat: "A4",
201
- });
202
- }
203
- catch (e) {
204
- const msg = e instanceof Error ? e.message : "Printen mislukt";
205
- for (const it of chunk)
206
- summary.failed.push({ id: it.id, error: msg });
207
- return;
208
- }
209
- summary.success += data.success ?? chunk.length;
210
- for (const r of data.results ?? []) {
211
- if (!r.ok)
212
- summary.failed.push({ id: r.id, error: r.error ?? "onbekende fout" });
213
- }
214
- };
215
- for (let i = 0; i < enriched.length; i += CHUNK_SIZE) {
216
- await printChunk(enriched.slice(i, i + CHUNK_SIZE));
217
- }
218
- return summary;
219
- }
1
+ // Client-side helpers voor het ophalen en printen van Floriday-afleverbrieven
2
+ // via de gateway-endpoints van de Authenticatie-module.
3
+ // De Authenticatie-module accepteert een Supabase Bearer-token en stuurt
4
+ // CORS-headers, dus we bellen direct cross-origin — geen eigen proxy nodig.
5
+ import { printPdfBase64 } from "../components/pickstation/printDocuments";
6
+ import { supabase } from "../integrations/supabase/moduleClient";
7
+ import { resolveGatewayBaseClient } from "./gatewayBase";
8
+ let floridayEnvironmentPromise = null;
9
+ async function getFloridayEnvironment() {
10
+ floridayEnvironmentPromise ?? (floridayEnvironmentPromise = Promise.resolve(supabase.from("floriday_settings").select("active_environment").eq("id", 1).maybeSingle()).then(({ data, error }) => {
11
+ if (error) {
12
+ console.warn("[delivery-note-print] active Floriday environment ophalen mislukt", error);
13
+ }
14
+ return data?.active_environment ?? "live";
15
+ }));
16
+ return floridayEnvironmentPromise;
17
+ }
18
+ async function getAccessToken() {
19
+ const { data } = await supabase.auth.getSession();
20
+ const token = data.session?.access_token;
21
+ if (!token) {
22
+ throw new Error("Niet ingelogd — kan afleverbrief niet ophalen.");
23
+ }
24
+ return token;
25
+ }
26
+ async function postJson(path, body) {
27
+ const token = await getAccessToken();
28
+ const base = resolveGatewayBaseClient();
29
+ const res = await fetch(`${base}${path}`, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ Authorization: `Bearer ${token}`,
34
+ },
35
+ body: JSON.stringify(body),
36
+ });
37
+ const ct = res.headers.get("content-type") ?? "";
38
+ if (!ct.includes("application/json")) {
39
+ throw new Error(`Gateway onbereikbaar (HTTP ${res.status}) — ontving ${ct || "onbekend content-type"}.`);
40
+ }
41
+ const text = await res.text();
42
+ let data = null;
43
+ try {
44
+ data = text ? JSON.parse(text) : null;
45
+ }
46
+ catch {
47
+ data = { ok: false, error: text };
48
+ }
49
+ return { status: res.status, data: data };
50
+ }
51
+ /**
52
+ * Zoekt delivery-order IDs in de lokale cache voor een gegeven sales-order.
53
+ * De gateway kan een delivery-note alleen genereren als er een delivery-order bestaat;
54
+ * door hier eerst zelf te resolven omzeilen we de "Geen delivery-order beschikbaar" fout
55
+ * wanneer de gateway de koppeling nog niet ziet.
56
+ */
57
+ async function resolveDeliveryOrderIds(salesOrderId) {
58
+ const { data, error } = await supabase
59
+ .from("floriday_delivery_orders_cache")
60
+ .select("floriday_id, data")
61
+ .contains("data", { fulfillmentRequests: [{ salesOrderId }] });
62
+ if (error) {
63
+ console.warn("[delivery-note-print] delivery-order lookup mislukt", error);
64
+ return [];
65
+ }
66
+ const ids = new Set();
67
+ for (const row of (data ?? [])) {
68
+ const d = row.data;
69
+ if (d?.isDeleted)
70
+ continue;
71
+ if (d?.fulfillmentRequests?.some((f) => f.salesOrderId === salesOrderId)) {
72
+ ids.add(row.floriday_id);
73
+ }
74
+ }
75
+ return [...ids];
76
+ }
77
+ /** Haalt de signed URL van een enkele afleverbrief op. */
78
+ export async function fetchDeliveryNoteUrl(salesOrderId) {
79
+ const environment = await getFloridayEnvironment();
80
+ const deliveryOrderIds = await resolveDeliveryOrderIds(salesOrderId);
81
+ if (deliveryOrderIds.length > 1) {
82
+ throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
83
+ }
84
+ const payload = {
85
+ environment,
86
+ kind: "delivery-note",
87
+ salesOrderId,
88
+ };
89
+ if (deliveryOrderIds[0])
90
+ payload.deliveryOrderId = deliveryOrderIds[0];
91
+ const { status, data } = await postJson("/api/public/gateway/pdf", payload);
92
+ if (status === 409) {
93
+ throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
94
+ }
95
+ if (!data?.ok || !data.url) {
96
+ throw new Error(data?.error ?? `Afleverbrief ophalen mislukt (HTTP ${status})`);
97
+ }
98
+ return data.url;
99
+ }
100
+ /** Print een PDF vanaf een (signed) URL via de printwachtrij. */
101
+ export async function printPdfFromUrl(url, opties) {
102
+ const res = await fetch(url);
103
+ if (!res.ok)
104
+ throw new Error(`PDF download mislukt (HTTP ${res.status})`);
105
+ const buf = new Uint8Array(await res.arrayBuffer());
106
+ let binary = "";
107
+ const chunk = 0x8000;
108
+ for (let i = 0; i < buf.length; i += chunk) {
109
+ binary += String.fromCharCode(...buf.subarray(i, i + chunk));
110
+ }
111
+ const base64 = btoa(binary);
112
+ await printPdfBase64(base64, {
113
+ documenttype: "afleverbrief",
114
+ documentnaam: opties.documentnaam,
115
+ isHerprint: opties.isHerprint,
116
+ papierformaat: "A4",
117
+ });
118
+ }
119
+ /** Haal en print één afleverbrief. */
120
+ export async function printDeliveryNote(salesOrderId, opties) {
121
+ const url = await fetchDeliveryNoteUrl(salesOrderId);
122
+ await printPdfFromUrl(url, {
123
+ documentnaam: opties?.documentnaam ?? `AFL-${salesOrderId}`,
124
+ isHerprint: opties?.isHerprint,
125
+ });
126
+ }
127
+ /** Maximaal aantal afleverbrieven in één samengevoegde printopdracht. */
128
+ const CHUNK_SIZE = 25;
129
+ /** Boven deze payloadgrootte (bytes) wordt de chunk gehalveerd. */
130
+ const MAX_PAYLOAD_BYTES = 5 * 1024 * 1024;
131
+ function base64Bytes(b64) {
132
+ return Math.floor((b64.length * 3) / 4);
133
+ }
134
+ function vandaagIso() {
135
+ return new Date().toISOString().slice(0, 10);
136
+ }
137
+ /**
138
+ * Print meerdere afleverbrieven als samengevoegde PDF's van maximaal 25 stuks.
139
+ * Te grote opdrachten worden automatisch verder opgeknipt.
140
+ */
141
+ export async function printDeliveryNotesMerged(items, opties) {
142
+ const valid = items.filter((i) => i.salesOrderId || i.deliveryOrderId || i.fulfillmentOrderId);
143
+ const summary = { total: valid.length, success: 0, failed: [] };
144
+ if (valid.length === 0)
145
+ return summary;
146
+ const environment = await getFloridayEnvironment();
147
+ // Verrijk items met deliveryOrderId uit de lokale cache waar mogelijk,
148
+ // zodat de gateway niet meer op salesOrderId hoeft te zoeken.
149
+ const enriched = [];
150
+ for (const it of valid) {
151
+ if (it.deliveryOrderId || it.fulfillmentOrderId || !it.salesOrderId) {
152
+ enriched.push(it);
153
+ continue;
154
+ }
155
+ const ids = await resolveDeliveryOrderIds(it.salesOrderId);
156
+ if (ids.length === 0) {
157
+ enriched.push(it);
158
+ }
159
+ else {
160
+ for (const doId of ids)
161
+ enriched.push({ ...it, deliveryOrderId: doId });
162
+ }
163
+ }
164
+ const dag = vandaagIso();
165
+ let deel = 0;
166
+ const printChunk = async (chunk) => {
167
+ if (chunk.length === 0)
168
+ return;
169
+ const { status, data } = await postJson("/api/public/gateway/pdf/bulk-merged", {
170
+ environment,
171
+ items: chunk.map((it) => ({
172
+ id: it.id,
173
+ ...(it.salesOrderId ? { salesOrderId: it.salesOrderId } : {}),
174
+ ...(it.deliveryOrderId ? { deliveryOrderId: it.deliveryOrderId } : {}),
175
+ ...(it.fulfillmentOrderId ? { fulfillmentOrderId: it.fulfillmentOrderId } : {}),
176
+ })),
177
+ });
178
+ if (!data?.ok || !data.pdfBase64) {
179
+ const err = data?.error ?? `HTTP ${status}`;
180
+ for (const it of chunk)
181
+ summary.failed.push({ id: it.id, error: err });
182
+ return;
183
+ }
184
+ // Te grote samengevoegde PDF: halveren en opnieuw opvragen.
185
+ if (chunk.length > 1 && base64Bytes(data.pdfBase64) > MAX_PAYLOAD_BYTES) {
186
+ const half = Math.ceil(chunk.length / 2);
187
+ await printChunk(chunk.slice(0, half));
188
+ await printChunk(chunk.slice(half));
189
+ return;
190
+ }
191
+ deel += 1;
192
+ const documentnaam = chunk.length === 1
193
+ ? `AFL-${chunk[0].salesOrderId ?? chunk[0].deliveryOrderId ?? chunk[0].id}`
194
+ : `AFL-${dag}-deel-${deel}`;
195
+ try {
196
+ await printPdfBase64(data.pdfBase64, {
197
+ documenttype: "afleverbrief",
198
+ documentnaam,
199
+ isHerprint: opties?.isHerprint,
200
+ papierformaat: "A4",
201
+ });
202
+ }
203
+ catch (e) {
204
+ const msg = e instanceof Error ? e.message : "Printen mislukt";
205
+ for (const it of chunk)
206
+ summary.failed.push({ id: it.id, error: msg });
207
+ return;
208
+ }
209
+ summary.success += data.success ?? chunk.length;
210
+ for (const r of data.results ?? []) {
211
+ if (!r.ok)
212
+ summary.failed.push({ id: r.id, error: r.error ?? "onbekende fout" });
213
+ }
214
+ };
215
+ for (let i = 0; i < enriched.length; i += CHUNK_SIZE) {
216
+ await printChunk(enriched.slice(i, i + CHUNK_SIZE));
217
+ }
218
+ return summary;
219
+ }
@@ -2,6 +2,11 @@ export interface GatewayResult {
2
2
  httpStatus: number;
3
3
  body: any;
4
4
  }
5
+ /**
6
+ * Begrijpelijke zin met de echte reden (veld error/message/errors van het antwoord),
7
+ * gevolgd door de technische code tussen [ ] die het scherm klein toont.
8
+ */
9
+ export declare function gatewayFoutTekst(wat: string, r: GatewayResult): string;
5
10
  export interface FulfillmentRequestStatus {
6
11
  fulfillmentRequestId: string;
7
12
  deliveryOrderId: string | null;
@@ -26,6 +31,6 @@ export interface SalesOrderStatus {
26
31
  * fulfillmentRequests[] { fulfillmentRequestId, deliveryOrderId, fulfillmentOrderIds },
27
32
  * fulfillmentOrders[] { fulfillmentOrderId, status, deliveryNoteReady }.
28
33
  */
29
- export declare function fetchFulfillmentStatus(salesOrderIds: string[]): Promise<Map<string, SalesOrderStatus>>;
34
+ export declare function fetchFulfillmentStatus(salesOrderIds: string[], fulfillmentOrderIds?: string[]): Promise<Map<string, SalesOrderStatus>>;
30
35
  export declare function sendFulfillmentOrder(payload: Record<string, unknown>): Promise<GatewayResult>;
31
36
  //# sourceMappingURL=floridayFulfillmentSend.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"floridayFulfillmentSend.server.d.ts","sourceRoot":"","sources":["../../src/lib/floridayFulfillmentSend.server.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;CACX;AA4BD,MAAM,WAAW,wBAAwB;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AACD,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,wBAAwB,EAAE,CAAC;IAChD,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAgC5G;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAEnG"}
1
+ {"version":3,"file":"floridayFulfillmentSend.server.d.ts","sourceRoot":"","sources":["../../src/lib/floridayFulfillmentSend.server.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;CACX;AA6BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,GAAG,MAAM,CAMtE;AAED,MAAM,WAAW,wBAAwB;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AACD,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,wBAAwB,EAAE,CAAC;IAChD,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EAAE,EACvB,mBAAmB,GAAE,MAAM,EAAO,GACjC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAoCxC;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAEnG"}
@@ -9,7 +9,8 @@ async function signedPost(path, payload) {
9
9
  const secret = await getFloridayGatewaySecret(); // throws als het ontbreekt
10
10
  const base = await resolveGatewayBaseServer(); // throws als het ontbreekt
11
11
  const bodyStr = JSON.stringify(payload);
12
- const timestamp = new Date().toISOString();
12
+ // De gateway verwacht epoch-milliseconden; we tekenen over precies deze waarde.
13
+ const timestamp = String(Date.now());
13
14
  const signature = await signBody(secret, timestamp, bodyStr);
14
15
  const res = await fetch(`${base}/api/public/gateway/${path}`, {
15
16
  method: "POST",
@@ -29,20 +30,36 @@ async function signedPost(path, payload) {
29
30
  }
30
31
  const arr = (v) => (Array.isArray(v) ? v : []);
31
32
  const str = (v) => (typeof v === "string" && v ? v : null);
33
+ /**
34
+ * Begrijpelijke zin met de echte reden (veld error/message/errors van het antwoord),
35
+ * gevolgd door de technische code tussen [ ] die het scherm klein toont.
36
+ */
37
+ export function gatewayFoutTekst(wat, r) {
38
+ const b = r.body ?? {};
39
+ const reden = [str(b.error), str(b.message), ...arr(b.errors).map((e) => (typeof e === "string" ? e : str(e?.message)))]
40
+ .filter((x, i, a) => !!x && a.indexOf(x) === i && x !== b.code).join(" — ");
41
+ const tech = [str(b.code), `HTTP ${r.httpStatus}`].filter(Boolean).join(" · ");
42
+ return `Floriday-authenticatie weigerde ${wat}${reden ? `: ${reden}` : "."} [${tech}]`;
43
+ }
32
44
  /**
33
45
  * Statusoverzicht (Floriday-authenticatie 1.0.64), in porties van maximaal 100.
34
46
  * Exact contract per order: salesOrderId, found, salesOrderStatus, floridayStage,
35
47
  * fulfillmentRequests[] { fulfillmentRequestId, deliveryOrderId, fulfillmentOrderIds },
36
48
  * fulfillmentOrders[] { fulfillmentOrderId, status, deliveryNoteReady }.
37
49
  */
38
- export async function fetchFulfillmentStatus(salesOrderIds) {
50
+ export async function fetchFulfillmentStatus(salesOrderIds, fulfillmentOrderIds = []) {
39
51
  const out = new Map();
40
52
  const ids = [...new Set(salesOrderIds.filter(Boolean))];
53
+ const foIds = [...new Set(fulfillmentOrderIds.filter(Boolean))];
41
54
  for (let i = 0; i < ids.length; i += 100) {
42
- const r = await signedPost("fulfillment-order/status", { salesOrderIds: ids.slice(i, i + 100) });
43
- if (r.httpStatus >= 400 || !r.body) {
44
- throw new Error(`Statusoverzicht van Floriday-authenticatie mislukt (HTTP ${r.httpStatus}${r.body?.code ? `, ${r.body.code}` : ""}).`);
45
- }
55
+ // Vaste kenmerken van Afhandeling meesturen: oudere gateway-versies weigeren het
56
+ // statusoverzicht zonder fulfillmentOrderId (HTTP 400).
57
+ const r = await signedPost("fulfillment-order/status", {
58
+ salesOrderIds: ids.slice(i, i + 100),
59
+ ...(foIds.length ? { fulfillmentOrderIds: foIds, fulfillmentOrderId: foIds[0] } : {}),
60
+ });
61
+ if (r.httpStatus >= 400 || !r.body)
62
+ throw new Error(gatewayFoutTekst("het statusoverzicht", r));
46
63
  const rows = Array.isArray(r.body) ? r.body : r.body.orders;
47
64
  if (!Array.isArray(rows))
48
65
  throw new Error("Statusoverzicht heeft geen lijst met orders.");
@@ -11,6 +11,8 @@ export interface LoadingCarrier {
11
11
  cartLabel: string;
12
12
  sortIndex: number;
13
13
  shared: boolean;
14
+ /** Extra lagen volgens de Engine; null = onbekend (niet meegestuurd). */
15
+ additionalLayers: number | null;
14
16
  items: LoadingItem[];
15
17
  }
16
18
  export interface OrderCheck {
@@ -1 +1 @@
1
- {"version":3,"file":"floridayLoading.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floridayLoading.functions.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AACD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AACD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3H;AAiOD,sEAAsE;AACtE,eAAO,MAAM,sBAAsB;;;;0CAEb;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;2BAC4E,CAAC;AAEvH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;0CAEV;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;uBAwDtC,CAAC"}
1
+ {"version":3,"file":"floridayLoading.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floridayLoading.functions.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AACD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AACD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3H;AA0PD,sEAAsE;AACtE,eAAO,MAAM,sBAAsB;;;;0CAEb;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;2BAC4E,CAAC;AAEvH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;0CAEV;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;uBA0DtC,CAAC"}