@flowselections/floriday-afhandeling-module 1.0.64 → 1.0.66
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 +4 -0
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +26 -11
- package/dist-lib/components/afhandeling/LeveringenPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/LeveringenPage.js +24 -2
- package/dist-lib/components/afhandeling/SignupMailMoments.js +7 -4
- package/dist-lib/components/afhandeling/VervoerderForm.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/VervoerderForm.js +14 -7
- package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/AfhandelingSettingsCard.js +1 -1
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +20 -5
- package/dist-lib/integrations/supabase/types.d.ts +249 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/carrierPlanning.d.ts +4 -0
- package/dist-lib/lib/carrierPlanning.d.ts.map +1 -1
- package/dist-lib/lib/carrierPlanning.js +14 -8
- package/dist-lib/lib/carrierSignup.functions.d.ts +2 -0
- package/dist-lib/lib/carrierSignup.functions.d.ts.map +1 -1
- package/dist-lib/lib/carrierSignup.functions.js +2 -0
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/carriers.functions.js +13 -6
- package/dist-lib/lib/pickWorkdays.d.ts +24 -0
- package/dist-lib/lib/pickWorkdays.d.ts.map +1 -0
- package/dist-lib/lib/pickWorkdays.js +30 -0
- package/dist-lib/lib/pickstationOrders.server.d.ts.map +1 -1
- package/dist-lib/lib/pickstationOrders.server.js +9 -3
- package/dist-lib/lib/planning.d.ts +19 -0
- package/dist-lib/lib/planning.d.ts.map +1 -1
- package/dist-lib/lib/planning.js +58 -11
- package/dist-lib/lib/signupMailText.d.ts.map +1 -1
- package/dist-lib/lib/signupMailText.js +2 -0
- package/package.json +1 -1
|
@@ -18,6 +18,10 @@ export interface CarrierOrderTarget {
|
|
|
18
18
|
city?: string | null;
|
|
19
19
|
}
|
|
20
20
|
export declare function sanitizeWeekdays(input: unknown): number[];
|
|
21
|
+
/**
|
|
22
|
+
* Ophaalmomenten van een vervoerder. Tijden worden nooit aangevuld: een moment
|
|
23
|
+
* zonder aanmeld-, ophaal- of bezorgtijd valt weg en telt niet mee.
|
|
24
|
+
*/
|
|
21
25
|
export declare function normalizePickupMoments(raw: unknown): PickupMoment[];
|
|
22
26
|
export declare function carrierLeadDaysFromMoments(raw: unknown): number;
|
|
23
27
|
export declare function normalizePlanningCarriers<T extends CarrierPlanningInfo>(carriers: T[]): T[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carrierPlanning.d.ts","sourceRoot":"","sources":["../../src/lib/carrierPlanning.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"carrierPlanning.d.ts","sourceRoot":"","sources":["../../src/lib/carrierPlanning.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAIxF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAUzD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CAenE;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAK/D;AAED,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,mBAAmB,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAU3F;AAED,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,mBAAmB,EAClE,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,EAAE,kBAAkB,GACzB,CAAC,GAAG,IAAI,CAiCV"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { matchesServiceArea } from "./geo/euServiceAreas";
|
|
2
2
|
import { countryCode } from "./countries";
|
|
3
|
-
import { DEFAULT_PICKUP_MOMENT } from "./planning";
|
|
3
|
+
import { DEFAULT_PICKUP_MOMENT, isCompleteMoment } from "./planning";
|
|
4
4
|
const DEFAULT_WEEKDAYS = [1, 2, 3, 4, 5];
|
|
5
5
|
export function sanitizeWeekdays(input) {
|
|
6
6
|
if (!Array.isArray(input))
|
|
@@ -10,20 +10,26 @@ export function sanitizeWeekdays(input) {
|
|
|
10
10
|
.filter((n) => Number.isFinite(n) && n >= 1 && n <= 7))).sort((a, b) => a - b);
|
|
11
11
|
return clean.length > 0 ? clean : DEFAULT_WEEKDAYS;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Ophaalmomenten van een vervoerder. Tijden worden nooit aangevuld: een moment
|
|
15
|
+
* zonder aanmeld-, ophaal- of bezorgtijd valt weg en telt niet mee.
|
|
16
|
+
*/
|
|
13
17
|
export function normalizePickupMoments(raw) {
|
|
14
|
-
if (!Array.isArray(raw)
|
|
15
|
-
return [
|
|
16
|
-
return raw
|
|
18
|
+
if (!Array.isArray(raw))
|
|
19
|
+
return [];
|
|
20
|
+
return raw
|
|
21
|
+
.map((m) => {
|
|
17
22
|
const r = (m ?? {});
|
|
18
23
|
return {
|
|
19
24
|
signup_days: Math.max(0, Math.floor(Number(r.signup_days ?? DEFAULT_PICKUP_MOMENT.signup_days) || 0)),
|
|
20
|
-
signup_time:
|
|
25
|
+
signup_time: typeof r.signup_time === "string" ? r.signup_time.trim() : "",
|
|
21
26
|
pickup_days: Math.max(0, Math.floor(Number(r.pickup_days ?? DEFAULT_PICKUP_MOMENT.pickup_days) || 0)),
|
|
22
|
-
pickup_time:
|
|
27
|
+
pickup_time: typeof r.pickup_time === "string" ? r.pickup_time.trim() : "",
|
|
23
28
|
delivery_days: Math.max(0, Math.floor(Number(r.delivery_days ?? DEFAULT_PICKUP_MOMENT.delivery_days) || 0)),
|
|
24
|
-
delivery_time:
|
|
29
|
+
delivery_time: typeof r.delivery_time === "string" ? r.delivery_time.trim() : "",
|
|
25
30
|
};
|
|
26
|
-
})
|
|
31
|
+
})
|
|
32
|
+
.filter(isCompleteMoment);
|
|
27
33
|
}
|
|
28
34
|
export function carrierLeadDaysFromMoments(raw) {
|
|
29
35
|
return normalizePickupMoments(raw).reduce((max, moment) => Math.max(max, moment.signup_days, moment.pickup_days, moment.delivery_days), 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carrierSignup.functions.d.ts","sourceRoot":"","sources":["../../src/lib/carrierSignup.functions.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/G,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"carrierSignup.functions.d.ts","sourceRoot":"","sources":["../../src/lib/carrierSignup.functions.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/G,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAoCD,wGAAwG;AACxG,eAAO,MAAM,mBAAmB;;;;0CAEV;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS;;6BAchD,CAAC;AAEL,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnG;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACrF;AAED,eAAO,MAAM,iBAAiB;;;;0CAER;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE;UAApB,MAAM;QAAM,MAAM;2BAkB5C,CAAC;AAEL,UAAU,QAAQ;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AAQ/E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC5B;AAED,eAAO,MAAM,iBAAiB;;;;0CAnBN,QAAQ,sCAwC5B,CAAC;AAEL,eAAO,MAAM,iBAAiB;;;;0CA1CN,QAAQ;QA6CoB,OAAO;UAAQ,MAAM;GAQrE,CAAC"}
|
|
@@ -30,6 +30,8 @@ async function readStatus(supabase) {
|
|
|
30
30
|
timezone: r.timezone ?? null,
|
|
31
31
|
lastRun: r.last_run ?? null,
|
|
32
32
|
sentToday: Number(r.sent_today ?? 0),
|
|
33
|
+
senderEmail: r.sender_email ?? null,
|
|
34
|
+
purpose: r.purpose ?? null,
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
37
|
/** Leest de status; herstelt de taak (alleen beheerder) als hij ontbreekt terwijl de mail aan staat. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carriers.functions.d.ts","sourceRoot":"","sources":["../../src/lib/carriers.functions.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"carriers.functions.d.ts","sourceRoot":"","sources":["../../src/lib/carriers.functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
|
|
3
|
-
import { DEFAULT_PICKUP_MOMENT } from "./planning";
|
|
3
|
+
import { DEFAULT_PICKUP_MOMENT, isCompleteMoment } from "./planning";
|
|
4
4
|
import { carrierLeadDaysFromMoments } from "./carrierPlanning";
|
|
5
5
|
function clean(obj) {
|
|
6
6
|
const out = {};
|
|
@@ -21,18 +21,20 @@ function sanitizeWeekdays(input) {
|
|
|
21
21
|
.filter((n) => Number.isFinite(n) && n >= 1 && n <= 7))).sort((a, b) => a - b);
|
|
22
22
|
return clean.length > 0 ? clean : DEFAULT_WEEKDAYS_ARR;
|
|
23
23
|
}
|
|
24
|
+
/** Leest ophaalmomenten zonder tijden aan te vullen; lege tijden blijven leeg. */
|
|
24
25
|
function normalizeMoments(raw) {
|
|
25
|
-
if (!Array.isArray(raw)
|
|
26
|
-
return [
|
|
26
|
+
if (!Array.isArray(raw))
|
|
27
|
+
return [];
|
|
27
28
|
return raw.map((m) => {
|
|
28
29
|
const r = (m ?? {});
|
|
30
|
+
const t = (v) => (typeof v === "string" ? v.trim() : "");
|
|
29
31
|
return {
|
|
30
32
|
signup_days: Number(r.signup_days ?? DEFAULT_PICKUP_MOMENT.signup_days),
|
|
31
|
-
signup_time:
|
|
33
|
+
signup_time: t(r.signup_time),
|
|
32
34
|
pickup_days: Number(r.pickup_days ?? DEFAULT_PICKUP_MOMENT.pickup_days),
|
|
33
|
-
pickup_time:
|
|
35
|
+
pickup_time: t(r.pickup_time),
|
|
34
36
|
delivery_days: Number(r.delivery_days ?? DEFAULT_PICKUP_MOMENT.delivery_days),
|
|
35
|
-
delivery_time:
|
|
37
|
+
delivery_time: t(r.delivery_time),
|
|
36
38
|
};
|
|
37
39
|
});
|
|
38
40
|
}
|
|
@@ -109,6 +111,11 @@ export const upsertCarrier = createServerFn({ method: "POST" })
|
|
|
109
111
|
throw new Error("Bedrijfsnaam is verplicht");
|
|
110
112
|
}
|
|
111
113
|
const moments = normalizeMoments(carrier.pickup_moments);
|
|
114
|
+
if (moments.length === 0)
|
|
115
|
+
throw new Error("Voeg minimaal één ophaalmoment toe.");
|
|
116
|
+
if (!moments.every(isCompleteMoment)) {
|
|
117
|
+
throw new Error("Vul bij elk ophaalmoment alle tijden in.");
|
|
118
|
+
}
|
|
112
119
|
const leadDays = carrierLeadDaysFromMoments(moments);
|
|
113
120
|
const signupDays = moments.reduce((max, moment) => Math.max(max, moment.signup_days), 0);
|
|
114
121
|
const payload = clean({
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Laadt de pickwerkdagen uit de Werktijden (afh_pick_workdays →
|
|
3
|
+
* logistics_is_pick_workday, inclusief gesloten afwijkende dagen) en zet ze
|
|
4
|
+
* als enige werkdagkalender voor de planning. Ontbreekt de bron, dan blijft de
|
|
5
|
+
* kalender leeg en wordt er niet gepland (fail closed).
|
|
6
|
+
*/
|
|
7
|
+
type RpcClient = {
|
|
8
|
+
rpc: (fn: string, args: Record<string, unknown>) => PromiseLike<{
|
|
9
|
+
data: unknown;
|
|
10
|
+
error: {
|
|
11
|
+
message: string;
|
|
12
|
+
} | null;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
export declare function pickWorkdayRange(now?: Date): {
|
|
16
|
+
from: string;
|
|
17
|
+
to: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function loadPickWorkdays(client: RpcClient): Promise<{
|
|
20
|
+
available: boolean;
|
|
21
|
+
count: number;
|
|
22
|
+
}>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=pickWorkdays.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickWorkdays.d.ts","sourceRoot":"","sources":["../../src/lib/pickWorkdays.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,KAAK,SAAS,GAAG;IACf,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,WAAW,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACvH,CAAC;AASF,wBAAgB,gBAAgB,CAAC,GAAG,OAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAM/E;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAexG"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { setPickWorkdayCalendar } from "./planning";
|
|
2
|
+
function iso(d) {
|
|
3
|
+
const y = d.getFullYear();
|
|
4
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
5
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
6
|
+
return `${y}-${m}-${day}`;
|
|
7
|
+
}
|
|
8
|
+
export function pickWorkdayRange(now = new Date()) {
|
|
9
|
+
const from = new Date(now);
|
|
10
|
+
from.setDate(from.getDate() - 120);
|
|
11
|
+
const to = new Date(now);
|
|
12
|
+
to.setDate(to.getDate() + 270);
|
|
13
|
+
return { from: iso(from), to: iso(to) };
|
|
14
|
+
}
|
|
15
|
+
export async function loadPickWorkdays(client) {
|
|
16
|
+
const { from, to } = pickWorkdayRange();
|
|
17
|
+
const { data, error } = await client.rpc("afh_pick_workdays", { p_from: from, p_to: to });
|
|
18
|
+
if (error) {
|
|
19
|
+
setPickWorkdayCalendar(null);
|
|
20
|
+
throw new Error(error.message);
|
|
21
|
+
}
|
|
22
|
+
const res = (data ?? {});
|
|
23
|
+
if (!res.available) {
|
|
24
|
+
setPickWorkdayCalendar(null);
|
|
25
|
+
return { available: false, count: 0 };
|
|
26
|
+
}
|
|
27
|
+
const workdays = Array.isArray(res.workdays) ? res.workdays : [];
|
|
28
|
+
setPickWorkdayCalendar({ workdays, from, to });
|
|
29
|
+
return { available: true, count: workdays.length };
|
|
30
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pickstationOrders.server.d.ts","sourceRoot":"","sources":["../../src/lib/pickstationOrders.server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAgBrD,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA8P5E,wBAAsB,2BAA2B,CAC/C,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,OAAO,CAAC,gBAAgB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"pickstationOrders.server.d.ts","sourceRoot":"","sources":["../../src/lib/pickstationOrders.server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAgBrD,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA8P5E,wBAAsB,2BAA2B,CAC/C,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8W7B;AAED,wBAAsB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC,CAER;AAED,kFAAkF;AAClF,wBAAsB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC,CAGR;AAED,wBAAsB,aAAa,CACjC,WAAW,EAAE,UAAU,GAAG,QAAQ,EAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,EACjE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Uses the publishable-key Supabase client + SECURITY DEFINER RPCs so the
|
|
3
3
|
// public Pickstation works without a service-role key.
|
|
4
4
|
import { createClient } from "@supabase/supabase-js";
|
|
5
|
-
import { calculateOrderPlanning, distributePickDates,
|
|
5
|
+
import { calculateOrderPlanning, distributePickDates, } from "./planning";
|
|
6
6
|
import { normalizePickupMoments, normalizePlanningCarriers, sanitizeWeekdays, selectCarrierForTarget, } from "./carrierPlanning";
|
|
7
|
+
import { loadPickWorkdays } from "./pickWorkdays";
|
|
7
8
|
const LOG_SCOPE = "[pickstation]";
|
|
8
9
|
function debug(action, details) {
|
|
9
10
|
console.info(`${LOG_SCOPE} ${action}`, {
|
|
@@ -164,6 +165,11 @@ export async function loadTodaysPickstationOrders(client) {
|
|
|
164
165
|
const [settingsRes, ordersRes] = await Promise.all([
|
|
165
166
|
supabase.rpc("pickstation_get_planning_context"),
|
|
166
167
|
supabase.rpc("pickstation_get_orders_raw"),
|
|
168
|
+
// Werkdagen uitsluitend uit de Werktijden; mislukt dit, dan wordt er niet gepland.
|
|
169
|
+
loadPickWorkdays(supabase).catch((e) => {
|
|
170
|
+
warn("pick workdays load failed", { message: e instanceof Error ? e.message : String(e) });
|
|
171
|
+
return null;
|
|
172
|
+
}),
|
|
167
173
|
]);
|
|
168
174
|
if (settingsRes.error) {
|
|
169
175
|
errorLog("settings rpc failed", new Error(settingsRes.error.message), {
|
|
@@ -236,7 +242,7 @@ export async function loadTodaysPickstationOrders(client) {
|
|
|
236
242
|
province: pickProvince(data),
|
|
237
243
|
city: pickCity(data),
|
|
238
244
|
});
|
|
239
|
-
const pickupMoments = carrier ? normalizePickupMoments(carrier.pickup_moments) : [
|
|
245
|
+
const pickupMoments = carrier ? normalizePickupMoments(carrier.pickup_moments) : [];
|
|
240
246
|
const planning = calculateOrderPlanning(deliveryDate, {
|
|
241
247
|
pickupMoments,
|
|
242
248
|
pickDurationWorkdays: pickDays,
|
|
@@ -286,7 +292,7 @@ export async function loadTodaysPickstationOrders(client) {
|
|
|
286
292
|
province: target.province,
|
|
287
293
|
city: target.city,
|
|
288
294
|
});
|
|
289
|
-
const pickupMoments = carrier ? normalizePickupMoments(carrier.pickup_moments) : [
|
|
295
|
+
const pickupMoments = carrier ? normalizePickupMoments(carrier.pickup_moments) : [];
|
|
290
296
|
const planning = calculateOrderPlanning(row.delivery_date, {
|
|
291
297
|
pickupMoments,
|
|
292
298
|
pickDurationWorkdays: pickDays,
|
|
@@ -20,7 +20,21 @@ export interface PickupMoment {
|
|
|
20
20
|
/** Bezorgtijd ("HH:MM"). */
|
|
21
21
|
delivery_time: string;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Leeg sjabloon voor een nieuw ophaalmoment: werkdagen ingevuld, tijden leeg.
|
|
25
|
+
* Er wordt nooit stil een tijd aangenomen; een moment zonder tijden telt niet mee.
|
|
26
|
+
*/
|
|
23
27
|
export declare const DEFAULT_PICKUP_MOMENT: PickupMoment;
|
|
28
|
+
export declare function isValidTime(t: string | null | undefined): boolean;
|
|
29
|
+
/** Een ophaalmoment telt pas mee als aanmeld-, ophaal- en bezorgtijd zijn gekozen. */
|
|
30
|
+
export declare function isCompleteMoment(m: PickupMoment): boolean;
|
|
31
|
+
/** Zet de pickwerkdagen (JJJJ-MM-DD) voor een periode; null wist de kalender. */
|
|
32
|
+
export declare function setPickWorkdayCalendar(cal: {
|
|
33
|
+
workdays: string[];
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
} | null): void;
|
|
37
|
+
export declare function isPickWorkdayCalendarReady(): boolean;
|
|
24
38
|
export interface PlanningRules {
|
|
25
39
|
/** Beschikbare ophaalmomenten — minimaal één. */
|
|
26
40
|
pickupMoments: PickupMoment[];
|
|
@@ -87,6 +101,11 @@ export declare function normalizeWeekdays(days: number[] | undefined | null): nu
|
|
|
87
101
|
* of naar de toekomst opschuiven.
|
|
88
102
|
*/
|
|
89
103
|
export declare function snapToAllowedDay(date: Date, allowedWeekdays: number[] | undefined, direction: "backward" | "forward", holidays?: Date[]): Date;
|
|
104
|
+
/**
|
|
105
|
+
* Werkdag volgens de Werktijden (inclusief gesloten afwijkende dagen).
|
|
106
|
+
* Geen kalender of datum buiten de geladen periode → geen werkdag (fail closed).
|
|
107
|
+
* `holidays` blijft alleen voor oude aanroepers; niemand geeft hem nog mee.
|
|
108
|
+
*/
|
|
90
109
|
export declare function isWorkday(d: Date, holidays?: Date[]): boolean;
|
|
91
110
|
export declare function subtractWorkdays(date: Date, n: number, holidays?: Date[]): Date;
|
|
92
111
|
export declare function addWorkdays(date: Date, n: number, holidays?: Date[]): Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../src/lib/planning.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,qBAAqB,EAAE,YAOnC,CAAC;
|
|
1
|
+
{"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../src/lib/planning.ts"],"names":[],"mappings":"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"}
|
package/dist-lib/lib/planning.js
CHANGED
|
@@ -6,14 +6,44 @@
|
|
|
6
6
|
* ophalen, bezorgen) hoeveel werkdagen vóór de bezorgdag de stap plaatsvindt
|
|
7
7
|
* en op welk tijdstip.
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Leeg sjabloon voor een nieuw ophaalmoment: werkdagen ingevuld, tijden leeg.
|
|
11
|
+
* Er wordt nooit stil een tijd aangenomen; een moment zonder tijden telt niet mee.
|
|
12
|
+
*/
|
|
9
13
|
export const DEFAULT_PICKUP_MOMENT = {
|
|
10
14
|
signup_days: 2,
|
|
11
|
-
signup_time: "
|
|
15
|
+
signup_time: "",
|
|
12
16
|
pickup_days: 1,
|
|
13
|
-
pickup_time: "
|
|
17
|
+
pickup_time: "",
|
|
14
18
|
delivery_days: 0,
|
|
15
|
-
delivery_time: "
|
|
19
|
+
delivery_time: "",
|
|
16
20
|
};
|
|
21
|
+
const TIME_RE = /^\d{1,2}:\d{2}$/;
|
|
22
|
+
export function isValidTime(t) {
|
|
23
|
+
return typeof t === "string" && TIME_RE.test(t.trim());
|
|
24
|
+
}
|
|
25
|
+
/** Een ophaalmoment telt pas mee als aanmeld-, ophaal- en bezorgtijd zijn gekozen. */
|
|
26
|
+
export function isCompleteMoment(m) {
|
|
27
|
+
return isValidTime(m.signup_time) && isValidTime(m.pickup_time) && isValidTime(m.delivery_time);
|
|
28
|
+
}
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Werkdagen: één bron, de Werktijden (logistics_is_pick_workday via
|
|
31
|
+
// afh_pick_workdays). Zonder geladen kalender wordt er niet gepland.
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
let pickWorkdayCalendar = null;
|
|
34
|
+
function dateKey(d) {
|
|
35
|
+
const y = d.getFullYear();
|
|
36
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
37
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
38
|
+
return `${y}-${m}-${day}`;
|
|
39
|
+
}
|
|
40
|
+
/** Zet de pickwerkdagen (JJJJ-MM-DD) voor een periode; null wist de kalender. */
|
|
41
|
+
export function setPickWorkdayCalendar(cal) {
|
|
42
|
+
pickWorkdayCalendar = cal ? { days: new Set(cal.workdays), from: cal.from, to: cal.to } : null;
|
|
43
|
+
}
|
|
44
|
+
export function isPickWorkdayCalendarReady() {
|
|
45
|
+
return pickWorkdayCalendar !== null;
|
|
46
|
+
}
|
|
17
47
|
/** ISO-dagnummer 1=ma … 7=zo van een Date. */
|
|
18
48
|
export function isoWeekday(d) {
|
|
19
49
|
const g = d.getDay();
|
|
@@ -51,9 +81,18 @@ function sameDay(a, b) {
|
|
|
51
81
|
a.getMonth() === b.getMonth() &&
|
|
52
82
|
a.getDate() === b.getDate());
|
|
53
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Werkdag volgens de Werktijden (inclusief gesloten afwijkende dagen).
|
|
86
|
+
* Geen kalender of datum buiten de geladen periode → geen werkdag (fail closed).
|
|
87
|
+
* `holidays` blijft alleen voor oude aanroepers; niemand geeft hem nog mee.
|
|
88
|
+
*/
|
|
54
89
|
export function isWorkday(d, holidays) {
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
if (!pickWorkdayCalendar)
|
|
91
|
+
return false;
|
|
92
|
+
const key = dateKey(d);
|
|
93
|
+
if (key < pickWorkdayCalendar.from || key > pickWorkdayCalendar.to)
|
|
94
|
+
return false;
|
|
95
|
+
if (!pickWorkdayCalendar.days.has(key))
|
|
57
96
|
return false;
|
|
58
97
|
if (holidays && holidays.some((h) => sameDay(h, d)))
|
|
59
98
|
return false;
|
|
@@ -67,7 +106,8 @@ function normalize(d) {
|
|
|
67
106
|
export function subtractWorkdays(date, n, holidays) {
|
|
68
107
|
const out = normalize(date);
|
|
69
108
|
let remaining = Math.max(0, Math.floor(n));
|
|
70
|
-
|
|
109
|
+
let guard = 0;
|
|
110
|
+
while (remaining > 0 && guard++ < 60) {
|
|
71
111
|
out.setDate(out.getDate() - 1);
|
|
72
112
|
if (isWorkday(out, holidays))
|
|
73
113
|
remaining--;
|
|
@@ -77,7 +117,8 @@ export function subtractWorkdays(date, n, holidays) {
|
|
|
77
117
|
export function addWorkdays(date, n, holidays) {
|
|
78
118
|
const out = normalize(date);
|
|
79
119
|
let remaining = Math.max(0, Math.floor(n));
|
|
80
|
-
|
|
120
|
+
let guard = 0;
|
|
121
|
+
while (remaining > 0 && guard++ < 60) {
|
|
81
122
|
out.setDate(out.getDate() + 1);
|
|
82
123
|
if (isWorkday(out, holidays))
|
|
83
124
|
remaining--;
|
|
@@ -137,7 +178,7 @@ export function getSignupDeadline(deliveryDate, moment, holidays) {
|
|
|
137
178
|
*/
|
|
138
179
|
export function selectPickupMoment(deliveryDate, orderCreatedAt, moments, holidays) {
|
|
139
180
|
if (moments.length === 0)
|
|
140
|
-
return DEFAULT_PICKUP_MOMENT;
|
|
181
|
+
return DEFAULT_PICKUP_MOMENT; // aanroepers controleren vooraf
|
|
141
182
|
if (moments.length === 1)
|
|
142
183
|
return moments[0];
|
|
143
184
|
const now = orderCreatedAt ?? new Date();
|
|
@@ -160,7 +201,7 @@ export function calculateEarliestDeliveryDate(rules) {
|
|
|
160
201
|
? rules.orderCreatedAt
|
|
161
202
|
: new Date(rules.orderCreatedAt);
|
|
162
203
|
const base = Number.isNaN(orderCreated.getTime()) ? new Date() : orderCreated;
|
|
163
|
-
const moments = rules.pickupMoments.
|
|
204
|
+
const moments = rules.pickupMoments.filter(isCompleteMoment);
|
|
164
205
|
const leadDays = moments.reduce((max, moment) => Math.max(max, moment.signup_days, moment.pickup_days, moment.delivery_days), 0);
|
|
165
206
|
const workdaysToAdd = Math.max(0, Math.floor(rules.pickDurationWorkdays)) + leadDays;
|
|
166
207
|
const raw = addWorkdays(base, workdaysToAdd, rules.holidays);
|
|
@@ -185,8 +226,14 @@ export function calculateOrderPlanning(deliveryDate, rules) {
|
|
|
185
226
|
const d = typeof deliveryDate === "string" ? new Date(deliveryDate) : deliveryDate;
|
|
186
227
|
if (Number.isNaN(d.getTime()))
|
|
187
228
|
return null;
|
|
229
|
+
// Zonder werkdagen uit de Werktijden of zonder volledig ingevuld ophaalmoment
|
|
230
|
+
// wordt er niet gepland: nooit stil terugvallen op ma–vr of een standaardtijd.
|
|
231
|
+
if (!isPickWorkdayCalendarReady())
|
|
232
|
+
return null;
|
|
188
233
|
const requested = normalize(d);
|
|
189
|
-
const moments = rules.pickupMoments.
|
|
234
|
+
const moments = rules.pickupMoments.filter(isCompleteMoment);
|
|
235
|
+
if (moments.length === 0)
|
|
236
|
+
return null;
|
|
190
237
|
const orderCreated = rules.orderCreatedAt == null
|
|
191
238
|
? null
|
|
192
239
|
: rules.orderCreatedAt instanceof Date
|
|
@@ -299,7 +346,7 @@ export function distributePickDates(items, options) {
|
|
|
299
346
|
const carts = getCarts(item);
|
|
300
347
|
// Kandidaten in chronologische volgorde — alleen toegestane pickdagen.
|
|
301
348
|
const allowedSet = new Set(normalizeWeekdays(options.pickWeekdays));
|
|
302
|
-
const isAllowed = (d) => allowedSet.has(isoWeekday(d)) &&
|
|
349
|
+
const isAllowed = (d) => allowedSet.has(isoWeekday(d)) && isWorkday(d, options.holidays);
|
|
303
350
|
const candidates = [];
|
|
304
351
|
if (distribute) {
|
|
305
352
|
let cursor = deadline;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signupMailText.d.ts","sourceRoot":"","sources":["../../src/lib/signupMailText.ts"],"names":[],"mappings":"AACA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"signupMailText.d.ts","sourceRoot":"","sources":["../../src/lib/signupMailText.ts"],"names":[],"mappings":"AACA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAyBjF;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGjF;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGpF"}
|
|
@@ -11,6 +11,8 @@ export function signupReasonText(reason) {
|
|
|
11
11
|
return "Het verzendadres voor ‘Aanmeldmail vervoerders’ moet opnieuw worden gekoppeld bij E-mailkoppeling.";
|
|
12
12
|
case "no_timezone":
|
|
13
13
|
return "De tijdzone van de vestiging ontbreekt. Stel die in bij Werktijden; tot dan gaan er geen aanmeldmails weg.";
|
|
14
|
+
case "no_pick_workdays":
|
|
15
|
+
return "Er zijn geen werkdagen ingesteld bij Werktijden; de aanmeldmail kan niet worden berekend.";
|
|
14
16
|
case "mail_disabled":
|
|
15
17
|
return "De aanmeldmail staat uit.";
|
|
16
18
|
case "group_not_found":
|