@flowselections/floriday-afhandeling-module 1.0.52 → 1.0.56
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-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +183 -145
- package/dist-lib/components/afhandeling/NuVersturenButton.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/NuVersturenButton.js +16 -5
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +4 -3
- package/dist-lib/hooks/useKnownOrders.d.ts +1 -0
- package/dist-lib/hooks/useKnownOrders.d.ts.map +1 -1
- package/dist-lib/hooks/useKnownOrders.js +20 -1
- package/dist-lib/hooks/usePickAgenda.d.ts.map +1 -1
- package/dist-lib/hooks/usePickAgenda.js +7 -3
- package/dist-lib/integrations/supabase/types.d.ts +101 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/authGateway.server.d.ts.map +1 -1
- package/dist-lib/lib/authGateway.server.js +3 -2
- package/dist-lib/lib/cartAssignments.functions.d.ts +29 -0
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.js +64 -0
- package/dist-lib/lib/floridayFulfillmentSend.server.d.ts +6 -0
- package/dist-lib/lib/floridayFulfillmentSend.server.d.ts.map +1 -1
- package/dist-lib/lib/floridayFulfillmentSend.server.js +83 -6
- package/dist-lib/lib/floridayLoading.functions.d.ts +2 -0
- package/dist-lib/lib/floridayLoading.functions.d.ts.map +1 -1
- package/dist-lib/lib/floridayLoading.functions.js +111 -18
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authGateway.server.d.ts","sourceRoot":"","sources":["../../src/lib/authGateway.server.ts"],"names":[],"mappings":"AA6BA,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAqB9D;AA2BD,iFAAiF;AACjF,wBAAsB,0BAA0B,CAC9C,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CA6BhC;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB/F;AA4BD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"authGateway.server.d.ts","sourceRoot":"","sources":["../../src/lib/authGateway.server.ts"],"names":[],"mappings":"AA6BA,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAqB9D;AA2BD,iFAAiF;AACjF,wBAAsB,0BAA0B,CAC9C,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CA6BhC;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB/F;AA4BD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA0ElD"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// message = `${timestamp}.${JSON.stringify(body)}`
|
|
7
7
|
// signature = hex(HMAC-SHA256(AUTH_GATEWAY_HMAC_SECRET, message))
|
|
8
8
|
// headers = { "X-Signature": signature, "X-Timestamp": timestamp }
|
|
9
|
-
// Timestamp =
|
|
9
|
+
// Timestamp = epoch-milliseconden als tekst (String(Date.now())), ±5 min venster.
|
|
10
10
|
// Web Crypto (browser/Node 15+/Workers) — geen node:crypto, want dist-lib
|
|
11
11
|
// wordt ook in de client-bundle van consumer-shells opgenomen.
|
|
12
12
|
import { createClient } from "@supabase/supabase-js";
|
|
@@ -161,7 +161,8 @@ export async function fetchDeliveryNotePdf(salesOrderId) {
|
|
|
161
161
|
deliveryOrderId: deliveryOrderIds[0],
|
|
162
162
|
};
|
|
163
163
|
const bodyStr = JSON.stringify(payload);
|
|
164
|
-
|
|
164
|
+
// De gateway verwacht epoch-milliseconden; we tekenen over precies deze waarde.
|
|
165
|
+
const timestamp = String(Date.now());
|
|
165
166
|
const signature = await signBody(secret, timestamp, bodyStr);
|
|
166
167
|
try {
|
|
167
168
|
const base = await resolveGatewayBaseServer();
|
|
@@ -77,6 +77,8 @@ export declare const getOrderLines: import("@tanstack/start-client-core").Requir
|
|
|
77
77
|
}>>;
|
|
78
78
|
export interface DayCartContent {
|
|
79
79
|
orderRef: string;
|
|
80
|
+
/** Engine-kar-id; leeg als de Engine geen kar-id gaf. */
|
|
81
|
+
cartId: string | null;
|
|
80
82
|
cartNumber: number;
|
|
81
83
|
layersUsed: number | null;
|
|
82
84
|
maxLayers: number | null;
|
|
@@ -133,4 +135,31 @@ export declare const getOrderCartIds: import("@tanstack/start-client-core").Requ
|
|
|
133
135
|
cartNumber: number;
|
|
134
136
|
}[];
|
|
135
137
|
}>>;
|
|
138
|
+
export interface PakbonCartInfo {
|
|
139
|
+
cartId: string;
|
|
140
|
+
/** Vaste LC-code van de kar (logistics_ensure_cart_barcode), dezelfde als op het pickstation. */
|
|
141
|
+
barcode: string;
|
|
142
|
+
/** Bestaande pakbon voor deze kar (documenttype pakbon, niet mislukt/geannuleerd), zoals Pickschermen controleert. */
|
|
143
|
+
bestaand: {
|
|
144
|
+
herkomst: string;
|
|
145
|
+
printer: string | null;
|
|
146
|
+
tijd: string;
|
|
147
|
+
status: string;
|
|
148
|
+
} | null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Per Engine-kar de vaste kar-barcode en de bestaande pakbon in de Printwachtrij.
|
|
152
|
+
* Match uitsluitend op cart_id; verzendbrieven tellen niet mee.
|
|
153
|
+
*/
|
|
154
|
+
export declare const getPakbonCartInfo: import("@tanstack/start-client-core").RequiredFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
155
|
+
supabase: import("../integrations/supabase/auth-middleware").AuthedSupabaseClient;
|
|
156
|
+
userId: string;
|
|
157
|
+
claims: import("@supabase/auth-js").JwtPayload;
|
|
158
|
+
}, undefined, undefined, undefined>], (d: {
|
|
159
|
+
cartIds: string[];
|
|
160
|
+
}) => {
|
|
161
|
+
cartIds: string[];
|
|
162
|
+
}, Promise<{
|
|
163
|
+
carts: PakbonCartInfo[];
|
|
164
|
+
}>>;
|
|
136
165
|
//# sourceMappingURL=cartAssignments.functions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cartAssignments.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cartAssignments.functions.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AACnE,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAUD,eAAO,MAAM,iBAAiB;;;;;eAEuB,YAAY,EAAE;GAQ/D,CAAC;AAEL,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CACjC;AAED,eAAO,MAAM,QAAQ;;;;0CAEC,aAAa;QACiB,IAAI;cAAY,YAAY;GAqB5E,CAAC;AAEL,eAAO,MAAM,iBAAiB;;;;0CAER;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;aAArD,MAAM;iBAAe,WAAW;eAAa,MAAM;;QAChC,IAAI;GAUpD,CAAC;AAEL,eAAO,MAAM,qBAAqB;;;;;QAEY,IAAI;aAAW,MAAM;GAQ/D,CAAC;AAEL,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,aAAa;;;;0CAEJ;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE;aAAlC,MAAM;iBAAe,WAAW;;WACV,SAAS,EAAE;GA0D9D,CAAC;AAEL,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,OAAO,GAAG,eAAe,GAAG,aAAa,CAAC;AACpF,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wFAAwF;IACxF,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,YAAY,EAAE,OAAO,CAAC;CACvB;AAKD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;0CAET;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE;;;WAMI,cAAc,EAAE;YAAgB,gBAAgB,EAAE;
|
|
1
|
+
{"version":3,"file":"cartAssignments.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cartAssignments.functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -197,6 +197,7 @@ export const getDayCartContents = createServerFn({ method: "POST" })
|
|
|
197
197
|
const lines = arr(k?.lines);
|
|
198
198
|
carts.push({
|
|
199
199
|
orderRef,
|
|
200
|
+
cartId: typeof k?.cartId === "string" && k.cartId ? k.cartId : null,
|
|
200
201
|
cartNumber: num(k?.cartNumber) ?? idx + 1,
|
|
201
202
|
layersUsed: num(s.layersUsed ?? s.totalLayersUsed),
|
|
202
203
|
maxLayers: num(s.maxLayers),
|
|
@@ -255,3 +256,66 @@ export const getOrderCartIds = createServerFn({ method: "POST" })
|
|
|
255
256
|
.filter((k) => k.cartId);
|
|
256
257
|
return { carts };
|
|
257
258
|
});
|
|
259
|
+
/**
|
|
260
|
+
* Per Engine-kar de vaste kar-barcode en de bestaande pakbon in de Printwachtrij.
|
|
261
|
+
* Match uitsluitend op cart_id; verzendbrieven tellen niet mee.
|
|
262
|
+
*/
|
|
263
|
+
export const getPakbonCartInfo = createServerFn({ method: "POST" })
|
|
264
|
+
.middleware([requireSupabaseAuth])
|
|
265
|
+
.inputValidator((d) => ({
|
|
266
|
+
cartIds: Array.from(new Set((d?.cartIds ?? []).map((x) => String(x).trim()).filter(Boolean))).slice(0, 200),
|
|
267
|
+
}))
|
|
268
|
+
.handler(async ({ data, context }) => {
|
|
269
|
+
const supabase = context.supabase;
|
|
270
|
+
if (data.cartIds.length === 0)
|
|
271
|
+
return { carts: [] };
|
|
272
|
+
const barcodes = new Map();
|
|
273
|
+
await Promise.all(data.cartIds.map(async (id) => {
|
|
274
|
+
const { data: bc, error } = await supabase.rpc("logistics_ensure_cart_barcode", { _cart_id: id });
|
|
275
|
+
if (error)
|
|
276
|
+
throw new Error(`Kar-barcode niet opgehaald: ${error.message}`);
|
|
277
|
+
if (typeof bc !== "string" || !bc)
|
|
278
|
+
throw new Error("De Engine gaf geen kar-barcode terug.");
|
|
279
|
+
barcodes.set(id, bc);
|
|
280
|
+
}));
|
|
281
|
+
const { data: jobs, error } = await supabase
|
|
282
|
+
.from("print_jobs")
|
|
283
|
+
.select("payload, herkomst, gebruiker_naam, created_at, status, printer_id")
|
|
284
|
+
.eq("documenttype", "pakbon")
|
|
285
|
+
.not("status", "in", "(mislukt,geannuleerd)")
|
|
286
|
+
.in("payload->>cart_id", data.cartIds)
|
|
287
|
+
.order("created_at", { ascending: true });
|
|
288
|
+
if (error)
|
|
289
|
+
throw new Error(`Printwachtrij niet gelezen: ${error.message}`);
|
|
290
|
+
const printerIds = [...new Set((jobs ?? []).map((j) => j.printer_id).filter(Boolean))];
|
|
291
|
+
const printerNaam = new Map();
|
|
292
|
+
if (printerIds.length) {
|
|
293
|
+
const { data: pr } = await supabase.from("printers").select("id, naam").in("id", printerIds);
|
|
294
|
+
for (const p of pr ?? [])
|
|
295
|
+
printerNaam.set(p.id, p.naam);
|
|
296
|
+
}
|
|
297
|
+
const eerste = new Map();
|
|
298
|
+
for (const j of jobs ?? []) {
|
|
299
|
+
const cid = j?.payload?.cart_id;
|
|
300
|
+
if (typeof cid === "string" && !eerste.has(cid))
|
|
301
|
+
eerste.set(cid, j);
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
carts: data.cartIds.map((id) => {
|
|
305
|
+
const j = eerste.get(id);
|
|
306
|
+
const bron = j ? (j.payload?.source ?? j.herkomst ?? j.gebruiker_naam ?? "onbekend") : null;
|
|
307
|
+
return {
|
|
308
|
+
cartId: id,
|
|
309
|
+
barcode: barcodes.get(id),
|
|
310
|
+
bestaand: j
|
|
311
|
+
? {
|
|
312
|
+
herkomst: String(bron) === "afhandeling" ? "Afhandeling" : String(bron).includes("pick") ? "het pickstation" : String(bron),
|
|
313
|
+
printer: j.printer_id ? printerNaam.get(j.printer_id) ?? null : null,
|
|
314
|
+
tijd: j.created_at,
|
|
315
|
+
status: j.status,
|
|
316
|
+
}
|
|
317
|
+
: null,
|
|
318
|
+
};
|
|
319
|
+
}),
|
|
320
|
+
};
|
|
321
|
+
});
|
|
@@ -2,6 +2,12 @@ export interface GatewayResult {
|
|
|
2
2
|
httpStatus: number;
|
|
3
3
|
body: any;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Begrijpelijke zin met de echte reden, gevolgd door veld(en) en technische code
|
|
7
|
+
* tussen [ ] die het scherm klein toont.
|
|
8
|
+
*/
|
|
9
|
+
export declare function floridayFoutTekst(inleiding: string, r: GatewayResult): string;
|
|
10
|
+
export declare function gatewayFoutTekst(wat: string, r: GatewayResult): string;
|
|
5
11
|
export interface FulfillmentRequestStatus {
|
|
6
12
|
fulfillmentRequestId: string;
|
|
7
13
|
deliveryOrderId: string | null;
|
|
@@ -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;
|
|
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;AA8ED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,GAAG,MAAM,CAI7E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,GAAG,MAAM,CAEtE;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
|
-
|
|
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,6 +30,85 @@ 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
|
+
/** Floriday-veldfout omzetten naar gewone taal. */
|
|
34
|
+
function veldUitleg(field, msg) {
|
|
35
|
+
const f = field.toLowerCase();
|
|
36
|
+
const max = /maximum length of '?(\d+)'?|max(?:imum)? length (\d+)|maxlength (\d+)/i.exec(msg);
|
|
37
|
+
const n = max ? (max[1] ?? max[2] ?? max[3]) : null;
|
|
38
|
+
if (f.endsWith("loadcarrierreference"))
|
|
39
|
+
return n ? `het karkenmerk is te lang (maximaal ${n} tekens)` : "het karkenmerk klopt niet";
|
|
40
|
+
if (f.endsWith("loadcarrieritemid"))
|
|
41
|
+
return "het regelkenmerk is geen geldige uuid";
|
|
42
|
+
if (f.endsWith("fulfillmentrequestid"))
|
|
43
|
+
return "het Floriday-verzoek van een regel klopt niet";
|
|
44
|
+
if (f.endsWith("numberofpackages"))
|
|
45
|
+
return "het aantal fusten van een regel klopt niet";
|
|
46
|
+
if (f.endsWith("numberofadditionallayers"))
|
|
47
|
+
return "het aantal extra lagen van een kar ontbreekt of klopt niet";
|
|
48
|
+
if (f.endsWith("loadcarriertype"))
|
|
49
|
+
return "het type kar ontbreekt of klopt niet";
|
|
50
|
+
if (f.endsWith("deliveryorderid"))
|
|
51
|
+
return "de levering is niet bekend bij Floriday";
|
|
52
|
+
if (f.endsWith("fulfillmentorderid"))
|
|
53
|
+
return "het opdrachtkenmerk klopt niet";
|
|
54
|
+
return msg;
|
|
55
|
+
}
|
|
56
|
+
/** Verzamelt alle foutvormen die de gateway kan doorgeven (ook een doorgegeven Floriday-antwoord). */
|
|
57
|
+
function verzamelFouten(b) {
|
|
58
|
+
const zinnen = [];
|
|
59
|
+
const velden = [];
|
|
60
|
+
let code = null;
|
|
61
|
+
const visit = (x, depth) => {
|
|
62
|
+
if (!x || typeof x !== "object" || depth > 3)
|
|
63
|
+
return;
|
|
64
|
+
code = code ?? str(x.code) ?? str(x.type) ?? str(x.errorCode);
|
|
65
|
+
const errs = x.errors;
|
|
66
|
+
if (Array.isArray(errs)) {
|
|
67
|
+
for (const e of errs) {
|
|
68
|
+
if (typeof e === "string")
|
|
69
|
+
zinnen.push(e);
|
|
70
|
+
else if (e && typeof e === "object") {
|
|
71
|
+
const fld = str(e.field) ?? str(e.propertyName) ?? str(e.property) ?? str(e.name);
|
|
72
|
+
const m = str(e.message) ?? str(e.errorMessage) ?? str(e.detail) ?? "";
|
|
73
|
+
if (fld) {
|
|
74
|
+
velden.push(fld);
|
|
75
|
+
zinnen.push(veldUitleg(fld, m));
|
|
76
|
+
}
|
|
77
|
+
else if (m)
|
|
78
|
+
zinnen.push(m);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (errs && typeof errs === "object") {
|
|
83
|
+
for (const [fld, v] of Object.entries(errs)) {
|
|
84
|
+
const m = Array.isArray(v) ? v.filter((y) => typeof y === "string").join(" ") : String(v ?? "");
|
|
85
|
+
velden.push(fld);
|
|
86
|
+
zinnen.push(veldUitleg(fld, m));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (const k of ["detail", "title", "error", "message"]) {
|
|
90
|
+
const s = str(x[k]);
|
|
91
|
+
if (s && !/^http_\d+$/.test(s) && s !== code)
|
|
92
|
+
zinnen.push(s);
|
|
93
|
+
}
|
|
94
|
+
for (const k of ["floriday", "upstream", "response", "body", "details", "data"])
|
|
95
|
+
visit(x[k], depth + 1);
|
|
96
|
+
};
|
|
97
|
+
visit(b, 0);
|
|
98
|
+
return { zinnen: [...new Set(zinnen)], velden: [...new Set(velden)], code };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Begrijpelijke zin met de echte reden, gevolgd door veld(en) en technische code
|
|
102
|
+
* tussen [ ] die het scherm klein toont.
|
|
103
|
+
*/
|
|
104
|
+
export function floridayFoutTekst(inleiding, r) {
|
|
105
|
+
const { zinnen, velden, code } = verzamelFouten(r.body ?? {});
|
|
106
|
+
const tech = [...velden, code, `HTTP ${r.httpStatus}`].filter(Boolean).join(" · ");
|
|
107
|
+
return `${inleiding}${zinnen.length ? `: ${zinnen.join("; ")}.` : " zonder reden te geven."} [${tech}]`;
|
|
108
|
+
}
|
|
109
|
+
export function gatewayFoutTekst(wat, r) {
|
|
110
|
+
return floridayFoutTekst(`Floriday-authenticatie weigerde ${wat}`, r);
|
|
111
|
+
}
|
|
32
112
|
/**
|
|
33
113
|
* Statusoverzicht (Floriday-authenticatie 1.0.64), in porties van maximaal 100.
|
|
34
114
|
* Exact contract per order: salesOrderId, found, salesOrderStatus, floridayStage,
|
|
@@ -46,11 +126,8 @@ export async function fetchFulfillmentStatus(salesOrderIds, fulfillmentOrderIds
|
|
|
46
126
|
salesOrderIds: ids.slice(i, i + 100),
|
|
47
127
|
...(foIds.length ? { fulfillmentOrderIds: foIds, fulfillmentOrderId: foIds[0] } : {}),
|
|
48
128
|
});
|
|
49
|
-
if (r.httpStatus >= 400 || !r.body)
|
|
50
|
-
|
|
51
|
-
.filter((x) => typeof x === "string" && x).join(" — ");
|
|
52
|
-
throw new Error(`Statusoverzicht van Floriday-authenticatie mislukt (HTTP ${r.httpStatus}${detail ? `: ${detail}` : ""}).`);
|
|
53
|
-
}
|
|
129
|
+
if (r.httpStatus >= 400 || !r.body)
|
|
130
|
+
throw new Error(gatewayFoutTekst("het statusoverzicht", r));
|
|
54
131
|
const rows = Array.isArray(r.body) ? r.body : r.body.orders;
|
|
55
132
|
if (!Array.isArray(rows))
|
|
56
133
|
throw new Error("Statusoverzicht heeft geen lijst met orders.");
|
|
@@ -65,6 +65,8 @@ export interface SendResult {
|
|
|
65
65
|
deliveryNote: string;
|
|
66
66
|
}[];
|
|
67
67
|
}
|
|
68
|
+
/** Floriday 2026v1 AddLoadCarrierConfiguration.loadCarrierReference: maximaal 14 tekens. */
|
|
69
|
+
export declare const LOAD_CARRIER_REF_MAX = 14;
|
|
68
70
|
/** Stelt de belading samen en toont de controles. Verstuurt niets. */
|
|
69
71
|
export declare const prepareFloridayLoading: import("@tanstack/start-client-core").RequiredFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
70
72
|
supabase: import("../integrations/supabase/auth-middleware").AuthedSupabaseClient;
|
|
@@ -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,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;
|
|
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;AAQD,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AA+TvC,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"}
|
|
@@ -7,30 +7,81 @@ import { createServerFn } from "@tanstack/react-start";
|
|
|
7
7
|
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
|
|
8
8
|
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
9
9
|
const num = (v) => v == null || v === "" || !Number.isFinite(Number(v)) ? null : Number(v);
|
|
10
|
-
|
|
10
|
+
/** Floriday 2026v1 AddLoadCarrierConfiguration.loadCarrierReference: maximaal 14 tekens. */
|
|
11
|
+
export const LOAD_CARRIER_REF_MAX = 14;
|
|
12
|
+
/** Deterministische korte code uit het cart_id: "K" + 8 tekens (FNV-1a, base36). */
|
|
13
|
+
function shortCartCode(cartId, salt = 0) {
|
|
14
|
+
let h = 0x811c9dc5 ^ salt;
|
|
15
|
+
for (let i = 0; i < cartId.length; i++) {
|
|
16
|
+
h ^= cartId.charCodeAt(i);
|
|
17
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
18
|
+
}
|
|
19
|
+
let h2 = 0x9e3779b9 ^ salt;
|
|
20
|
+
for (let i = cartId.length - 1; i >= 0; i--) {
|
|
21
|
+
h2 ^= cartId.charCodeAt(i);
|
|
22
|
+
h2 = Math.imul(h2, 0x01000193) >>> 0;
|
|
23
|
+
}
|
|
24
|
+
return ("K" + (h.toString(36) + h2.toString(36)).toUpperCase().padStart(8, "0").slice(0, 8));
|
|
25
|
+
}
|
|
26
|
+
/** Leesbaar karkenmerk: ordernummer zonder streepjes + "-K" + karnummer, bijv. FO2601418-K1. */
|
|
27
|
+
function readableCartRef(orderRef, cartLabel) {
|
|
28
|
+
const o = orderRef.replace(/[^A-Za-z0-9]/g, "").toUpperCase();
|
|
29
|
+
const k = cartLabel.replace(/[^A-Za-z0-9]/g, "").toUpperCase();
|
|
30
|
+
if (!o || !k)
|
|
31
|
+
return null;
|
|
32
|
+
const ref = `${o}-K${k}`;
|
|
33
|
+
return ref.length <= LOAD_CARRIER_REF_MAX ? ref : null;
|
|
34
|
+
}
|
|
35
|
+
async function ensureIds(supabase, scope, keys, makeIdentifier) {
|
|
11
36
|
const out = new Map();
|
|
12
37
|
const uniq = [...new Set(keys)];
|
|
13
38
|
if (!uniq.length)
|
|
14
39
|
return out;
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
const read = async () => {
|
|
41
|
+
const { data, error } = await supabase
|
|
42
|
+
.from("floriday_loading_identifiers")
|
|
43
|
+
.select("natural_key, identifier")
|
|
44
|
+
.eq("scope", scope)
|
|
45
|
+
.in("natural_key", uniq);
|
|
46
|
+
if (error)
|
|
47
|
+
throw new Error(error.message);
|
|
48
|
+
for (const r of data ?? [])
|
|
49
|
+
out.set(r.natural_key, r.identifier);
|
|
50
|
+
};
|
|
51
|
+
if (!makeIdentifier) {
|
|
52
|
+
const { error: insErr } = await supabase
|
|
53
|
+
.from("floriday_loading_identifiers")
|
|
54
|
+
.upsert(uniq.map((k) => ({ scope, natural_key: k })), { onConflict: "scope,natural_key", ignoreDuplicates: true });
|
|
55
|
+
if (insErr)
|
|
56
|
+
throw new Error(insErr.message);
|
|
57
|
+
await read();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Eén keer aanmaken met een eigen kenmerk; bestaande kenmerken nooit wijzigen.
|
|
61
|
+
await read();
|
|
62
|
+
for (const k of uniq.filter((x) => !out.has(x))) {
|
|
63
|
+
for (const candidate of makeIdentifier(k)) {
|
|
64
|
+
const { error } = await supabase.from("floriday_loading_identifiers")
|
|
65
|
+
.insert({ scope, natural_key: k, identifier: candidate });
|
|
66
|
+
if (!error)
|
|
67
|
+
break;
|
|
68
|
+
if (error.code !== "23505")
|
|
69
|
+
throw new Error(error.message);
|
|
70
|
+
// Conflict: óf de kar heeft intussen een kenmerk (klaar), óf het kenmerk is al bezet (volgende kandidaat).
|
|
71
|
+
const { data } = await supabase.from("floriday_loading_identifiers")
|
|
72
|
+
.select("identifier").eq("scope", scope).eq("natural_key", k).maybeSingle();
|
|
73
|
+
if (data?.identifier)
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
await read();
|
|
78
|
+
}
|
|
29
79
|
for (const k of uniq)
|
|
30
80
|
if (!out.has(k))
|
|
31
81
|
throw new Error("Vast kenmerk kon niet worden vastgelegd.");
|
|
32
82
|
return out;
|
|
33
83
|
}
|
|
84
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
34
85
|
// Auto-verwerking (1.0.64) neemt alleen aan; deze statussen betekenen dat de oude
|
|
35
86
|
// route tóch al belading/verzendbrief heeft gedaan → nooit nog eens versturen.
|
|
36
87
|
const AUTO_ALREADY_SENT = new Set(["sending_fulfillment", "generating_delivery_note", "done"]);
|
|
@@ -198,7 +249,12 @@ async function buildLoading(supabase, orderRef) {
|
|
|
198
249
|
const shipKey = (dl) => (deliveries.length <= 1 ? foKey : `${foKey}|${dl}`);
|
|
199
250
|
const [foIds, lcIds, itemIds] = await Promise.all([
|
|
200
251
|
ensureIds(supabase, "fulfillment_order", orderIds.length ? deliveries.map(shipKey) : []),
|
|
201
|
-
ensureIds(supabase, "load_carrier", [...carts.keys()])
|
|
252
|
+
ensureIds(supabase, "load_carrier", [...carts.keys()], (ck) => {
|
|
253
|
+
const c = carts.get(ck);
|
|
254
|
+
const firstRef = [...new Set(c.lines.map((l) => l.ref))].sort()[0] ?? "";
|
|
255
|
+
const readable = readableCartRef(firstRef, c.label);
|
|
256
|
+
return [...(readable ? [readable] : []), shortCartCode(ck), shortCartCode(ck, 1), shortCartCode(ck, 2)];
|
|
257
|
+
}),
|
|
202
258
|
ensureIds(supabase, "load_carrier_item", [...carts].flatMap(([ck, c]) => c.lines.map((l) => `${ck}|${l.orderId}|${l.key}`))),
|
|
203
259
|
]);
|
|
204
260
|
const carriers = [...carts].map(([ck, c], i) => ({
|
|
@@ -249,6 +305,43 @@ async function buildLoading(supabase, orderRef) {
|
|
|
249
305
|
createdAt: a.created_at,
|
|
250
306
|
}));
|
|
251
307
|
}
|
|
308
|
+
// Controle tegen Floriday Suppliers API 2026v1 (FulfillmentOrderCreate / AddLoadCarrierConfiguration).
|
|
309
|
+
for (const s of shipments) {
|
|
310
|
+
const nm = s.orderRefs.join(", ");
|
|
311
|
+
if (!UUID_RE.test(s.fulfillmentOrderId))
|
|
312
|
+
blockers.push(`Opdracht voor ${nm} heeft geen geldig opdrachtkenmerk (uuid). [fulfillmentOrderId]`);
|
|
313
|
+
if (s.deliveryOrderId && !UUID_RE.test(s.deliveryOrderId))
|
|
314
|
+
blockers.push(`Levering voor ${nm} heeft geen geldig Floriday-kenmerk (uuid). [deliveryOrderId]`);
|
|
315
|
+
if (!s.carriers.length)
|
|
316
|
+
blockers.push(`Opdracht voor ${nm} heeft geen karren. [loadCarriers]`);
|
|
317
|
+
const seen = new Set();
|
|
318
|
+
s.carriers.forEach((c, ci) => {
|
|
319
|
+
const f = `LoadCarriers[${ci}]`;
|
|
320
|
+
const ref = c.loadCarrierReference ?? "";
|
|
321
|
+
if (!ref)
|
|
322
|
+
blockers.push(`Kar ${c.cartLabel} heeft geen karkenmerk. [${f}.LoadCarrierReference]`);
|
|
323
|
+
else if (ref.length > LOAD_CARRIER_REF_MAX)
|
|
324
|
+
blockers.push(`Kar ${c.cartLabel} heeft een kenmerk van ${ref.length} tekens; Floriday staat er maximaal ${LOAD_CARRIER_REF_MAX} toe. [${f}.LoadCarrierReference]`);
|
|
325
|
+
if (ref && seen.has(ref))
|
|
326
|
+
blockers.push(`Karkenmerk ${ref} komt twee keer voor in dezelfde opdracht. [${f}.LoadCarrierReference]`);
|
|
327
|
+
seen.add(ref);
|
|
328
|
+
if (!(c.sortIndex >= 1))
|
|
329
|
+
blockers.push(`Kar ${c.cartLabel} heeft geen geldige volgorde. [${f}.SortIndex]`);
|
|
330
|
+
if (c.additionalLayers != null && !(Number.isInteger(c.additionalLayers) && c.additionalLayers >= 0))
|
|
331
|
+
blockers.push(`Kar ${c.cartLabel}: aantal extra lagen moet een heel getal van 0 of meer zijn. [${f}.NumberOfAdditionalLayers]`);
|
|
332
|
+
if (!c.items.length)
|
|
333
|
+
blockers.push(`Kar ${c.cartLabel} heeft geen regels. [${f}.Items]`);
|
|
334
|
+
c.items.forEach((it, ii) => {
|
|
335
|
+
const g = `${f}.Items[${ii}]`;
|
|
336
|
+
if (!UUID_RE.test(it.loadCarrierItemId))
|
|
337
|
+
blockers.push(`Regel ${ii + 1} op kar ${c.cartLabel} heeft geen geldig regelkenmerk (uuid). [${g}.LoadCarrierItemId]`);
|
|
338
|
+
if (it.fulfillmentRequestId && !UUID_RE.test(it.fulfillmentRequestId))
|
|
339
|
+
blockers.push(`Regel ${ii + 1} op kar ${c.cartLabel} (${it.orderRef}) heeft geen geldig Floriday-verzoek (uuid). [${g}.FulfillmentRequestId]`);
|
|
340
|
+
if (!(Number.isInteger(it.numberOfPackages) && it.numberOfPackages >= 1))
|
|
341
|
+
blockers.push(`Regel ${ii + 1} op kar ${c.cartLabel} (${it.orderRef}) heeft geen geldig aantal fusten. [${g}.NumberOfPackages]`);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
}
|
|
252
345
|
const uniqBlockers = [...new Set(blockers)];
|
|
253
346
|
return {
|
|
254
347
|
fulfillmentOrderId: shipments[0]?.fulfillmentOrderId ?? null,
|
|
@@ -282,7 +375,7 @@ export const sendFloridayLoading = createServerFn({ method: "POST" })
|
|
|
282
375
|
const p = await buildLoading(supabase, data.orderRef);
|
|
283
376
|
if (!p.canSend)
|
|
284
377
|
throw new Error(`Niet verstuurd: ${p.blockers.join(" ") || "geen opdracht."}`);
|
|
285
|
-
const { sendFulfillmentOrder } = await import("./floridayFulfillmentSend.server");
|
|
378
|
+
const { sendFulfillmentOrder, floridayFoutTekst } = await import("./floridayFulfillmentSend.server");
|
|
286
379
|
const log = async (s, row) => {
|
|
287
380
|
const { error } = await supabase.from("floriday_loading_attempts").insert({
|
|
288
381
|
fulfillment_order_id: s.fulfillmentOrderId, delivery_order_id: s.deliveryOrderId,
|
|
@@ -326,7 +419,7 @@ export const sendFloridayLoading = createServerFn({ method: "POST" })
|
|
|
326
419
|
const code = String(body?.code ?? (httpStatus && httpStatus < 400 ? "ok" : `http_${httpStatus}`));
|
|
327
420
|
const accepted = httpStatus === 200 && body?.ok === true && ACCEPTED.has(code);
|
|
328
421
|
const message = accepted ? (code === "created" ? "Belading verstuurd, verzendbrief volgt via de Engine." : "Belading was al verstuurd (niets dubbel aangemaakt), verzendbrief volgt via de Engine.")
|
|
329
|
-
:
|
|
422
|
+
: floridayFoutTekst("Floriday weigert de opdracht", { httpStatus: httpStatus ?? 0, body });
|
|
330
423
|
await log(s, {
|
|
331
424
|
step: "send", http_status: httpStatus, code, message,
|
|
332
425
|
warnings: arr(body?.warnings), skipped_requests: arr(body?.skippedRequests), request_summary: summary,
|