@flowselections/floriday-afhandeling-module 1.0.38 → 1.0.39
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/ControleLijstPrint.js +54 -54
- package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControlePage.js +1 -3
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +5 -38
- package/dist-lib/components/afhandeling/LeveringenPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/LeveringenPage.js +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts +1 -3
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +6 -57
- package/dist-lib/components/pickstation/PakbonTemplate.js +70 -70
- package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/AfhandelingSettingsCard.js +4 -55
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +6 -27
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +108 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +108 -1
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +108 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +111 -1
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +226 -4
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/carrierSignupMail.server.js +26 -26
- package/dist-lib/lib/carriers.functions.d.ts +540 -5
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.d.ts +540 -5
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +1110 -20
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday.functions.d.ts +109 -2
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/printing.d.ts +2 -11
- package/dist-lib/lib/printing.d.ts.map +1 -1
- package/dist-lib/lib/printing.js +8 -64
- package/package.json +1 -1
|
@@ -70,62 +70,62 @@ export function renderControleLijstHtml(carts, lang = "nl") {
|
|
|
70
70
|
});
|
|
71
71
|
const rows = sorted.length
|
|
72
72
|
? sorted
|
|
73
|
-
.map(({ cart: c, klaarzet }) => `
|
|
74
|
-
<tr>
|
|
75
|
-
<td class="mono bold">${esc(c.cartNumber ?? "—")}</td>
|
|
76
|
-
<td class="right">${esc(c.cratesOnCart ?? "—")}</td>
|
|
77
|
-
<td class="bold">${esc(countryCode(c.country) ?? c.country ?? "—")}</td>
|
|
78
|
-
<td class="bold">${esc(klaarzet.label)}</td>
|
|
79
|
-
<td>${esc(statusLabel(c.status, c.printedCount))}</td>
|
|
73
|
+
.map(({ cart: c, klaarzet }) => `
|
|
74
|
+
<tr>
|
|
75
|
+
<td class="mono bold">${esc(c.cartNumber ?? "—")}</td>
|
|
76
|
+
<td class="right">${esc(c.cratesOnCart ?? "—")}</td>
|
|
77
|
+
<td class="bold">${esc(countryCode(c.country) ?? c.country ?? "—")}</td>
|
|
78
|
+
<td class="bold">${esc(klaarzet.label)}</td>
|
|
79
|
+
<td>${esc(statusLabel(c.status, c.printedCount))}</td>
|
|
80
80
|
</tr>`)
|
|
81
81
|
.join("")
|
|
82
82
|
: `<tr><td colspan="5" class="empty">${esc(t.noCartsToday)}</td></tr>`;
|
|
83
|
-
return `<!DOCTYPE html>
|
|
84
|
-
<html lang="${esc(lang)}">
|
|
85
|
-
<head>
|
|
86
|
-
<meta charset="utf-8" />
|
|
87
|
-
<title>${esc(t.checklistTitle)}</title>
|
|
88
|
-
<style>
|
|
89
|
-
@page { size: A4 portrait; margin: 12mm; }
|
|
90
|
-
body { font-family: Arial, Helvetica, sans-serif; color: #000; margin: 0; }
|
|
91
|
-
h1 { font-size: 20px; margin: 0; }
|
|
92
|
-
.head { display: flex; align-items: baseline; justify-content: space-between;
|
|
93
|
-
border-bottom: 1px solid #000; padding-bottom: 6px; margin-bottom: 12px; }
|
|
94
|
-
.total { font-size: 12px; margin-bottom: 10px; }
|
|
95
|
-
table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
|
96
|
-
th { text-align: left; border-bottom: 1px solid #000; padding: 3px 6px 3px 0; }
|
|
97
|
-
td { border-bottom: 1px solid #ccc; padding: 6px 6px 6px 0; white-space: nowrap; }
|
|
98
|
-
td.right, th.right { text-align: right; }
|
|
99
|
-
.mono { font-family: "Courier New", monospace; }
|
|
100
|
-
.bold { font-weight: 700; }
|
|
101
|
-
.empty { text-align: center; color: #666; padding: 24px 0; border: none; }
|
|
102
|
-
.sign { margin-top: 24px; font-size: 11px; }
|
|
103
|
-
.sign div { margin-top: 8px; }
|
|
104
|
-
.line { display: inline-block; border-bottom: 1px solid #000; width: 220px; }
|
|
105
|
-
tr { page-break-inside: avoid; }
|
|
106
|
-
thead { display: table-header-group; }
|
|
107
|
-
</style>
|
|
108
|
-
</head>
|
|
109
|
-
<body>
|
|
110
|
-
<div class="head"><h1>${esc(t.checklistTitle)}</h1><div>${esc(today)}</div></div>
|
|
111
|
-
<div class="total">${esc(t.totalCarts)}: <strong>${carts.length}</strong></div>
|
|
112
|
-
<table>
|
|
113
|
-
<thead>
|
|
114
|
-
<tr>
|
|
115
|
-
<th>${esc(t.colKarnr)}</th>
|
|
116
|
-
<th class="right">${esc(t.colFusten)}</th>
|
|
117
|
-
<th>${esc(t.colLand)}</th>
|
|
118
|
-
<th>${esc(t.colKlaarzetten)}</th>
|
|
119
|
-
<th>${esc(t.colStatus)}</th>
|
|
120
|
-
</tr>
|
|
121
|
-
</thead>
|
|
122
|
-
<tbody>${rows}</tbody>
|
|
123
|
-
</table>
|
|
124
|
-
<div class="sign">
|
|
125
|
-
<div>${esc(t.checkedBy)}: <span class="line"></span></div>
|
|
126
|
-
<div>${esc(t.dateTime)}: <span class="line"></span></div>
|
|
127
|
-
<div>${esc(t.signature)}: <span class="line"></span></div>
|
|
128
|
-
</div>
|
|
129
|
-
</body>
|
|
83
|
+
return `<!DOCTYPE html>
|
|
84
|
+
<html lang="${esc(lang)}">
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="utf-8" />
|
|
87
|
+
<title>${esc(t.checklistTitle)}</title>
|
|
88
|
+
<style>
|
|
89
|
+
@page { size: A4 portrait; margin: 12mm; }
|
|
90
|
+
body { font-family: Arial, Helvetica, sans-serif; color: #000; margin: 0; }
|
|
91
|
+
h1 { font-size: 20px; margin: 0; }
|
|
92
|
+
.head { display: flex; align-items: baseline; justify-content: space-between;
|
|
93
|
+
border-bottom: 1px solid #000; padding-bottom: 6px; margin-bottom: 12px; }
|
|
94
|
+
.total { font-size: 12px; margin-bottom: 10px; }
|
|
95
|
+
table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
|
96
|
+
th { text-align: left; border-bottom: 1px solid #000; padding: 3px 6px 3px 0; }
|
|
97
|
+
td { border-bottom: 1px solid #ccc; padding: 6px 6px 6px 0; white-space: nowrap; }
|
|
98
|
+
td.right, th.right { text-align: right; }
|
|
99
|
+
.mono { font-family: "Courier New", monospace; }
|
|
100
|
+
.bold { font-weight: 700; }
|
|
101
|
+
.empty { text-align: center; color: #666; padding: 24px 0; border: none; }
|
|
102
|
+
.sign { margin-top: 24px; font-size: 11px; }
|
|
103
|
+
.sign div { margin-top: 8px; }
|
|
104
|
+
.line { display: inline-block; border-bottom: 1px solid #000; width: 220px; }
|
|
105
|
+
tr { page-break-inside: avoid; }
|
|
106
|
+
thead { display: table-header-group; }
|
|
107
|
+
</style>
|
|
108
|
+
</head>
|
|
109
|
+
<body>
|
|
110
|
+
<div class="head"><h1>${esc(t.checklistTitle)}</h1><div>${esc(today)}</div></div>
|
|
111
|
+
<div class="total">${esc(t.totalCarts)}: <strong>${carts.length}</strong></div>
|
|
112
|
+
<table>
|
|
113
|
+
<thead>
|
|
114
|
+
<tr>
|
|
115
|
+
<th>${esc(t.colKarnr)}</th>
|
|
116
|
+
<th class="right">${esc(t.colFusten)}</th>
|
|
117
|
+
<th>${esc(t.colLand)}</th>
|
|
118
|
+
<th>${esc(t.colKlaarzetten)}</th>
|
|
119
|
+
<th>${esc(t.colStatus)}</th>
|
|
120
|
+
</tr>
|
|
121
|
+
</thead>
|
|
122
|
+
<tbody>${rows}</tbody>
|
|
123
|
+
</table>
|
|
124
|
+
<div class="sign">
|
|
125
|
+
<div>${esc(t.checkedBy)}: <span class="line"></span></div>
|
|
126
|
+
<div>${esc(t.dateTime)}: <span class="line"></span></div>
|
|
127
|
+
<div>${esc(t.signature)}: <span class="line"></span></div>
|
|
128
|
+
</div>
|
|
129
|
+
</body>
|
|
130
130
|
</html>`;
|
|
131
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AAmHA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BAyzBpE"}
|
|
@@ -9,7 +9,6 @@ import { useServerFn } from "@tanstack/react-start";
|
|
|
9
9
|
import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, saveControlDraft, } from "../../lib/cartControl.functions";
|
|
10
10
|
import { renderControleLijstHtml } from "./ControleLijstPrint";
|
|
11
11
|
import { printHtmlDocument, printFoutMelding } from "../../lib/printing";
|
|
12
|
-
import { WerkplekWaarschuwing, useWerkplek } from "./WerkplekWaarschuwing";
|
|
13
12
|
function fmtDate(iso) {
|
|
14
13
|
if (!iso)
|
|
15
14
|
return "—";
|
|
@@ -63,7 +62,6 @@ export function ControlePage({ onExit } = {}) {
|
|
|
63
62
|
const [checked, setChecked] = useState(new Set());
|
|
64
63
|
const [cartStates, setCartStates] = useState({});
|
|
65
64
|
const [printBezig, setPrintBezig] = useState(false);
|
|
66
|
-
const werkplek = useWerkplek();
|
|
67
65
|
const [result, setResult] = useState(null);
|
|
68
66
|
const [pendingProposal, setPendingProposal] = useState(null);
|
|
69
67
|
const [confirmApproval, setConfirmApproval] = useState(null);
|
|
@@ -416,7 +414,7 @@ export function ControlePage({ onExit } = {}) {
|
|
|
416
414
|
supabase.removeChannel(channel);
|
|
417
415
|
};
|
|
418
416
|
}, [qc]);
|
|
419
|
-
return (_jsxs("main", { className: "p-6 space-y-6", children: [
|
|
417
|
+
return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Controle karren" }), _jsxs("p", { className: "text-sm text-muted-foreground", children: ["Dagelijkse eindcontrole \u2014 vandaag ", new Date().toLocaleDateString("nl-NL")] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", disabled: printBezig || carts.length === 0, onClick: async () => {
|
|
420
418
|
setPrintBezig(true);
|
|
421
419
|
try {
|
|
422
420
|
await printHtmlDocument({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAsCjE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAID,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,oBAAoB,sCAgF1F"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
@@ -8,8 +8,6 @@ import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter,
|
|
|
8
8
|
import { isSameDay } from "../../lib/pickDate";
|
|
9
9
|
import { getOrderLines, } from "../../lib/cartAssignments.functions";
|
|
10
10
|
import { printLayoutDocument, printFoutMelding } from "../../lib/printing";
|
|
11
|
-
import { WerkplekWaarschuwing, useWerkplek } from "./WerkplekWaarschuwing";
|
|
12
|
-
import { printDeliveryNotesMerged } from "../../lib/deliveryNotePrint";
|
|
13
11
|
import { AutoProcessStatus } from "./AutoProcessStatus";
|
|
14
12
|
import { CapacityWarning } from "./CapacityWarning";
|
|
15
13
|
import { useCapacityCheck } from "../../hooks/useCapacityCheck";
|
|
@@ -18,11 +16,6 @@ import { VerzetOrderDialog } from "./VerzetOrderDialog";
|
|
|
18
16
|
import { setPickDay } from "../../lib/logisticsEngine/reschedule";
|
|
19
17
|
import { clearDayStaffPlan, computeCapacity, getDayStaffPlan, getEngineStaffDefaults, setDayStaffPlan, toDateKey, } from "../../lib/logisticsEngine/staffPlanning";
|
|
20
18
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { dateStyle: "full" });
|
|
21
|
-
/** Eén melding per dagdialoog zolang de werkplek niet is ingesteld. */
|
|
22
|
-
function DagWerkplekBanner() {
|
|
23
|
-
const werkplek = useWerkplek();
|
|
24
|
-
return _jsx(WerkplekWaarschuwing, { werkplek: werkplek });
|
|
25
|
-
}
|
|
26
19
|
export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
27
20
|
if (!date)
|
|
28
21
|
return null;
|
|
@@ -65,7 +58,7 @@ export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
|
65
58
|
runningIdx += a.cartCount;
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsxs(ResponsiveDialogBody, { children: [_jsx(
|
|
61
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsxs(ResponsiveDialogBody, { children: [_jsx(DayCapacityWarning, { date: date }), _jsx(BezettingCard, { date: date, cartsToday: cartRows.length }), _jsxs(Tabs, { defaultValue: "bestellingen", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows }) })] })] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Sluiten" }) })] }) }));
|
|
69
62
|
}
|
|
70
63
|
function BezettingCard({ date, cartsToday }) {
|
|
71
64
|
const queryClient = useQueryClient();
|
|
@@ -152,7 +145,6 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
152
145
|
const [open, setOpen] = useState(false);
|
|
153
146
|
const [printing, setPrinting] = useState(false);
|
|
154
147
|
const [verzetOpen, setVerzetOpen] = useState(false);
|
|
155
|
-
const werkplek = useWerkplek();
|
|
156
148
|
const source = p.order.source;
|
|
157
149
|
const fetchLines = useServerFn(getOrderLines);
|
|
158
150
|
const linesQuery = useQuery({
|
|
@@ -217,37 +209,12 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
217
209
|
console.warn("[print-all] pakbon mislukt", cartNumber, err);
|
|
218
210
|
}
|
|
219
211
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const salesOrderId = p.order.salesOrderId ?? (source === "floriday" ? p.order.id : null);
|
|
223
|
-
if (salesOrderId) {
|
|
224
|
-
try {
|
|
225
|
-
const res = await printDeliveryNotesMerged([
|
|
226
|
-
{ id: p.order.id, salesOrderId },
|
|
227
|
-
]);
|
|
228
|
-
deliveryOk = res.success;
|
|
229
|
-
deliveryFailed = res.failed.length;
|
|
230
|
-
if (res.failed.length > 0) {
|
|
231
|
-
console.warn("[print-all] afleverbrief mislukt", res.failed);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
catch (err) {
|
|
235
|
-
deliveryFailed = 1;
|
|
236
|
-
console.warn("[print-all] afleverbrief-fout", err);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
const parts = [`${printed} pakbon${printed === 1 ? "" : "nen"}`];
|
|
240
|
-
if (deliveryOk > 0)
|
|
241
|
-
parts.push(`${deliveryOk} afleverbrief`);
|
|
242
|
-
if (printed > 0 || deliveryOk > 0) {
|
|
243
|
-
toast.success(`Documenten geprint — ${parts.join(", ")}.`);
|
|
212
|
+
if (printed > 0) {
|
|
213
|
+
toast.success(`Documenten geprint — ${printed} pakbon${printed === 1 ? "" : "nen"}.`);
|
|
244
214
|
}
|
|
245
215
|
if (pakbonFailed > 0) {
|
|
246
216
|
toast.error(`${pakbonFailed} pakbon kon niet worden geprint.`);
|
|
247
217
|
}
|
|
248
|
-
if (deliveryFailed > 0) {
|
|
249
|
-
toast.error(`${deliveryFailed} afleverbrief kon niet worden geprint.`);
|
|
250
|
-
}
|
|
251
218
|
}
|
|
252
219
|
catch (err) {
|
|
253
220
|
toast.error(printFoutMelding(err));
|
|
@@ -267,7 +234,7 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
267
234
|
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
268
235
|
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
269
236
|
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId })) : null;
|
|
270
|
-
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing
|
|
237
|
+
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing, title: "Alle pakbonnen van deze bestelling afdrukken", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), printing ? "Bezig…" : "Alle documenten afdrukken"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: (e) => {
|
|
271
238
|
e.stopPropagation();
|
|
272
239
|
setVerzetOpen(true);
|
|
273
240
|
}, title: "Ophaaldag of ophaaltijd van deze order wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: p.order.orderNumber, carrierTarget: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LeveringenPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/LeveringenPage.tsx"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"LeveringenPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/LeveringenPage.tsx"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,gCA6B7B"}
|
|
@@ -8,5 +8,5 @@ export function LeveringenPage() {
|
|
|
8
8
|
const [weekStart, setWeekStart] = useState(() => currentWeekStart());
|
|
9
9
|
const range = useMemo(() => agendaRange(weekStart), [weekStart]);
|
|
10
10
|
const { planned, nearestDeliveryDate, isLoading, error, warning, refetch } = useOrderPlanning(range);
|
|
11
|
-
return (_jsxs("main", { className: "p-6 space-y-6", children: [warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: planned, mode: "delivery", isLoading: isLoading,
|
|
11
|
+
return (_jsxs("main", { className: "p-6 space-y-6", children: [warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: planned, mode: "delivery", isLoading: isLoading, onWeekChange: setWeekStart, jumpToDate: nearestDeliveryDate }))] }));
|
|
12
12
|
}
|
|
@@ -8,12 +8,10 @@ export interface WeekAgendaViewProps {
|
|
|
8
8
|
onOrderClick?: (order: FloridayOrder) => void;
|
|
9
9
|
onDayClick?: (date: Date) => void;
|
|
10
10
|
title?: string;
|
|
11
|
-
/** Toon "Afleverbrief" print-knoppen (per order + per dag). */
|
|
12
|
-
showPrintButtons?: boolean;
|
|
13
11
|
/** Meld de zichtbare week zodat de pagina alleen die periode ophaalt. */
|
|
14
12
|
onWeekChange?: (weekStart: Date, weekEnd: Date) => void;
|
|
15
13
|
/** Dichtstbijzijnde datum met data buiten de zichtbare week (auto-jump). */
|
|
16
14
|
jumpToDate?: string | null;
|
|
17
15
|
}
|
|
18
|
-
export declare function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title,
|
|
16
|
+
export declare function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title, onWeekChange, jumpToDate, }: WeekAgendaViewProps): import("react").JSX.Element;
|
|
19
17
|
//# sourceMappingURL=WeekAgendaView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKjE,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,oBAAoB,GAAG,MAAM,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA+DD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,EACL,YAAY,EACZ,UAAU,GACX,EAAE,mBAAmB,+BAwJrB"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { Button, Badge
|
|
4
|
-
import { ChevronLeft, ChevronRight, Package, Truck, Sprout, Clock, CheckCircle2, Scale
|
|
5
|
-
import { printFoutMelding } from "../../lib/printing";
|
|
6
|
-
import { WerkplekWaarschuwing, useWerkplek } from "./WerkplekWaarschuwing";
|
|
3
|
+
import { Button, Badge } from "@flowselections/core";
|
|
4
|
+
import { ChevronLeft, ChevronRight, Package, Truck, Sprout, Clock, CheckCircle2, Scale } from "lucide-react";
|
|
7
5
|
import { isSameDay, startOfWeek, addDays } from "../../lib/pickDate";
|
|
8
|
-
import { printDeliveryNote, printDeliveryNotesMerged, } from "../../lib/deliveryNotePrint";
|
|
9
6
|
import { useCapacityCheck } from "../../hooks/useCapacityCheck";
|
|
10
7
|
import { CapacityWarning } from "./CapacityWarning";
|
|
11
8
|
import { toDayKey } from "../../lib/logisticsEngine/capacity";
|
|
@@ -43,7 +40,7 @@ const MODE_LABELS = {
|
|
|
43
40
|
"transport-register": { summary: "Aanmeldingen deze week" },
|
|
44
41
|
pick: { summary: "Te picken deze week" },
|
|
45
42
|
};
|
|
46
|
-
export function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title,
|
|
43
|
+
export function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title, onWeekChange, jumpToDate, }) {
|
|
47
44
|
const [cursor, setCursor] = useState(() => {
|
|
48
45
|
const d = new Date();
|
|
49
46
|
d.setHours(0, 0, 0, 0);
|
|
@@ -146,66 +143,18 @@ export function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayCl
|
|
|
146
143
|
d.setHours(0, 0, 0, 0);
|
|
147
144
|
setCursor(startOfWeek(d));
|
|
148
145
|
};
|
|
149
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("h2", { className: "text-xl font-semibold tracking-tight", children: title ?? headerLabel }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: goPrev, children: [_jsx(ChevronLeft, { className: "mr-1 h-4 w-4" }), " Vorige week"] }), _jsx(Button, { variant: "outline", size: "sm", onClick: goToday, children: "Deze week" }), _jsxs(Button, { variant: "outline", size: "sm", onClick: goNext, children: ["Volgende week ", _jsx(ChevronRight, { className: "ml-1 h-4 w-4" })] })] })] }), _jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4", children: [_jsx(SummaryCard, { label: MODE_LABELS[mode].summary, value: totals.leveringen, tone: "default" }), _jsx(SummaryCard, { label: "Verzendklaar", value: totals.verzendklaar, tone: "success" }), _jsx(SummaryCard, { label: "In voorbereiding", value: totals.voorbereiding, tone: "muted" }), _jsx(SummaryCard, { label: "Totaal stuks", value: totals.totaalStuks, tone: "default" })] }),
|
|
146
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("h2", { className: "text-xl font-semibold tracking-tight", children: title ?? headerLabel }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: goPrev, children: [_jsx(ChevronLeft, { className: "mr-1 h-4 w-4" }), " Vorige week"] }), _jsx(Button, { variant: "outline", size: "sm", onClick: goToday, children: "Deze week" }), _jsxs(Button, { variant: "outline", size: "sm", onClick: goNext, children: ["Volgende week ", _jsx(ChevronRight, { className: "ml-1 h-4 w-4" })] })] })] }), _jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4", children: [_jsx(SummaryCard, { label: MODE_LABELS[mode].summary, value: totals.leveringen, tone: "default" }), _jsx(SummaryCard, { label: "Verzendklaar", value: totals.verzendklaar, tone: "success" }), _jsx(SummaryCard, { label: "In voorbereiding", value: totals.voorbereiding, tone: "muted" }), _jsx(SummaryCard, { label: "Totaal stuks", value: totals.totaalStuks, tone: "default" })] }), _jsx("div", { className: "max-h-[520px] space-y-2 overflow-y-auto rounded-lg border bg-muted/20 p-2", children: isLoading ? (_jsx("div", { className: "rounded-lg border bg-card p-10 text-center text-sm text-muted-foreground", children: "Laden\u2026" })) : (days.map((day) => (_jsx(DayRow, { day: day, onOrderClick: onOrderClick, onDayClick: onDayClick, capacity: mode === "delivery" ? undefined : capacity.byDate.get(toDayKey(day.date)) }, day.date.toISOString())))) })] }));
|
|
150
147
|
}
|
|
151
148
|
function SummaryCard({ label, value, tone, }) {
|
|
152
149
|
const valueClass = tone === "success" ? "text-green-600" : "text-foreground";
|
|
153
150
|
return (_jsxs("div", { className: "rounded-lg border bg-card p-4", children: [_jsx("div", { className: `text-3xl font-bold ${valueClass}`, children: value }), _jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: label })] }));
|
|
154
151
|
}
|
|
155
|
-
|
|
156
|
-
function AgendaWerkplekBanner() {
|
|
157
|
-
const werkplek = useWerkplek();
|
|
158
|
-
return _jsx(WerkplekWaarschuwing, { werkplek: werkplek });
|
|
159
|
-
}
|
|
160
|
-
function DayRow({ day, onOrderClick, onDayClick, showPrintButtons, capacity, }) {
|
|
152
|
+
function DayRow({ day, onOrderClick, onDayClick, capacity, }) {
|
|
161
153
|
const weekdayIdx = (day.date.getDay() + 6) % 7;
|
|
162
154
|
const today = new Date();
|
|
163
155
|
today.setHours(0, 0, 0, 0);
|
|
164
156
|
const isToday = isSameDay(day.date, today);
|
|
165
|
-
|
|
166
|
-
const [printingOrderId, setPrintingOrderId] = useState(null);
|
|
167
|
-
const printableItems = day.entries
|
|
168
|
-
.filter((e) => e.order.source === "floriday" && e.order.salesOrderId)
|
|
169
|
-
.map((e) => ({ id: e.order.id, salesOrderId: e.order.salesOrderId ?? undefined }));
|
|
170
|
-
const werkplek = useWerkplek();
|
|
171
|
-
const handlePrintDay = async () => {
|
|
172
|
-
if (printingDay || printableItems.length === 0)
|
|
173
|
-
return;
|
|
174
|
-
setPrintingDay(true);
|
|
175
|
-
try {
|
|
176
|
-
const res = await printDeliveryNotesMerged(printableItems);
|
|
177
|
-
if (res.success > 0) {
|
|
178
|
-
toast.success(`${res.success}/${res.total} afleverbrieven verstuurd naar printer`);
|
|
179
|
-
}
|
|
180
|
-
for (const f of res.failed.slice(0, 5)) {
|
|
181
|
-
toast.error(`Afleverbrief ${f.id} mislukt: ${f.error}`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
toast.error(printFoutMelding(err));
|
|
186
|
-
}
|
|
187
|
-
finally {
|
|
188
|
-
setPrintingDay(false);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
const handlePrintOrder = async (order) => {
|
|
192
|
-
if (!order.salesOrderId || printingOrderId)
|
|
193
|
-
return;
|
|
194
|
-
setPrintingOrderId(order.id);
|
|
195
|
-
try {
|
|
196
|
-
await printDeliveryNote(order.salesOrderId, {
|
|
197
|
-
documentnaam: `AFL-${order.orderNumber}`,
|
|
198
|
-
});
|
|
199
|
-
toast.success(`Afleverbrief ${order.orderNumber} naar de printer gestuurd.`);
|
|
200
|
-
}
|
|
201
|
-
catch (err) {
|
|
202
|
-
toast.error(printFoutMelding(err));
|
|
203
|
-
}
|
|
204
|
-
finally {
|
|
205
|
-
setPrintingOrderId(null);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
return (_jsxs("div", { className: `rounded-lg border bg-card ${isToday ? "ring-1 ring-primary" : ""}`, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-6 px-4 py-4 sm:px-6", children: [_jsxs("div", { className: "w-20 shrink-0", children: [_jsx("div", { className: "text-xs font-medium tracking-wider text-muted-foreground", children: WEEKDAY_LABELS[weekdayIdx] }), _jsx("div", { className: "mt-1 text-3xl font-bold leading-none", children: day.date.getDate() }), _jsxs("div", { className: "text-sm text-muted-foreground", children: [MONTHS_NL_SHORT[day.date.getMonth()], "."] })] }), _jsxs("div", { className: "flex flex-1 flex-wrap items-center gap-6", children: [_jsx(Stat, { icon: _jsx(Package, { className: "h-4 w-4 text-slate-500" }), bg: "bg-slate-100", value: day.bestellingen, label: "bestellingen" }), _jsx(Stat, { icon: _jsx(Truck, { className: "h-4 w-4 text-amber-600" }), bg: "bg-amber-100", value: day.karren, label: "karren" }), _jsx(Stat, { icon: _jsx(Sprout, { className: "h-4 w-4 text-green-600" }), bg: "bg-green-100", value: day.planten, label: "planten" })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [day.movedEarlierOrderIds.size > 0 && (_jsxs(Badge, { className: "bg-purple-500/10 text-purple-700 hover:bg-purple-500/10", variant: "secondary", title: "Aantal orders dat vervroegd is ingepland door Pickverdeling.", children: [_jsx(Scale, { className: "mr-1 h-3.5 w-3.5" }), day.movedEarlierOrderIds.size, " vervroegd"] })), day.verzendklaar > 0 && (_jsxs(Badge, { className: "bg-green-500/15 text-green-700 hover:bg-green-500/15", variant: "secondary", children: [_jsx(CheckCircle2, { className: "mr-1 h-3.5 w-3.5" }), day.verzendklaar, " verzendklaar"] })), day.voorbereiding > 0 && (_jsxs(Badge, { className: "bg-blue-500/10 text-blue-700 hover:bg-blue-500/10", variant: "secondary", children: [_jsx(Clock, { className: "mr-1 h-3.5 w-3.5" }), day.voorbereiding, " in voorbereiding"] })), showPrintButtons && printableItems.length > 0 && (_jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintDay, disabled: printingDay || !werkplek, children: [_jsx(Printer, { className: "mr-1 h-4 w-4" }), printingDay ? "Printen…" : `Print afleverbrieven (${printableItems.length})`] })), onDayClick && day.bestellingen > 0 && (_jsx(Button, { size: "sm", variant: "outline", onClick: () => onDayClick(day.date), children: "Dagdetails" }))] })] }), _jsx(CapacityWarning, { day: capacity, className: "mx-4 mb-4 sm:mx-6" })] }));
|
|
157
|
+
return (_jsxs("div", { className: `rounded-lg border bg-card ${isToday ? "ring-1 ring-primary" : ""}`, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-6 px-4 py-4 sm:px-6", children: [_jsxs("div", { className: "w-20 shrink-0", children: [_jsx("div", { className: "text-xs font-medium tracking-wider text-muted-foreground", children: WEEKDAY_LABELS[weekdayIdx] }), _jsx("div", { className: "mt-1 text-3xl font-bold leading-none", children: day.date.getDate() }), _jsxs("div", { className: "text-sm text-muted-foreground", children: [MONTHS_NL_SHORT[day.date.getMonth()], "."] })] }), _jsxs("div", { className: "flex flex-1 flex-wrap items-center gap-6", children: [_jsx(Stat, { icon: _jsx(Package, { className: "h-4 w-4 text-slate-500" }), bg: "bg-slate-100", value: day.bestellingen, label: "bestellingen" }), _jsx(Stat, { icon: _jsx(Truck, { className: "h-4 w-4 text-amber-600" }), bg: "bg-amber-100", value: day.karren, label: "karren" }), _jsx(Stat, { icon: _jsx(Sprout, { className: "h-4 w-4 text-green-600" }), bg: "bg-green-100", value: day.planten, label: "planten" })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [day.movedEarlierOrderIds.size > 0 && (_jsxs(Badge, { className: "bg-purple-500/10 text-purple-700 hover:bg-purple-500/10", variant: "secondary", title: "Aantal orders dat vervroegd is ingepland door Pickverdeling.", children: [_jsx(Scale, { className: "mr-1 h-3.5 w-3.5" }), day.movedEarlierOrderIds.size, " vervroegd"] })), day.verzendklaar > 0 && (_jsxs(Badge, { className: "bg-green-500/15 text-green-700 hover:bg-green-500/15", variant: "secondary", children: [_jsx(CheckCircle2, { className: "mr-1 h-3.5 w-3.5" }), day.verzendklaar, " verzendklaar"] })), day.voorbereiding > 0 && (_jsxs(Badge, { className: "bg-blue-500/10 text-blue-700 hover:bg-blue-500/10", variant: "secondary", children: [_jsx(Clock, { className: "mr-1 h-3.5 w-3.5" }), day.voorbereiding, " in voorbereiding"] })), onDayClick && day.bestellingen > 0 && (_jsx(Button, { size: "sm", variant: "outline", onClick: () => onDayClick(day.date), children: "Dagdetails" }))] })] }), _jsx(CapacityWarning, { day: capacity, className: "mx-4 mb-4 sm:mx-6" })] }));
|
|
209
158
|
}
|
|
210
159
|
function Stat({ icon, bg, value, label, }) {
|
|
211
160
|
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: `grid h-8 w-8 place-items-center rounded-full ${bg}`, children: icon }), _jsxs("div", { children: [_jsx("div", { className: "text-lg font-bold leading-none", children: value }), _jsx("div", { className: "text-xs text-muted-foreground", children: label })] })] }));
|
|
@@ -14,82 +14,82 @@ export function renderPakbonHtml(order, lang = "nl") {
|
|
|
14
14
|
};
|
|
15
15
|
const rows = order.lines.length
|
|
16
16
|
? order.lines
|
|
17
|
-
.map((l) => `
|
|
18
|
-
<tr>
|
|
19
|
-
<td>${escapeHtml(l.description)}</td>
|
|
20
|
-
<td style="text-align:right">${l.crates ?? ""}</td>
|
|
21
|
-
<td>${escapeHtml(l.unit ?? "")}</td>
|
|
17
|
+
.map((l) => `
|
|
18
|
+
<tr>
|
|
19
|
+
<td>${escapeHtml(l.description)}</td>
|
|
20
|
+
<td style="text-align:right">${l.crates ?? ""}</td>
|
|
21
|
+
<td>${escapeHtml(l.unit ?? "")}</td>
|
|
22
22
|
</tr>`)
|
|
23
23
|
.join("")
|
|
24
24
|
: `<tr><td colspan="3" style="text-align:center;color:#666">${escapeHtml(t.noLines)}</td></tr>`;
|
|
25
25
|
const cartLabel = t.cartOf(order.cartIndex, order.cartTotal);
|
|
26
26
|
const fustenLabel = order.cratesOnCart != null ? `${order.cratesOnCart}` : "—";
|
|
27
27
|
const cartNumber = order.cartNumber ?? `${order.orderNumber}-${order.cartIndex}`;
|
|
28
|
-
return `<!doctype html>
|
|
29
|
-
<html lang="${escapeHtml(htmlLang)}">
|
|
30
|
-
<head>
|
|
31
|
-
<meta charset="utf-8">
|
|
32
|
-
<title>${escapeHtml(t.packingSlip)} ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartNumber)}</title>
|
|
33
|
-
<style>
|
|
34
|
-
@page {
|
|
35
|
-
size: A4;
|
|
36
|
-
margin: 16mm;
|
|
37
|
-
@top-center { content: element(cartno); }
|
|
38
|
-
}
|
|
39
|
-
body { font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; color:#111; }
|
|
40
|
-
h1 { margin: 0 0 4px; font-size: 26px; }
|
|
41
|
-
.sub { color:#444; margin-bottom: 8px; }
|
|
42
|
-
|
|
43
|
-
.cart-number-hero {
|
|
44
|
-
position: running(cartno);
|
|
45
|
-
font-size: 88px;
|
|
46
|
-
font-weight: 900;
|
|
47
|
-
letter-spacing: 4px;
|
|
48
|
-
line-height: 1;
|
|
49
|
-
color: #000;
|
|
50
|
-
background: #fff;
|
|
51
|
-
border: 4px solid #000;
|
|
52
|
-
padding: 12px 20px;
|
|
53
|
-
display: inline-block;
|
|
54
|
-
margin: 6px 0 20px;
|
|
55
|
-
font-family: "Arial Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; margin: 8px 0 22px; }
|
|
59
|
-
.grid div { font-size: 14px; }
|
|
60
|
-
.label { color:#666; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
|
|
61
|
-
.value { font-size: 16px; font-weight: 600; }
|
|
62
|
-
table { width:100%; border-collapse: collapse; font-size: 14px; }
|
|
63
|
-
th, td { padding: 8px 6px; border-bottom: 1px solid #ddd; vertical-align: top; }
|
|
64
|
-
th { text-align: left; background:#f5f5f5; }
|
|
65
|
-
.barcode-fallback { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px; letter-spacing: 4px; padding: 8px 12px; border: 2px solid #111; display: inline-block; margin-top: 18px; }
|
|
66
|
-
.footer { margin-top: 28px; font-size: 11px; color:#666; }
|
|
67
|
-
</style>
|
|
68
|
-
</head>
|
|
69
|
-
<body>
|
|
70
|
-
<h1>${escapeHtml(t.packingSlip)}</h1>
|
|
71
|
-
<div class="sub">${escapeHtml(t.order)} ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartLabel)}</div>
|
|
72
|
-
|
|
73
|
-
<div class="cart-number-hero">${escapeHtml(cartNumber)}</div>
|
|
74
|
-
|
|
75
|
-
<div class="grid">
|
|
76
|
-
<div><div class="label">${escapeHtml(t.customer)}</div><div class="value">${escapeHtml(order.customerName)}</div></div>
|
|
77
|
-
<div><div class="label">${escapeHtml(t.country)}</div><div class="value">${escapeHtml(order.country ?? "—")}</div></div>
|
|
78
|
-
<div><div class="label">${escapeHtml(t.deliveryDate)}</div><div class="value">${fmt(order.deliveryDate)}</div></div>
|
|
79
|
-
<div><div class="label">${escapeHtml(t.pickDate)}</div><div class="value">${fmt(order.pickDate)}</div></div>
|
|
80
|
-
<div><div class="label">${escapeHtml(t.cart)}</div><div class="value">${escapeHtml(cartLabel)}</div></div>
|
|
81
|
-
<div><div class="label">${escapeHtml(t.cratesOnThisCart)}</div><div class="value">${escapeHtml(fustenLabel)}</div></div>
|
|
82
|
-
</div>
|
|
83
|
-
|
|
84
|
-
<table>
|
|
85
|
-
<thead><tr><th>${escapeHtml(t.description)}</th><th style="text-align:right;width:90px">${escapeHtml(t.crates)}</th><th style="width:90px">${escapeHtml(t.unit)}</th></tr></thead>
|
|
86
|
-
<tbody>${rows}</tbody>
|
|
87
|
-
</table>
|
|
88
|
-
|
|
89
|
-
<div class="barcode-fallback">*${escapeHtml(order.orderNumber)}*</div>
|
|
90
|
-
|
|
91
|
-
<div class="footer">${escapeHtml(t.printedVia)} · ${new Date().toLocaleString(locale)}</div>
|
|
92
|
-
</body>
|
|
28
|
+
return `<!doctype html>
|
|
29
|
+
<html lang="${escapeHtml(htmlLang)}">
|
|
30
|
+
<head>
|
|
31
|
+
<meta charset="utf-8">
|
|
32
|
+
<title>${escapeHtml(t.packingSlip)} ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartNumber)}</title>
|
|
33
|
+
<style>
|
|
34
|
+
@page {
|
|
35
|
+
size: A4;
|
|
36
|
+
margin: 16mm;
|
|
37
|
+
@top-center { content: element(cartno); }
|
|
38
|
+
}
|
|
39
|
+
body { font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; color:#111; }
|
|
40
|
+
h1 { margin: 0 0 4px; font-size: 26px; }
|
|
41
|
+
.sub { color:#444; margin-bottom: 8px; }
|
|
42
|
+
|
|
43
|
+
.cart-number-hero {
|
|
44
|
+
position: running(cartno);
|
|
45
|
+
font-size: 88px;
|
|
46
|
+
font-weight: 900;
|
|
47
|
+
letter-spacing: 4px;
|
|
48
|
+
line-height: 1;
|
|
49
|
+
color: #000;
|
|
50
|
+
background: #fff;
|
|
51
|
+
border: 4px solid #000;
|
|
52
|
+
padding: 12px 20px;
|
|
53
|
+
display: inline-block;
|
|
54
|
+
margin: 6px 0 20px;
|
|
55
|
+
font-family: "Arial Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; margin: 8px 0 22px; }
|
|
59
|
+
.grid div { font-size: 14px; }
|
|
60
|
+
.label { color:#666; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
|
|
61
|
+
.value { font-size: 16px; font-weight: 600; }
|
|
62
|
+
table { width:100%; border-collapse: collapse; font-size: 14px; }
|
|
63
|
+
th, td { padding: 8px 6px; border-bottom: 1px solid #ddd; vertical-align: top; }
|
|
64
|
+
th { text-align: left; background:#f5f5f5; }
|
|
65
|
+
.barcode-fallback { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px; letter-spacing: 4px; padding: 8px 12px; border: 2px solid #111; display: inline-block; margin-top: 18px; }
|
|
66
|
+
.footer { margin-top: 28px; font-size: 11px; color:#666; }
|
|
67
|
+
</style>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<h1>${escapeHtml(t.packingSlip)}</h1>
|
|
71
|
+
<div class="sub">${escapeHtml(t.order)} ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartLabel)}</div>
|
|
72
|
+
|
|
73
|
+
<div class="cart-number-hero">${escapeHtml(cartNumber)}</div>
|
|
74
|
+
|
|
75
|
+
<div class="grid">
|
|
76
|
+
<div><div class="label">${escapeHtml(t.customer)}</div><div class="value">${escapeHtml(order.customerName)}</div></div>
|
|
77
|
+
<div><div class="label">${escapeHtml(t.country)}</div><div class="value">${escapeHtml(order.country ?? "—")}</div></div>
|
|
78
|
+
<div><div class="label">${escapeHtml(t.deliveryDate)}</div><div class="value">${fmt(order.deliveryDate)}</div></div>
|
|
79
|
+
<div><div class="label">${escapeHtml(t.pickDate)}</div><div class="value">${fmt(order.pickDate)}</div></div>
|
|
80
|
+
<div><div class="label">${escapeHtml(t.cart)}</div><div class="value">${escapeHtml(cartLabel)}</div></div>
|
|
81
|
+
<div><div class="label">${escapeHtml(t.cratesOnThisCart)}</div><div class="value">${escapeHtml(fustenLabel)}</div></div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<table>
|
|
85
|
+
<thead><tr><th>${escapeHtml(t.description)}</th><th style="text-align:right;width:90px">${escapeHtml(t.crates)}</th><th style="width:90px">${escapeHtml(t.unit)}</th></tr></thead>
|
|
86
|
+
<tbody>${rows}</tbody>
|
|
87
|
+
</table>
|
|
88
|
+
|
|
89
|
+
<div class="barcode-fallback">*${escapeHtml(order.orderNumber)}*</div>
|
|
90
|
+
|
|
91
|
+
<div class="footer">${escapeHtml(t.printedVia)} · ${new Date().toLocaleString(locale)}</div>
|
|
92
|
+
</body>
|
|
93
93
|
</html>`;
|
|
94
94
|
}
|
|
95
95
|
function escapeHtml(s) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AfhandelingSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/components/settings/AfhandelingSettingsCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AfhandelingSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/components/settings/AfhandelingSettingsCard.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,uBAAuB,gCAyHtC"}
|