@flowselections/floriday-afhandeling-module 1.0.12 → 1.0.14
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/AutoProcessStatus.d.ts +12 -0
- package/dist-lib/components/afhandeling/AutoProcessStatus.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/AutoProcessStatus.js +103 -0
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts +3 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.js +56 -17
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +96 -4
- package/dist-lib/components/afhandeling/LeveringenPage.js +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.js +2 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts +3 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +58 -17
- package/dist-lib/components/pickstation/KioskControle.d.ts +2 -0
- package/dist-lib/components/pickstation/KioskControle.d.ts.map +1 -0
- package/dist-lib/components/pickstation/KioskControle.js +7 -0
- package/dist-lib/components/pickstation/PakbonTemplate.d.ts +2 -1
- package/dist-lib/components/pickstation/PakbonTemplate.d.ts.map +1 -1
- package/dist-lib/components/pickstation/PakbonTemplate.js +20 -17
- package/dist-lib/components/pickstation/PickstationPage.d.ts +2 -0
- package/dist-lib/components/pickstation/PickstationPage.d.ts.map +1 -0
- package/dist-lib/components/pickstation/PickstationPage.js +266 -0
- package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/AfhandelingSettingsCard.js +14 -2
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +28 -11
- package/dist-lib/index.d.ts +4 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +4 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1243 -63
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1243 -63
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +1243 -63
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1264 -56
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +2483 -111
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.js +28 -1
- package/dist-lib/lib/carrierPlanning.d.ts +25 -0
- package/dist-lib/lib/carrierPlanning.d.ts.map +1 -0
- package/dist-lib/lib/carrierPlanning.js +65 -0
- package/dist-lib/lib/carrierSignupMail.server.d.ts +0 -2
- package/dist-lib/lib/carrierSignupMail.server.d.ts.map +1 -1
- package/dist-lib/lib/carrierSignupMail.server.js +53 -216
- package/dist-lib/lib/carriers.functions.d.ts +5920 -20
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/carriers.functions.js +5 -0
- package/dist-lib/lib/cartAssignments.functions.d.ts +5920 -20
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +11843 -40
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.js +4 -1
- package/dist-lib/lib/cartRescheduling.d.ts.map +1 -1
- package/dist-lib/lib/cartRescheduling.js +8 -6
- package/dist-lib/lib/countries.d.ts +2 -0
- package/dist-lib/lib/countries.d.ts.map +1 -1
- package/dist-lib/lib/countries.js +51 -0
- package/dist-lib/lib/deliveryNotePrint.d.ts +26 -0
- package/dist-lib/lib/deliveryNotePrint.d.ts.map +1 -0
- package/dist-lib/lib/deliveryNotePrint.js +172 -0
- package/dist-lib/lib/floriday.functions.d.ts +1251 -63
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday.functions.js +126 -8
- package/dist-lib/lib/floridayAutoProcess.d.ts +30 -0
- package/dist-lib/lib/floridayAutoProcess.d.ts.map +1 -0
- package/dist-lib/lib/floridayAutoProcess.js +70 -0
- package/dist-lib/lib/pickstationI18n.d.ts +46 -0
- package/dist-lib/lib/pickstationI18n.d.ts.map +1 -1
- package/dist-lib/lib/pickstationI18n.js +251 -0
- package/dist-lib/lib/pickstationOrders.server.d.ts.map +1 -1
- package/dist-lib/lib/pickstationOrders.server.js +56 -19
- package/dist-lib/lib/pickstationTypes.d.ts +2 -0
- package/dist-lib/lib/pickstationTypes.d.ts.map +1 -1
- package/dist-lib/lib/planning.d.ts +34 -0
- package/dist-lib/lib/planning.d.ts.map +1 -1
- package/dist-lib/lib/planning.js +84 -0
- package/package.json +15 -1
|
@@ -17,7 +17,7 @@ async function loadControlPlanningSettings(supabase, userId) {
|
|
|
17
17
|
const pickWeekdays = Array.isArray(settings?.pick_weekdays) && settings.pick_weekdays.length > 0
|
|
18
18
|
? settings.pick_weekdays
|
|
19
19
|
: [1, 2, 3, 4, 5];
|
|
20
|
-
const minWorkdays = Math.max(
|
|
20
|
+
const minWorkdays = Math.max(0, Number(settings?.pick_days_before_transport ?? 1));
|
|
21
21
|
return { pickWeekdays, minWorkdays };
|
|
22
22
|
}
|
|
23
23
|
/** Haal alle karren op die vandaag gepickt / klaargezet hadden moeten worden. */
|
|
@@ -39,6 +39,9 @@ export const getTodaysControlCarts = createServerFn({ method: "GET" })
|
|
|
39
39
|
carrierName: o.carrierName,
|
|
40
40
|
deliveryDate: o.deliveryDate,
|
|
41
41
|
pickupDate: o.pickupDate,
|
|
42
|
+
pickupTime: o.pickupTime,
|
|
43
|
+
country: o.country,
|
|
44
|
+
cratesOnCart: o.cratesOnCart,
|
|
42
45
|
pickDate: o.pickDate,
|
|
43
46
|
printedCount: o.printedCount,
|
|
44
47
|
status: o.status,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cartRescheduling.d.ts","sourceRoot":"","sources":["../../src/lib/cartRescheduling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,eAAe,EAAE,IAAI,CAAC;IACtB,gCAAgC;IAChC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mFAAmF;IACnF,yBAAyB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgClC,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"cartRescheduling.d.ts","sourceRoot":"","sources":["../../src/lib/cartRescheduling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,eAAe,EAAE,IAAI,CAAC;IACtB,gCAAgC;IAChC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mFAAmF;IACnF,yBAAyB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgClC,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CA2DtE"}
|
|
@@ -44,24 +44,26 @@ export function tryReschedule(input) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
const newDate = nextAllowedPickDay(normalize(input.currentPickDate), allowed, input.holidays);
|
|
47
|
+
const minWorkdays = Math.max(0, input.minWorkdaysBeforeDelivery);
|
|
47
48
|
// Uiterste pickdatum: minWorkdaysBeforeDelivery werkdagen vóór levering.
|
|
48
|
-
const latest = subtractWorkdays(delivery,
|
|
49
|
+
const latest = subtractWorkdays(delivery, minWorkdays, input.holidays);
|
|
49
50
|
if (newDate.getTime() > latest.getTime()) {
|
|
50
51
|
return {
|
|
51
52
|
ok: false,
|
|
52
53
|
reason: `Volgende pickdag ${fmt(newDate)} valt na de uiterste pickdatum ${fmt(latest)} voor levering op ${fmt(delivery)}.`,
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
|
-
// Extra check:
|
|
56
|
-
if (newDate.getTime()
|
|
56
|
+
// Extra check: met 0 pickdagen mag picken op de leverdag; anders moet het ervoor liggen.
|
|
57
|
+
if ((minWorkdays === 0 && newDate.getTime() > delivery.getTime()) ||
|
|
58
|
+
(minWorkdays > 0 && newDate.getTime() >= delivery.getTime())) {
|
|
57
59
|
return {
|
|
58
60
|
ok: false,
|
|
59
61
|
reason: `Nieuwe pickdatum ${fmt(newDate)} ligt niet vóór de leverdatum ${fmt(delivery)}.`,
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
|
-
// Sanity: hebben we
|
|
63
|
-
const minRequired = addWorkdays(newDate,
|
|
64
|
-
if (minRequired.getTime() > delivery.getTime()) {
|
|
64
|
+
// Sanity: hebben we voldoende werkdagen tussen pick en levering?
|
|
65
|
+
const minRequired = addWorkdays(newDate, minWorkdays, input.holidays);
|
|
66
|
+
if (minWorkdays > 0 && minRequired.getTime() > delivery.getTime()) {
|
|
65
67
|
return {
|
|
66
68
|
ok: false,
|
|
67
69
|
reason: `Onvoldoende werkdagen tussen pickdatum en leverdatum ${fmt(delivery)}.`,
|
|
@@ -4,4 +4,6 @@ export interface Country {
|
|
|
4
4
|
}
|
|
5
5
|
export declare const COUNTRIES: Country[];
|
|
6
6
|
export declare function countryName(code: string | null | undefined): string;
|
|
7
|
+
/** Normaliseer een landwaarde (code of naam) naar ISO alpha-2, of null. */
|
|
8
|
+
export declare function countryCode(value: string | null | undefined): string | null;
|
|
7
9
|
//# sourceMappingURL=countries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"countries.d.ts","sourceRoot":"","sources":["../../src/lib/countries.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAeD,eAAO,MAAM,SAAS,EAAE,OAAO,EAAqB,CAAC;AAErD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGnE"}
|
|
1
|
+
{"version":3,"file":"countries.d.ts","sourceRoot":"","sources":["../../src/lib/countries.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAeD,eAAO,MAAM,SAAS,EAAE,OAAO,EAAqB,CAAC;AAErD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGnE;AAgCD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAU3E"}
|
|
@@ -45,3 +45,54 @@ export function countryName(code) {
|
|
|
45
45
|
return "";
|
|
46
46
|
return COUNTRIES.find((c) => c.code === code)?.name ?? code;
|
|
47
47
|
}
|
|
48
|
+
// Build a name → ISO alpha-2 map (Dutch + English) once.
|
|
49
|
+
const NAME_TO_CODE = (() => {
|
|
50
|
+
const map = {};
|
|
51
|
+
const add = (name, code) => {
|
|
52
|
+
if (!name)
|
|
53
|
+
return;
|
|
54
|
+
map[name.trim().toLowerCase()] = code;
|
|
55
|
+
};
|
|
56
|
+
let dnNl = null;
|
|
57
|
+
let dnEn = null;
|
|
58
|
+
try {
|
|
59
|
+
dnNl = new Intl.DisplayNames(["nl"], { type: "region" });
|
|
60
|
+
}
|
|
61
|
+
catch { /* ignore */ }
|
|
62
|
+
try {
|
|
63
|
+
dnEn = new Intl.DisplayNames(["en"], { type: "region" });
|
|
64
|
+
}
|
|
65
|
+
catch { /* ignore */ }
|
|
66
|
+
for (const code of CODES) {
|
|
67
|
+
add(dnNl?.of(code), code);
|
|
68
|
+
add(dnEn?.of(code), code);
|
|
69
|
+
add(code, code);
|
|
70
|
+
}
|
|
71
|
+
// Common aliases
|
|
72
|
+
add("holland", "NL");
|
|
73
|
+
add("the netherlands", "NL");
|
|
74
|
+
add("nederland", "NL");
|
|
75
|
+
add("belgië", "BE");
|
|
76
|
+
add("belgie", "BE");
|
|
77
|
+
add("duitsland", "DE");
|
|
78
|
+
add("frankrijk", "FR");
|
|
79
|
+
add("engeland", "GB");
|
|
80
|
+
add("verenigd koninkrijk", "GB");
|
|
81
|
+
add("groot-brittannië", "GB");
|
|
82
|
+
return map;
|
|
83
|
+
})();
|
|
84
|
+
/** Normaliseer een landwaarde (code of naam) naar ISO alpha-2, of null. */
|
|
85
|
+
export function countryCode(value) {
|
|
86
|
+
if (!value)
|
|
87
|
+
return null;
|
|
88
|
+
const trimmed = value.trim();
|
|
89
|
+
if (!trimmed)
|
|
90
|
+
return null;
|
|
91
|
+
if (/^[A-Za-z]{2}$/.test(trimmed)) {
|
|
92
|
+
const up = trimmed.toUpperCase();
|
|
93
|
+
if (CODES.includes(up))
|
|
94
|
+
return up;
|
|
95
|
+
}
|
|
96
|
+
const hit = NAME_TO_CODE[trimmed.toLowerCase()];
|
|
97
|
+
return hit ?? null;
|
|
98
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface DeliveryNoteItem {
|
|
2
|
+
id: string;
|
|
3
|
+
salesOrderId?: string | null;
|
|
4
|
+
deliveryOrderId?: string | null;
|
|
5
|
+
fulfillmentOrderId?: string | null;
|
|
6
|
+
}
|
|
7
|
+
/** Haalt de signed URL van een enkele afleverbrief op. */
|
|
8
|
+
export declare function fetchDeliveryNoteUrl(salesOrderId: string): Promise<string>;
|
|
9
|
+
/** Print een PDF vanaf een (signed) URL via een verborgen iframe. */
|
|
10
|
+
export declare function printPdfFromUrl(url: string): Promise<void>;
|
|
11
|
+
/** Haal en print één afleverbrief. */
|
|
12
|
+
export declare function printDeliveryNote(salesOrderId: string): Promise<void>;
|
|
13
|
+
export interface BulkPrintResult {
|
|
14
|
+
total: number;
|
|
15
|
+
success: number;
|
|
16
|
+
failed: Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
error: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Print meerdere afleverbrieven als één samengevoegde PDF per chunk van 50.
|
|
23
|
+
* Bij ≤50 items: exact één printdialoog.
|
|
24
|
+
*/
|
|
25
|
+
export declare function printDeliveryNotesMerged(items: DeliveryNoteItem[]): Promise<BulkPrintResult>;
|
|
26
|
+
//# sourceMappingURL=deliveryNotePrint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliveryNotePrint.d.ts","sourceRoot":"","sources":["../../src/lib/deliveryNotePrint.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AA0FD,0DAA0D;AAC1D,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BhF;AAED,qEAAqE;AACrE,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhE;AAED,sCAAsC;AACtC,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,gBAAgB,EAAE,GACxB,OAAO,CAAC,eAAe,CAAC,CAuD1B"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// Client-side helpers voor het ophalen en printen van Floriday-afleverbrieven
|
|
2
|
+
// via de gateway-endpoints van de Authenticatie-module.
|
|
3
|
+
// De Authenticatie-module accepteert een Supabase Bearer-token en stuurt
|
|
4
|
+
// CORS-headers, dus we bellen direct cross-origin — geen eigen proxy nodig.
|
|
5
|
+
import { printPdfBase64 } from "../components/pickstation/printDocuments";
|
|
6
|
+
import { supabase } from "../integrations/supabase/client";
|
|
7
|
+
const GATEWAY_BASE = import.meta.env.VITE_AUTH_GATEWAY_URL?.replace(/\/$/, "") ??
|
|
8
|
+
"https://floriday-authenticatie-module.lovable.app";
|
|
9
|
+
let floridayEnvironmentPromise = null;
|
|
10
|
+
async function getFloridayEnvironment() {
|
|
11
|
+
floridayEnvironmentPromise ?? (floridayEnvironmentPromise = Promise.resolve(supabase.from("floriday_settings").select("active_environment").eq("id", 1).maybeSingle()).then(({ data, error }) => {
|
|
12
|
+
if (error) {
|
|
13
|
+
console.warn("[delivery-note-print] active Floriday environment ophalen mislukt", error);
|
|
14
|
+
}
|
|
15
|
+
return data?.active_environment ?? "live";
|
|
16
|
+
}));
|
|
17
|
+
return floridayEnvironmentPromise;
|
|
18
|
+
}
|
|
19
|
+
async function getAccessToken() {
|
|
20
|
+
const { data } = await supabase.auth.getSession();
|
|
21
|
+
const token = data.session?.access_token;
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new Error("Niet ingelogd — kan afleverbrief niet ophalen.");
|
|
24
|
+
}
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
async function postJson(path, body) {
|
|
28
|
+
const token = await getAccessToken();
|
|
29
|
+
const res = await fetch(`${GATEWAY_BASE}${path}`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
Authorization: `Bearer ${token}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify(body),
|
|
36
|
+
});
|
|
37
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
38
|
+
if (!ct.includes("application/json")) {
|
|
39
|
+
throw new Error(`Gateway onbereikbaar (HTTP ${res.status}) — ontving ${ct || "onbekend content-type"}.`);
|
|
40
|
+
}
|
|
41
|
+
const text = await res.text();
|
|
42
|
+
let data = null;
|
|
43
|
+
try {
|
|
44
|
+
data = text ? JSON.parse(text) : null;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
data = { ok: false, error: text };
|
|
48
|
+
}
|
|
49
|
+
return { status: res.status, data: data };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Zoekt delivery-order IDs in de lokale cache voor een gegeven sales-order.
|
|
53
|
+
* De gateway kan een delivery-note alleen genereren als er een delivery-order bestaat;
|
|
54
|
+
* door hier eerst zelf te resolven omzeilen we de "Geen delivery-order beschikbaar" fout
|
|
55
|
+
* wanneer de gateway de koppeling nog niet ziet.
|
|
56
|
+
*/
|
|
57
|
+
async function resolveDeliveryOrderIds(salesOrderId) {
|
|
58
|
+
const { data, error } = await supabase
|
|
59
|
+
.from("floriday_delivery_orders_cache")
|
|
60
|
+
.select("floriday_id, data")
|
|
61
|
+
.contains("data", { fulfillmentRequests: [{ salesOrderId }] });
|
|
62
|
+
if (error) {
|
|
63
|
+
console.warn("[delivery-note-print] delivery-order lookup mislukt", error);
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const ids = new Set();
|
|
67
|
+
for (const row of (data ?? [])) {
|
|
68
|
+
const d = row.data;
|
|
69
|
+
if (d?.isDeleted)
|
|
70
|
+
continue;
|
|
71
|
+
if (d?.fulfillmentRequests?.some((f) => f.salesOrderId === salesOrderId)) {
|
|
72
|
+
ids.add(row.floriday_id);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return [...ids];
|
|
76
|
+
}
|
|
77
|
+
/** Haalt de signed URL van een enkele afleverbrief op. */
|
|
78
|
+
export async function fetchDeliveryNoteUrl(salesOrderId) {
|
|
79
|
+
const environment = await getFloridayEnvironment();
|
|
80
|
+
const deliveryOrderIds = await resolveDeliveryOrderIds(salesOrderId);
|
|
81
|
+
if (deliveryOrderIds.length > 1) {
|
|
82
|
+
throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
|
|
83
|
+
}
|
|
84
|
+
const payload = {
|
|
85
|
+
environment,
|
|
86
|
+
kind: "delivery-note",
|
|
87
|
+
salesOrderId,
|
|
88
|
+
};
|
|
89
|
+
if (deliveryOrderIds[0])
|
|
90
|
+
payload.deliveryOrderId = deliveryOrderIds[0];
|
|
91
|
+
const { status, data } = await postJson("/api/public/gateway/pdf", payload);
|
|
92
|
+
if (status === 409) {
|
|
93
|
+
throw new Error("Deze verkooporder heeft meerdere afleverbrieven — gebruik de dag-print om ze samen af te drukken.");
|
|
94
|
+
}
|
|
95
|
+
if (!data?.ok || !data.url) {
|
|
96
|
+
throw new Error(data?.error ?? `Afleverbrief ophalen mislukt (HTTP ${status})`);
|
|
97
|
+
}
|
|
98
|
+
return data.url;
|
|
99
|
+
}
|
|
100
|
+
/** Print een PDF vanaf een (signed) URL via een verborgen iframe. */
|
|
101
|
+
export async function printPdfFromUrl(url) {
|
|
102
|
+
const res = await fetch(url);
|
|
103
|
+
if (!res.ok)
|
|
104
|
+
throw new Error(`PDF download mislukt (HTTP ${res.status})`);
|
|
105
|
+
const buf = new Uint8Array(await res.arrayBuffer());
|
|
106
|
+
let binary = "";
|
|
107
|
+
const chunk = 0x8000;
|
|
108
|
+
for (let i = 0; i < buf.length; i += chunk) {
|
|
109
|
+
binary += String.fromCharCode(...buf.subarray(i, i + chunk));
|
|
110
|
+
}
|
|
111
|
+
const base64 = btoa(binary);
|
|
112
|
+
await printPdfBase64(base64);
|
|
113
|
+
}
|
|
114
|
+
/** Haal en print één afleverbrief. */
|
|
115
|
+
export async function printDeliveryNote(salesOrderId) {
|
|
116
|
+
const url = await fetchDeliveryNoteUrl(salesOrderId);
|
|
117
|
+
await printPdfFromUrl(url);
|
|
118
|
+
}
|
|
119
|
+
const CHUNK_SIZE = 50;
|
|
120
|
+
/**
|
|
121
|
+
* Print meerdere afleverbrieven als één samengevoegde PDF per chunk van 50.
|
|
122
|
+
* Bij ≤50 items: exact één printdialoog.
|
|
123
|
+
*/
|
|
124
|
+
export async function printDeliveryNotesMerged(items) {
|
|
125
|
+
const valid = items.filter((i) => i.salesOrderId || i.deliveryOrderId || i.fulfillmentOrderId);
|
|
126
|
+
const summary = { total: valid.length, success: 0, failed: [] };
|
|
127
|
+
if (valid.length === 0)
|
|
128
|
+
return summary;
|
|
129
|
+
const environment = await getFloridayEnvironment();
|
|
130
|
+
// Verrijk items met deliveryOrderId uit de lokale cache waar mogelijk,
|
|
131
|
+
// zodat de gateway niet meer op salesOrderId hoeft te zoeken.
|
|
132
|
+
const enriched = [];
|
|
133
|
+
for (const it of valid) {
|
|
134
|
+
if (it.deliveryOrderId || it.fulfillmentOrderId || !it.salesOrderId) {
|
|
135
|
+
enriched.push(it);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const ids = await resolveDeliveryOrderIds(it.salesOrderId);
|
|
139
|
+
if (ids.length === 0) {
|
|
140
|
+
enriched.push(it);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
for (const doId of ids)
|
|
144
|
+
enriched.push({ ...it, deliveryOrderId: doId });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (let i = 0; i < enriched.length; i += CHUNK_SIZE) {
|
|
148
|
+
const chunk = enriched.slice(i, i + CHUNK_SIZE);
|
|
149
|
+
const { status, data } = await postJson("/api/public/gateway/pdf/bulk-merged", {
|
|
150
|
+
environment,
|
|
151
|
+
items: chunk.map((it) => ({
|
|
152
|
+
id: it.id,
|
|
153
|
+
...(it.salesOrderId ? { salesOrderId: it.salesOrderId } : {}),
|
|
154
|
+
...(it.deliveryOrderId ? { deliveryOrderId: it.deliveryOrderId } : {}),
|
|
155
|
+
...(it.fulfillmentOrderId ? { fulfillmentOrderId: it.fulfillmentOrderId } : {}),
|
|
156
|
+
})),
|
|
157
|
+
});
|
|
158
|
+
if (!data?.ok || !data.pdfBase64) {
|
|
159
|
+
const err = data?.error ?? `HTTP ${status}`;
|
|
160
|
+
for (const it of chunk)
|
|
161
|
+
summary.failed.push({ id: it.id, error: err });
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
summary.success += data.success ?? chunk.length;
|
|
165
|
+
for (const r of data.results ?? []) {
|
|
166
|
+
if (!r.ok)
|
|
167
|
+
summary.failed.push({ id: r.id, error: r.error ?? "onbekende fout" });
|
|
168
|
+
}
|
|
169
|
+
await printPdfBase64(data.pdfBase64);
|
|
170
|
+
}
|
|
171
|
+
return summary;
|
|
172
|
+
}
|