@flowselections/floriday-afhandeling-module 1.0.41 → 1.0.43
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 +3 -1
- package/dist-lib/components/afhandeling/AutoProcessStatus.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/AutoProcessStatus.js +36 -3
- package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControlePage.js +53 -13
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +409 -120
- package/dist-lib/components/afhandeling/PickAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/PickAgendaView.js +4 -4
- package/dist-lib/components/afhandeling/PickingPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/PickingPage.js +1 -1
- package/dist-lib/components/afhandeling/ScanControleView.d.ts +2 -0
- package/dist-lib/components/afhandeling/ScanControleView.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/ScanControleView.js +158 -0
- package/dist-lib/components/afhandeling/WeekAgendaView.js +1 -1
- package/dist-lib/hooks/useCartIndex.d.ts.map +1 -1
- package/dist-lib/hooks/useCartIndex.js +6 -1
- package/dist-lib/hooks/useEngineTasks.js +1 -1
- package/dist-lib/hooks/useKnownOrders.d.ts +11 -0
- package/dist-lib/hooks/useKnownOrders.d.ts.map +1 -0
- package/dist-lib/hooks/useKnownOrders.js +54 -0
- package/dist-lib/hooks/useOrderBuffers.d.ts +17 -0
- package/dist-lib/hooks/useOrderBuffers.d.ts.map +1 -0
- package/dist-lib/hooks/useOrderBuffers.js +53 -0
- package/dist-lib/hooks/useOrderPickDates.d.ts +10 -0
- package/dist-lib/hooks/useOrderPickDates.d.ts.map +1 -0
- package/dist-lib/hooks/useOrderPickDates.js +62 -0
- package/dist-lib/hooks/useOrderPlanning.d.ts +1 -3
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +9 -13
- package/dist-lib/hooks/usePickAgenda.d.ts +1 -6
- package/dist-lib/hooks/usePickAgenda.d.ts.map +1 -1
- package/dist-lib/hooks/usePickAgenda.js +62 -9
- package/dist-lib/hooks/usePickMode.d.ts +10 -0
- package/dist-lib/hooks/usePickMode.d.ts.map +1 -0
- package/dist-lib/hooks/usePickMode.js +31 -0
- package/dist-lib/index.d.ts +2 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +19 -6
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +3598 -1225
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +3598 -1225
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +3598 -1225
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +3645 -1246
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +1 -0
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +6076 -1330
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/carriers.functions.d.ts +15052 -3187
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.d.ts +15052 -3187
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +55913 -6313
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.js +134 -10
- package/dist-lib/lib/deliveryNote.functions.d.ts +25891 -0
- package/dist-lib/lib/deliveryNote.functions.d.ts.map +1 -0
- package/dist-lib/lib/deliveryNote.functions.js +32 -0
- package/dist-lib/lib/engineLayouts.functions.d.ts +25889 -0
- package/dist-lib/lib/engineLayouts.functions.d.ts.map +1 -0
- package/dist-lib/lib/engineLayouts.functions.js +42 -0
- package/dist-lib/lib/floriday.functions.d.ts +28979 -712
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday.functions.js +118 -343
- package/dist-lib/lib/logisticsEngine/reschedule.d.ts +17 -0
- package/dist-lib/lib/logisticsEngine/reschedule.d.ts.map +1 -1
- package/dist-lib/lib/logisticsEngine/reschedule.js +63 -0
- package/dist-lib/lib/orderFulfilment.functions.d.ts +25891 -0
- package/dist-lib/lib/orderFulfilment.functions.d.ts.map +1 -0
- package/dist-lib/lib/orderFulfilment.functions.js +35 -0
- package/dist-lib/lib/orderStatus.d.ts +10 -0
- package/dist-lib/lib/orderStatus.d.ts.map +1 -0
- package/dist-lib/lib/orderStatus.js +81 -0
- package/dist-lib/lib/pickDates.functions.d.ts +25896 -0
- package/dist-lib/lib/pickDates.functions.d.ts.map +1 -0
- package/dist-lib/lib/pickDates.functions.js +56 -0
- package/dist-lib/lib/pickMode.d.ts +14 -0
- package/dist-lib/lib/pickMode.d.ts.map +1 -0
- package/dist-lib/lib/pickMode.js +103 -0
- package/dist-lib/lib/printing.d.ts +3 -1
- package/dist-lib/lib/printing.d.ts.map +1 -1
- package/dist-lib/lib/printing.js +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
interface Props {
|
|
2
2
|
salesOrderId: string;
|
|
3
|
+
/** Ordernummer (order_ref) — nodig om opnieuw in te plannen via de Engine. */
|
|
4
|
+
orderRef?: string | null;
|
|
3
5
|
/** Datum waarop de auto-verwerking mag starten (targetPickDate). */
|
|
4
6
|
autoProcessDate?: Date | null;
|
|
5
7
|
/** Toon knop "Nu verwerken" ook als datum nog niet bereikt. */
|
|
@@ -7,6 +9,6 @@ interface Props {
|
|
|
7
9
|
/** Compact = alleen badge, geen knoppen. */
|
|
8
10
|
compact?: boolean;
|
|
9
11
|
}
|
|
10
|
-
export declare function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger, compact, }: Props): import("react").JSX.Element;
|
|
12
|
+
export declare function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, allowManualTrigger, compact, }: Props): import("react").JSX.Element;
|
|
11
13
|
export {};
|
|
12
14
|
//# sourceMappingURL=AutoProcessStatus.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoProcessStatus.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/AutoProcessStatus.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AutoProcessStatus.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/AutoProcessStatus.tsx"],"names":[],"mappings":"AAYA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oEAAoE;IACpE,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAeD,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,kBAAyB,EACzB,OAAe,GAChB,EAAE,KAAK,+BAiLP"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
4
|
import { Badge, Button, toast } from "@flowselections/core";
|
|
4
5
|
import { CheckCircle2, Clock, Loader2, PlayCircle, RefreshCw, AlertTriangle } from "lucide-react";
|
|
5
6
|
import { autoProcessSalesOrder, fetchAutoProcessStatuses, } from "../../lib/floridayAutoProcess";
|
|
6
7
|
import { supabase } from "../../integrations/supabase/moduleClient";
|
|
8
|
+
import { replanToNextDeliveryMoment } from "../../lib/logisticsEngine/reschedule";
|
|
7
9
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { day: "2-digit", month: "short" });
|
|
8
10
|
function formatWaiting(date) {
|
|
9
11
|
const today = new Date();
|
|
@@ -17,17 +19,20 @@ function formatWaiting(date) {
|
|
|
17
19
|
return "Verwerkt morgen";
|
|
18
20
|
return `Wacht tot ${NL_DATE.format(target)} (${diffDays} dagen)`;
|
|
19
21
|
}
|
|
20
|
-
export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger = true, compact = false, }) {
|
|
22
|
+
export function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, allowManualTrigger = true, compact = false, }) {
|
|
21
23
|
const [row, setRow] = useState(null);
|
|
22
24
|
const [loading, setLoading] = useState(false);
|
|
25
|
+
const queryClient = useQueryClient();
|
|
23
26
|
useEffect(() => {
|
|
24
27
|
let cancelled = false;
|
|
25
28
|
fetchAutoProcessStatuses([salesOrderId]).then((m) => {
|
|
26
29
|
if (!cancelled)
|
|
27
30
|
setRow(m.get(salesOrderId) ?? null);
|
|
28
31
|
});
|
|
32
|
+
// Unieke kanaalnaam per instantie: dezelfde order kan meerdere keren in
|
|
33
|
+
// beeld staan en Supabase hergebruikt anders een al geabonneerd kanaal.
|
|
29
34
|
const channel = supabase
|
|
30
|
-
.channel(`auto-process-${salesOrderId}`)
|
|
35
|
+
.channel(`auto-process-${salesOrderId}-${Math.random().toString(36).slice(2)}`)
|
|
31
36
|
.on("postgres_changes", {
|
|
32
37
|
event: "*",
|
|
33
38
|
schema: "public",
|
|
@@ -48,6 +53,34 @@ export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTr
|
|
|
48
53
|
const handleProcess = async () => {
|
|
49
54
|
setLoading(true);
|
|
50
55
|
try {
|
|
56
|
+
if (orderRef) {
|
|
57
|
+
// Opnieuw inplannen op het eerstvolgende aflevermoment; de Engine
|
|
58
|
+
// bepaalt daarna zelf de pickdag en de bijbehorende taken.
|
|
59
|
+
const res = await replanToNextDeliveryMoment(orderRef);
|
|
60
|
+
if (!res.ok) {
|
|
61
|
+
toast.error(res.error ?? "Opnieuw inplannen mislukt");
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const d = res.moment
|
|
65
|
+
? new Date(`${res.moment.date}T00:00:00`).toLocaleDateString("nl-NL")
|
|
66
|
+
: null;
|
|
67
|
+
toast.success(d
|
|
68
|
+
? `Ingepland op ${d}${res.moment?.time ? ` om ${res.moment.time}` : ""}`
|
|
69
|
+
: "Order opnieuw ingepland");
|
|
70
|
+
// Direct verversen zodat de nieuwe leverdatum en de status meteen
|
|
71
|
+
// in beeld staan, precies zoals bij de andere bestellingen.
|
|
72
|
+
await Promise.all([
|
|
73
|
+
queryClient.invalidateQueries({ queryKey: ["logistics-pick-agenda"] }),
|
|
74
|
+
queryClient.invalidateQueries({ queryKey: ["engine", "tasks"] }),
|
|
75
|
+
queryClient.invalidateQueries({ queryKey: ["order-buffers"] }),
|
|
76
|
+
queryClient.invalidateQueries({ queryKey: ["floriday", "orders"] }),
|
|
77
|
+
queryClient.invalidateQueries({ queryKey: ["logistics-cart-index"] }),
|
|
78
|
+
queryClient.invalidateQueries({ queryKey: ["known-orders"] }),
|
|
79
|
+
]);
|
|
80
|
+
await queryClient.refetchQueries({ queryKey: ["logistics-pick-agenda"], type: "active" });
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
51
84
|
const res = await autoProcessSalesOrder(salesOrderId);
|
|
52
85
|
toast.success(res.status === "done"
|
|
53
86
|
? "Verwerkt — afleverbrief wordt aangemaakt"
|
|
@@ -99,5 +132,5 @@ export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTr
|
|
|
99
132
|
return _jsx(_Fragment, { children: badge });
|
|
100
133
|
const showRetry = status === "error";
|
|
101
134
|
const showTrigger = allowManualTrigger && status !== "done" && status !== "acknowledging" && !loading;
|
|
102
|
-
return (_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [badge, showTrigger ? (_jsx(Button, { size: "sm", variant: showRetry ? "outline" : "secondary", onClick: handleProcess, disabled: loading, children: showRetry ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-3 w-3 mr-1" }), " Opnieuw"] })) : (_jsxs(_Fragment, { children: [_jsx(PlayCircle, { className: "h-3 w-3 mr-1" }), " Nu verwerken"] })) })) : null] }));
|
|
135
|
+
return (_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [badge, showTrigger ? (_jsx(Button, { size: "sm", variant: showRetry ? "outline" : "secondary", onClick: handleProcess, disabled: loading, children: showRetry ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-3 w-3 mr-1" }), " Opnieuw"] })) : (_jsxs(_Fragment, { children: [_jsx(PlayCircle, { className: "h-3 w-3 mr-1" }), " ", orderRef ? "Nu inplannen" : "Nu verwerken"] })) })) : null] }));
|
|
103
136
|
}
|
|
@@ -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":"AAkJA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BAu3BpE"}
|
|
@@ -2,25 +2,48 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { supabase } from "../../integrations/supabase/moduleClient";
|
|
4
4
|
import { Button, Card, Checkbox, Dialog, DialogDescription, DialogTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Textarea, Badge, toast, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
5
|
-
import { Printer, CheckCircle2, AlertTriangle, History, ChevronLeft, ChevronRight } from "lucide-react";
|
|
5
|
+
import { Printer, CheckCircle2, AlertTriangle, History, ChevronLeft, ChevronRight, ScanLine } from "lucide-react";
|
|
6
6
|
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
7
7
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
8
8
|
import { useServerFn } from "@tanstack/react-start";
|
|
9
|
-
import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, saveControlDraft, } from "../../lib/cartControl.functions";
|
|
9
|
+
import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, listDeliveredToday, saveControlDraft, } from "../../lib/cartControl.functions";
|
|
10
|
+
import { ScanControleView } from "./ScanControleView";
|
|
10
11
|
import { renderControleLijstHtml } from "./ControleLijstPrint";
|
|
11
12
|
import { printHtmlDocument, printFoutMelding } from "../../lib/printing";
|
|
13
|
+
function dayDiffFromToday(iso) {
|
|
14
|
+
const d = new Date(iso);
|
|
15
|
+
if (Number.isNaN(d.getTime()))
|
|
16
|
+
return null;
|
|
17
|
+
const today = new Date();
|
|
18
|
+
today.setHours(0, 0, 0, 0);
|
|
19
|
+
d.setHours(0, 0, 0, 0);
|
|
20
|
+
return Math.round((d.getTime() - today.getTime()) / 86400000);
|
|
21
|
+
}
|
|
22
|
+
/** "vandaag", "morgen", "over 3 dagen" of een korte datum. */
|
|
23
|
+
function relDayLabel(iso) {
|
|
24
|
+
const diff = dayDiffFromToday(iso);
|
|
25
|
+
const d = new Date(iso);
|
|
26
|
+
if (diff === null)
|
|
27
|
+
return iso;
|
|
28
|
+
if (diff === 0)
|
|
29
|
+
return "vandaag";
|
|
30
|
+
if (diff === 1)
|
|
31
|
+
return "morgen";
|
|
32
|
+
if (diff === -1)
|
|
33
|
+
return "gisteren";
|
|
34
|
+
if (diff > 1 && diff <= 7)
|
|
35
|
+
return `over ${diff} dagen`;
|
|
36
|
+
if (diff < -1)
|
|
37
|
+
return `${Math.abs(diff)} dagen geleden`;
|
|
38
|
+
return d.toLocaleDateString("nl-NL", { weekday: "short", day: "2-digit", month: "2-digit" });
|
|
39
|
+
}
|
|
12
40
|
function fmtDate(iso) {
|
|
13
41
|
if (!iso)
|
|
14
42
|
return "—";
|
|
15
43
|
const d = new Date(iso);
|
|
16
44
|
if (Number.isNaN(d.getTime()))
|
|
17
45
|
return iso;
|
|
18
|
-
return
|
|
19
|
-
weekday: "short",
|
|
20
|
-
day: "2-digit",
|
|
21
|
-
month: "2-digit",
|
|
22
|
-
year: "numeric",
|
|
23
|
-
});
|
|
46
|
+
return relDayLabel(iso);
|
|
24
47
|
}
|
|
25
48
|
function isTomorrowIso(iso) {
|
|
26
49
|
if (!iso)
|
|
@@ -74,6 +97,7 @@ export function ControlePage({ onExit } = {}) {
|
|
|
74
97
|
const fetchProposals = useServerFn(getControlRescheduleProposals);
|
|
75
98
|
const submit = useServerFn(submitControlSession);
|
|
76
99
|
const fetchDraft = useServerFn(getControlDraft);
|
|
100
|
+
const fetchDelivered = useServerFn(listDeliveredToday);
|
|
77
101
|
const saveDraft = useServerFn(saveControlDraft);
|
|
78
102
|
const cartsQ = useQuery({
|
|
79
103
|
queryKey: ["control", "today"],
|
|
@@ -89,6 +113,13 @@ export function ControlePage({ onExit } = {}) {
|
|
|
89
113
|
refetchOnMount: "always",
|
|
90
114
|
refetchOnWindowFocus: true,
|
|
91
115
|
});
|
|
116
|
+
const deliveredQ = useQuery({
|
|
117
|
+
queryKey: ["control", "delivered"],
|
|
118
|
+
queryFn: () => fetchDelivered(),
|
|
119
|
+
enabled: tab === "afgeleverd",
|
|
120
|
+
refetchOnMount: "always",
|
|
121
|
+
refetchOnWindowFocus: true,
|
|
122
|
+
});
|
|
92
123
|
const draftQ = useQuery({
|
|
93
124
|
queryKey: controlDraftQueryKey,
|
|
94
125
|
queryFn: async () => (await fetchDraft()),
|
|
@@ -96,7 +127,9 @@ export function ControlePage({ onExit } = {}) {
|
|
|
96
127
|
refetchOnMount: "always",
|
|
97
128
|
refetchOnWindowFocus: true,
|
|
98
129
|
});
|
|
99
|
-
|
|
130
|
+
// Karren die al zijn goedgekeurd (klaargezet/verzonden/geleverd) verdwijnen uit de controlelijst.
|
|
131
|
+
const APPROVED_CART_STATUSES = ["ready", "checked", "shipped", "delivered"];
|
|
132
|
+
const carts = (cartsQ.data?.carts ?? []).filter((c) => !APPROVED_CART_STATUSES.includes(String(c.status ?? "pending")));
|
|
100
133
|
const currentDraftPayload = useMemo(() => {
|
|
101
134
|
const nextStates = { ...cartStates };
|
|
102
135
|
for (const cart of carts) {
|
|
@@ -408,6 +441,7 @@ export function ControlePage({ onExit } = {}) {
|
|
|
408
441
|
setPage(pageCount);
|
|
409
442
|
}, [pageCount, page]);
|
|
410
443
|
const pagedCarts = useMemo(() => carts.slice((currentPage - 1) * pageSize, currentPage * pageSize), [carts, currentPage, pageSize]);
|
|
444
|
+
// Geen eigen hernummering meer: het karnummer komt uitsluitend uit de Engine.
|
|
411
445
|
const pendingProposals = pendingProposal?.proposals ?? [];
|
|
412
446
|
const pendingBlocked = pendingProposal?.blocked ?? [];
|
|
413
447
|
const pendingNotReadyCount = pendingProposals.length + pendingBlocked.length;
|
|
@@ -465,13 +499,13 @@ export function ControlePage({ onExit } = {}) {
|
|
|
465
499
|
finally {
|
|
466
500
|
setPrintBezig(false);
|
|
467
501
|
}
|
|
468
|
-
}, children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), printBezig ? "Bezig met printen…" : "Controlelijst afdrukken"] }), _jsxs(Button, { onClick: runControl, disabled: submitM.isPending || proposalM.isPending || carts.length === 0 || tab !== "controle", children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), proposalM.isPending ? "Controleren…" : "Controle uitvoeren"] })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: tab === "controle" ? "default" : "outline", onClick: () => setTab("controle"), children: "Controle" }), _jsxs(Button, { variant: tab === "historie" ? "default" : "outline", onClick: () => setTab("historie"), children: [_jsx(History, { className: "h-4 w-4 mr-2" }), "Historie"] })] }), tab === "controle" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-3 items-center", children: [_jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Totaal karren vandaag" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.total })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Geprint" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.printed })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Aangevinkt" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.checked })] })] }), _jsxs(Card, { className: "p-0 overflow-hidden", children: [_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-12", children: _jsx(Checkbox, { checked: carts.length > 0 && carts.every((c) => checked.has(controlCartKey(c)))
|
|
502
|
+
}, children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), printBezig ? "Bezig met printen…" : "Controlelijst afdrukken"] }), _jsxs(Button, { onClick: runControl, disabled: submitM.isPending || proposalM.isPending || carts.length === 0 || tab !== "controle", children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), proposalM.isPending ? "Controleren…" : "Controle uitvoeren"] })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: tab === "controle" ? "default" : "outline", onClick: () => setTab("controle"), children: "Controle" }), _jsxs(Button, { variant: tab === "scan" ? "default" : "outline", onClick: () => setTab("scan"), children: [_jsx(ScanLine, { className: "h-4 w-4 mr-2" }), "Scancontrole"] }), _jsxs(Button, { variant: tab === "afgeleverd" ? "default" : "outline", onClick: () => setTab("afgeleverd"), children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), "Afgeleverd"] }), _jsxs(Button, { variant: tab === "historie" ? "default" : "outline", onClick: () => setTab("historie"), children: [_jsx(History, { className: "h-4 w-4 mr-2" }), "Historie"] })] }), tab === "controle" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-3 items-center", children: [_jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Totaal karren vandaag" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.total })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Geprint" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.printed })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Aangevinkt" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.checked })] })] }), _jsxs(Card, { className: "p-0 overflow-hidden", children: [_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-12", children: _jsx(Checkbox, { checked: carts.length > 0 && carts.every((c) => checked.has(controlCartKey(c)))
|
|
469
503
|
? true
|
|
470
504
|
: carts.some((c) => checked.has(controlCartKey(c)))
|
|
471
505
|
? "indeterminate"
|
|
472
|
-
: false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "
|
|
506
|
+
: false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Karnummer" }), _jsx(TableHead, { children: "Uitgeprint" })] }) }), _jsxs(TableBody, { children: [cartsQ.isLoading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !cartsQ.isLoading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Geen karren om vandaag te controleren." }) })), pagedCarts.map((c) => {
|
|
473
507
|
const k = controlCartKey(c);
|
|
474
|
-
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }),
|
|
508
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }), _jsxs(TableCell, { className: "font-mono font-semibold", children: [c.orderNumber || "—", _jsxs("span", { className: "ml-2 text-muted-foreground font-normal", children: ["[", c.cartSeq, " - ", c.cartTotal ?? c.cartSeq, "]"] })] }), _jsx(TableCell, { className: "font-mono font-semibold", children: c.cartNumber ?? "—" }), _jsx(TableCell, { children: (c.printedToday ?? (c.printedCount ?? 0) > 0) ? (_jsx(Badge, { variant: "secondary", children: "Ja" })) : (_jsx(Badge, { variant: "outline", children: "Nee" })) })] }, k));
|
|
475
509
|
})] })] }), carts.length > 0 && (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-t bg-muted/20 px-4 py-3 text-sm", children: [_jsxs("span", { className: "text-muted-foreground", children: [carts.length, " resultaten"] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Resultaten per pagina" }), _jsxs(Select, { value: String(pageSize), onValueChange: (v) => {
|
|
476
510
|
setPageSize(Number(v));
|
|
477
511
|
setPage(1);
|
|
@@ -481,7 +515,7 @@ export function ControlePage({ onExit } = {}) {
|
|
|
481
515
|
? "Voortgang automatisch opgeslagen"
|
|
482
516
|
: lastSavedRef.current && notes === lastSavedRef.current
|
|
483
517
|
? "Concept bewaard"
|
|
484
|
-
: "" })] }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Bijzonderheden, afwijkingen\u2026", rows: 3 }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Wordt automatisch bewaard tot de controle definitief is goedgekeurd." })] })] })), tab === "historie" && _jsx(HistorieView, { loading: histQ.isLoading, sessions: histQ.data?.sessions ?? [] }), _jsx(Dialog, { open: !!result, onOpenChange: (v) => !v && setResult(null), children: _jsxs(ResponsiveDialogContent, { size: "md", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsx(DialogTitle, { children: "Resultaat controle" }), _jsxs(DialogDescription, { children: [result?.checkedCount, " klaar \u00B7 ", result?.rescheduledCount, " doorgeschoven \u00B7", " ", result?.blockedCount, " geblokkeerd"] })] }), _jsxs(ResponsiveDialogBody, { className: "space-y-4", children: [result?.blocked && result.blocked.length > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2 text-destructive font-medium", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: "De volgende karren kunnen niet automatisch worden doorgeschoven omdat hierdoor de planning of levering in gevaar komt." })] }), _jsx(BlockedTable, { blocked: result.blocked })] })), result?.rescheduled && result.rescheduled.length > 0 && (_jsxs("div", { className: "border rounded-md p-3", children: [_jsx("div", { className: "font-medium mb-2", children: "Doorgeschoven karren" }), _jsx("ul", { className: "text-sm space-y-1", children: result.rescheduled.map((r, i) => (_jsxs("li", { children: [_jsx("span", { className: "font-mono", children: r.cartNumber ?? "—" }), " \u2014", " ", r.customerName, " \u2192 nieuwe pickdatum", " ", _jsx("strong", { children: fmtDate(r.newPickDate) })] }, i))) })] }))] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { onClick: () => {
|
|
518
|
+
: "" })] }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Bijzonderheden, afwijkingen\u2026", rows: 3 }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Wordt automatisch bewaard tot de controle definitief is goedgekeurd." })] })] })), tab === "scan" && _jsx(ScanControleView, {}), tab === "afgeleverd" && (_jsx(AfgeleverdView, { loading: deliveredQ.isLoading, carts: deliveredQ.data?.carts ?? [] })), tab === "historie" && _jsx(HistorieView, { loading: histQ.isLoading, sessions: histQ.data?.sessions ?? [] }), _jsx(Dialog, { open: !!result, onOpenChange: (v) => !v && setResult(null), children: _jsxs(ResponsiveDialogContent, { size: "md", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsx(DialogTitle, { children: "Resultaat controle" }), _jsxs(DialogDescription, { children: [result?.checkedCount, " klaar \u00B7 ", result?.rescheduledCount, " doorgeschoven \u00B7", " ", result?.blockedCount, " geblokkeerd"] })] }), _jsxs(ResponsiveDialogBody, { className: "space-y-4", children: [result?.blocked && result.blocked.length > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2 text-destructive font-medium", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: "De volgende karren kunnen niet automatisch worden doorgeschoven omdat hierdoor de planning of levering in gevaar komt." })] }), _jsx(BlockedTable, { blocked: result.blocked })] })), result?.rescheduled && result.rescheduled.length > 0 && (_jsxs("div", { className: "border rounded-md p-3", children: [_jsx("div", { className: "font-medium mb-2", children: "Doorgeschoven karren" }), _jsx("ul", { className: "text-sm space-y-1", children: result.rescheduled.map((r, i) => (_jsxs("li", { children: [_jsx("span", { className: "font-mono", children: r.cartNumber ?? "—" }), " \u2014", " ", r.customerName, " \u2192 nieuwe pickdatum", " ", _jsx("strong", { children: fmtDate(r.newPickDate) })] }, i))) })] }))] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { onClick: () => {
|
|
485
519
|
setResult(null);
|
|
486
520
|
if (onExit)
|
|
487
521
|
onExit();
|
|
@@ -528,3 +562,9 @@ function SummaryTile({ label, value, tone = "default", }) {
|
|
|
528
562
|
}
|
|
529
563
|
// Silence unused Input import (may be used later); keep tree-shakeable
|
|
530
564
|
void Input;
|
|
565
|
+
function AfgeleverdView({ loading, carts }) {
|
|
566
|
+
return (_jsx(Card, { className: "p-0 overflow-hidden", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Karnummer" }), _jsx(TableHead, { children: "Gecontroleerd om" })] }) }), _jsxs(TableBody, { children: [loading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 3, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !loading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 3, className: "text-center text-muted-foreground py-8", children: "Vandaag zijn er nog geen karren afgeleverd." }) })), carts.map((c, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-mono font-semibold", children: c.orderNumber || "—" }), _jsx(TableCell, { className: "font-mono", children: c.cartNumberLabel || "—" }), _jsx(TableCell, { children: new Date(c.deliveredAt).toLocaleTimeString("nl-NL", {
|
|
567
|
+
hour: "2-digit",
|
|
568
|
+
minute: "2-digit",
|
|
569
|
+
}) })] }, `${c.orderNumber ?? "?"}-${c.cartNumberLabel ?? i}-${i}`)))] })] }) }));
|
|
570
|
+
}
|
|
@@ -5,5 +5,5 @@ export interface DagDetailDialogProps {
|
|
|
5
5
|
planned: PlannedOrder[];
|
|
6
6
|
onOpenChange: (open: boolean) => void;
|
|
7
7
|
}
|
|
8
|
-
export declare function DagDetailDialog(
|
|
8
|
+
export declare function DagDetailDialog(props: DagDetailDialogProps): import("react").JSX.Element | null;
|
|
9
9
|
//# sourceMappingURL=DagDetailDialog.d.ts.map
|
|
@@ -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;AAyEjE,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;AAQD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,sCAG1D"}
|