@flowselections/floriday-verkoop-module 1.0.90 → 1.0.93
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/verkoop/CreateOrderPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/CreateOrderPage.js +1 -1
- package/dist-lib/components/verkoop/OrderPickupMomentPicker.d.ts +2 -2
- package/dist-lib/components/verkoop/OrderPickupMomentPicker.d.ts.map +1 -1
- package/dist-lib/components/verkoop/OrderPickupMomentPicker.js +10 -23
- package/dist-lib/integrations/supabase/types.d.ts +162 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/invoice-timing.check.d.ts +2 -0
- package/dist-lib/lib/invoice-timing.check.d.ts.map +1 -0
- package/dist-lib/lib/invoice-timing.check.js +19 -0
- package/dist-lib/lib/invoice-timing.d.ts +2 -0
- package/dist-lib/lib/invoice-timing.d.ts.map +1 -1
- package/dist-lib/lib/invoice-timing.js +22 -4
- package/dist-lib/lib/order-departure.check.d.ts +2 -0
- package/dist-lib/lib/order-departure.check.d.ts.map +1 -0
- package/dist-lib/lib/order-departure.check.js +25 -0
- package/dist-lib/lib/order-departure.d.ts +25 -0
- package/dist-lib/lib/order-departure.d.ts.map +1 -0
- package/dist-lib/lib/order-departure.js +54 -0
- package/dist-lib/lib/order-departure.server.d.ts +4 -0
- package/dist-lib/lib/order-departure.server.d.ts.map +1 -0
- package/dist-lib/lib/order-departure.server.js +62 -0
- package/dist-lib/lib/order-pickup.functions.d.ts +8 -13
- package/dist-lib/lib/order-pickup.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-pickup.functions.js +48 -75
- package/dist-lib/lib/salesorders-list.server.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-list.server.js +23 -37
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-timing.check.d.ts","sourceRoot":"","sources":["../../src/lib/invoice-timing.check.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Controle factuurtijdstip in Nederlandse tijd. Draai: bun src/lib/invoice-timing.check.ts
|
|
2
|
+
import { computeInvoiceDueAt, DEFAULT_INVOICE_TIMING } from "./invoice-timing.js";
|
|
3
|
+
let failed = 0;
|
|
4
|
+
function check(name, got, want) {
|
|
5
|
+
const ok = got === want;
|
|
6
|
+
if (!ok)
|
|
7
|
+
failed++;
|
|
8
|
+
console.log(`${ok ? "OK " : "FOUT"} ${name}: ${got}${ok ? "" : ` (verwacht ${want})`}`);
|
|
9
|
+
}
|
|
10
|
+
const s = { ...DEFAULT_INVOICE_TIMING, timeOfDay: "18:00" };
|
|
11
|
+
check("zomertijd 21-10 18:00 NL = 16:00 UTC", computeInvoiceDueAt({ expectedDeliveryDate: "2026-10-21" }, s), "2026-10-21T16:00:00.000Z");
|
|
12
|
+
check("wintertijd 2-11 18:00 NL = 17:00 UTC", computeInvoiceDueAt({ expectedDeliveryDate: "2026-11-02" }, s), "2026-11-02T17:00:00.000Z");
|
|
13
|
+
check("+1 dag over de omschakeling (24-10 → 25-10, wintertijd)", computeInvoiceDueAt({ expectedDeliveryDate: "2026-10-24" }, { ...s, offsetDays: 1 }), "2026-10-25T17:00:00.000Z");
|
|
14
|
+
check("tijdstip-ijkpunt laat op de avond telt Nederlandse kalenderdag", computeInvoiceDueAt({ createdAt: "2026-10-20T22:30:00Z" }, { ...s, anchor: "order_created", offsetDays: 1 }), "2026-10-22T16:00:00.000Z");
|
|
15
|
+
if (failed) {
|
|
16
|
+
console.error(`${failed} controle(s) mislukt`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
console.log("Alle controles geslaagd");
|
|
@@ -29,6 +29,8 @@ export interface InvoiceAnchorInput {
|
|
|
29
29
|
selfPickup?: boolean;
|
|
30
30
|
}
|
|
31
31
|
export declare function normalizeTimeOfDay(value: unknown): string;
|
|
32
|
+
/** Zet de kalenderdag van `date` op tijdstip T in Nederlandse tijd (zomer-/wintertijd). */
|
|
33
|
+
export declare function applyTime(date: Date, timeOfDay: string): Date;
|
|
32
34
|
/**
|
|
33
35
|
* Berekent het moment waarop de order gefactureerd mag worden.
|
|
34
36
|
* Geeft `null` wanneer het ijkpunt (nog) onbekend is.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-timing.d.ts","sourceRoot":"","sources":["../../src/lib/invoice-timing.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,WAAW,GACX,QAAQ,GACR,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,eAAe,CAAC;AAEpB,eAAO,MAAM,eAAe,EAAE;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAQ/E,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,aAAa,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,sBAAsB,EAAE,qBAUpC,CAAC;AAEF,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOzD;
|
|
1
|
+
{"version":3,"file":"invoice-timing.d.ts","sourceRoot":"","sources":["../../src/lib/invoice-timing.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,WAAW,GACX,QAAQ,GACR,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,eAAe,CAAC;AAEpB,eAAO,MAAM,eAAe,EAAE;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAQ/E,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,aAAa,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,sBAAsB,EAAE,qBAUpC,CAAC;AAEF,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOzD;AAoDD,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAS7D;AAqCD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,SAAS,UAAQ,GAAG,MAAM,CAWhG"}
|
|
@@ -66,11 +66,29 @@ function addDays(date, days, businessOnly) {
|
|
|
66
66
|
}
|
|
67
67
|
return out;
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
const INVOICE_TIME_ZONE = "Europe/Amsterdam";
|
|
70
|
+
/** Verschil (ms) tussen Amsterdamse kloktijd en UTC op dit moment. */
|
|
71
|
+
function zoneOffsetMs(at) {
|
|
72
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
73
|
+
timeZone: INVOICE_TIME_ZONE,
|
|
74
|
+
hourCycle: "h23",
|
|
75
|
+
year: "numeric", month: "2-digit", day: "2-digit",
|
|
76
|
+
hour: "2-digit", minute: "2-digit", second: "2-digit",
|
|
77
|
+
}).formatToParts(at);
|
|
78
|
+
const get = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
|
|
79
|
+
const asUtc = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour"), get("minute"), get("second"));
|
|
80
|
+
return asUtc - at.getTime();
|
|
81
|
+
}
|
|
82
|
+
/** Zet de kalenderdag van `date` op tijdstip T in Nederlandse tijd (zomer-/wintertijd). */
|
|
83
|
+
export function applyTime(date, timeOfDay) {
|
|
70
84
|
const [h, m] = normalizeTimeOfDay(timeOfDay).split(":").map(Number);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
// Kalenderdag volgens Amsterdam (bij tijdstip-ijkpunten), anders de UTC-datum.
|
|
86
|
+
const off0 = zoneOffsetMs(date);
|
|
87
|
+
const local = new Date(date.getTime() + off0);
|
|
88
|
+
const wall = Date.UTC(local.getUTCFullYear(), local.getUTCMonth(), local.getUTCDate(), h ?? 18, m ?? 0, 0, 0);
|
|
89
|
+
let guess = wall - zoneOffsetMs(new Date(wall));
|
|
90
|
+
guess = wall - zoneOffsetMs(new Date(guess));
|
|
91
|
+
return new Date(guess);
|
|
74
92
|
}
|
|
75
93
|
function anchorDate(anchor, input) {
|
|
76
94
|
switch (anchor) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-departure.check.d.ts","sourceRoot":"","sources":["../../src/lib/order-departure.check.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Controle weergave ophaalmoment. Draai: bun src/lib/order-departure.check.ts
|
|
2
|
+
import { departureView, normalizeDeparture } from "./order-departure.js";
|
|
3
|
+
let failed = 0;
|
|
4
|
+
function check(name, got, want) {
|
|
5
|
+
const ok = got === want;
|
|
6
|
+
if (!ok)
|
|
7
|
+
failed++;
|
|
8
|
+
console.log(`${ok ? "OK " : "FOUT"} ${name}: ${got}${ok ? "" : ` (verwacht ${want})`}`);
|
|
9
|
+
}
|
|
10
|
+
const ho = departureView(normalizeDeparture({
|
|
11
|
+
ok: true, departureAt: "2026-10-20T13:00:00Z", signupDeadline: "2026-10-20T11:00:00Z", lateSignup: false,
|
|
12
|
+
}));
|
|
13
|
+
check("HO-2601441", ho.text, "di 20 okt 15:00 ophalen · aanmelden di 20 okt 13:00");
|
|
14
|
+
check("wintertijd", departureView(normalizeDeparture({ ok: true, departureAt: "2026-11-02T14:00:00Z" })).short, "ma 2 nov 15:00");
|
|
15
|
+
check("te laat aangemeld", departureView(normalizeDeparture({ ok: true, departureAt: "2026-10-20T13:00:00Z", lateSignup: true })).lateSignup, true);
|
|
16
|
+
const bad = departureView(normalizeDeparture({ ok: false, reason: "Geen vervoerder gekozen", departureAt: "2026-10-20T13:00:00Z" }));
|
|
17
|
+
check("ok=false: geen tijd", bad.text, null);
|
|
18
|
+
check("ok=false: reden", bad.reason, "Geen vervoerder gekozen");
|
|
19
|
+
check("geen antwoord: geen tijd", departureView(null).text, null);
|
|
20
|
+
check("ontbrekende velden", normalizeDeparture({ ok: true })?.departureAt, null);
|
|
21
|
+
if (failed) {
|
|
22
|
+
console.error(`${failed} controle(s) mislukt`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
console.log("Alle controles geslaagd");
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface OrderDeparture {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
reason: string | null;
|
|
4
|
+
carrierId: string | null;
|
|
5
|
+
momentKey: string | null;
|
|
6
|
+
departureAt: string | null;
|
|
7
|
+
signupDeadline: string | null;
|
|
8
|
+
lateSignup: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Engine-antwoord veilig omzetten; ontbrekende velden worden null. */
|
|
11
|
+
export declare function normalizeDeparture(raw: unknown): OrderDeparture | null;
|
|
12
|
+
/** "di 20 okt 15:00" in Nederlandse tijd. */
|
|
13
|
+
export declare function formatMoment(iso: string | null): string | null;
|
|
14
|
+
export declare const DEPARTURE_UNKNOWN = "Ophaalmoment nu niet bekend. Ververs over een minuut.";
|
|
15
|
+
export interface DepartureView {
|
|
16
|
+
/** Hoofdtekst, bv. "di 20 okt 15:00 ophalen · aanmelden di 20 okt 13:00". */
|
|
17
|
+
text: string | null;
|
|
18
|
+
/** Kort label voor de lijst, bv. "di 20 okt 15:00". */
|
|
19
|
+
short: string | null;
|
|
20
|
+
lateSignup: boolean;
|
|
21
|
+
/** Reden als er geen geldig ophaalmoment is (nooit met een tijd erbij). */
|
|
22
|
+
reason: string | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function departureView(dep: OrderDeparture | null | undefined): DepartureView;
|
|
25
|
+
//# sourceMappingURL=order-departure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-departure.d.ts","sourceRoot":"","sources":["../../src/lib/order-departure.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;CACrB;AAQD,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAYtE;AAED,6CAA6C;AAC7C,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAS9D;AAED,eAAO,MAAM,iBAAiB,0DAA0D,CAAC;AAEzF,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uDAAuD;IACvD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAenF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Ophaal- en aanmeldmoment van een order, zoals de Logistiek Engine het
|
|
2
|
+
// berekent (logistics_order_departure). Deze module rekent zelf niets uit:
|
|
3
|
+
// alleen normaliseren en weergeven.
|
|
4
|
+
const TIME_ZONE = "Europe/Amsterdam";
|
|
5
|
+
function str(v) {
|
|
6
|
+
return typeof v === "string" && v.trim() !== "" ? v : null;
|
|
7
|
+
}
|
|
8
|
+
/** Engine-antwoord veilig omzetten; ontbrekende velden worden null. */
|
|
9
|
+
export function normalizeDeparture(raw) {
|
|
10
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
11
|
+
return null;
|
|
12
|
+
const r = raw;
|
|
13
|
+
return {
|
|
14
|
+
ok: r.ok === true,
|
|
15
|
+
reason: str(r.reason),
|
|
16
|
+
carrierId: str(r.carrierId),
|
|
17
|
+
momentKey: str(r.momentKey),
|
|
18
|
+
departureAt: str(r.departureAt),
|
|
19
|
+
signupDeadline: str(r.signupDeadline),
|
|
20
|
+
lateSignup: r.lateSignup === true,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** "di 20 okt 15:00" in Nederlandse tijd. */
|
|
24
|
+
export function formatMoment(iso) {
|
|
25
|
+
if (!iso)
|
|
26
|
+
return null;
|
|
27
|
+
const d = new Date(iso);
|
|
28
|
+
if (Number.isNaN(d.getTime()))
|
|
29
|
+
return null;
|
|
30
|
+
const date = d
|
|
31
|
+
.toLocaleDateString("nl-NL", { timeZone: TIME_ZONE, weekday: "short", day: "numeric", month: "short" })
|
|
32
|
+
.replace(/\./g, "");
|
|
33
|
+
const time = d.toLocaleTimeString("nl-NL", { timeZone: TIME_ZONE, hour: "2-digit", minute: "2-digit", hour12: false });
|
|
34
|
+
return `${date} ${time}`;
|
|
35
|
+
}
|
|
36
|
+
export const DEPARTURE_UNKNOWN = "Ophaalmoment nu niet bekend. Ververs over een minuut.";
|
|
37
|
+
export function departureView(dep) {
|
|
38
|
+
if (!dep)
|
|
39
|
+
return { text: null, short: null, lateSignup: false, reason: DEPARTURE_UNKNOWN };
|
|
40
|
+
const pickup = dep.ok ? formatMoment(dep.departureAt) : null;
|
|
41
|
+
if (!pickup) {
|
|
42
|
+
return {
|
|
43
|
+
text: null,
|
|
44
|
+
short: null,
|
|
45
|
+
lateSignup: false,
|
|
46
|
+
reason: dep.reason ?? "Er is geen ophaalmoment bekend voor deze order.",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const signup = formatMoment(dep.signupDeadline);
|
|
50
|
+
const parts = [`${pickup} ophalen`];
|
|
51
|
+
if (signup)
|
|
52
|
+
parts.push(`aanmelden ${signup}`);
|
|
53
|
+
return { text: parts.join(" · "), short: pickup, lateSignup: dep.lateSignup, reason: dep.ok ? null : dep.reason };
|
|
54
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type OrderDeparture } from "./order-departure.js";
|
|
2
|
+
export declare function loadOrderDepartures(supabase: any, orderIds: string[]): Promise<Map<string, OrderDeparture>>;
|
|
3
|
+
export declare function forgetOrderDeparture(orderId: string): void;
|
|
4
|
+
//# sourceMappingURL=order-departure.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-departure.server.d.ts","sourceRoot":"","sources":["../../src/lib/order-departure.server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAM5E,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAiDtC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,QAEnD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Leest ophaal-/aanmeldmomenten bij de Engine. Gebruikt de lijstversie
|
|
2
|
+
// (logistics_order_departure_list) als die bestaat, anders één aanroep per
|
|
3
|
+
// order (maximaal 12 tegelijk). Fout => order ontbreekt in het resultaat.
|
|
4
|
+
import { normalizeDeparture } from "./order-departure.js";
|
|
5
|
+
const PARALLEL = 12;
|
|
6
|
+
const CACHE_MS = 30000;
|
|
7
|
+
const cache = new Map();
|
|
8
|
+
export async function loadOrderDepartures(supabase, orderIds) {
|
|
9
|
+
const out = new Map();
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
const todo = [];
|
|
12
|
+
for (const id of Array.from(new Set(orderIds))) {
|
|
13
|
+
const hit = cache.get(id);
|
|
14
|
+
if (hit && now - hit.at < CACHE_MS)
|
|
15
|
+
out.set(id, hit.dep);
|
|
16
|
+
else
|
|
17
|
+
todo.push(id);
|
|
18
|
+
}
|
|
19
|
+
if (todo.length === 0)
|
|
20
|
+
return out;
|
|
21
|
+
// Lijstversie (Engine 1.0.162+): één aanroep.
|
|
22
|
+
try {
|
|
23
|
+
const { data, error } = await supabase.rpc("logistics_order_departure_list", { p_order_ids: todo });
|
|
24
|
+
if (!error) {
|
|
25
|
+
const rows = Array.isArray(data) ? data : [];
|
|
26
|
+
for (const row of rows) {
|
|
27
|
+
const r = (row && typeof row === "object" && "departure" in row ? row.departure : row);
|
|
28
|
+
const id = String(row?.order_id ?? row?.orderId ?? r?.orderId ?? "");
|
|
29
|
+
const dep = normalizeDeparture(r);
|
|
30
|
+
if (id && dep) {
|
|
31
|
+
out.set(id, dep);
|
|
32
|
+
cache.set(id, { at: now, dep });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* lijstversie niet beschikbaar: per order */
|
|
40
|
+
}
|
|
41
|
+
for (let i = 0; i < todo.length; i += PARALLEL) {
|
|
42
|
+
await Promise.all(todo.slice(i, i + PARALLEL).map(async (id) => {
|
|
43
|
+
try {
|
|
44
|
+
const { data, error } = await supabase.rpc("logistics_order_departure", { p_order_id: id });
|
|
45
|
+
if (error)
|
|
46
|
+
return;
|
|
47
|
+
const dep = normalizeDeparture(data);
|
|
48
|
+
if (dep) {
|
|
49
|
+
out.set(id, dep);
|
|
50
|
+
cache.set(id, { at: now, dep });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
/* fail closed: onbekend */
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
export function forgetOrderDeparture(orderId) {
|
|
61
|
+
cache.delete(orderId);
|
|
62
|
+
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
+
import { type DepartureView, type OrderDeparture } from "./order-departure.js";
|
|
1
2
|
export interface PickupMomentOption {
|
|
2
|
-
/**
|
|
3
|
+
/** Sleutel in Engine-formaat: "dagen@ophaaltijd|dagen@aanmeldtijd". */
|
|
3
4
|
key: string;
|
|
4
|
-
pickupDate: string;
|
|
5
|
-
pickupTime: string | null;
|
|
6
|
-
signupDate: string | null;
|
|
7
|
-
signupTime: string | null;
|
|
8
5
|
deliveryTime: string | null;
|
|
9
6
|
label: string;
|
|
10
7
|
}
|
|
11
|
-
|
|
8
|
+
/** Keuzes uit de vervoerdersmomenten — alleen tijden en dagen, geen datum. */
|
|
9
|
+
export declare function carrierMomentOptions(carrier: any | null): PickupMomentOption[];
|
|
12
10
|
export declare const getOrderPickupMoment: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
13
11
|
supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
|
|
14
12
|
userId: string;
|
|
@@ -16,15 +14,12 @@ export declare const getOrderPickupMoment: import("@tanstack/start-client-core")
|
|
|
16
14
|
}, undefined, undefined, undefined>], (input: unknown) => {
|
|
17
15
|
orderId: string;
|
|
18
16
|
}, Promise<{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
hasCarrier?: undefined;
|
|
23
|
-
} | {
|
|
24
|
-
selectedKey: string;
|
|
25
|
-
selected: PickupMomentOption;
|
|
17
|
+
view: DepartureView;
|
|
18
|
+
departure: OrderDeparture | null;
|
|
19
|
+
selectedKey: string | null;
|
|
26
20
|
options: PickupMomentOption[];
|
|
27
21
|
hasCarrier: boolean;
|
|
22
|
+
deliveryTime: string | null;
|
|
28
23
|
}>>;
|
|
29
24
|
export declare const setOrderPickupMoment: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
30
25
|
supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order-pickup.functions.d.ts","sourceRoot":"","sources":["../../src/lib/order-pickup.functions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"order-pickup.functions.d.ts","sourceRoot":"","sources":["../../src/lib/order-pickup.functions.ts"],"names":[],"mappings":"AAMA,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAG3F,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,GAAG,kBAAkB,EAAE,CAoB9E;AAaD,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;;;;;;;GAyC7B,CAAC;AAEL,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;;;GAoB7B,CAAC"}
|
|
@@ -1,75 +1,47 @@
|
|
|
1
|
-
// Ophaalmoment
|
|
1
|
+
// Ophaalmoment van een order: tonen uit de Logistiek Engine, kiezen uit de
|
|
2
|
+
// momenten van de vervoerder. Deze module rekent zelf geen datum uit.
|
|
2
3
|
import { createServerFn } from "@tanstack/react-start";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
|
|
5
6
|
import { normalizeTime } from "./carrier-availability.js";
|
|
7
|
+
import { departureView } from "./order-departure.js";
|
|
6
8
|
import { assertRowsAffected, resolveOrderRow } from "./order-row.server.js";
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return `${dt.getFullYear()}-${String(dt.getMonth() + 1).padStart(2, "0")}-${String(dt.getDate()).padStart(2, "0")}`;
|
|
9
|
+
function daysText(n, what) {
|
|
10
|
+
if (n <= 0)
|
|
11
|
+
return `${what} op de leverdag`;
|
|
12
|
+
return `${what} ${n} werkdag${n === 1 ? "" : "en"} vóór levering`;
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
if (Number.isNaN(dt.getTime()))
|
|
17
|
-
return iso;
|
|
18
|
-
return dt.toLocaleDateString("nl-NL", { weekday: "short", day: "numeric", month: "short" });
|
|
19
|
-
}
|
|
20
|
-
export function buildPickupOptions(carrier, deliveryISO) {
|
|
21
|
-
if (!carrier || !deliveryISO)
|
|
22
|
-
return [];
|
|
23
|
-
const raw = Array.isArray(carrier.pickup_moments) ? carrier.pickup_moments : [];
|
|
24
|
-
const moments = raw.length > 0
|
|
25
|
-
? raw
|
|
26
|
-
: [carrier.signup_time_1, carrier.signup_time_2]
|
|
27
|
-
.filter(Boolean)
|
|
28
|
-
.map((t) => ({
|
|
29
|
-
signup_time: t,
|
|
30
|
-
signup_days: carrier.signup_days_before_delivery ?? 0,
|
|
31
|
-
delivery_days: carrier.delivery_days ?? 0,
|
|
32
|
-
}));
|
|
14
|
+
/** Keuzes uit de vervoerdersmomenten — alleen tijden en dagen, geen datum. */
|
|
15
|
+
export function carrierMomentOptions(carrier) {
|
|
16
|
+
const raw = Array.isArray(carrier?.pickup_moments) ? carrier.pickup_moments : [];
|
|
33
17
|
const seen = new Set();
|
|
34
18
|
const out = [];
|
|
35
|
-
for (const m of
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const key = `${pickupDate}|${signupTime ?? ""}|${deliveryTime ?? ""}`;
|
|
19
|
+
for (const m of raw) {
|
|
20
|
+
const pt = normalizeTime(m.pickup_time);
|
|
21
|
+
if (!pt)
|
|
22
|
+
continue;
|
|
23
|
+
const pd = Math.max(0, Number(m.pickup_days ?? 0) || 0);
|
|
24
|
+
const st = normalizeTime(m.signup_time);
|
|
25
|
+
const sd = Math.max(0, Number(m.signup_days ?? pd) || 0);
|
|
26
|
+
const key = `${pd}@${pt}${st ? `|${sd}@${st}` : ""}`;
|
|
44
27
|
if (seen.has(key))
|
|
45
28
|
continue;
|
|
46
29
|
seen.add(key);
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
pickupDate,
|
|
55
|
-
pickupTime,
|
|
56
|
-
signupDate,
|
|
57
|
-
signupTime,
|
|
58
|
-
deliveryTime,
|
|
59
|
-
label: parts.join(" · "),
|
|
60
|
-
});
|
|
30
|
+
const dt = normalizeTime(m.delivery_time);
|
|
31
|
+
const parts = [`${daysText(pd, "ophalen")} ${pt}`];
|
|
32
|
+
if (st)
|
|
33
|
+
parts.push(`aanmelden ${st}`);
|
|
34
|
+
if (dt)
|
|
35
|
+
parts.push(`aanlevering ${dt}`);
|
|
36
|
+
out.push({ key, deliveryTime: dt, label: parts.join(" · ") });
|
|
61
37
|
}
|
|
62
|
-
out.sort((a, b) => a.pickupDate === b.pickupDate
|
|
63
|
-
? (a.deliveryTime ?? "99:99").localeCompare(b.deliveryTime ?? "99:99")
|
|
64
|
-
: a.pickupDate.localeCompare(b.pickupDate));
|
|
65
38
|
return out;
|
|
66
39
|
}
|
|
67
40
|
async function findOrder(supabase, orderId) {
|
|
68
|
-
// DTO-id kan een Floriday salesOrderId zijn; resolveOrderRow vertaalt dat.
|
|
69
41
|
const row = await resolveOrderRow(supabase, orderId);
|
|
70
42
|
const { data, error } = await supabase
|
|
71
43
|
.from("orders")
|
|
72
|
-
.select("id,
|
|
44
|
+
.select("id, custom_fields")
|
|
73
45
|
.eq("id", row.id)
|
|
74
46
|
.maybeSingle();
|
|
75
47
|
if (error)
|
|
@@ -89,48 +61,47 @@ export const getOrderPickupMoment = createServerFn({ method: "GET" })
|
|
|
89
61
|
order = null;
|
|
90
62
|
}
|
|
91
63
|
if (!order) {
|
|
92
|
-
return {
|
|
64
|
+
return {
|
|
65
|
+
view: departureView(null),
|
|
66
|
+
departure: null,
|
|
67
|
+
selectedKey: null,
|
|
68
|
+
options: [],
|
|
69
|
+
hasCarrier: false,
|
|
70
|
+
deliveryTime: null,
|
|
71
|
+
};
|
|
93
72
|
}
|
|
94
73
|
const cf = (order.custom_fields ?? {});
|
|
95
74
|
const carrierId = cf.carrier ? String(cf.carrier) : null;
|
|
96
75
|
let carrier = null;
|
|
97
76
|
if (carrierId) {
|
|
98
|
-
const { data: c } = await supabase
|
|
99
|
-
.from("carriers")
|
|
100
|
-
.select("delivery_days, signup_time_1, signup_time_2, signup_days_before_delivery, pickup_weekdays, delivery_weekdays, pickup_moments")
|
|
101
|
-
.eq("id", carrierId)
|
|
102
|
-
.maybeSingle();
|
|
77
|
+
const { data: c } = await supabase.from("carriers").select("pickup_moments").eq("id", carrierId).maybeSingle();
|
|
103
78
|
carrier = c ?? null;
|
|
104
79
|
}
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const t = normalizeTime(cf.delivery_time);
|
|
110
|
-
selected = options.find((o) => o.deliveryTime === t) ?? null;
|
|
111
|
-
}
|
|
112
|
-
if (!selected)
|
|
113
|
-
selected = options[0] ?? null;
|
|
80
|
+
const { loadOrderDepartures } = await import("./order-departure.server.js");
|
|
81
|
+
const departure = (await loadOrderDepartures(supabase, [order.id])).get(order.id) ?? null;
|
|
82
|
+
const options = carrierMomentOptions(carrier);
|
|
83
|
+
const selectedKey = departure?.momentKey ?? (cf.pickup_moment ? String(cf.pickup_moment) : null);
|
|
114
84
|
return {
|
|
115
|
-
|
|
116
|
-
|
|
85
|
+
view: departureView(departure),
|
|
86
|
+
departure,
|
|
87
|
+
selectedKey: options.some((o) => o.key === selectedKey) ? selectedKey : null,
|
|
117
88
|
options,
|
|
118
89
|
hasCarrier: !!carrier,
|
|
90
|
+
deliveryTime: normalizeTime(cf.delivery_time),
|
|
119
91
|
};
|
|
120
92
|
});
|
|
121
93
|
export const setOrderPickupMoment = createServerFn({ method: "POST" })
|
|
122
94
|
.middleware([requireSupabaseAuth])
|
|
123
|
-
.inputValidator((input) => z.object({ orderId: z.string().min(1), key: z.string().min(1) }).parse(input))
|
|
95
|
+
.inputValidator((input) => z.object({ orderId: z.string().min(1), key: z.string().min(1).max(64) }).parse(input))
|
|
124
96
|
.handler(async ({ data, context }) => {
|
|
125
97
|
const supabase = context.supabase;
|
|
126
98
|
const order = await findOrder(supabase, data.orderId);
|
|
127
99
|
if (!order)
|
|
128
100
|
throw new Error("Order niet gevonden");
|
|
129
|
-
const deliveryTime = data.key.split("|")[2] || null;
|
|
130
101
|
const cf = { ...(order.custom_fields ?? {}) };
|
|
102
|
+
if (cf.pickup_moment === data.key)
|
|
103
|
+
return { ok: true };
|
|
131
104
|
cf.pickup_moment = data.key;
|
|
132
|
-
if (deliveryTime)
|
|
133
|
-
cf.delivery_time = deliveryTime;
|
|
134
105
|
const { data: updated, error } = await supabase.from("orders")
|
|
135
106
|
.update({ custom_fields: cf })
|
|
136
107
|
.eq("id", order.id)
|
|
@@ -138,5 +109,7 @@ export const setOrderPickupMoment = createServerFn({ method: "POST" })
|
|
|
138
109
|
if (error)
|
|
139
110
|
throw new Error(error.message);
|
|
140
111
|
assertRowsAffected(updated, "Ophaalmoment opslaan");
|
|
112
|
+
const { forgetOrderDeparture } = await import("./order-departure.server.js");
|
|
113
|
+
forgetOrderDeparture(order.id);
|
|
141
114
|
return { ok: true };
|
|
142
115
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"salesorders-list.server.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-list.server.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"salesorders-list.server.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-list.server.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjF,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AA8ID,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,UAAU,EAClB,kBAAkB,GAAE,cAAyB,GAC5C,OAAO,CAAC,UAAU,CAAC,CAimCrB"}
|
|
@@ -12,7 +12,6 @@ import { combineStages } from "./floriday-status.js";
|
|
|
12
12
|
import { combinedCartCount, mergeSummaries, summarize } from "./plan-coverage.js";
|
|
13
13
|
import { resolveOrderNumbers } from "./order-numbers.server.js";
|
|
14
14
|
import { mergeStages, resolveOrderStage } from "./order-status.js";
|
|
15
|
-
import { buildPickupOptions } from "./order-pickup.functions.js";
|
|
16
15
|
import { loadBacklogFlags } from "./order-backlog.server.js";
|
|
17
16
|
const FO_CAP = 20000;
|
|
18
17
|
const LOCAL_CAP = 5000;
|
|
@@ -802,42 +801,7 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
|
|
|
802
801
|
}
|
|
803
802
|
// 12a-ter) Ladingdragers en indelingsstatus komen uit de Engine
|
|
804
803
|
// (logistics_order_plan_coverage), alleen voor de zichtbare rijen — zie stap 14.
|
|
805
|
-
// 12a-bis) Ophaalmoment
|
|
806
|
-
{
|
|
807
|
-
const shortPickup = (dateISO, time) => {
|
|
808
|
-
const [y, m, d] = dateISO.split("-").map(Number);
|
|
809
|
-
const dt = new Date(y ?? 0, (m ?? 1) - 1, d ?? 1);
|
|
810
|
-
const date = Number.isNaN(dt.getTime())
|
|
811
|
-
? dateISO
|
|
812
|
-
: dt
|
|
813
|
-
.toLocaleDateString("nl-NL", { weekday: "short", day: "numeric", month: "short" })
|
|
814
|
-
.replace(/\./g, "");
|
|
815
|
-
return time ? `${date} ${time}` : date;
|
|
816
|
-
};
|
|
817
|
-
const localRowForDto = (o) => o.id.startsWith("local:")
|
|
818
|
-
? (localOrderRows.find((r) => String(r.id) === o.id.slice("local:".length)) ?? null)
|
|
819
|
-
: (localRowByFoId.get(o.id) ?? null);
|
|
820
|
-
for (const o of all) {
|
|
821
|
-
const r = localRowForDto(o);
|
|
822
|
-
if (!r)
|
|
823
|
-
continue;
|
|
824
|
-
const cf = r.custom_fields ?? {};
|
|
825
|
-
const carrier = cf.carrier ? (carrierById.get(String(cf.carrier)) ?? null) : null;
|
|
826
|
-
const deliveryISO = r.delivery_date ? String(r.delivery_date).slice(0, 10) : null;
|
|
827
|
-
const options = buildPickupOptions(carrier, deliveryISO);
|
|
828
|
-
if (options.length === 0)
|
|
829
|
-
continue;
|
|
830
|
-
const storedKey = cf.pickup_moment ? String(cf.pickup_moment) : null;
|
|
831
|
-
let selected = (storedKey ? options.find((op) => op.key === storedKey) : undefined) ?? null;
|
|
832
|
-
if (!selected && cf.delivery_time) {
|
|
833
|
-
const t = normalizeTime(cf.delivery_time);
|
|
834
|
-
selected = options.find((op) => op.deliveryTime === t) ?? null;
|
|
835
|
-
}
|
|
836
|
-
if (!selected)
|
|
837
|
-
selected = options[0];
|
|
838
|
-
o.pickupLabel = shortPickup(selected.pickupDate, selected.pickupTime ?? selected.signupTime);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
804
|
+
// 12a-bis) Ophaalmoment komt uit de Engine, alleen voor zichtbare rijen (stap 14).
|
|
841
805
|
// 12a) Weggehaalde beoordelingsmeldingen (vals alarm) — los vastgelegd,
|
|
842
806
|
// zodat de order zelf niet gewijzigd hoeft te worden.
|
|
843
807
|
{
|
|
@@ -1074,6 +1038,28 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
|
|
|
1074
1038
|
: (localRowByFoId.get(o.id)?.id ? String(localRowByFoId.get(o.id).id) : null);
|
|
1075
1039
|
const ids = visible.map(idFor).filter((v) => !!v);
|
|
1076
1040
|
if (ids.length) {
|
|
1041
|
+
// Ophaalmoment uit de Engine (nooit zelf rekenen).
|
|
1042
|
+
try {
|
|
1043
|
+
const { loadOrderDepartures } = await import("./order-departure.server.js");
|
|
1044
|
+
const { departureView } = await import("./order-departure.js");
|
|
1045
|
+
const deps = await loadOrderDepartures(supabase, ids);
|
|
1046
|
+
for (const o of visible) {
|
|
1047
|
+
const oid = idFor(o);
|
|
1048
|
+
if (!oid)
|
|
1049
|
+
continue;
|
|
1050
|
+
const v = departureView(deps.get(oid));
|
|
1051
|
+
o.pickupLabel = v.short
|
|
1052
|
+
? `${v.short}${v.lateSignup ? " · te laat aangemeld" : ""}`
|
|
1053
|
+
: deps.has(oid)
|
|
1054
|
+
? (v.reason ?? "onbekend")
|
|
1055
|
+
: "onbekend";
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
catch {
|
|
1059
|
+
for (const o of visible)
|
|
1060
|
+
if (idFor(o))
|
|
1061
|
+
o.pickupLabel = "onbekend";
|
|
1062
|
+
}
|
|
1077
1063
|
const coverage = await loadPlanCoverage(supabase, ids, "list");
|
|
1078
1064
|
let failed = 0;
|
|
1079
1065
|
for (const o of visible) {
|