@flowselections/logistiek-engine 1.0.191 → 1.0.195
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/db/schema/logistiek-engine.sql +1936 -1
- package/dist-lib/components/InplanVoortgangCard.d.ts +16 -0
- package/dist-lib/components/InplanVoortgangCard.d.ts.map +1 -0
- package/dist-lib/components/InplanVoortgangCard.js +34 -0
- package/dist-lib/components/RegiePage.d.ts.map +1 -1
- package/dist-lib/components/RegiePage.js +2 -1
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +513 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
- package/dist-lib/lib/handlers/logistics-tick.server.js +58 -26
- package/dist-lib/lib/logisticsRecalcJob.server.d.ts.map +1 -1
- package/dist-lib/lib/logisticsRecalcJob.server.js +2 -1
- package/dist-lib/lib/moduleVersion.d.ts +1 -1
- package/dist-lib/lib/moduleVersion.js +1 -1
- package/dist-lib/lib/planQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/planQueue.server.js +2 -1
- package/dist-lib/lib/scheduleTasks.server.d.ts +18 -12
- package/dist-lib/lib/scheduleTasks.server.d.ts.map +1 -1
- package/dist-lib/lib/scheduleTasks.server.js +99 -51
- package/dist-lib/lib/stickerQueue.server.d.ts +6 -0
- package/dist-lib/lib/stickerQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/stickerQueue.server.js +23 -18
- package/dist-lib/lib/voorraadFouten.d.ts +14 -0
- package/dist-lib/lib/voorraadFouten.d.ts.map +1 -0
- package/dist-lib/lib/voorraadFouten.js +18 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logistics-tick.server.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/logistics-tick.server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE;;;;EAE7D;AAQD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"logistics-tick.server.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/logistics-tick.server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE;;;;EAE7D;AAQD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,QAAQ,CAAC,CAoGnB;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
|
|
@@ -53,13 +53,8 @@ export async function handleLogisticsTick(request, supabase, opts) {
|
|
|
53
53
|
catch {
|
|
54
54
|
// Niet aanvullen = fail closed (verzendbrieven wachten); ronde loopt door.
|
|
55
55
|
}
|
|
56
|
-
// 1.0.
|
|
57
|
-
|
|
58
|
-
await supabase.rpc("logistics_ensure_rebuffer_setting");
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
// Ontbreekt de functie nog (schemasync), dan geldt de standaard (aan).
|
|
62
|
-
}
|
|
56
|
+
// 1.0.194: "Opnieuw indelen bij wijziging" aanvullen gebeurt niet meer elke
|
|
57
|
+
// ronde, maar hooguit 1x per uur in logistics_tick() (logistics_ensure_periodiek).
|
|
63
58
|
// 1.0.190: open orders zonder kar opnieuw inplannen (max. 3 pogingen, daarna melding).
|
|
64
59
|
try {
|
|
65
60
|
await supabase.rpc("logistics_bewaak_zonder_kar");
|
|
@@ -72,6 +67,7 @@ export async function handleLogisticsTick(request, supabase, opts) {
|
|
|
72
67
|
// vervaltijd. Fail-closed: bij twijfel wordt de ronde overgeslagen; de
|
|
73
68
|
// volgende minuut-ronde is het vangnet.
|
|
74
69
|
const roundId = crypto.randomUUID();
|
|
70
|
+
const roundStart = new Date(Date.now() - 1000).toISOString();
|
|
75
71
|
let held = false;
|
|
76
72
|
let lockUnknown = false;
|
|
77
73
|
try {
|
|
@@ -94,8 +90,15 @@ export async function handleLogisticsTick(request, supabase, opts) {
|
|
|
94
90
|
}
|
|
95
91
|
return Response.json({ ...ident, ok: true, skipped: lockUnknown ? "slot_onbekend" : "ronde_loopt_al" }, { status: 200, headers: CORS_HEADERS });
|
|
96
92
|
}
|
|
93
|
+
// 1.0.194 (B0): start van de ronde koppelen aan de wek-aanroepen die erop wachtten.
|
|
97
94
|
try {
|
|
98
|
-
|
|
95
|
+
await supabase.rpc("logistics_kick_round_start");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Alleen meting; mag de ronde niet tegenhouden.
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return await runTickRound(supabase, tickJob, ident, roundStart);
|
|
99
102
|
}
|
|
100
103
|
finally {
|
|
101
104
|
try {
|
|
@@ -111,7 +114,8 @@ export async function handleLogisticsTick(request, supabase, opts) {
|
|
|
111
114
|
}
|
|
112
115
|
/** Vaste sleutel van het rondeslot; gelijk aan de check in logistics_plan_kick(). */
|
|
113
116
|
export const TICK_ROUND_LOCK_KEY = "tick:ronde";
|
|
114
|
-
async function runTickRound(supabase, tickJob, ident) {
|
|
117
|
+
async function runTickRound(supabase, tickJob, ident, roundStart = new Date().toISOString()) {
|
|
118
|
+
const roundStartedMs = Date.now();
|
|
115
119
|
// Meerdere batches per aanroep, met een ruime marge tot de time-out.
|
|
116
120
|
const deadline = Date.now() + 8000;
|
|
117
121
|
let last = null;
|
|
@@ -201,17 +205,9 @@ async function runTickRound(supabase, tickJob, ident) {
|
|
|
201
205
|
catch (e) {
|
|
202
206
|
buffers = { error: String(e?.message ?? e) };
|
|
203
207
|
}
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
let queueRefresh = null;
|
|
208
|
-
try {
|
|
209
|
-
const { data, error } = await supabase.rpc("logistics_sync_pick_queue");
|
|
210
|
-
queueRefresh = error ? { error: error.message } : data;
|
|
211
|
-
}
|
|
212
|
-
catch (e) {
|
|
213
|
-
queueRefresh = { error: String(e?.message ?? e) };
|
|
214
|
-
}
|
|
208
|
+
// 1.0.194: de pickwachtrij wordt elke minuut in logistics_tick() (SQL) gevuld
|
|
209
|
+
// en direct na elke indeling door de planwachtrij; niet meer in deze HTTP-ronde.
|
|
210
|
+
const queueRefresh = "in_sql_ronde";
|
|
215
211
|
// 1.0.169: rijen die op "alleen lezen" geparkeerd stonden vrijgeven zodra
|
|
216
212
|
// de Floriday-koppeling weer mag schrijven (doet niets zolang alleen lezen).
|
|
217
213
|
let floridayReadOnly = null;
|
|
@@ -383,19 +379,55 @@ async function runTickRound(supabase, tickJob, ident) {
|
|
|
383
379
|
catch (e) {
|
|
384
380
|
barcodes = { error: String(e?.message ?? e) };
|
|
385
381
|
}
|
|
386
|
-
//
|
|
387
|
-
|
|
388
|
-
|
|
382
|
+
// 1.0.194: laadtoestand draait in logistics_tick() (SQL), alleen bij wijziging.
|
|
383
|
+
const planState = "in_sql_ronde";
|
|
384
|
+
// 1.0.194 (B1): kwam er tijdens deze ronde een wek-aanroep binnen, dan nog
|
|
385
|
+
// één keer (begrensd) indelen vóór het slot vrijgaat.
|
|
386
|
+
let kickPending = null;
|
|
389
387
|
try {
|
|
390
|
-
const { data, error } = await supabase.rpc("
|
|
391
|
-
|
|
388
|
+
const { data: pending, error: pendingError } = await supabase.rpc("logistics_kick_pending_take", { p_since: roundStart });
|
|
389
|
+
if (pendingError) {
|
|
390
|
+
kickPending = { error: pendingError.message };
|
|
391
|
+
}
|
|
392
|
+
else if (pending === true) {
|
|
393
|
+
const { runPlanQueue } = await import("../planQueue.server.js");
|
|
394
|
+
kickPending = { extraRonde: await runPlanQueue(supabase, { deadlineAt: Date.now() + 10000 }) };
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
kickPending = { extraRonde: false };
|
|
398
|
+
}
|
|
392
399
|
}
|
|
393
400
|
catch (e) {
|
|
394
|
-
|
|
401
|
+
kickPending = { error: String(e?.message ?? e) };
|
|
402
|
+
}
|
|
403
|
+
// 1.0.194 (A3): fouten van de sticker-sync luid melden en vastleggen.
|
|
404
|
+
const stickerSyncFouten = Array.isArray(stickers?.syncFouten)
|
|
405
|
+
? stickers.syncFouten
|
|
406
|
+
: stickers && typeof stickers === "object" && "error" in stickers
|
|
407
|
+
? [{ stap: "stickerronde", functie: "runStickerQueue", fout: stickers.error }]
|
|
408
|
+
: [];
|
|
409
|
+
if (stickerSyncFouten.length > 0) {
|
|
410
|
+
console.error("[logistics-tick] sticker-sync fout:", JSON.stringify(stickerSyncFouten));
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
await supabase.rpc("logistics_tick_http_log", {
|
|
414
|
+
p_steps: {
|
|
415
|
+
gestart: roundStart,
|
|
416
|
+
duurMs: Date.now() - roundStartedMs,
|
|
417
|
+
stickerSyncFouten,
|
|
418
|
+
kickPending,
|
|
419
|
+
shippingNotesOk,
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
// Vastleggen mag de ronde niet blokkeren; de fout staat al in het antwoord.
|
|
395
425
|
}
|
|
396
426
|
return Response.json({
|
|
397
427
|
...ident,
|
|
398
428
|
ok: shippingNotesOk,
|
|
429
|
+
stickerSyncFouten,
|
|
430
|
+
kickPending,
|
|
399
431
|
planState,
|
|
400
432
|
ticks,
|
|
401
433
|
status: last?.status ?? "idle",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logisticsRecalcJob.server.d.ts","sourceRoot":"","sources":["../../src/lib/logisticsRecalcJob.server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAGjF;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAOhF;AAED,8DAA8D;AAC9D,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,SAAS,CAAC,CAsBpB;AAED,6EAA6E;AAC7E,wBAAsB,OAAO,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2D3E;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"logisticsRecalcJob.server.d.ts","sourceRoot":"","sources":["../../src/lib/logisticsRecalcJob.server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAGjF;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAOhF;AAED,8DAA8D;AAC9D,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,SAAS,CAAC,CAsBpB;AAED,6EAA6E;AAC7E,wBAAsB,OAAO,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2D3E;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,iFAAiF;AACjF,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,SAAK;UAiBpC,MAAM;QAAM,OAAO;YAAU,MAAM;KAO/D"}
|
|
@@ -106,6 +106,7 @@ export async function tickJob(sb) {
|
|
|
106
106
|
}
|
|
107
107
|
export { scheduleTasksPerOrder } from "./scheduleTasks.server.js";
|
|
108
108
|
import { scheduleTasksPerOrder } from "./scheduleTasks.server.js";
|
|
109
|
+
import { voorraadFoutTekst } from "./voorraadFouten.js";
|
|
109
110
|
/** Draait de afsluitende herberekenstappen (planning, tellingen, capaciteit). */
|
|
110
111
|
export async function runFinalSteps(sb, days = 21) {
|
|
111
112
|
const today = new Date();
|
|
@@ -126,7 +127,7 @@ export async function runFinalSteps(sb, days = 21) {
|
|
|
126
127
|
steps.push(await scheduleTasksPerOrder(sb));
|
|
127
128
|
for (const call of calls) {
|
|
128
129
|
const { error } = await sb.rpc(call.fn, call.args);
|
|
129
|
-
steps.push({ step: call.step, ok: !error, ...(error ? { error: error
|
|
130
|
+
steps.push({ step: call.step, ok: !error, ...(error ? { error: voorraadFoutTekst(error) } : {}) });
|
|
130
131
|
}
|
|
131
132
|
return steps;
|
|
132
133
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const MODULE_VERSION = "1.0.
|
|
1
|
+
export declare const MODULE_VERSION = "1.0.195";
|
|
2
2
|
//# sourceMappingURL=moduleVersion.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Automatisch gegenereerd door prebuild:lib; niet handmatig aanpassen.
|
|
2
|
-
export const MODULE_VERSION = "1.0.
|
|
2
|
+
export const MODULE_VERSION = "1.0.195";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/planQueue.server.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"planQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/planQueue.server.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAW5D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAwBD,wFAAwF;AACxF,wBAAsB,YAAY,CAChC,EAAE,EAAE,cAAc,EAClB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC3D,OAAO,CAAC,eAAe,CAAC,CA8S1B;AAmCD,iGAAiG;AACjG,eAAO,MAAM,eAAe,0EAA2E,CAAC;AAgCxG,4EAA4E;AAE5E,wBAAsB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE"}
|
|
@@ -14,6 +14,7 @@ import { FLOW_NODE } from "./flowNodes.js";
|
|
|
14
14
|
import { completePlannerDiffRuns, skipPlannerDiffRuns } from "./plannerDiff.server.js";
|
|
15
15
|
import { opnieuwOverSeconden } from "./beladingRegels.js";
|
|
16
16
|
import { scheduleTasksPerOrder } from "./scheduleTasks.server.js";
|
|
17
|
+
import { voorraadFoutTekst } from "./voorraadFouten.js";
|
|
17
18
|
const EMPTY = {
|
|
18
19
|
claimed: 0,
|
|
19
20
|
planned: 0,
|
|
@@ -337,7 +338,7 @@ async function runDayLevelSteps(sb, dates, result) {
|
|
|
337
338
|
for (const call of calls) {
|
|
338
339
|
const { error } = await sb.rpc(call.fn, call.args);
|
|
339
340
|
if (error && result.errors.length < 10)
|
|
340
|
-
result.errors.push(`${call.fn}: ${error
|
|
341
|
+
result.errors.push(`${call.fn}: ${voorraadFoutTekst(error)}`);
|
|
341
342
|
}
|
|
342
343
|
await runCartAndTaskFollowUp(sb, result);
|
|
343
344
|
}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
2
|
/**
|
|
3
|
-
* 1.0.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* 1.0.192: "Taken opnieuw inplannen" in porties via logistics_schedule_tasks_batch.
|
|
4
|
+
* - Eén ronde = werklijst van alle orders met open taken (zelfde selectie als 1.0.190).
|
|
5
|
+
* - Per portie een eigen databaseaanroep met tijdsbudget; per order een eigen
|
|
6
|
+
* subtransactie, dus een fout laat de oude planning staan.
|
|
7
|
+
* - Ongewijzigde orders (vingerafdruk incl. algemene invoer) worden overgeslagen.
|
|
8
|
+
* - Wat niet binnen het totale budget past, loopt de volgende minuutronde verder
|
|
9
|
+
* (de werklijst blijft staan; voortgang "x van y" in Overzicht & meldingen).
|
|
10
|
+
* Ontbreekt de nieuwe functie (Shell zonder 1.0.192-schema), dan valt hij terug
|
|
11
|
+
* op het inplannen per order van 1.0.190.
|
|
8
12
|
*/
|
|
9
|
-
export declare
|
|
13
|
+
export declare const PORTIE_ORDERS = 25;
|
|
14
|
+
export declare const PORTIE_BUDGET_MS = 20000;
|
|
15
|
+
export declare const TOTAAL_BUDGET_MS = 110000;
|
|
16
|
+
export declare function isOntbrekendeFunctie(msg: string): boolean;
|
|
17
|
+
export type InplanStap = {
|
|
10
18
|
step: string;
|
|
11
19
|
ok: boolean;
|
|
12
|
-
error?:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
error: string;
|
|
17
|
-
}>;
|
|
20
|
+
error?: string;
|
|
21
|
+
voortgang?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function scheduleTasksPerOrder(sb: SupabaseClient, nu?: () => number): Promise<InplanStap>;
|
|
18
24
|
//# sourceMappingURL=scheduleTasks.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduleTasks.server.d.ts","sourceRoot":"","sources":["../../src/lib/scheduleTasks.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduleTasks.server.d.ts","sourceRoot":"","sources":["../../src/lib/scheduleTasks.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC,eAAO,MAAM,gBAAgB,SAAU,CAAC;AAUxC,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3F,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,GAAE,MAAM,MAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoChH"}
|
|
@@ -1,65 +1,113 @@
|
|
|
1
|
+
import { voorraadFoutTekst } from "./voorraadFouten.js";
|
|
1
2
|
/**
|
|
2
|
-
* 1.0.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* 1.0.192: "Taken opnieuw inplannen" in porties via logistics_schedule_tasks_batch.
|
|
4
|
+
* - Eén ronde = werklijst van alle orders met open taken (zelfde selectie als 1.0.190).
|
|
5
|
+
* - Per portie een eigen databaseaanroep met tijdsbudget; per order een eigen
|
|
6
|
+
* subtransactie, dus een fout laat de oude planning staan.
|
|
7
|
+
* - Ongewijzigde orders (vingerafdruk incl. algemene invoer) worden overgeslagen.
|
|
8
|
+
* - Wat niet binnen het totale budget past, loopt de volgende minuutronde verder
|
|
9
|
+
* (de werklijst blijft staan; voortgang "x van y" in Overzicht & meldingen).
|
|
10
|
+
* Ontbreekt de nieuwe functie (Shell zonder 1.0.192-schema), dan valt hij terug
|
|
11
|
+
* op het inplannen per order van 1.0.190.
|
|
7
12
|
*/
|
|
8
|
-
export
|
|
13
|
+
export const PORTIE_ORDERS = 25;
|
|
14
|
+
export const PORTIE_BUDGET_MS = 20000;
|
|
15
|
+
export const TOTAAL_BUDGET_MS = 110000;
|
|
16
|
+
export function isOntbrekendeFunctie(msg) {
|
|
17
|
+
return /could not find the function|does not exist|PGRST202/i.test(msg);
|
|
18
|
+
}
|
|
19
|
+
export async function scheduleTasksPerOrder(sb, nu = Date.now) {
|
|
9
20
|
const step = "Taken opnieuw inplannen";
|
|
21
|
+
const start = nu();
|
|
10
22
|
try {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const { data, error } = await sb
|
|
21
|
-
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (rows.length < 1000)
|
|
23
|
+
let runId = null;
|
|
24
|
+
let laatste = {};
|
|
25
|
+
const fouten = [];
|
|
26
|
+
for (;;) {
|
|
27
|
+
const opties = { max_orders: PORTIE_ORDERS, budget_ms: PORTIE_BUDGET_MS };
|
|
28
|
+
if (runId)
|
|
29
|
+
opties.run_id = runId;
|
|
30
|
+
else
|
|
31
|
+
opties.start = true;
|
|
32
|
+
const { data, error } = await sb.rpc("logistics_schedule_tasks_batch", { p_opties: opties });
|
|
33
|
+
if (error) {
|
|
34
|
+
if (!runId && isOntbrekendeFunctie(error.message))
|
|
35
|
+
return await perOrderOud(sb, step);
|
|
36
|
+
throw new Error(voorraadFoutTekst(error));
|
|
37
|
+
}
|
|
38
|
+
laatste = (data ?? {});
|
|
39
|
+
runId = laatste.runId ?? runId;
|
|
40
|
+
for (const f of Array.isArray(laatste.fouten) ? laatste.fouten : []) {
|
|
41
|
+
fouten.push(`${f.order ?? "?"}: ${voorraadFoutTekst({ message: String(f.fout ?? "") })}`);
|
|
42
|
+
}
|
|
43
|
+
if (!laatste.resterend || laatste.resterend <= 0)
|
|
33
44
|
break;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
.select("order_number, created_at")
|
|
41
|
-
.in("order_number", lijst.slice(s, s + 200))
|
|
42
|
-
.is("deleted_at", null);
|
|
43
|
-
if (error)
|
|
44
|
-
throw new Error(error.message);
|
|
45
|
-
for (const o of Array.isArray(data) ? data : []) {
|
|
46
|
-
const c = String(o.created_at ?? "");
|
|
47
|
-
const inVenster = since && r160 && c >= since && c < r160;
|
|
48
|
-
if (!inVenster)
|
|
49
|
-
toegestaan.push(String(o.order_number));
|
|
45
|
+
if (nu() - start > TOTAAL_BUDGET_MS) {
|
|
46
|
+
return {
|
|
47
|
+
step,
|
|
48
|
+
ok: true,
|
|
49
|
+
voortgang: `${laatste.verwerkt ?? 0} van ${laatste.totaal ?? 0} opnieuw ingepland; de rest volgt in de volgende ronde`,
|
|
50
|
+
};
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
const fouten = [];
|
|
53
|
-
for (const ref of toegestaan) {
|
|
54
|
-
const { error } = await sb.rpc("logistics_schedule_tasks", { p_order_ref: ref });
|
|
55
|
-
if (error)
|
|
56
|
-
fouten.push(`${ref}: ${error.message}`);
|
|
57
|
-
}
|
|
58
53
|
return fouten.length === 0
|
|
59
54
|
? { step, ok: true }
|
|
60
|
-
: { step, ok: false, error: `${fouten.length} van ${
|
|
55
|
+
: { step, ok: false, error: `${fouten.length} van ${laatste.totaal ?? 0} order(s) niet ingepland: ${fouten.slice(0, 3).join(" | ")}` };
|
|
61
56
|
}
|
|
62
57
|
catch (e) {
|
|
63
58
|
return { step, ok: false, error: e?.message ? String(e.message) : String(e) };
|
|
64
59
|
}
|
|
65
60
|
}
|
|
61
|
+
/** 1.0.190-gedrag: per order logistics_schedule_tasks aanroepen. */
|
|
62
|
+
async function perOrderOud(sb, step) {
|
|
63
|
+
const { data: ts } = await sb
|
|
64
|
+
.from("logistics_time_settings")
|
|
65
|
+
.select("departure_rule_since, rule_160_since")
|
|
66
|
+
.order("updated_at", { ascending: false, nullsFirst: false })
|
|
67
|
+
.limit(1);
|
|
68
|
+
const since = ts?.[0]?.departure_rule_since ?? null;
|
|
69
|
+
const r160 = ts?.[0]?.rule_160_since ?? null;
|
|
70
|
+
const refs = new Set();
|
|
71
|
+
for (let from = 0;; from += 1000) {
|
|
72
|
+
const { data, error } = await sb
|
|
73
|
+
.from("logistics_tasks")
|
|
74
|
+
.select("order_ref")
|
|
75
|
+
.in("status", ["planned", "ready"])
|
|
76
|
+
.not("order_ref", "is", null)
|
|
77
|
+
.range(from, from + 999);
|
|
78
|
+
if (error)
|
|
79
|
+
throw new Error(error.message);
|
|
80
|
+
const rows = Array.isArray(data) ? data : [];
|
|
81
|
+
for (const r of rows)
|
|
82
|
+
if (r.order_ref)
|
|
83
|
+
refs.add(String(r.order_ref));
|
|
84
|
+
if (rows.length < 1000)
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const lijst = [...refs];
|
|
88
|
+
const toegestaan = [];
|
|
89
|
+
for (let s = 0; s < lijst.length; s += 200) {
|
|
90
|
+
const { data, error } = await sb
|
|
91
|
+
.from("orders")
|
|
92
|
+
.select("order_number, created_at")
|
|
93
|
+
.in("order_number", lijst.slice(s, s + 200))
|
|
94
|
+
.is("deleted_at", null);
|
|
95
|
+
if (error)
|
|
96
|
+
throw new Error(error.message);
|
|
97
|
+
for (const o of Array.isArray(data) ? data : []) {
|
|
98
|
+
const c = String(o.created_at ?? "");
|
|
99
|
+
const inVenster = since && r160 && c >= since && c < r160;
|
|
100
|
+
if (!inVenster)
|
|
101
|
+
toegestaan.push(String(o.order_number));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const fouten = [];
|
|
105
|
+
for (const ref of toegestaan) {
|
|
106
|
+
const { error } = await sb.rpc("logistics_schedule_tasks", { p_order_ref: ref });
|
|
107
|
+
if (error)
|
|
108
|
+
fouten.push(`${ref}: ${voorraadFoutTekst(error)}`);
|
|
109
|
+
}
|
|
110
|
+
return fouten.length === 0
|
|
111
|
+
? { step, ok: true }
|
|
112
|
+
: { step, ok: false, error: `${fouten.length} van ${toegestaan.length} order(s) niet ingepland: ${fouten.slice(0, 3).join(" | ")}` };
|
|
113
|
+
}
|
|
@@ -8,6 +8,12 @@ export interface StickerRun {
|
|
|
8
8
|
handled: number;
|
|
9
9
|
warnings: number;
|
|
10
10
|
errors: string[];
|
|
11
|
+
/** 1.0.194: fouten van de sync-stappen in de database (luid melden). */
|
|
12
|
+
syncFouten: Array<{
|
|
13
|
+
stap: string;
|
|
14
|
+
functie: string;
|
|
15
|
+
fout: string;
|
|
16
|
+
}>;
|
|
11
17
|
}
|
|
12
18
|
interface Row {
|
|
13
19
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stickerQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/stickerQueue.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAuB5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"stickerQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/stickerQueue.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAuB5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wEAAwE;IACxE,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,UAAU,GAAG;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,eAAe,GAAG,mBAAmB,CAAC;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAKD,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AAExD,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,CAEzD;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA+a5G;AAoGD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzD"}
|
|
@@ -38,28 +38,33 @@ function base64NaarBytes(b64) {
|
|
|
38
38
|
}
|
|
39
39
|
export async function runStickerQueue(sb, opts = {}) {
|
|
40
40
|
const limit = Math.max(1, opts.limit ?? 10);
|
|
41
|
-
const run = { synced: null, released: 0, printed: 0, blocked: 0, retrying: 0, handled: 0, warnings: 0, errors: [] };
|
|
41
|
+
const run = { synced: null, released: 0, printed: 0, blocked: 0, retrying: 0, handled: 0, warnings: 0, errors: [], syncFouten: [] };
|
|
42
42
|
const nu = () => new Date().toISOString();
|
|
43
43
|
const zet = (id, velden) => sb.from("logistics_sticker_prints").update(velden).eq("id", id);
|
|
44
|
-
// 1. Rekenen in de database.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
// 1. Rekenen in de database. 1.0.194: een fout van een sync-stap is een
|
|
45
|
+
// zichtbare melding (syncFouten), niet alleen een regel in errors.
|
|
46
|
+
const syncStap = async (naam, fn) => {
|
|
47
|
+
try {
|
|
48
|
+
const { data, error } = await sb.rpc(fn, { p_limit: 200 });
|
|
49
|
+
if (error) {
|
|
50
|
+
run.errors.push(`${naam}: ${error.message}`);
|
|
51
|
+
run.syncFouten.push({ stap: naam, functie: fn, fout: error.message });
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return data ?? null;
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
const msg = String(e?.message ?? e);
|
|
58
|
+
run.errors.push(`${naam}: ${msg}`);
|
|
59
|
+
run.syncFouten.push({ stap: naam, functie: fn, fout: msg });
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
run.synced = await syncStap("sync", "logistics_sticker_sync");
|
|
51
64
|
// 1b. Eigen stickers (1.0.176): needs_sticker per orderregel, vrij met de pakbon.
|
|
52
|
-
|
|
53
|
-
const { error } = await sb.rpc("logistics_own_sticker_sync", { p_limit: 200 });
|
|
54
|
-
if (error)
|
|
55
|
-
run.errors.push(`eigen stickers: ${error.message}`);
|
|
56
|
-
}
|
|
65
|
+
await syncStap("eigen stickers", "logistics_own_sticker_sync");
|
|
57
66
|
// 1c. Eigen traystickers (1.0.178): één per tray volgens de karindeling.
|
|
58
|
-
|
|
59
|
-
const { error } = await sb.rpc("logistics_own_traysticker_sync", { p_limit: 200 });
|
|
60
|
-
if (error)
|
|
61
|
-
run.errors.push(`eigen traystickers: ${error.message}`);
|
|
62
|
-
}
|
|
67
|
+
await syncStap("eigen traystickers", "logistics_own_traysticker_sync");
|
|
63
68
|
// 2. Tray-stickers: vrij na geaccepteerde belading.
|
|
64
69
|
{
|
|
65
70
|
const { data } = await sb
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 1.0.192 (Voorraad 1.0.107): foutcodes van get_stock_context() in gewone taal.
|
|
3
|
+
* VR001 = meer dan één actieve Floriday-koppeling (voor de gekozen omgeving).
|
|
4
|
+
* VR002 = de gekozen Floriday-omgeving heeft geen actieve koppeling, een andere wel.
|
|
5
|
+
* Andere fouten blijven ongewijzigd. Een connection_id is nooit bewijs van een
|
|
6
|
+
* Floriday-koppeling; alleen get_stock_context() bepaalt dat.
|
|
7
|
+
*/
|
|
8
|
+
export declare const VR001_TEKST = "Voorraad kan niet worden bijgewerkt: er staan meerdere Floriday-koppelingen aan. Zet er \u00E9\u00E9n uit in de Floriday-instellingen.";
|
|
9
|
+
export declare const VR002_TEKST = "Voorraad kan niet worden bijgewerkt: de gekozen Floriday-omgeving heeft geen actieve koppeling. Kies de juiste omgeving in de Floriday-instellingen.";
|
|
10
|
+
export declare function voorraadFoutTekst(err: {
|
|
11
|
+
code?: string | null;
|
|
12
|
+
message?: string | null;
|
|
13
|
+
} | null | undefined): string;
|
|
14
|
+
//# sourceMappingURL=voorraadFouten.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voorraadFouten.d.ts","sourceRoot":"","sources":["../../src/lib/voorraadFouten.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,2IACwG,CAAC;AACjI,eAAO,MAAM,WAAW,yJACgI,CAAC;AAEzJ,wBAAgB,iBAAiB,CAAC,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAMnH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 1.0.192 (Voorraad 1.0.107): foutcodes van get_stock_context() in gewone taal.
|
|
3
|
+
* VR001 = meer dan één actieve Floriday-koppeling (voor de gekozen omgeving).
|
|
4
|
+
* VR002 = de gekozen Floriday-omgeving heeft geen actieve koppeling, een andere wel.
|
|
5
|
+
* Andere fouten blijven ongewijzigd. Een connection_id is nooit bewijs van een
|
|
6
|
+
* Floriday-koppeling; alleen get_stock_context() bepaalt dat.
|
|
7
|
+
*/
|
|
8
|
+
export const VR001_TEKST = "Voorraad kan niet worden bijgewerkt: er staan meerdere Floriday-koppelingen aan. Zet er één uit in de Floriday-instellingen.";
|
|
9
|
+
export const VR002_TEKST = "Voorraad kan niet worden bijgewerkt: de gekozen Floriday-omgeving heeft geen actieve koppeling. Kies de juiste omgeving in de Floriday-instellingen.";
|
|
10
|
+
export function voorraadFoutTekst(err) {
|
|
11
|
+
const code = String(err?.code ?? "");
|
|
12
|
+
const msg = String(err?.message ?? "");
|
|
13
|
+
if (code === "VR001" || /\bVR001\b/.test(msg))
|
|
14
|
+
return VR001_TEKST;
|
|
15
|
+
if (code === "VR002" || /\bVR002\b/.test(msg))
|
|
16
|
+
return VR002_TEKST;
|
|
17
|
+
return msg;
|
|
18
|
+
}
|