@flowselections/floriday-afhandeling-module 1.0.48 → 1.0.50
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.map +1 -1
- package/dist-lib/components/afhandeling/AutoProcessStatus.js +4 -1
- package/dist-lib/components/afhandeling/ControlePage.js +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +12 -6
- package/dist-lib/components/afhandeling/NuVersturenButton.d.ts +5 -0
- package/dist-lib/components/afhandeling/NuVersturenButton.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/NuVersturenButton.js +50 -0
- package/dist-lib/components/afhandeling/ScanControleView.js +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.js +1 -1
- package/dist-lib/components/afhandeling/VerzetOrderDialog.js +1 -1
- package/dist-lib/components/afhandeling/WerkplekWaarschuwing.d.ts +9 -9
- package/dist-lib/components/afhandeling/WerkplekWaarschuwing.js +28 -28
- package/dist-lib/components/ui/responsive-dialog.js +1 -1
- package/dist-lib/hooks/usePickMode.d.ts +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +4 -31315
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +3518 -66
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.js +2 -1
- package/dist-lib/lib/authGateway.server.d.ts +2 -0
- package/dist-lib/lib/authGateway.server.d.ts.map +1 -1
- package/dist-lib/lib/authGateway.server.js +2 -2
- package/dist-lib/lib/cartAssignments.functions.d.ts +20 -3
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.js +48 -37
- package/dist-lib/lib/deliveryNotePrint.d.ts +33 -33
- package/dist-lib/lib/deliveryNotePrint.js +219 -219
- package/dist-lib/lib/floridayAutoProcess.d.ts +1 -1
- package/dist-lib/lib/floridayAutoProcess.d.ts.map +1 -1
- package/dist-lib/lib/floridayFulfillmentSend.server.d.ts +31 -0
- package/dist-lib/lib/floridayFulfillmentSend.server.d.ts.map +1 -0
- package/dist-lib/lib/floridayFulfillmentSend.server.js +75 -0
- package/dist-lib/lib/floridayLoading.functions.d.ts +91 -0
- package/dist-lib/lib/floridayLoading.functions.d.ts.map +1 -0
- package/dist-lib/lib/floridayLoading.functions.js +311 -0
- package/dist-lib/lib/logisticsEngine/capacity.js +1 -1
- package/dist-lib/lib/logisticsEngine/staffPlanning.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
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,+
|
|
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,+BAuLP"}
|
|
@@ -113,6 +113,9 @@ export function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, all
|
|
|
113
113
|
else if (status === "waiting_for_delivery_order") {
|
|
114
114
|
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " Wacht op Floriday delivery-order"] }));
|
|
115
115
|
}
|
|
116
|
+
else if (status === "waiting_for_afhandeling") {
|
|
117
|
+
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " Klaar voor belading"] }));
|
|
118
|
+
}
|
|
116
119
|
else if (status === "ready_to_fulfill") {
|
|
117
120
|
badge = (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(PlayCircle, { className: "h-3 w-3" }), " Klaar voor fulfillment"] }));
|
|
118
121
|
}
|
|
@@ -131,6 +134,6 @@ export function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, all
|
|
|
131
134
|
if (compact)
|
|
132
135
|
return _jsx(_Fragment, { children: badge });
|
|
133
136
|
const showRetry = status === "error";
|
|
134
|
-
const showTrigger = allowManualTrigger && status !== "done" && status !== "acknowledging" && !loading;
|
|
137
|
+
const showTrigger = allowManualTrigger && status !== "done" && status !== "acknowledging" && status !== "waiting_for_afhandeling" && !loading;
|
|
135
138
|
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] }));
|
|
136
139
|
}
|
|
@@ -2,7 +2,7 @@ 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 { Button, Card, Checkbox, Dialog, DialogDescription, DialogTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Textarea, Badge, toast, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
4
4
|
import { Printer, CheckCircle2, AlertTriangle, History, ChevronLeft, ChevronRight, ScanLine } from "lucide-react";
|
|
5
|
-
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "
|
|
5
|
+
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
6
6
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
7
7
|
import { useServerFn } from "@tanstack/react-start";
|
|
8
8
|
import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, listDeliveredToday, saveControlDraft, } from "../../lib/cartControl.functions";
|
|
@@ -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;AAkFjE,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"}
|
|
@@ -4,13 +4,14 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
5
5
|
import { Badge, Checkbox, Button, Dialog, DialogTitle, DialogDescription, Input, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
|
|
6
6
|
import { CalendarClock, CheckCircle2, ChevronDown, ChevronRight, Printer, Users } from "lucide-react";
|
|
7
|
-
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "
|
|
7
|
+
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
8
8
|
import { usePickAgenda } from "../../hooks/usePickAgenda";
|
|
9
9
|
import { useOrderBuffers } from "../../hooks/useOrderBuffers";
|
|
10
10
|
import { isSameDay } from "../../lib/pickDate";
|
|
11
11
|
import { getOrderLines, getDayCartContents, } from "../../lib/cartAssignments.functions";
|
|
12
12
|
import { printLayoutDocument, printPdfDocument, printFoutMelding } from "../../lib/printing";
|
|
13
13
|
import { AutoProcessStatus } from "./AutoProcessStatus";
|
|
14
|
+
import { NuVersturenButton } from "./NuVersturenButton";
|
|
14
15
|
import { CapacityWarning } from "./CapacityWarning";
|
|
15
16
|
import { useCapacityCheck } from "../../hooks/useCapacityCheck";
|
|
16
17
|
import { toDayKey } from "../../lib/logisticsEngine/capacity";
|
|
@@ -97,11 +98,14 @@ function DagDetailContent({ open, date, planned, onOpenChange, }) {
|
|
|
97
98
|
list.push(c);
|
|
98
99
|
contentsByRef.set(k, list);
|
|
99
100
|
}
|
|
100
|
-
|
|
101
|
+
const coverageByRef = new Map();
|
|
102
|
+
for (const o of contentsQuery.data?.orders ?? [])
|
|
103
|
+
coverageByRef.set(refKey(o.orderRef), o.label);
|
|
104
|
+
// Eén rij per kar die op deze dag valt (Engine-dekking is leidend, ook voor bufferkarren).
|
|
101
105
|
const cartRows = [];
|
|
102
106
|
for (const o of ordersOnDay) {
|
|
103
|
-
const total = Math.max(0, o.carts);
|
|
104
107
|
const real = contentsByRef.get(refKey(o.ref)) ?? [];
|
|
108
|
+
const total = Math.max(0, real.length || o.carts);
|
|
105
109
|
for (let idx = 0; idx < total; idx++) {
|
|
106
110
|
const rc = real[idx] ?? null;
|
|
107
111
|
const nr = rc?.cartNumber ?? idx + 1;
|
|
@@ -118,6 +122,8 @@ function DagDetailContent({ open, date, planned, onOpenChange, }) {
|
|
|
118
122
|
plants: rc?.plants ?? null,
|
|
119
123
|
occupancy: rc?.occupancy ?? null,
|
|
120
124
|
layerUtilization: rc?.layerUtilization ?? null,
|
|
125
|
+
shared: rc?.shared ?? false,
|
|
126
|
+
coverageLabel: coverageByRef.get(refKey(o.ref)) ?? null,
|
|
121
127
|
hasContent: !!rc,
|
|
122
128
|
contentLoading: contentsQuery.isLoading,
|
|
123
129
|
status: o.status,
|
|
@@ -439,7 +445,7 @@ function OrderRow({ planned: p, cartsToday, engineStatus, }) {
|
|
|
439
445
|
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
440
446
|
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
441
447
|
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId, orderRef: p.order.orderNumber })) : null;
|
|
442
|
-
})(), _jsx(AfhandelenButton, { orderRef: p.order.orderNumber, done: voortgang(p.order.status).done }), _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) => {
|
|
448
|
+
})(), p.order.orderNumber ? _jsx(NuVersturenButton, { orderRef: p.order.orderNumber }) : null, _jsx(AfhandelenButton, { orderRef: p.order.orderNumber, done: voortgang(p.order.status).done }), _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) => {
|
|
443
449
|
e.stopPropagation();
|
|
444
450
|
setVerzetOpen(true);
|
|
445
451
|
}, 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: {
|
|
@@ -622,9 +628,9 @@ function KarRow({ cart: c, cartTotal, selected, onToggle, }) {
|
|
|
622
628
|
setBezig(null);
|
|
623
629
|
}
|
|
624
630
|
};
|
|
625
|
-
return (_jsxs("div", { className: `rounded-md border p-3 ${selected ? "border-primary bg-primary/5" : ""}`, children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { checked: selected, onCheckedChange: onToggle, className: "mt-1" }), _jsxs("div", { className: "grid flex-1 gap-3 lg:grid-cols-[1fr_1.4fr_1fr_auto] lg:items-center", children: [_jsx(Field, { label: "Karnummer", value: c.cartNumber }), _jsx(Field, { label: "Klant", value: c.customerName }), _jsx(Field, { label: "Bestelling", value: c.orderRef }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Badge, { variant: voortgang(c.status).variant, children: voortgang(c.status).label }), c.hasContent ? (_jsxs(_Fragment, { children: [_jsxs(Badge, { variant: "outline", children: [c.occupancy ?? "—", "%", c.layerUtilization != null
|
|
631
|
+
return (_jsxs("div", { className: `rounded-md border p-3 ${selected ? "border-primary bg-primary/5" : ""}`, children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { checked: selected, onCheckedChange: onToggle, className: "mt-1" }), _jsxs("div", { className: "grid flex-1 gap-3 lg:grid-cols-[1fr_1.4fr_1fr_auto] lg:items-center", children: [_jsx(Field, { label: "Karnummer", value: c.cartNumber }), _jsx(Field, { label: "Klant", value: c.customerName }), _jsx(Field, { label: "Bestelling", value: c.orderRef }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Badge, { variant: voortgang(c.status).variant, children: voortgang(c.status).label }), c.coverageLabel && _jsx(Badge, { variant: "secondary", children: c.coverageLabel }), c.hasContent ? (_jsxs(_Fragment, { children: [c.shared && _jsx(Badge, { variant: "outline", children: "Gedeelde bufferkar" }), _jsxs(Badge, { variant: "outline", children: [c.occupancy ?? "—", "%", c.layerUtilization != null
|
|
626
632
|
? ` · ${Number(c.layerUtilization.toFixed(1)).toLocaleString("nl-NL")}% van de kar`
|
|
627
|
-
: ""] }), _jsxs(Badge, { variant: "outline", children: [c.layers ?? "—", c.maxLayers != null ? ` / ${c.maxLayers}` : "", " lagen"] }), _jsxs(Badge, { variant: "outline", children: [c.crates ?? "—", " fusten"] }), _jsxs(Badge, { variant: "outline", children: [c.plants ?? "—", " planten"] })] })) : (_jsx(Badge, { variant: "outline", className: "text-muted-foreground", children: c.contentLoading ? "Karinhoud laden…" : "Nog geen karindeling" })), _jsxs(Button, { size: "sm", variant: "outline", disabled: bezig !== null, onClick: printPakbon, title: "Pakbon van deze kar opnieuw printen", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), bezig === "pakbon" ? "Bezig…" : "Pakbon"] }), _jsxs(Button, { size: "sm", variant: "outline", disabled: bezig !== null, onClick: printVerzendbrief, title: "Verzendbrief van deze bestelling printen", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), bezig === "brief" ? "Bezig…" : "Verzendbrief"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => setVerzetOpen(true), title: "Ophaaldag of ophaaltijd van de bestelling van deze kar wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: c.orderRef, carrierTarget: {
|
|
633
|
+
: ""] }), _jsxs(Badge, { variant: "outline", children: [c.layers ?? "—", c.maxLayers != null ? ` / ${c.maxLayers}` : "", " lagen"] }), _jsxs(Badge, { variant: "outline", children: [c.crates ?? "—", " fusten"] }), _jsxs(Badge, { variant: "outline", children: [c.plants ?? "—", " planten"] })] })) : (_jsx(Badge, { variant: "outline", className: "text-muted-foreground", children: c.contentLoading ? "Karinhoud laden…" : c.coverageLabel ? "Geen kar in deze indeling" : "Nog geen karindeling" })), _jsxs(Button, { size: "sm", variant: "outline", disabled: bezig !== null, onClick: printPakbon, title: "Pakbon van deze kar opnieuw printen", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), bezig === "pakbon" ? "Bezig…" : "Pakbon"] }), _jsxs(Button, { size: "sm", variant: "outline", disabled: bezig !== null, onClick: printVerzendbrief, title: "Verzendbrief van deze bestelling printen", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), bezig === "brief" ? "Bezig…" : "Verzendbrief"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => setVerzetOpen(true), title: "Ophaaldag of ophaaltijd van de bestelling van deze kar wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: c.orderRef, carrierTarget: {
|
|
628
634
|
carrierId: c.order?.order.carrierId ?? null,
|
|
629
635
|
country: c.order?.order.country ?? null,
|
|
630
636
|
province: c.order?.order.province ?? null,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NuVersturenButton.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/NuVersturenButton.tsx"],"names":[],"mappings":"AAYA,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,+BAkGnE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
4
|
+
import { Button, toast, AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@flowselections/core";
|
|
5
|
+
import { Send, Loader2, CheckCircle2, XCircle } from "lucide-react";
|
|
6
|
+
import { prepareFloridayLoading, sendFloridayLoading, } from "../../lib/floridayLoading.functions";
|
|
7
|
+
/** "Nu versturen": toont eerst een samenvatting met controles en vraagt bevestiging. */
|
|
8
|
+
export function NuVersturenButton({ orderRef }) {
|
|
9
|
+
const prepare = useServerFn(prepareFloridayLoading);
|
|
10
|
+
const send = useServerFn(sendFloridayLoading);
|
|
11
|
+
const [loading, setLoading] = useState(false);
|
|
12
|
+
const [sending, setSending] = useState(false);
|
|
13
|
+
const [preview, setPreview] = useState(null);
|
|
14
|
+
const load = async () => setPreview(await prepare({ data: { orderRef } }));
|
|
15
|
+
const open = async () => {
|
|
16
|
+
setLoading(true);
|
|
17
|
+
try {
|
|
18
|
+
await load();
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
toast.error(e instanceof Error ? e.message : "Belading samenstellen mislukt");
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
setLoading(false);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const doSend = async () => {
|
|
28
|
+
setSending(true);
|
|
29
|
+
try {
|
|
30
|
+
const r = await send({ data: { orderRef } });
|
|
31
|
+
for (const x of r.results) {
|
|
32
|
+
const text = x.code === "created" || x.code === "already_fulfilled" ? x.message : `${x.code}: ${x.message}`;
|
|
33
|
+
if (x.code === "created" || x.code === "already_fulfilled")
|
|
34
|
+
toast.success(text);
|
|
35
|
+
else
|
|
36
|
+
toast.error(text);
|
|
37
|
+
}
|
|
38
|
+
await load();
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
toast.error(e instanceof Error ? e.message : "Versturen mislukt");
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
setSending(false);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: open, disabled: loading, children: [loading ? _jsx(Loader2, { className: "h-3 w-3 mr-1 animate-spin" }) : _jsx(Send, { className: "h-3 w-3 mr-1" }), "Nu versturen"] }), _jsx(AlertDialog, { open: !!preview, onOpenChange: (o) => !o && !sending && setPreview(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Belading naar Floriday versturen?" }), _jsx(AlertDialogDescription, { children: "Een geaccepteerde opdracht start de verzendbrief, vooraankondiging, fust-administratie en afrekening, en is op productie niet terug te draaien." })] }), preview && (_jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Orders:" }), " ", preview.orderRefs.join(", ")] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Leveringen:" }), " ", preview.shipments.length] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Karren:" }), " ", preview.cartCount, preview.carriers.some((c) => c.shared) ? " (waarvan gedeeld)" : ""] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Regels:" }), " ", preview.lineCount] }), _jsx("ul", { className: "space-y-1", children: preview.orders.map((o) => (_jsxs("li", { className: "flex items-center gap-2", children: [o.controlled
|
|
48
|
+
? _jsx(CheckCircle2, { className: "h-3.5 w-3.5 text-primary" })
|
|
49
|
+
: _jsx(XCircle, { className: "h-3.5 w-3.5 text-destructive" }), _jsxs("span", { children: [o.orderRef, ": ", o.cartsControlled, "/", o.cartsTotal, " karren goedgekeurd op Scan-controle \u00B7 ", o.pickStatus ?? "geen pickrij", o.autoStatus ? ` · auto-verwerking: ${o.autoStatus}` : ""] })] }, o.orderRef))) }), preview.shipments.filter((sh) => sh.floridayStatus || preview.lastAttempts.some((a) => a.fulfillmentOrderId === sh.fulfillmentOrderId && (a.code === "created" || a.code === "already_fulfilled"))).map((sh) => (_jsxs("div", { className: "rounded border border-border p-2", children: ["Belading verstuurd", sh.floridayStatus ? ` (Floriday: ${sh.floridayStatus})` : "", " \u00B7", " ", sh.deliveryNoteReady === true ? "verzendbrief klaar" : "verzendbrief volgt via de Engine"] }, sh.fulfillmentOrderId))), preview.lastAttempts.length > 0 && (_jsxs("div", { className: "rounded border border-border p-2", children: [_jsx("div", { className: "text-muted-foreground mb-1", children: "Laatste pogingen" }), preview.lastAttempts.slice(0, 4).map((a) => (_jsxs("div", { children: [new Date(a.createdAt).toLocaleString("nl-NL"), " \u00B7 versturen \u00B7 ", a.code] }, a.createdAt + a.step)))] })), preview.blockers.length > 0 && (_jsx("ul", { className: "list-disc pl-5 text-destructive", children: preview.blockers.map((b) => _jsx("li", { children: b }, b)) }))] })), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: sending, children: "Annuleren" }), _jsxs(Button, { onClick: doSend, disabled: !preview?.canSend || sending, children: [sending ? _jsx(Loader2, { className: "h-3 w-3 mr-1 animate-spin" }) : null, "Versturen"] })] })] }) })] }));
|
|
50
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { supabase } from "../../integrations/supabase/moduleClient
|
|
3
|
+
import { supabase } from "../../integrations/supabase/moduleClient";
|
|
4
4
|
import { Button, Badge, Card, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, } from "@flowselections/core";
|
|
5
5
|
import { AlertTriangle, CheckCircle2, RefreshCw, ScanLine } from "lucide-react";
|
|
6
6
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogDescription, AlertDialogTitle, toast, } from "@flowselections/core";
|
|
4
4
|
import { Plus, Pencil, Trash2, Truck, ArrowUp, ArrowDown } from "lucide-react";
|
|
5
|
-
import { ResponsiveAlertDialogBody, ResponsiveAlertDialogContent, ResponsiveAlertDialogFooter, ResponsiveAlertDialogHeader, } from "
|
|
5
|
+
import { ResponsiveAlertDialogBody, ResponsiveAlertDialogContent, ResponsiveAlertDialogFooter, ResponsiveAlertDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
6
6
|
import { Link } from "@tanstack/react-router";
|
|
7
7
|
import { useServerFn } from "@tanstack/react-start";
|
|
8
8
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
@@ -3,7 +3,7 @@ import { useEffect, useMemo, useState } from "react";
|
|
|
3
3
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
5
5
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Dialog, DialogTitle, DialogDescription, Input, Label, Textarea, toast, } from "@flowselections/core";
|
|
6
|
-
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "
|
|
6
|
+
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
7
7
|
import { applyReschedule, listRescheduleHistory, previewReschedule, getPickMoments, setPickDay, } from "../../lib/logisticsEngine/reschedule";
|
|
8
8
|
import { ENGINE_TASKS_KEY } from "../../hooks/useEngineTasks";
|
|
9
9
|
import { listCarriers } from "../../lib/carriers.functions";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/** Leest de ingestelde werkplek client-side (SSR-veilig). */
|
|
2
|
-
export declare function useWerkplek(): string | null;
|
|
3
|
-
/**
|
|
4
|
-
* Eén melding bovenaan een printscherm zolang er geen werkplek is ingesteld.
|
|
5
|
-
* Printknoppen zijn dan uitgeschakeld, zodat er geen fout per printactie komt.
|
|
6
|
-
*/
|
|
7
|
-
export declare function WerkplekWaarschuwing({ werkplek }: {
|
|
8
|
-
werkplek: string | null;
|
|
9
|
-
}): import("react").JSX.Element | null;
|
|
1
|
+
/** Leest de ingestelde werkplek client-side (SSR-veilig). */
|
|
2
|
+
export declare function useWerkplek(): string | null;
|
|
3
|
+
/**
|
|
4
|
+
* Eén melding bovenaan een printscherm zolang er geen werkplek is ingesteld.
|
|
5
|
+
* Printknoppen zijn dan uitgeschakeld, zodat er geen fout per printactie komt.
|
|
6
|
+
*/
|
|
7
|
+
export declare function WerkplekWaarschuwing({ werkplek }: {
|
|
8
|
+
werkplek: string | null;
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
10
10
|
//# sourceMappingURL=WerkplekWaarschuwing.d.ts.map
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
import { AlertTriangle } from "lucide-react";
|
|
4
|
-
import { getWerkplek } from "../../lib/printing";
|
|
5
|
-
/** Leest de ingestelde werkplek client-side (SSR-veilig). */
|
|
6
|
-
export function useWerkplek() {
|
|
7
|
-
const [werkplek, setWerkplekState] = useState(null);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
setWerkplekState(getWerkplek());
|
|
10
|
-
const onStorage = () => setWerkplekState(getWerkplek());
|
|
11
|
-
window.addEventListener("storage", onStorage);
|
|
12
|
-
window.addEventListener("focus", onStorage);
|
|
13
|
-
return () => {
|
|
14
|
-
window.removeEventListener("storage", onStorage);
|
|
15
|
-
window.removeEventListener("focus", onStorage);
|
|
16
|
-
};
|
|
17
|
-
}, []);
|
|
18
|
-
return werkplek;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Eén melding bovenaan een printscherm zolang er geen werkplek is ingesteld.
|
|
22
|
-
* Printknoppen zijn dan uitgeschakeld, zodat er geen fout per printactie komt.
|
|
23
|
-
*/
|
|
24
|
-
export function WerkplekWaarschuwing({ werkplek }) {
|
|
25
|
-
if (werkplek)
|
|
26
|
-
return null;
|
|
27
|
-
return (_jsxs("div", { className: "flex items-start gap-2 rounded-lg border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), _jsxs("div", { children: [_jsx("span", { className: "font-medium", children: "Geen werkplek ingesteld." }), " Printen is uitgeschakeld. Stel de werkplek (pickstation- of computernaam) in bij ", _jsx("strong", { children: "Instellingen" }), "."] })] }));
|
|
28
|
-
}
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { AlertTriangle } from "lucide-react";
|
|
4
|
+
import { getWerkplek } from "../../lib/printing";
|
|
5
|
+
/** Leest de ingestelde werkplek client-side (SSR-veilig). */
|
|
6
|
+
export function useWerkplek() {
|
|
7
|
+
const [werkplek, setWerkplekState] = useState(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
setWerkplekState(getWerkplek());
|
|
10
|
+
const onStorage = () => setWerkplekState(getWerkplek());
|
|
11
|
+
window.addEventListener("storage", onStorage);
|
|
12
|
+
window.addEventListener("focus", onStorage);
|
|
13
|
+
return () => {
|
|
14
|
+
window.removeEventListener("storage", onStorage);
|
|
15
|
+
window.removeEventListener("focus", onStorage);
|
|
16
|
+
};
|
|
17
|
+
}, []);
|
|
18
|
+
return werkplek;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Eén melding bovenaan een printscherm zolang er geen werkplek is ingesteld.
|
|
22
|
+
* Printknoppen zijn dan uitgeschakeld, zodat er geen fout per printactie komt.
|
|
23
|
+
*/
|
|
24
|
+
export function WerkplekWaarschuwing({ werkplek }) {
|
|
25
|
+
if (werkplek)
|
|
26
|
+
return null;
|
|
27
|
+
return (_jsxs("div", { className: "flex items-start gap-2 rounded-lg border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), _jsxs("div", { children: [_jsx("span", { className: "font-medium", children: "Geen werkplek ingesteld." }), " Printen is uitgeschakeld. Stel de werkplek (pickstation- of computernaam) in bij ", _jsx("strong", { children: "Instellingen" }), "."] })] }));
|
|
28
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { AlertDialogContent, AlertDialogFooter, AlertDialogHeader, DialogContent, DialogFooter, DialogHeader, } from "@flowselections/core";
|
|
3
|
-
import { cn } from "../../lib/utils
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
4
|
const WIDTH_BY_SIZE = {
|
|
5
5
|
sm: "min(40rem, calc(100vw - 2rem))",
|
|
6
6
|
md: "min(48rem, calc(100vw - 2rem))",
|
|
@@ -11,6 +11,6 @@ export declare function usePickMode(): {
|
|
|
11
11
|
isError: boolean;
|
|
12
12
|
isUnknown: boolean;
|
|
13
13
|
error: string | undefined;
|
|
14
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<PickModeInfo
|
|
14
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<PickModeInfo>, Error>>;
|
|
15
15
|
};
|
|
16
16
|
//# sourceMappingURL=usePickMode.d.ts.map
|
|
@@ -20,7 +20,7 @@ function createSupabaseAdminClient() {
|
|
|
20
20
|
let _supabaseAdmin;
|
|
21
21
|
// Server-side Supabase client with service role - bypasses RLS
|
|
22
22
|
// SECURITY: Only use this for trusted server-side operations, never expose to client code
|
|
23
|
-
// Import like: import { supabaseAdmin } from "
|
|
23
|
+
// Import like: import { supabaseAdmin } from "../../integrations/supabase/client.server";
|
|
24
24
|
export const supabaseAdmin = new Proxy({}, {
|
|
25
25
|
get(_, prop, receiver) {
|
|
26
26
|
if (!_supabaseAdmin)
|