@flowselections/logistiek-engine 1.0.163 → 1.0.169
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/BeheerPage.d.ts.map +1 -1
- package/dist-lib/components/BeheerPage.js +3 -1
- package/dist-lib/components/GeblokkeerdeStickersCard.d.ts +2 -0
- package/dist-lib/components/GeblokkeerdeStickersCard.d.ts.map +1 -0
- package/dist-lib/components/GeblokkeerdeStickersCard.js +31 -0
- package/dist-lib/components/HerindelingMeldingCard.d.ts +2 -0
- package/dist-lib/components/HerindelingMeldingCard.d.ts.map +1 -0
- package/dist-lib/components/HerindelingMeldingCard.js +37 -0
- package/dist-lib/index.d.ts +2 -1
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +3 -5
- package/dist-lib/integrations/supabase/types.d.ts +364 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/autoSend.server.d.ts.map +1 -1
- package/dist-lib/lib/autoSend.server.js +14 -0
- package/dist-lib/lib/externalFulfillment.d.ts +14 -0
- package/dist-lib/lib/externalFulfillment.d.ts.map +1 -0
- package/dist-lib/lib/externalFulfillment.js +26 -0
- package/dist-lib/lib/handlers/logistics-tick.server.js +7 -0
- package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
- package/dist-lib/lib/loadCarrierPlanning.server.js +12 -2
- package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
- package/dist-lib/lib/modulePrompts.js +189 -0
- package/dist-lib/lib/moduleVersion.d.ts +1 -1
- package/dist-lib/lib/moduleVersion.js +1 -1
- package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
- package/dist-lib/lib/ruleEngineSchema.js +1 -0
- package/dist-lib/lib/shippingNoteQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/shippingNoteQueue.server.js +12 -0
- package/dist-lib/lib/shippingNoteStates.d.ts +4 -0
- package/dist-lib/lib/shippingNoteStates.d.ts.map +1 -1
- package/dist-lib/lib/shippingNoteStates.js +4 -0
- package/dist-lib/lib/stickerQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/stickerQueue.server.js +85 -9
- package/dist-lib/lib/stickerRules.d.ts +2 -0
- package/dist-lib/lib/stickerRules.d.ts.map +1 -1
- package/dist-lib/lib/stickerRules.js +5 -0
- package/package.json +1 -1
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
import { trace, newTraceId } from "./trace.server.js";
|
|
16
16
|
import { printViaLayoutGecontroleerd, floridayLayout, bucketUitLink } from "./layoutPrint.server.js";
|
|
17
17
|
import { getFlorydayDocument, getFlorydayFulfillmentStatus } from "./floridayDocuments.server.js";
|
|
18
|
-
import { controleerEtiket, parseGeladenEtiketten, pdfFormaat, stickerBackoffMinuten, waarschuwingTekst, } from "./stickerRules.js";
|
|
19
|
-
const COLS = "id, soort, bron_id, order_id, order_number, cart_id, kopieen, breedte_mm, hoogte_mm, print_plek_id, fulfillment_order_id, status, attempts";
|
|
18
|
+
import { controleerEtiket, parseGeladenEtiketten, pdfFormaat, stickerBackoffMinuten, stickerKopieen, waarschuwingTekst, } from "./stickerRules.js";
|
|
19
|
+
const COLS = "id, soort, bron_id, order_id, order_number, cart_id, kopieen, breedte_mm, hoogte_mm, print_plek_id, fulfillment_order_id, status, attempts, sticker_type, print_job_id, herprint_reden, herprint_requested_at";
|
|
20
20
|
function formaat(r) {
|
|
21
21
|
return r.breedte_mm && r.hoogte_mm ? { breedteMm: Number(r.breedte_mm), hoogteMm: Number(r.hoogte_mm) } : null;
|
|
22
22
|
}
|
|
@@ -131,7 +131,20 @@ export async function runStickerQueue(sb, opts = {}) {
|
|
|
131
131
|
.or(`next_attempt_at.is.null,next_attempt_at.lte.${nu()}`)
|
|
132
132
|
.order("created_at")
|
|
133
133
|
.limit(limit);
|
|
134
|
-
|
|
134
|
+
// Expliciet gevraagde herprints (pickstation_sticker_reprint). Een pakbon-herprint komt hier nooit.
|
|
135
|
+
const { data: herprints } = await sb
|
|
136
|
+
.from("logistics_sticker_prints")
|
|
137
|
+
.select(COLS)
|
|
138
|
+
.eq("soort", "sticker")
|
|
139
|
+
.not("herprint_requested_at", "is", null)
|
|
140
|
+
.in("status", ["in_printwachtrij", "afgemeld"])
|
|
141
|
+
.limit(limit);
|
|
142
|
+
const teDoen = [
|
|
143
|
+
...(Array.isArray(klaar) ? klaar : []),
|
|
144
|
+
...(Array.isArray(herprints) ? herprints : []),
|
|
145
|
+
];
|
|
146
|
+
for (const r of teDoen) {
|
|
147
|
+
const isHerprint = r.status !== "klaar" && !!r.herprint_requested_at;
|
|
135
148
|
const traceId = newTraceId();
|
|
136
149
|
const basis = {
|
|
137
150
|
traceId,
|
|
@@ -143,21 +156,53 @@ export async function runStickerQueue(sb, opts = {}) {
|
|
|
143
156
|
};
|
|
144
157
|
const label = r.soort === "sticker" ? "Sticker" : "Tray-stickers";
|
|
145
158
|
const blokkeer = async (reden) => {
|
|
159
|
+
if (isHerprint) {
|
|
160
|
+
await zet(r.id, { herprint_requested_at: null, herprint_reden: `Herprint mislukt: ${reden}` });
|
|
161
|
+
await trace(sb, { ...basis, step: `${label}: herprint mislukt`, status: "waarschuwing", reason: reden });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
146
164
|
await zet(r.id, { status: "geblokkeerd", reden });
|
|
147
165
|
run.blocked++;
|
|
148
166
|
await trace(sb, { ...basis, step: `${label} niet geprint`, status: "waarschuwing", reason: reden });
|
|
149
167
|
};
|
|
150
168
|
const later = async (reden) => {
|
|
169
|
+
if (isHerprint) {
|
|
170
|
+
await trace(sb, { ...basis, step: `${label}: herprint opnieuw proberen`, status: "wachtend", reason: reden });
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
151
173
|
const attempts = (r.attempts ?? 0) + 1;
|
|
152
174
|
const volgende = new Date(Date.now() + stickerBackoffMinuten(attempts) * 60000).toISOString();
|
|
153
175
|
await zet(r.id, { attempts, next_attempt_at: volgende, reden });
|
|
154
176
|
run.retrying++;
|
|
155
177
|
await trace(sb, { ...basis, step: `${label}: opnieuw proberen`, status: "wachtend", reason: reden, attempts, nextAttemptAt: volgende });
|
|
156
178
|
};
|
|
179
|
+
// 1.0.166: order/bestelling afgehandeld in Floriday => niet printen, nooit afmelden.
|
|
180
|
+
{
|
|
181
|
+
const { data: extern, error: externError } = await sb.rpc("logistics_sticker_external_fulfilled", { p_sticker_print_id: r.id });
|
|
182
|
+
if (externError) {
|
|
183
|
+
await later(`Afhandeling in Floriday niet leesbaar: ${externError.message}`);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (extern === true) {
|
|
187
|
+
if (isHerprint) {
|
|
188
|
+
await zet(r.id, { herprint_requested_at: null, herprint_reden: "Afgehandeld in Floriday; niet opnieuw geprint." });
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
await zet(r.id, { status: "niet_printen", reden: "Afgehandeld in Floriday; door ons niet geprint en niet afgemeld." });
|
|
192
|
+
}
|
|
193
|
+
await trace(sb, { ...basis, step: `${label} niet geprint`, status: "overgeslagen", reason: "Afgehandeld in Floriday" });
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
157
197
|
if (!r.cart_id) {
|
|
158
198
|
await blokkeer("Geen kar bekend voor deze sticker.");
|
|
159
199
|
continue;
|
|
160
200
|
}
|
|
201
|
+
const kopieen = r.soort === "sticker" ? stickerKopieen(r.kopieen) : Math.max(1, Math.floor(Number(r.kopieen) || 1));
|
|
202
|
+
if (kopieen === null) {
|
|
203
|
+
await blokkeer(`Aantal afdrukken ongeldig (${String(r.kopieen)}).`);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
161
206
|
if (!r.print_plek_id) {
|
|
162
207
|
await blokkeer("Geen printplek bekend (geen pakbon met printplek en geen pickstation in de werkwijze).");
|
|
163
208
|
continue;
|
|
@@ -230,8 +275,11 @@ export async function runStickerQueue(sb, opts = {}) {
|
|
|
230
275
|
layoutId: layout.layoutId,
|
|
231
276
|
printPlekId: r.print_plek_id,
|
|
232
277
|
herkomst: "floriday",
|
|
233
|
-
|
|
234
|
-
|
|
278
|
+
isHerprint,
|
|
279
|
+
kopieen,
|
|
280
|
+
idempotentieSleutel: isHerprint
|
|
281
|
+
? `${r.soort}:${r.bron_id}:${r.cart_id}:${layout.layoutId}:herprint:${r.herprint_requested_at}`
|
|
282
|
+
: `${r.soort}:${r.bron_id}:${r.cart_id}:${layout.layoutId}`,
|
|
235
283
|
payload: {
|
|
236
284
|
source: "logistiek-engine",
|
|
237
285
|
documenttype: r.soort,
|
|
@@ -241,8 +289,12 @@ export async function runStickerQueue(sb, opts = {}) {
|
|
|
241
289
|
ordernummer: r.order_number,
|
|
242
290
|
order_number: r.order_number,
|
|
243
291
|
cart_id: r.cart_id,
|
|
244
|
-
kopieen
|
|
245
|
-
|
|
292
|
+
kopieen,
|
|
293
|
+
is_herprint: isHerprint,
|
|
294
|
+
...(isHerprint ? { herprint_reden: r.herprint_reden ?? null } : {}),
|
|
295
|
+
...(r.soort === "sticker"
|
|
296
|
+
? { sticker_id: r.bron_id, floriday_sticker_id: String(r.bron_id), sticker_type: r.sticker_type ?? null }
|
|
297
|
+
: { delivery_order_id: r.bron_id }),
|
|
246
298
|
fulfillment_order_id: r.fulfillment_order_id,
|
|
247
299
|
sticker_formaat_mm: f ? { breedte: f.breedteMm, hoogte: f.hoogteMm } : null,
|
|
248
300
|
...(pdfOpslag ? { pdf_opslag: pdfOpslag } : {}),
|
|
@@ -257,13 +309,19 @@ export async function runStickerQueue(sb, opts = {}) {
|
|
|
257
309
|
}
|
|
258
310
|
continue;
|
|
259
311
|
}
|
|
312
|
+
if (isHerprint) {
|
|
313
|
+
await zet(r.id, { herprint_requested_at: null, print_job_id: printed.jobId });
|
|
314
|
+
run.printed++;
|
|
315
|
+
await trace(sb, { ...basis, step: `${label} opnieuw geprint (opdracht ${printed.jobId}, ${kopieen}×)`, status: "geslaagd" });
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
260
318
|
await zet(r.id, { status: "in_printwachtrij", print_job_id: printed.jobId, reden: null, next_attempt_at: null });
|
|
261
319
|
run.printed++;
|
|
262
320
|
await trace(sb, {
|
|
263
321
|
...basis,
|
|
264
322
|
step: printed.bestaand
|
|
265
323
|
? `${label} staat in de printwachtrij (opdracht ${printed.jobId})`
|
|
266
|
-
: `${label} in de printwachtrij gezet (opdracht ${printed.jobId}, ${
|
|
324
|
+
: `${label} in de printwachtrij gezet (opdracht ${printed.jobId}, ${kopieen}×)`,
|
|
267
325
|
status: "geslaagd",
|
|
268
326
|
});
|
|
269
327
|
}
|
|
@@ -289,15 +347,33 @@ async function afmelden(sb, run) {
|
|
|
289
347
|
perSticker.set(r.bron_id, [...(perSticker.get(r.bron_id) ?? []), r.id]);
|
|
290
348
|
const klaarVoorAfmelden = [];
|
|
291
349
|
for (const stickerId of perSticker.keys()) {
|
|
350
|
+
// 1.0.166: nooit afmelden voor een order/bestelling die in Floriday is afgehandeld.
|
|
351
|
+
{
|
|
352
|
+
const eerste = (perSticker.get(stickerId) ?? [])[0];
|
|
353
|
+
const { data: extern, error: externError } = eerste
|
|
354
|
+
? await sb.rpc("logistics_sticker_external_fulfilled", { p_sticker_print_id: eerste })
|
|
355
|
+
: { data: null, error: null };
|
|
356
|
+
if (externError || extern === true)
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
292
359
|
const { data: alle } = await sb
|
|
293
360
|
.from("logistics_sticker_prints")
|
|
294
|
-
.select("cart_id, status")
|
|
361
|
+
.select("cart_id, status, print_job_id")
|
|
295
362
|
.eq("soort", "sticker")
|
|
296
363
|
.eq("bron_id", stickerId)
|
|
297
364
|
.neq("status", "niet_printen");
|
|
298
365
|
const regels = (Array.isArray(alle) ? alle : []);
|
|
366
|
+
// Nooit afmelden bij geblokkeerd/wachtend; shouldBePrinted=false (niet_printen) telt niet als geprint.
|
|
299
367
|
if (regels.length === 0 || regels.some((x) => x.status !== "in_printwachtrij" || !x.cart_id))
|
|
300
368
|
continue;
|
|
369
|
+
// "Printed and placed" (swagger): de printopdracht moet echt voltooid zijn in Layouts.
|
|
370
|
+
const jobIds = regels.map((x) => x.print_job_id).filter((x) => !!x);
|
|
371
|
+
if (jobIds.length !== regels.length)
|
|
372
|
+
continue;
|
|
373
|
+
const { data: jobs } = await sb.from("print_jobs").select("id, status").in("id", jobIds);
|
|
374
|
+
const voltooid = (Array.isArray(jobs) ? jobs : []).filter((j) => j.status === "voltooid");
|
|
375
|
+
if (voltooid.length !== new Set(jobIds).size)
|
|
376
|
+
continue;
|
|
301
377
|
const carts = regels.map((x) => x.cart_id);
|
|
302
378
|
const { data: scans } = await sb
|
|
303
379
|
.from("logistics_control_scan")
|
|
@@ -35,4 +35,6 @@ export declare function controleerEtiket(sticker: Formaat | null, etiketten: Gel
|
|
|
35
35
|
export declare function waarschuwingTekst(sticker: Formaat, etiket: GeladenEtiket | null, plek: string): string;
|
|
36
36
|
/** Wachttijd na een mislukte poging: 5, 15, daarna 60 minuten. */
|
|
37
37
|
export declare function stickerBackoffMinuten(attempts: number): number;
|
|
38
|
+
/** 1.0.165: aantal afdrukken voor een klantsticker; null = ongeldig (geen stille terugval naar 1, geen maximum). */
|
|
39
|
+
export declare function stickerKopieen(v: unknown): number | null;
|
|
38
40
|
//# sourceMappingURL=stickerRules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stickerRules.d.ts","sourceRoot":"","sources":["../../src/lib/stickerRules.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,IAAI,CAY5D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAG/C;AAED,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,SAAI,GAAG,OAAO,CAG9E;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,IAAI,CAsB3E;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,EACjC,IAAI,SAAY,GACf,cAAc,CAwBhB;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItG;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI9D"}
|
|
1
|
+
{"version":3,"file":"stickerRules.d.ts","sourceRoot":"","sources":["../../src/lib/stickerRules.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,IAAI,CAY5D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAG/C;AAED,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,SAAI,GAAG,OAAO,CAG9E;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,IAAI,CAsB3E;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,EACjC,IAAI,SAAY,GACf,cAAc,CAwBhB;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItG;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAGxD"}
|
|
@@ -109,3 +109,8 @@ export function stickerBackoffMinuten(attempts) {
|
|
|
109
109
|
return 15;
|
|
110
110
|
return 60;
|
|
111
111
|
}
|
|
112
|
+
/** 1.0.165: aantal afdrukken voor een klantsticker; null = ongeldig (geen stille terugval naar 1, geen maximum). */
|
|
113
|
+
export function stickerKopieen(v) {
|
|
114
|
+
const n = typeof v === "string" && v.trim() !== "" ? Number(v) : v;
|
|
115
|
+
return typeof n === "number" && Number.isInteger(n) && n >= 1 ? n : null;
|
|
116
|
+
}
|