@flowselections/floriday-verkoop-module 1.0.21 → 1.0.24
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/karindeling/AfmetingenTab.d.ts +6 -0
- package/dist-lib/components/karindeling/AfmetingenTab.d.ts.map +1 -0
- package/dist-lib/components/karindeling/AfmetingenTab.js +128 -0
- package/dist-lib/components/karindeling/KarindelingPage.d.ts +2 -0
- package/dist-lib/components/karindeling/KarindelingPage.d.ts.map +1 -0
- package/dist-lib/components/karindeling/KarindelingPage.js +102 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +83 -37
- package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailPage.js +59 -8
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts +2 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -2
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +36 -4
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +18 -2
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +12 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1531 -592
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1531 -592
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.js +24 -9
- package/dist-lib/integrations/supabase/client.server.d.ts +1531 -592
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1542 -577
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +3 -9
- package/dist-lib/lib/cart-lock.functions.d.ts +1531 -592
- package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-planner.d.ts +9 -1
- package/dist-lib/lib/cart-planner.d.ts.map +1 -1
- package/dist-lib/lib/cart-planner.js +21 -4
- package/dist-lib/lib/cart-planning-settings.functions.d.ts +140842 -0
- package/dist-lib/lib/cart-planning-settings.functions.d.ts.map +1 -0
- package/dist-lib/lib/cart-planning-settings.functions.js +375 -0
- package/dist-lib/lib/cart-replan.functions.d.ts +15808 -1111
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-replan.functions.js +85 -27
- package/dist-lib/lib/create-order.functions.d.ts +19021 -7753
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +4558 -1741
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-auto-fulfillment.server.js +1 -1
- package/dist-lib/lib/floriday-central-token.server.d.ts +12 -0
- package/dist-lib/lib/floriday-central-token.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-central-token.server.js +58 -0
- package/dist-lib/lib/floriday-gateway.server.d.ts +2 -2
- package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.server.js +10 -37
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +1531 -592
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-logistic-labels.functions.js +14 -4
- package/dist-lib/lib/floriday-mirror.functions.d.ts +12806 -0
- package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-mirror.functions.js +278 -0
- package/dist-lib/lib/floriday-public.functions.d.ts +10986 -4413
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-sync.d.ts +0 -1
- package/dist-lib/lib/floriday-sync.d.ts.map +1 -1
- package/dist-lib/lib/floriday-sync.js +1 -1
- package/dist-lib/lib/floriday-writes.functions.d.ts +7772 -3077
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-buffers.functions.d.ts +38420 -0
- package/dist-lib/lib/order-buffers.functions.d.ts.map +1 -0
- package/dist-lib/lib/order-buffers.functions.js +244 -0
- package/dist-lib/lib/order-shipments.functions.d.ts +6165 -2409
- package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.d.ts +3 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.d.ts +7774 -3077
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.js +129 -3
- package/dist-lib/lib/tradeitems.functions.d.ts +1531 -592
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +37 -2
- package/package.json +5 -5
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CartType, type CrateType } from "../../lib/cart-planning-settings.functions";
|
|
2
|
+
export declare function AfmetingenTab({ cartTypes, crateTypes, }: {
|
|
3
|
+
cartTypes: CartType[];
|
|
4
|
+
crateTypes: CrateType[];
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=AfmetingenTab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AfmetingenTab.d.ts","sourceRoot":"","sources":["../../../src/components/karindeling/AfmetingenTab.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,SAAS,EACf,MAAM,wCAAwC,CAAC;AAMhD,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,UAAU,GACX,EAAE;IACD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,2CA+BA"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
5
|
+
import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Label, Separator, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, } from "@flowselections/core";
|
|
6
|
+
import { Star, Trash2 } from "lucide-react";
|
|
7
|
+
import { deleteCartType, deleteCrateType, listUsedCartCarriers, listUsedCratePackages, setDefaultCartType, upsertCartType, upsertCrateType, } from "../../lib/cart-planning-settings.functions";
|
|
8
|
+
function areaM2(lengthCm, widthCm) {
|
|
9
|
+
return ((lengthCm * widthCm) / 10000).toFixed(2);
|
|
10
|
+
}
|
|
11
|
+
export function AfmetingenTab({ cartTypes, crateTypes, }) {
|
|
12
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Karren / containers" }), _jsxs(CardDescription, { children: ["Stel per kar-type de laag-afmetingen in. Fusten per laag =", " ", _jsx("em", { children: "laag-oppervlakte / fust-oppervlakte" }), ". \u00C9\u00E9n type is de standaard en wordt gebruikt door de planner."] })] }), _jsx(CardContent, { className: "space-y-4", children: _jsx(CartTypesEditor, { cartTypes: cartTypes }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Fusten" }), _jsx(CardDescription, { children: "Stel per fust-type de afmetingen in. Wordt gecombineerd met het gekozen kar-type om te bepalen hoeveel fusten er op een laag passen (ook bij menging)." })] }), _jsx(CardContent, { className: "space-y-4", children: _jsx(CrateTypesEditor, { crateTypes: crateTypes }) })] })] }));
|
|
13
|
+
}
|
|
14
|
+
function CartTypesEditor({ cartTypes }) {
|
|
15
|
+
const qc = useQueryClient();
|
|
16
|
+
const upsert = useServerFn(upsertCartType);
|
|
17
|
+
const remove = useServerFn(deleteCartType);
|
|
18
|
+
const setDefault = useServerFn(setDefaultCartType);
|
|
19
|
+
const fetchCarriers = useServerFn(listUsedCartCarriers);
|
|
20
|
+
const { data: carriers = [] } = useQuery({
|
|
21
|
+
queryKey: ["used-cart-carriers"],
|
|
22
|
+
queryFn: () => fetchCarriers(),
|
|
23
|
+
});
|
|
24
|
+
const [name, setName] = useState("");
|
|
25
|
+
const [len, setLen] = useState(135);
|
|
26
|
+
const [wid, setWid] = useState(56);
|
|
27
|
+
const [layers, setLayers] = useState(4);
|
|
28
|
+
const invalidate = () => qc.invalidateQueries({ queryKey: ["cart-planning-bundle"] });
|
|
29
|
+
const addMut = useMutation({
|
|
30
|
+
mutationFn: () => upsert({
|
|
31
|
+
data: {
|
|
32
|
+
name: name.trim(),
|
|
33
|
+
layer_length_cm: len,
|
|
34
|
+
layer_width_cm: wid,
|
|
35
|
+
layers_per_cart: layers,
|
|
36
|
+
is_default: cartTypes.length === 0,
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
onSuccess: () => {
|
|
40
|
+
toast.success("Kar-type opgeslagen");
|
|
41
|
+
setName("");
|
|
42
|
+
setLen(135);
|
|
43
|
+
setWid(56);
|
|
44
|
+
setLayers(4);
|
|
45
|
+
invalidate();
|
|
46
|
+
},
|
|
47
|
+
onError: (e) => toast.error(e?.message ?? "Fout"),
|
|
48
|
+
});
|
|
49
|
+
const delMut = useMutation({
|
|
50
|
+
mutationFn: (id) => remove({ data: { id } }),
|
|
51
|
+
onSuccess: invalidate,
|
|
52
|
+
});
|
|
53
|
+
const defMut = useMutation({
|
|
54
|
+
mutationFn: (id) => setDefault({ data: { id } }),
|
|
55
|
+
onSuccess: () => {
|
|
56
|
+
toast.success("Standaard bijgewerkt");
|
|
57
|
+
invalidate();
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-3 rounded-md border p-3 lg:grid-cols-5", children: [_jsxs("div", { className: "space-y-2 lg:col-span-2", children: [_jsx(Label, { children: "Naam" }), _jsx(Input, { list: "used-cart-carriers", value: name, onChange: (e) => {
|
|
61
|
+
const v = e.target.value;
|
|
62
|
+
setName(v);
|
|
63
|
+
const match = carriers.find((c) => c.label === v || c.name === v);
|
|
64
|
+
if (match) {
|
|
65
|
+
if (match.layer_length_cm)
|
|
66
|
+
setLen(match.layer_length_cm);
|
|
67
|
+
if (match.layer_width_cm)
|
|
68
|
+
setWid(match.layer_width_cm);
|
|
69
|
+
if (match.layers_per_cart)
|
|
70
|
+
setLayers(match.layers_per_cart);
|
|
71
|
+
}
|
|
72
|
+
}, placeholder: carriers.length > 0
|
|
73
|
+
? "Kies uit lijst of typ zelf"
|
|
74
|
+
: "bv. Deense container" }), _jsx("datalist", { id: "used-cart-carriers", children: carriers.map((c) => (_jsx("option", { value: c.label, children: c.usage_count > 0 ? `${c.usage_count}× gebruikt` : "niet in gebruik" }, c.key))) }), carriers.length > 0 && (_jsxs("p", { className: "text-xs text-muted-foreground", children: [carriers.length, " kar-types bekend uit Floriday; afmetingen worden automatisch ingevuld."] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Lengte (cm)" }), _jsx(Input, { type: "number", min: 1, value: len, onChange: (e) => setLen(Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Breedte (cm)" }), _jsx(Input, { type: "number", min: 1, value: wid, onChange: (e) => setWid(Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Lagen / kar" }), _jsx(Input, { type: "number", min: 1, value: layers, onChange: (e) => setLayers(Number(e.target.value)) })] }), _jsx("div", { className: "lg:col-span-5", children: _jsx(Button, { disabled: !name.trim() || addMut.isPending, onClick: () => addMut.mutate(), children: "Toevoegen" }) })] }), _jsx(Separator, {}), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Naam" }), _jsx(TableHead, { className: "text-right", children: "Lengte" }), _jsx(TableHead, { className: "text-right", children: "Breedte" }), _jsx(TableHead, { className: "text-right", children: "Oppervlakte (m\u00B2)" }), _jsx(TableHead, { children: "Standaard" }), _jsx(TableHead, { className: "w-16" })] }) }), _jsx(TableBody, { children: cartTypes.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 6, className: "text-sm text-muted-foreground", children: "Nog geen kar-types." }) })) : (cartTypes.map((c) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: c.name }), _jsxs(TableCell, { className: "text-right", children: [c.layer_length_cm, " cm"] }), _jsxs(TableCell, { className: "text-right", children: [c.layer_width_cm, " cm"] }), _jsx(TableCell, { className: "text-right", children: areaM2(c.layer_length_cm, c.layer_width_cm) }), _jsx(TableCell, { children: c.is_default ? (_jsx(Badge, { children: "Standaard" })) : (_jsxs(Button, { size: "sm", variant: "ghost", onClick: () => defMut.mutate(c.id), disabled: defMut.isPending, children: [_jsx(Star, { className: "mr-1 h-4 w-4" }), " Maak standaard"] })) }), _jsx(TableCell, { children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => delMut.mutate(c.id), children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, c.id)))) })] })] }));
|
|
75
|
+
}
|
|
76
|
+
function CrateTypesEditor({ crateTypes }) {
|
|
77
|
+
const qc = useQueryClient();
|
|
78
|
+
const upsert = useServerFn(upsertCrateType);
|
|
79
|
+
const remove = useServerFn(deleteCrateType);
|
|
80
|
+
const fetchUsed = useServerFn(listUsedCratePackages);
|
|
81
|
+
const { data: usedPackages = [] } = useQuery({
|
|
82
|
+
queryKey: ["used-crate-packages"],
|
|
83
|
+
queryFn: () => fetchUsed(),
|
|
84
|
+
});
|
|
85
|
+
const [name, setName] = useState("");
|
|
86
|
+
const [len, setLen] = useState(60);
|
|
87
|
+
const [wid, setWid] = useState(40);
|
|
88
|
+
const [plants, setPlants] = useState(1);
|
|
89
|
+
const invalidate = () => qc.invalidateQueries({ queryKey: ["cart-planning-bundle"] });
|
|
90
|
+
const addMut = useMutation({
|
|
91
|
+
mutationFn: () => upsert({
|
|
92
|
+
data: {
|
|
93
|
+
name: name.trim(),
|
|
94
|
+
length_cm: len,
|
|
95
|
+
width_cm: wid,
|
|
96
|
+
plants_per_crate: plants,
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
onSuccess: () => {
|
|
100
|
+
toast.success("Fust-type opgeslagen");
|
|
101
|
+
setName("");
|
|
102
|
+
setLen(60);
|
|
103
|
+
setWid(40);
|
|
104
|
+
setPlants(1);
|
|
105
|
+
invalidate();
|
|
106
|
+
},
|
|
107
|
+
onError: (e) => toast.error(e?.message ?? "Fout"),
|
|
108
|
+
});
|
|
109
|
+
const delMut = useMutation({
|
|
110
|
+
mutationFn: (id) => remove({ data: { id } }),
|
|
111
|
+
onSuccess: invalidate,
|
|
112
|
+
});
|
|
113
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-3 rounded-md border p-3 lg:grid-cols-5", children: [_jsxs("div", { className: "space-y-2 lg:col-span-2", children: [_jsx(Label, { children: "Naam" }), _jsx(Input, { list: "used-crate-packages", value: name, onChange: (e) => {
|
|
114
|
+
const v = e.target.value;
|
|
115
|
+
setName(v);
|
|
116
|
+
const match = usedPackages.find((p) => p.label === v);
|
|
117
|
+
if (match) {
|
|
118
|
+
if (match.pieces_per_package)
|
|
119
|
+
setPlants(match.pieces_per_package);
|
|
120
|
+
if (match.length_cm)
|
|
121
|
+
setLen(match.length_cm);
|
|
122
|
+
if (match.width_cm)
|
|
123
|
+
setWid(match.width_cm);
|
|
124
|
+
}
|
|
125
|
+
}, placeholder: usedPackages.length > 0
|
|
126
|
+
? "Kies uit lijst of typ zelf"
|
|
127
|
+
: "bv. Fust 40x60" }), _jsx("datalist", { id: "used-crate-packages", children: usedPackages.map((p) => (_jsx("option", { value: p.label, children: p.usage_count > 0 ? `${p.usage_count}× gebruikt` : "niet in gebruik" }, p.key))) }), usedPackages.length > 0 && (_jsxs("p", { className: "text-xs text-muted-foreground", children: [usedPackages.length, " fusten bekend uit VBN-lijst; afmetingen worden automatisch ingevuld."] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Lengte (cm)" }), _jsx(Input, { type: "number", min: 1, value: len, onChange: (e) => setLen(Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Breedte (cm)" }), _jsx(Input, { type: "number", min: 1, value: wid, onChange: (e) => setWid(Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Planten / fust" }), _jsx(Input, { type: "number", min: 1, value: plants, onChange: (e) => setPlants(Number(e.target.value)) })] }), _jsx("div", { className: "lg:col-span-5", children: _jsx(Button, { disabled: !name.trim() || addMut.isPending, onClick: () => addMut.mutate(), children: "Toevoegen" }) })] }), _jsx(Separator, {}), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Naam" }), _jsx(TableHead, { className: "text-right", children: "Lengte" }), _jsx(TableHead, { className: "text-right", children: "Breedte" }), _jsx(TableHead, { className: "text-right", children: "Oppervlakte (m\u00B2)" }), _jsx(TableHead, { className: "text-right", children: "Planten / fust" }), _jsx(TableHead, { className: "w-16" })] }) }), _jsx(TableBody, { children: crateTypes.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 6, className: "text-sm text-muted-foreground", children: "Nog geen fust-types." }) })) : (crateTypes.map((c) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: c.name }), _jsxs(TableCell, { className: "text-right", children: [c.length_cm, " cm"] }), _jsxs(TableCell, { className: "text-right", children: [c.width_cm, " cm"] }), _jsx(TableCell, { className: "text-right", children: areaM2(c.length_cm, c.width_cm) }), _jsx(TableCell, { className: "text-right", children: c.plants_per_crate }), _jsx(TableCell, { children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => delMut.mutate(c.id), children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, c.id)))) })] })] }));
|
|
128
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KarindelingPage.d.ts","sourceRoot":"","sources":["../../../src/components/karindeling/KarindelingPage.tsx"],"names":[],"mappings":"AA8CA,wBAAgB,eAAe,4CAuD9B"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
5
|
+
import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
|
|
6
|
+
import { Trash2 } from "lucide-react";
|
|
7
|
+
import { deletePickTime, getCartPlanningBundle, updateCartPlanningSettings, upsertPickTime, } from "../../lib/cart-planning-settings.functions";
|
|
8
|
+
import { rebufferAllOrders } from "../../lib/order-buffers.functions";
|
|
9
|
+
import { AfmetingenTab } from "./AfmetingenTab";
|
|
10
|
+
export function KarindelingPage() {
|
|
11
|
+
const fetchBundle = useServerFn(getCartPlanningBundle);
|
|
12
|
+
const { data, isLoading } = useQuery({
|
|
13
|
+
queryKey: ["cart-planning-bundle"],
|
|
14
|
+
queryFn: () => fetchBundle(),
|
|
15
|
+
});
|
|
16
|
+
return (_jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Karindeling" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Bepaal hoe de karplanner orders indeelt op karren." })] }), _jsxs(Tabs, { defaultValue: "regels", className: "space-y-4", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "regels", children: "Regels" }), _jsx(TabsTrigger, { value: "afmetingen", children: "Afmetingen" }), _jsx(TabsTrigger, { value: "picktijden", children: "Picktijden" }), _jsx(TabsTrigger, { value: "combineren", children: "Combineren" }), _jsx(TabsTrigger, { value: "orderbuffer", children: "Orderbuffer" }), _jsx(TabsTrigger, { value: "pickstation", children: "Pickstation" })] }), isLoading || !data ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Laden\u2026" })) : (_jsxs(_Fragment, { children: [_jsx(TabsContent, { value: "regels", children: _jsx(RegelsTab, { settings: data.settings }) }), _jsx(TabsContent, { value: "afmetingen", children: _jsx(AfmetingenTab, { cartTypes: data.cartTypes, crateTypes: data.crateTypes }) }), _jsx(TabsContent, { value: "picktijden", children: _jsx(PicktijdenTab, { settings: data.settings, pickTimes: data.pickTimes }) }), _jsx(TabsContent, { value: "combineren", children: _jsx(CombinerenTab, { settings: data.settings }) }), _jsx(TabsContent, { value: "orderbuffer", children: _jsx(OrderbufferTab, { settings: data.settings }) }), _jsx(TabsContent, { value: "pickstation", children: _jsx(PickstationTab, { settings: data.settings }) })] }))] })] }));
|
|
17
|
+
}
|
|
18
|
+
function useSaveSettings() {
|
|
19
|
+
const qc = useQueryClient();
|
|
20
|
+
const save = useServerFn(updateCartPlanningSettings);
|
|
21
|
+
return useMutation({
|
|
22
|
+
mutationFn: (input) => save({ data: input }),
|
|
23
|
+
onSuccess: () => {
|
|
24
|
+
toast.success("Opgeslagen");
|
|
25
|
+
qc.invalidateQueries({ queryKey: ["cart-planning-bundle"] });
|
|
26
|
+
},
|
|
27
|
+
onError: (e) => toast.error(e?.message ?? "Opslaan mislukt"),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function stripId(s) {
|
|
31
|
+
const { id: _id, ...rest } = s;
|
|
32
|
+
return rest;
|
|
33
|
+
}
|
|
34
|
+
function RegelsTab({ settings }) {
|
|
35
|
+
const [s, setS] = useState(settings);
|
|
36
|
+
const mut = useSaveSettings();
|
|
37
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Globale planner-regels" }), _jsx(CardDescription, { children: "Deze regels gelden voor alle orders die automatisch op karren worden ingedeeld." })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Max % per partij per laag" }), _jsx(Input, { type: "number", min: 1, max: 100, value: s.max_party_share_per_layer_pct, onChange: (e) => setS({ ...s, max_party_share_per_layer_pct: Number(e.target.value) }) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Hoeveel van \u00E9\u00E9n laag mag door \u00E9\u00E9n partij bezet worden. Standaard 50%." })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Max verschillende beladingen per laag" }), _jsx(Input, { type: "number", min: 1, max: 999, value: s.max_beladingen_per_layer >= 999 ? "" : s.max_beladingen_per_layer, disabled: s.max_beladingen_per_layer >= 999, onChange: (e) => setS({ ...s, max_beladingen_per_layer: Number(e.target.value) }) }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: s.max_beladingen_per_layer >= 999, onCheckedChange: (v) => setS({ ...s, max_beladingen_per_layer: v ? 999 : 2 }) }), "Onbeperkt aantal soorten per belading"] }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Hoeveel verschillende artikelen samen in \u00E9\u00E9n laag mogen. Standaard 2." })] }), _jsxs("div", { className: "space-y-2 lg:col-span-2", children: [_jsx(Label, { children: "Optimalisatie-strategie" }), _jsxs(Select, { value: s.optimization_strategy, onValueChange: (v) => setS({ ...s, optimization_strategy: v }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "min_carts", children: "Minimaal aantal karren" }), _jsx(SelectItem, { value: "min_mixing", children: "Minimaal mengen (voorkeur voor pure karren)" })] })] })] })] }), _jsx(Button, { disabled: mut.isPending, onClick: () => mut.mutate(stripId(s)), children: "Opslaan" })] })] }));
|
|
38
|
+
}
|
|
39
|
+
function PicktijdenTab({ settings, pickTimes, }) {
|
|
40
|
+
const qc = useQueryClient();
|
|
41
|
+
const upsert = useServerFn(upsertPickTime);
|
|
42
|
+
const remove = useServerFn(deletePickTime);
|
|
43
|
+
const [potSize, setPotSize] = useState("");
|
|
44
|
+
const [minutes, setMinutes] = useState(0);
|
|
45
|
+
const saveSettings = useSaveSettings();
|
|
46
|
+
const addMut = useMutation({
|
|
47
|
+
mutationFn: () => upsert({ data: { pot_size: potSize.trim(), seconds_per_cart: Math.round(minutes * 60) } }),
|
|
48
|
+
onSuccess: () => {
|
|
49
|
+
toast.success("Toegevoegd");
|
|
50
|
+
setPotSize("");
|
|
51
|
+
setMinutes(0);
|
|
52
|
+
qc.invalidateQueries({ queryKey: ["cart-planning-bundle"] });
|
|
53
|
+
},
|
|
54
|
+
onError: (e) => toast.error(e?.message ?? "Fout"),
|
|
55
|
+
});
|
|
56
|
+
const delMut = useMutation({
|
|
57
|
+
mutationFn: (id) => remove({ data: { id } }),
|
|
58
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: ["cart-planning-bundle"] }),
|
|
59
|
+
});
|
|
60
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Picktijden" }), _jsx(CardDescription, { children: "Kies hoe je de picksnelheid meet: per potmaat (minuten per kar) of als planten per uur." })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Meetmethode" }), _jsxs(Select, { value: settings.pick_time_mode, onValueChange: (v) => saveSettings.mutate({ ...stripId(settings), pick_time_mode: v }), children: [_jsx(SelectTrigger, { className: "max-w-md", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "per_pot_size", children: "Minuten per kar per potmaat" }), _jsx(SelectItem, { value: "plants_per_hour", children: "Planten per uur" }), _jsx(SelectItem, { value: "plants_per_day", children: "Planten per dag" })] })] })] }), settings.pick_time_mode === "plants_per_hour" ? (_jsx(PlantsPerHourEditor, { settings: settings })) : settings.pick_time_mode === "plants_per_day" ? (_jsx(PlantsPerDayEditor, { settings: settings })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-end gap-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Potmaat" }), _jsx(Input, { value: potSize, onChange: (e) => setPotSize(e.target.value), placeholder: "bv. P12" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Minuten per kar per medewerker" }), _jsx(Input, { type: "number", min: 0, step: 0.5, value: minutes, onChange: (e) => setMinutes(Number(e.target.value)) })] }), _jsx(Button, { disabled: addMut.isPending || !potSize.trim(), onClick: () => addMut.mutate(), children: "Toevoegen / bijwerken" })] }), _jsx(Separator, {}), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Potmaat" }), _jsx(TableHead, { className: "text-right", children: "Minuten / kar / medewerker" }), _jsx(TableHead, { className: "w-16" })] }) }), _jsx(TableBody, { children: pickTimes.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 3, className: "text-sm text-muted-foreground", children: "Nog geen picktijden ingesteld." }) })) : (pickTimes.map((pt) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: pt.pot_size }), _jsx(TableCell, { className: "text-right", children: (pt.seconds_per_cart / 60).toLocaleString("nl-NL", { maximumFractionDigits: 2 }) }), _jsx(TableCell, { children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => delMut.mutate(pt.id), children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, pt.id)))) })] })] }))] })] }));
|
|
61
|
+
}
|
|
62
|
+
function PlantsPerHourEditor({ settings }) {
|
|
63
|
+
const [pph, setPph] = useState(settings.plants_per_hour);
|
|
64
|
+
const save = useSaveSettings();
|
|
65
|
+
return (_jsxs("div", { className: "flex items-end gap-2 rounded-md border p-3", children: [_jsxs("div", { className: "space-y-2 flex-1 max-w-md", children: [_jsx(Label, { children: "Planten per uur per medewerker" }), _jsx(Input, { type: "number", min: 0, value: pph, onChange: (e) => setPph(Number(e.target.value)) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Wordt gebruikt om de totale picktijd te schatten op basis van het aantal planten." })] }), _jsx(Button, { disabled: save.isPending, onClick: () => save.mutate({ ...stripId(settings), plants_per_hour: pph }), children: "Opslaan" })] }));
|
|
66
|
+
}
|
|
67
|
+
function PlantsPerDayEditor({ settings }) {
|
|
68
|
+
const [ppd, setPpd] = useState(settings.plants_per_day ?? 0);
|
|
69
|
+
const save = useSaveSettings();
|
|
70
|
+
return (_jsxs("div", { className: "flex items-end gap-2 rounded-md border p-3", children: [_jsxs("div", { className: "space-y-2 flex-1 max-w-md", children: [_jsx(Label, { children: "Planten per dag per medewerker" }), _jsx(Input, { type: "number", min: 0, value: ppd, onChange: (e) => setPpd(Number(e.target.value)) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Wordt gebruikt om de totale picktijd te schatten op basis van het aantal planten per dag." })] }), _jsx(Button, { disabled: save.isPending, onClick: () => save.mutate({ ...stripId(settings), plants_per_day: ppd }), children: "Opslaan" })] }));
|
|
71
|
+
}
|
|
72
|
+
function CombinerenTab({ settings }) {
|
|
73
|
+
const [s, setS] = useState(settings);
|
|
74
|
+
const mut = useSaveSettings();
|
|
75
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Orders combineren op \u00E9\u00E9n kar" }), _jsx(CardDescription, { children: "Wanneer mogen order_items van verschillende (Floriday-)orders op dezelfde kar samengebracht worden?" })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between rounded-md border p-3", children: [_jsxs("div", { children: [_jsx(Label, { children: "Floriday-orders combineren" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Aan = de planner mag Floriday-orders bundelen; uit = elke order krijgt zijn eigen karren." })] }), _jsx(Switch, { checked: s.combine_floriday_orders, onCheckedChange: (v) => setS({ ...s, combine_floriday_orders: v }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Combineer-venster" }), _jsxs(Select, { value: s.combine_floriday_orders_window, onValueChange: (v) => setS({ ...s, combine_floriday_orders_window: v }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "same_day", children: "Zelfde leverdag" }), _jsx(SelectItem, { value: "same_delivery_slot", children: "Zelfde levermoment" }), _jsx(SelectItem, { value: "same_week", children: "Zelfde week" })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Bereik" }), _jsxs(Select, { value: s.combine_orders_scope, onValueChange: (v) => setS({ ...s, combine_orders_scope: v }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "same_customer", children: "Alleen zelfde klant" }), _jsx(SelectItem, { value: "same_delivery_location", children: "Zelfde leverlocatie" }), _jsx(SelectItem, { value: "never", children: "Nooit combineren" })] })] })] }), _jsx(Separator, {}), _jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Vanaf hoeveel lagen krijgt een klant een eigen kar?" }), _jsx(Input, { type: "number", min: 1, value: s.own_cart_from_layers, onChange: (e) => setS({ ...s, own_cart_from_layers: Number(e.target.value) }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Maximaal aantal klanten op \u00E9\u00E9n kar" }), _jsx(Input, { type: "number", min: 1, value: s.max_customers_per_cart, onChange: (e) => setS({ ...s, max_customers_per_cart: Number(e.target.value) }) })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Klanten per laag" }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: s.max_one_customer_per_layer ? "outline" : "default", onClick: () => setS({ ...s, max_one_customer_per_layer: false }), children: "Meerdere klanten op \u00E9\u00E9n laag" }), _jsx(Button, { variant: s.max_one_customer_per_layer ? "default" : "outline", onClick: () => setS({ ...s, max_one_customer_per_layer: true }), children: "Max \u00E9\u00E9n klant per laag" })] })] }), _jsxs("div", { className: "grid gap-3 lg:grid-cols-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: s.require_same_carrier, onCheckedChange: (v) => setS({ ...s, require_same_carrier: !!v }) }), "Alleen dezelfde vervoerder"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: s.require_same_delivery_location, onCheckedChange: (v) => setS({ ...s, require_same_delivery_location: !!v }) }), "Alleen dezelfde afleverlocatie"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: s.require_same_crate_type, onCheckedChange: (v) => setS({ ...s, require_same_crate_type: !!v }) }), "Alleen hetzelfde fusttype"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: s.require_same_delivery_date, onCheckedChange: (v) => setS({ ...s, require_same_delivery_date: !!v }) }), "Alleen dezelfde leverdatum"] })] }), _jsx(Button, { disabled: mut.isPending, onClick: () => mut.mutate(stripId(s)), children: "Opslaan" })] })] }));
|
|
76
|
+
}
|
|
77
|
+
function PickstationTab({ settings }) {
|
|
78
|
+
const [s, setS] = useState(settings);
|
|
79
|
+
const mut = useSaveSettings();
|
|
80
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Na verzending naar pickstation" }), _jsx(CardDescription, { children: "Wanneer een kar-pakbon eenmaal geprint is voor het pickstation, mag de karindeling dan nog wijzigen?" })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between rounded-md border p-3", children: [_jsxs("div", { children: [_jsx(Label, { children: "Wijzigen na pickstation-print toestaan" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Standaard uit: zodra de pakbon geprint is wordt de karindeling vergrendeld." })] }), _jsx(Switch, { checked: s.allow_editing_after_pickstation_send, onCheckedChange: (v) => setS({ ...s, allow_editing_after_pickstation_send: v }) })] }), _jsx(Badge, { variant: "outline", children: s.allow_editing_after_pickstation_send ? "Bewerken toegestaan" : "Vergrendeld na print" }), _jsx("div", { children: _jsx(Button, { disabled: mut.isPending, onClick: () => mut.mutate(stripId(s)), children: "Opslaan" }) })] })] }));
|
|
81
|
+
}
|
|
82
|
+
function OrderbufferTab({ settings }) {
|
|
83
|
+
const [s, setS] = useState(settings);
|
|
84
|
+
const mut = useSaveSettings();
|
|
85
|
+
const rebuffer = useServerFn(rebufferAllOrders);
|
|
86
|
+
const [rebuffering, setRebuffering] = useState(false);
|
|
87
|
+
const save = async () => {
|
|
88
|
+
await mut.mutateAsync(stripId(s));
|
|
89
|
+
setRebuffering(true);
|
|
90
|
+
try {
|
|
91
|
+
const res = await rebuffer();
|
|
92
|
+
toast.success(`Buffer bijgewerkt · ${res.processed} order(s) hergegroepeerd`);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
toast.error(`Herbufferen faalde: ${err.message}`);
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
setRebuffering(false);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Orderbuffer" }), _jsx(CardDescription, { children: "Bepaal wanneer orders in dezelfde buffer worden geplaatst voordat ze op karren worden ingedeeld." })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Wanneer horen orders in dezelfde buffer?" }), _jsxs(Select, { value: s.buffer_grouping_mode, onValueChange: (v) => setS({ ...s, buffer_grouping_mode: v }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "same_pickup_and_location", children: "Zelfde ophaalmoment \u00E9n zelfde afleverlocatie (aanbevolen)" }), _jsx(SelectItem, { value: "same_pickup", children: "Alleen zelfde ophaalmoment" }), _jsx(SelectItem, { value: "same_location", children: "Alleen zelfde afleverlocatie" }), _jsx(SelectItem, { value: "same_customer", children: "Alleen zelfde klant" }), _jsx(SelectItem, { value: "never", children: "Nooit samenvoegen \u2014 elke order eigen buffer" })] })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Na opslaan worden alle bestaande orders opnieuw in de juiste buffer geplaatst. De karindeling per buffer wordt bij de eerstvolgende (her)berekening opnieuw uitgevoerd." })] }), _jsx(Button, { disabled: mut.isPending || rebuffering, onClick: save, children: rebuffering ? "Bezig met herbufferen…" : "Opslaan" })] })] }));
|
|
102
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAuG/D,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,2CA4OvE"}
|
|
@@ -76,27 +76,53 @@ export function OrderKarindelingCard({ order }) {
|
|
|
76
76
|
const [lockedAt, setLockedAt] = useState(null);
|
|
77
77
|
const [dbItems, setDbItems] = useState(null);
|
|
78
78
|
const [plannerInputs, setPlannerInputs] = useState(null);
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const [bufferOrders, setBufferOrders] = useState([]);
|
|
80
|
+
const [, setBufferId] = useState(null);
|
|
81
81
|
useEffect(() => {
|
|
82
82
|
if (!orderId)
|
|
83
83
|
return;
|
|
84
84
|
let active = true;
|
|
85
85
|
const load = async () => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
// 1) Bepaal de buffer van deze order.
|
|
87
|
+
const { data: orderRow } = await supabase
|
|
88
|
+
.from("orders")
|
|
89
|
+
.select("plan_locked_at, buffer_id")
|
|
90
|
+
.eq("id", orderId)
|
|
91
|
+
.maybeSingle();
|
|
92
|
+
if (!active)
|
|
93
|
+
return;
|
|
94
|
+
const bid = orderRow?.buffer_id ?? null;
|
|
95
|
+
setLockedAt(orderRow?.plan_locked_at ?? null);
|
|
96
|
+
setBufferId(bid);
|
|
97
|
+
// 2) Verzamel alle orders in deze buffer (of alleen deze order als er
|
|
98
|
+
// geen buffer bekend is).
|
|
99
|
+
let orderIds = [orderId];
|
|
100
|
+
let siblingOrders = [];
|
|
101
|
+
if (bid) {
|
|
102
|
+
const { data: sibs } = await supabase
|
|
103
|
+
.from("orders")
|
|
104
|
+
.select("id, order_number")
|
|
105
|
+
.eq("buffer_id", bid)
|
|
106
|
+
.is("deleted_at", null);
|
|
107
|
+
siblingOrders = (sibs ?? []).map((s) => ({
|
|
108
|
+
id: s.id,
|
|
109
|
+
order_number: s.order_number,
|
|
110
|
+
}));
|
|
111
|
+
if (siblingOrders.length > 0)
|
|
112
|
+
orderIds = siblingOrders.map((s) => s.id);
|
|
113
|
+
}
|
|
114
|
+
if (!active)
|
|
115
|
+
return;
|
|
116
|
+
setBufferOrders(siblingOrders);
|
|
117
|
+
// 3) Items van alle orders in de buffer.
|
|
118
|
+
const { data: itemRows } = await supabase
|
|
119
|
+
.from("order_items")
|
|
120
|
+
.select("id, order_id, product_id, product_name, quantity, products(plants_per_crate, crates_per_layer, layers_per_cart)")
|
|
121
|
+
.in("order_id", orderIds);
|
|
93
122
|
if (!active)
|
|
94
123
|
return;
|
|
95
124
|
const items = itemRows ?? [];
|
|
96
125
|
setDbItems(items);
|
|
97
|
-
setLockedAt(orderRow?.plan_locked_at ?? null);
|
|
98
|
-
// Alle order_items doorgeven — expand-helper resolveert zelf groepen
|
|
99
|
-
// (via product_id óf via naamprefix "[Groep] ...") en losse artikelen.
|
|
100
126
|
const raws = items.map((it) => ({
|
|
101
127
|
id: it.id,
|
|
102
128
|
product_id: it.product_id,
|
|
@@ -114,8 +140,8 @@ export function OrderKarindelingCard({ order }) {
|
|
|
114
140
|
void load();
|
|
115
141
|
const channel = supabase
|
|
116
142
|
.channel(`order-karindeling-${orderId}`)
|
|
117
|
-
.on("postgres_changes", { event: "UPDATE", schema: "public", table: "orders"
|
|
118
|
-
.on("postgres_changes", { event: "*", schema: "public", table: "order_items"
|
|
143
|
+
.on("postgres_changes", { event: "UPDATE", schema: "public", table: "orders" }, () => void load())
|
|
144
|
+
.on("postgres_changes", { event: "*", schema: "public", table: "order_items" }, () => void load())
|
|
119
145
|
.on("postgres_changes", { event: "UPDATE", schema: "public", table: "products" }, () => void load())
|
|
120
146
|
.subscribe();
|
|
121
147
|
return () => {
|
|
@@ -123,36 +149,56 @@ export function OrderKarindelingCard({ order }) {
|
|
|
123
149
|
void supabase.removeChannel(channel);
|
|
124
150
|
};
|
|
125
151
|
}, [orderId]);
|
|
126
|
-
//
|
|
127
|
-
|
|
152
|
+
// Map: order_item_id -> order_id, en order_id -> order_number.
|
|
153
|
+
const itemToOrder = useMemo(() => {
|
|
154
|
+
const m = new Map();
|
|
155
|
+
for (const it of dbItems ?? [])
|
|
156
|
+
m.set(it.id, it.order_id);
|
|
157
|
+
return m;
|
|
158
|
+
}, [dbItems]);
|
|
159
|
+
const orderNumberById = useMemo(() => {
|
|
160
|
+
const m = new Map();
|
|
161
|
+
for (const o of bufferOrders)
|
|
162
|
+
m.set(o.id, o.order_number);
|
|
163
|
+
return m;
|
|
164
|
+
}, [bufferOrders]);
|
|
128
165
|
const plannerCarts = useMemo(() => {
|
|
129
|
-
if (!plannerInputs || plannerInputs.length === 0)
|
|
130
|
-
if (dbItems && dbItems.length > 0)
|
|
131
|
-
return null;
|
|
166
|
+
if (!plannerInputs || plannerInputs.length === 0)
|
|
132
167
|
return null;
|
|
133
|
-
}
|
|
134
168
|
return planCarts(plannerInputs).carts;
|
|
135
|
-
}, [plannerInputs
|
|
169
|
+
}, [plannerInputs]);
|
|
136
170
|
const floridayCarts = useMemo(() => deriveCartsFromFloriday(order), [order]);
|
|
137
171
|
const usingVoorraad = plannerCarts !== null;
|
|
138
172
|
const carts = usingVoorraad
|
|
139
|
-
? plannerCarts.map((c) =>
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
173
|
+
? plannerCarts.map((c) => {
|
|
174
|
+
const orderIds = new Set();
|
|
175
|
+
const items = c.items.map((i) => {
|
|
176
|
+
const oid = itemToOrder.get(i.order_item_id) ?? null;
|
|
177
|
+
if (oid)
|
|
178
|
+
orderIds.add(oid);
|
|
179
|
+
return {
|
|
180
|
+
product_name: i.product_name,
|
|
181
|
+
crates: i.crates,
|
|
182
|
+
plants: i.plants,
|
|
183
|
+
plants_per_crate: i.plants_per_crate,
|
|
184
|
+
crates_per_layer: i.crates_per_layer,
|
|
185
|
+
layers_per_cart: i.layers_per_cart,
|
|
186
|
+
layer_share_pct: i.layer_share_pct,
|
|
187
|
+
order_id: oid,
|
|
188
|
+
order_number: oid ? orderNumberById.get(oid) ?? null : null,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
cart_number: c.cart_number,
|
|
193
|
+
is_complete: c.is_complete,
|
|
194
|
+
occupancy_pct: c.occupancy_pct,
|
|
195
|
+
total_layers_used: c.total_layers_used,
|
|
196
|
+
items,
|
|
197
|
+
order_ids: [...orderIds],
|
|
198
|
+
};
|
|
199
|
+
})
|
|
154
200
|
: floridayCarts;
|
|
155
201
|
const source = usingVoorraad ? "voorraad" : "floriday";
|
|
156
202
|
const lockedDate = lockedAt ? new Date(lockedAt).toLocaleString("nl-NL") : null;
|
|
157
|
-
return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between", children: [_jsx(CardTitle, { className: "text-base", children: "Karindeling" }), _jsxs("div", { className: "flex items-center gap-2", children: [lockedAt && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Lock, { className: "h-3 w-3" }), "Vergrendeld \u2014 pakbon geprint ", lockedDate] })), _jsxs(Badge, { variant: "secondary", children: [carts.length, " kar(ren) \u00B7 bron: ", source === "voorraad" ? "Voorraad" : "Floriday"] })] })] }), _jsx(CardContent, { children: carts.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen karindeling beschikbaar voor deze order." })) : (_jsx("div", { className: "space-y-4", children: carts.map((c) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "font-mono font-medium", children: ["Kar ", c.cart_number] }), _jsxs(Badge, { variant: c.is_complete ? "default" : "secondary", className: "gap-1", children: [c.is_complete && _jsx(CheckCircle2, { className: "h-3 w-3" }), c.is_complete ? "Volledig" : "Deels"] })] }), _jsxs("div", { className: "text-muted-foreground", children: [c.total_layers_used, " lagen \u00B7 benutting ", c.occupancy_pct, "%"] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { children: "Belading" }), _jsx(TableHead, { className: "text-right", children: "Laag-aandeel" })] }) }), _jsx(TableBody, { children: c.items.map((i, idx) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: i.product_name }), _jsx(TableCell, { className: "text-right", children: i.plants }), _jsx(TableCell, { className: "text-right", children: i.crates }), _jsx(TableCell, { className: "font-mono text-xs", children: belading(i) }), _jsxs(TableCell, { className: "text-right", children: [Math.round(i.layer_share_pct * 10) / 10, "%"] })] }, idx))) })] })] }, c.cart_number))) })) })] }));
|
|
203
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between", children: [_jsx(CardTitle, { className: "text-base", children: "Karindeling" }), _jsxs("div", { className: "flex items-center gap-2", children: [lockedAt && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Lock, { className: "h-3 w-3" }), "Vergrendeld \u2014 pakbon geprint ", lockedDate] })), bufferOrders.length > 1 && (_jsxs(Badge, { variant: "outline", title: bufferOrders.map((o) => o.order_number).join(", "), children: ["Buffer \u00B7 ", bufferOrders.length, " orders"] })), _jsxs(Badge, { variant: "secondary", children: [carts.length, " kar(ren) \u00B7 bron: ", source === "voorraad" ? "Voorraad" : "Floriday"] })] })] }), _jsx(CardContent, { children: carts.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen karindeling beschikbaar voor deze order." })) : (_jsx("div", { className: "space-y-4", children: carts.map((c) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "font-mono font-medium", children: ["Kar ", c.cart_number] }), _jsxs(Badge, { variant: c.is_complete ? "default" : "secondary", className: "gap-1", children: [c.is_complete && _jsx(CheckCircle2, { className: "h-3 w-3" }), c.is_complete ? "Volledig" : "Deels"] })] }), _jsxs("div", { className: "text-muted-foreground", children: [c.total_layers_used, " lagen \u00B7 benutting ", c.occupancy_pct, "%"] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { children: "Belading" }), _jsx(TableHead, { className: "text-right", children: "Laag-aandeel" })] }) }), _jsx(TableBody, { children: c.items.map((i, idx) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { children: i.product_name }), i.order_number && bufferOrders.length > 1 && (_jsx(Badge, { variant: i.order_id === orderId ? "default" : "outline", className: "text-[10px]", children: i.order_number }))] }) }), _jsx(TableCell, { className: "text-right", children: i.plants }), _jsx(TableCell, { className: "text-right", children: i.crates }), _jsx(TableCell, { className: "font-mono text-xs", children: belading(i) }), _jsxs(TableCell, { className: "text-right", children: [Math.round(i.layer_share_pct * 10) / 10, "%"] })] }, idx))) })] })] }, c.cart_number))) })) })] }));
|
|
158
204
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrderDetailPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SalesOrderDetailPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailPage.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,oBAAoB,4CAsLnC"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
3
|
import { Link, useParams } from "@tanstack/react-router";
|
|
4
|
-
import { Button } from "@flowselections/core";
|
|
5
|
-
import { ArrowLeft, Pencil } from "lucide-react";
|
|
4
|
+
import { Badge, Button } from "@flowselections/core";
|
|
5
|
+
import { ArrowLeft, Pencil, Layers, ChevronDown, ChevronRight, ImageIcon } from "lucide-react";
|
|
6
6
|
import { SalesOrderDetailView } from "../../components/verkoop/SalesOrderDetailView";
|
|
7
|
+
import { OrderKarindelingCard } from "../../components/verkoop/OrderKarindelingCard";
|
|
7
8
|
import { EditLocalOrderDialog } from "../../components/verkoop/EditLocalOrderDialog";
|
|
8
9
|
import { useSalesOrdersQuery } from "../../lib/useSalesOrdersQuery";
|
|
9
10
|
import { useSalesOrderDetailQuery } from "../../lib/useSalesOrderDetailQuery";
|
|
11
|
+
const eur = new Intl.NumberFormat("nl-NL", {
|
|
12
|
+
style: "currency",
|
|
13
|
+
currency: "EUR",
|
|
14
|
+
minimumFractionDigits: 2,
|
|
15
|
+
maximumFractionDigits: 2,
|
|
16
|
+
});
|
|
10
17
|
export function SalesOrderDetailPage() {
|
|
11
18
|
const { salesOrderId } = useParams({
|
|
12
19
|
from: "/_authenticated/floriday-verkoop/verkooporders/$salesOrderId",
|
|
@@ -16,20 +23,64 @@ export function SalesOrderDetailPage() {
|
|
|
16
23
|
const isFloriday = !isLocal && !isMailboxProposal;
|
|
17
24
|
// Floriday-orders: gerichte, snelle per-order fetch.
|
|
18
25
|
const detailQuery = useSalesOrderDetailQuery(isFloriday ? salesOrderId : null);
|
|
19
|
-
//
|
|
26
|
+
// Lijst-query gebruiken we altijd: voor lokale/mailbox-orders als bron,
|
|
27
|
+
// en voor Floriday-orders om buffer-siblings te vinden.
|
|
20
28
|
const listQuery = useSalesOrdersQuery();
|
|
21
|
-
const listQueryEnabled = !isFloriday;
|
|
22
29
|
const isLoading = isFloriday ? detailQuery.isLoading : listQuery.isLoading;
|
|
23
30
|
const error = isFloriday ? detailQuery.error : listQuery.error;
|
|
24
|
-
const
|
|
31
|
+
const primary = isFloriday
|
|
25
32
|
? (detailQuery.data?.order ?? null)
|
|
26
|
-
: (
|
|
33
|
+
: (listQuery.data?.orders.find((o) => o.id === salesOrderId) ?? null);
|
|
27
34
|
const sellerFallback = isFloriday
|
|
28
35
|
? (detailQuery.data?.sellerFallback ?? null)
|
|
29
36
|
: (listQuery.data?.sellerFallback ?? null);
|
|
37
|
+
// Buffer-siblings: voor Floriday-orders levert de detailQuery zelf al de
|
|
38
|
+
// volledige buffer op (server-side gejoined via de orders-tabel), zodat we
|
|
39
|
+
// niet meer afhankelijk zijn van de tragere/gefilterde lijst-query.
|
|
40
|
+
const bufferId = useMemo(() => {
|
|
41
|
+
if (isFloriday) {
|
|
42
|
+
return detailQuery.data?.bufferId ?? primary?.bufferId ?? null;
|
|
43
|
+
}
|
|
44
|
+
if (primary?.bufferId)
|
|
45
|
+
return primary.bufferId;
|
|
46
|
+
const all = listQuery.data?.orders ?? [];
|
|
47
|
+
return all.find((o) => o.id === salesOrderId)?.bufferId ?? null;
|
|
48
|
+
}, [isFloriday, detailQuery.data?.bufferId, primary, listQuery.data?.orders, salesOrderId]);
|
|
49
|
+
const bufferOrders = useMemo(() => {
|
|
50
|
+
if (!bufferId)
|
|
51
|
+
return primary ? [primary] : [];
|
|
52
|
+
const head = primary;
|
|
53
|
+
if (isFloriday) {
|
|
54
|
+
const siblings = detailQuery.data?.bufferSiblings ?? [];
|
|
55
|
+
const rest = siblings
|
|
56
|
+
.filter((o) => o.id !== (primary?.id ?? salesOrderId))
|
|
57
|
+
.sort((a, b) => (b.orderedAt || "").localeCompare(a.orderedAt || ""));
|
|
58
|
+
return head ? [head, ...rest] : rest;
|
|
59
|
+
}
|
|
60
|
+
const all = listQuery.data?.orders ?? [];
|
|
61
|
+
const siblings = all.filter((o) => o.bufferId === bufferId);
|
|
62
|
+
if (siblings.length === 0)
|
|
63
|
+
return primary ? [primary] : [];
|
|
64
|
+
const rest = siblings
|
|
65
|
+
.filter((o) => o.id !== (primary?.id ?? salesOrderId))
|
|
66
|
+
.sort((a, b) => (b.orderedAt || "").localeCompare(a.orderedAt || ""));
|
|
67
|
+
const localHead = primary ?? siblings.find((o) => o.id === salesOrderId) ?? siblings[0];
|
|
68
|
+
return [localHead, ...rest];
|
|
69
|
+
}, [primary, bufferId, isFloriday, detailQuery.data?.bufferSiblings, listQuery.data?.orders, salesOrderId]);
|
|
70
|
+
const isBuffer = bufferOrders.length > 1;
|
|
71
|
+
const totals = useMemo(() => {
|
|
72
|
+
const revenue = bufferOrders.reduce((s, o) => s + (o.revenue ?? 0), 0);
|
|
73
|
+
const karren = bufferOrders.reduce((s, o) => s + (o.karCount ?? 0), 0);
|
|
74
|
+
const fusten = bufferOrders.reduce((s, o) => s + (o.fustCount ?? 0), 0);
|
|
75
|
+
return { revenue, karren, fusten };
|
|
76
|
+
}, [bufferOrders]);
|
|
30
77
|
const [editOpen, setEditOpen] = useState(false);
|
|
31
78
|
const rawLocalId = isLocal && salesOrderId.startsWith("local:")
|
|
32
79
|
? salesOrderId.slice("local:".length)
|
|
33
80
|
: null;
|
|
34
|
-
return (_jsxs("main", { className: "space-y-5 p-6", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsxs(Link, { to: "/floriday-verkoop/verkooporders", children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), "Terug naar verkooporders"] }) }), rawLocalId && (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => setEditOpen(true), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Bestelling bewerken"] }))] }), isLoading && (_jsx("div", { className: "rounded-lg border border-border bg-card p-8 text-sm text-muted-foreground", children: "Laden\u2026" })), error && (_jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: error.message })), !isLoading && !error && !
|
|
81
|
+
return (_jsxs("main", { className: "space-y-5 p-6", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsxs(Link, { to: "/floriday-verkoop/verkooporders", children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), "Terug naar verkooporders"] }) }), rawLocalId && (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => setEditOpen(true), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Bestelling bewerken"] }))] }), isLoading && (_jsx("div", { className: "rounded-lg border border-border bg-card p-8 text-sm text-muted-foreground", children: "Laden\u2026" })), error && (_jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: error.message })), !isLoading && !error && !primary && (_jsx("div", { className: "rounded-lg border border-border bg-card p-8 text-sm text-muted-foreground", children: "Order niet gevonden." })), primary && isBuffer && (_jsxs("div", { className: "rounded-lg border border-primary/30 bg-primary/5 p-4", children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx(Layers, { className: "h-4 w-4 text-primary" }), _jsx("span", { className: "text-sm font-semibold text-foreground", children: "Orderbuffer" }), _jsxs(Badge, { variant: "outline", className: "border-primary/40 text-primary", children: [bufferOrders.length, " orders samengevoegd"] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-3 text-sm md:grid-cols-4", children: [_jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: "Totale omzet" }), _jsx("div", { className: "font-semibold text-foreground", children: eur.format(totals.revenue) })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: "Karren" }), _jsx("div", { className: "font-semibold text-foreground", children: totals.karren })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: "Fusten" }), _jsx("div", { className: "font-semibold text-foreground", children: totals.fusten })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: "Klant" }), _jsx("div", { className: "font-semibold text-foreground", children: primary.customer.name })] })] }), _jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: bufferOrders.map((o) => (_jsx(Badge, { variant: "outline", className: "text-xs", children: o.orderNumber || o.id.slice(0, 8) }, o.id))) })] })), primary && !isBuffer && (_jsx(SalesOrderDetailView, { order: primary, sellerFallback: sellerFallback })), primary && isBuffer && (_jsxs("div", { className: "grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]", children: [_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "text-sm font-semibold text-foreground", children: ["Orders in deze buffer (", bufferOrders.length, ")"] }), bufferOrders.map((o) => (_jsx(BufferOrderRow, { order: o, sellerFallback: sellerFallback }, o.id)))] }), _jsxs("div", { className: "space-y-3 xl:sticky xl:top-4 xl:self-start", children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: "Gecombineerde karindeling" }), _jsx(OrderKarindelingCard, { order: primary })] })] })), rawLocalId && (_jsx(EditLocalOrderDialog, { orderId: rawLocalId, open: editOpen, onOpenChange: setEditOpen }))] }));
|
|
82
|
+
}
|
|
83
|
+
function BufferOrderRow({ order, sellerFallback, }) {
|
|
84
|
+
const [open, setOpen] = useState(false);
|
|
85
|
+
return (_jsxs("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-3 p-3 text-left hover:bg-muted/40", children: [open ? (_jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground" })) : (_jsx(ChevronRight, { className: "h-4 w-4 shrink-0 text-muted-foreground" })), _jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted", children: order.imageUrl ? (_jsx("img", { src: order.imageUrl, alt: "", className: "h-full w-full object-cover" })) : (_jsx(ImageIcon, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: order.productName }), _jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground", children: [order.orderNumber && _jsx("span", { children: order.orderNumber }), _jsxs("span", { children: [order.karCount, " karren"] }), _jsxs("span", { children: [order.fustCount, " fusten"] }), _jsx("span", { children: eur.format(order.revenue ?? 0) })] })] }), order.isLocal ? (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: "BVO" })) : (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: "FO" }))] }), open && (_jsx("div", { className: "border-t border-border bg-background p-4", children: _jsx(SalesOrderDetailView, { order: order, sellerFallback: sellerFallback ?? null, hideKarindeling: true }) }))] }));
|
|
35
86
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SalesOrderDTO } from "../../lib/salesorders-mapping";
|
|
2
|
-
export declare function SalesOrderDetailView({ order, sellerFallback, }: {
|
|
2
|
+
export declare function SalesOrderDetailView({ order, sellerFallback, hideKarindeling, }: {
|
|
3
3
|
order: SalesOrderDTO;
|
|
4
4
|
sellerFallback?: string | null;
|
|
5
|
+
hideKarindeling?: boolean;
|
|
5
6
|
}): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
//# sourceMappingURL=SalesOrderDetailView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAmInE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,
|
|
1
|
+
{"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAmInE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,EACd,eAAuB,GACxB,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,2CAuSA"}
|