@flowselections/floriday-voorraad 1.0.16 → 1.0.17

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.
Files changed (64) hide show
  1. package/dist-lib/components/voorraad/AdditionalPackagingDialog.d.ts +9 -0
  2. package/dist-lib/components/voorraad/AdditionalPackagingDialog.d.ts.map +1 -0
  3. package/dist-lib/components/voorraad/AdditionalPackagingDialog.js +51 -0
  4. package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
  5. package/dist-lib/components/voorraad/ArtikelWizard.js +372 -30
  6. package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
  7. package/dist-lib/components/voorraad/EditArtikelPage.js +78 -4
  8. package/dist-lib/components/voorraad/OrderHistoryCard.d.ts +8 -0
  9. package/dist-lib/components/voorraad/OrderHistoryCard.d.ts.map +1 -0
  10. package/dist-lib/components/voorraad/OrderHistoryCard.js +133 -0
  11. package/dist-lib/components/voorraad/PriceStatusBadge.d.ts +7 -0
  12. package/dist-lib/components/voorraad/PriceStatusBadge.d.ts.map +1 -0
  13. package/dist-lib/components/voorraad/PriceStatusBadge.js +67 -0
  14. package/dist-lib/components/voorraad/VoorraadStockCard.d.ts +2 -1
  15. package/dist-lib/components/voorraad/VoorraadStockCard.d.ts.map +1 -1
  16. package/dist-lib/components/voorraad/VoorraadStockCard.js +5 -4
  17. package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
  18. package/dist-lib/components/voorraad/VoorraadTable.js +6 -1
  19. package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
  20. package/dist-lib/hooks/useLocalTradeItems.js +4 -0
  21. package/dist-lib/hooks/useTradeItemStock.d.ts +14 -1
  22. package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -1
  23. package/dist-lib/hooks/useTradeItemStock.js +76 -17
  24. package/dist-lib/hooks/useTradeItemSupplyLine.d.ts +21 -0
  25. package/dist-lib/hooks/useTradeItemSupplyLine.d.ts.map +1 -0
  26. package/dist-lib/hooks/useTradeItemSupplyLine.js +49 -0
  27. package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
  28. package/dist-lib/hooks/useVoorraadData.js +35 -3
  29. package/dist-lib/integrations/supabase/auth-middleware.d.ts +473 -3
  30. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  31. package/dist-lib/integrations/supabase/client.d.ts +473 -3
  32. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  33. package/dist-lib/integrations/supabase/client.server.d.ts +473 -3
  34. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  35. package/dist-lib/integrations/supabase/types.d.ts +481 -3
  36. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  37. package/dist-lib/lib/floricode-required-features.functions.d.ts +480 -4
  38. package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -1
  39. package/dist-lib/lib/floricode-required-features.functions.js +20 -2
  40. package/dist-lib/lib/floriday-customer-offer.functions.d.ts +11264 -0
  41. package/dist-lib/lib/floriday-customer-offer.functions.d.ts.map +1 -0
  42. package/dist-lib/lib/floriday-customer-offer.functions.js +175 -0
  43. package/dist-lib/lib/floriday-gateway.functions.d.ts +13155 -15
  44. package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -1
  45. package/dist-lib/lib/floriday-gateway.functions.js +150 -0
  46. package/dist-lib/lib/floriday-gateway.server.d.ts +22 -0
  47. package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
  48. package/dist-lib/lib/floriday-gateway.server.js +3 -0
  49. package/dist-lib/lib/floriday-payload.d.ts +60 -6
  50. package/dist-lib/lib/floriday-payload.d.ts.map +1 -1
  51. package/dist-lib/lib/floriday-payload.js +104 -7
  52. package/dist-lib/lib/floriday-supply-line.d.ts +53 -0
  53. package/dist-lib/lib/floriday-supply-line.d.ts.map +1 -0
  54. package/dist-lib/lib/floriday-supply-line.js +109 -0
  55. package/dist-lib/lib/floriday-warehouse.functions.d.ts +1420 -10
  56. package/dist-lib/lib/floriday-warehouse.functions.d.ts.map +1 -1
  57. package/dist-lib/lib/floriday-writes.functions.d.ts +947 -7
  58. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  59. package/dist-lib/lib/floriday-writes.functions.js +6 -1
  60. package/dist-lib/lib/vrs-catalog.d.ts +27 -0
  61. package/dist-lib/lib/vrs-catalog.d.ts.map +1 -0
  62. package/dist-lib/lib/vrs-catalog.js +98 -0
  63. package/package.json +3 -2
  64. package/public/flowselections-assets/Voorraad/floriday-logo.png +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"AAWA,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,2CA0DrD"}
1
+ {"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"AAeA,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,2CAyHrD"}
@@ -1,11 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from "react";
3
+ import { useNavigate } from "@tanstack/react-router";
3
4
  import { Card } from "@flowselections/core";
4
5
  import { Loader2 } from "lucide-react";
5
6
  import { ArtikelWizard } from "./ArtikelWizard";
6
7
  import { supabase } from "../../integrations/supabase/client";
8
+ import { useFloridayConnection } from "../../hooks/useFloridayConnection";
9
+ import { upsertLocalTradeItem } from "../../hooks/useLocalTradeItems";
10
+ import { emptyWizardData, isValidGtin13 } from "../../lib/floriday-payload";
7
11
  export function EditArtikelPage({ id }) {
8
12
  const [resolved, setResolved] = useState(null);
13
+ const [promoting, setPromoting] = useState(false);
14
+ const { activeId } = useFloridayConnection();
15
+ const navigate = useNavigate();
9
16
  useEffect(() => {
10
17
  let cancelled = false;
11
18
  setResolved(null);
@@ -32,14 +39,81 @@ export function EditArtikelPage({ id }) {
32
39
  setResolved({ kind: "published", id });
33
40
  return;
34
41
  }
35
- setResolved({ kind: "notfound" });
42
+ // Fallback: ERP-only product → promote to editable draft transparently.
43
+ const prodRes = await supabase
44
+ .from("products")
45
+ .select("id,product,barcode,quantity,sale_price")
46
+ .eq("id", id)
47
+ .maybeSingle();
48
+ if (cancelled)
49
+ return;
50
+ if (!prodRes.data) {
51
+ setResolved({ kind: "notfound" });
52
+ return;
53
+ }
54
+ if (!activeId) {
55
+ // No Floriday connection yet — cannot create a draft (connection_id required).
56
+ setResolved({ kind: "notfound" });
57
+ return;
58
+ }
59
+ setPromoting(true);
60
+ try {
61
+ // Look for an existing draft already linked to this product.
62
+ const existing = await supabase
63
+ .from("trade_item_drafts")
64
+ .select("id,data")
65
+ .eq("connection_id", activeId)
66
+ .contains("data", { linkedProductId: id })
67
+ .maybeSingle();
68
+ if (cancelled)
69
+ return;
70
+ if (existing.data) {
71
+ navigate({
72
+ to: "/voorraad/$id",
73
+ params: { id: existing.data.id },
74
+ replace: true,
75
+ });
76
+ return;
77
+ }
78
+ const prod = prodRes.data;
79
+ const barcode = String(prod.barcode ?? "").trim();
80
+ const validGtin = isValidGtin13(barcode);
81
+ const seed = {
82
+ ...emptyWizardData,
83
+ name: prod.product ?? "",
84
+ articleCode: validGtin ? "" : barcode,
85
+ gtin: validGtin ? barcode : "",
86
+ salePricePerPiece: Number(prod.sale_price) || 0,
87
+ saleStockPieces: Number(prod.quantity) || 0,
88
+ linkedProductId: id,
89
+ };
90
+ const newId = await upsertLocalTradeItem({
91
+ connectionId: activeId,
92
+ data: seed,
93
+ });
94
+ if (cancelled)
95
+ return;
96
+ navigate({
97
+ to: "/voorraad/$id",
98
+ params: { id: newId },
99
+ replace: true,
100
+ });
101
+ }
102
+ catch {
103
+ if (!cancelled)
104
+ setResolved({ kind: "notfound" });
105
+ }
106
+ finally {
107
+ if (!cancelled)
108
+ setPromoting(false);
109
+ }
36
110
  })();
37
111
  return () => {
38
112
  cancelled = true;
39
113
  };
40
- }, [id]);
41
- if (!resolved) {
42
- return (_jsx("main", { className: "p-6", children: _jsxs(Card, { className: "p-6 flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), "Artikel zoeken..."] }) }));
114
+ }, [id, activeId, navigate]);
115
+ if (!resolved || promoting) {
116
+ return (_jsx("main", { className: "p-6", children: _jsxs(Card, { className: "p-6 flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), promoting ? "Artikel voorbereiden voor bewerken..." : "Artikel zoeken..."] }) }));
43
117
  }
44
118
  if (resolved.kind === "notfound") {
45
119
  return (_jsx("main", { className: "p-6", children: _jsx(Card, { className: "p-6 text-sm", children: "Artikel niet gevonden. Het is mogelijk verwijderd of nog niet gesynchroniseerd vanuit Floriday." }) }));
@@ -0,0 +1,8 @@
1
+ interface Props {
2
+ tradeItemKey: string | null;
3
+ productName: string | null;
4
+ productId?: string | null;
5
+ }
6
+ export declare function OrderHistoryCard({ tradeItemKey, productName, productId }: Props): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=OrderHistoryCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderHistoryCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/OrderHistoryCard.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAgDD,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,KAAK,2CAoK/E"}
@@ -0,0 +1,133 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { Card, CardContent, Badge } from "@flowselections/core";
4
+ import { Loader2, ClipboardList, ExternalLink } from "lucide-react";
5
+ import { supabase } from "../../integrations/supabase/client";
6
+ const STATUS_TONE = {
7
+ "nog te picken": "bg-amber-100 text-amber-800 border-amber-200",
8
+ "klaar voor verzending": "bg-blue-100 text-blue-800 border-blue-200",
9
+ verzonden: "bg-emerald-100 text-emerald-800 border-emerald-200",
10
+ geannuleerd: "bg-rose-100 text-rose-800 border-rose-200",
11
+ concept: "bg-slate-100 text-slate-700 border-slate-200",
12
+ };
13
+ // Legacy waarden mappen naar de nieuwe fases zolang de backfill/trigger
14
+ // nog niet elke rij heeft omgezet.
15
+ function normalizeStatus(raw) {
16
+ const s = (raw ?? "").trim().toLowerCase();
17
+ if (!s)
18
+ return "Nog te picken";
19
+ if (["verzonden", "geleverd", "shipped", "delivered"].includes(s))
20
+ return "Verzonden";
21
+ if (["nieuw", "open", "new", "pending"].includes(s))
22
+ return "Nog te picken";
23
+ if (["ready", "klaar", "klaar voor verzending"].includes(s))
24
+ return "Klaar voor verzending";
25
+ if (["geannuleerd", "cancelled", "canceled"].includes(s))
26
+ return "geannuleerd";
27
+ if (s === "concept")
28
+ return "concept";
29
+ if (s === "nog te picken")
30
+ return "Nog te picken";
31
+ return raw ?? "Nog te picken";
32
+ }
33
+ function formatDate(v) {
34
+ if (!v)
35
+ return "—";
36
+ try {
37
+ const d = new Date(v);
38
+ if (Number.isNaN(d.getTime()))
39
+ return v;
40
+ return d.toLocaleDateString("nl-NL", { day: "2-digit", month: "short", year: "numeric" });
41
+ }
42
+ catch {
43
+ return v;
44
+ }
45
+ }
46
+ export function OrderHistoryCard({ tradeItemKey, productName, productId }) {
47
+ const [rows, setRows] = useState(null);
48
+ const [error, setError] = useState(null);
49
+ useEffect(() => {
50
+ let cancelled = false;
51
+ const load = async () => {
52
+ setError(null);
53
+ try {
54
+ // Resolve all local product ids that map to this trade item key.
55
+ const productIds = new Set();
56
+ if (productId)
57
+ productIds.add(productId);
58
+ if (tradeItemKey) {
59
+ const { data: prods } = await supabase
60
+ .from("products")
61
+ .select("id")
62
+ .eq("trade_item_key", tradeItemKey)
63
+ .limit(50);
64
+ for (const p of (prods ?? []))
65
+ productIds.add(p.id);
66
+ }
67
+ // Build the OR filter: match on product_id OR on product_name for
68
+ // legacy rows that weren't linked to a product yet.
69
+ const orFilters = [];
70
+ if (productIds.size > 0) {
71
+ orFilters.push(`product_id.in.(${[...productIds].join(",")})`);
72
+ }
73
+ if (productName) {
74
+ const safe = productName.replace(/[\\%,()]/g, " ").trim();
75
+ if (safe)
76
+ orFilters.push(`product_name.eq.${safe}`);
77
+ }
78
+ if (orFilters.length === 0) {
79
+ if (!cancelled)
80
+ setRows([]);
81
+ return;
82
+ }
83
+ const { data, error } = await supabase
84
+ .from("order_items")
85
+ .select("order_id,quantity,unit,orders!inner(id,order_number,customer_name,order_date,created_at,status,order_source,deleted_at)")
86
+ .or(orFilters.join(","))
87
+ .is("orders.deleted_at", null)
88
+ .order("created_at", { ascending: false, foreignTable: "orders" })
89
+ .limit(100);
90
+ if (error)
91
+ throw error;
92
+ if (cancelled)
93
+ return;
94
+ const mapped = (data ?? [])
95
+ .map((r) => ({
96
+ order_id: r.order_id,
97
+ order_number: r.orders?.order_number ?? "—",
98
+ customer_name: r.orders?.customer_name ?? null,
99
+ quantity: r.quantity ?? 0,
100
+ unit: r.unit ?? null,
101
+ order_date: r.orders?.order_date ?? null,
102
+ created_at: r.orders?.created_at ?? "",
103
+ status: r.orders?.status ?? null,
104
+ order_source: r.orders?.order_source ?? null,
105
+ }))
106
+ .sort((a, b) => (a.created_at < b.created_at ? 1 : -1));
107
+ setRows(mapped);
108
+ }
109
+ catch (e) {
110
+ if (!cancelled)
111
+ setError(e.message);
112
+ }
113
+ };
114
+ load();
115
+ // Realtime: refresh when any order or order_item mutates.
116
+ const channel = supabase
117
+ .channel(`order-history-${tradeItemKey ?? "none"}`)
118
+ .on("postgres_changes", { event: "*", schema: "public", table: "order_items" }, load)
119
+ .on("postgres_changes", { event: "*", schema: "public", table: "orders" }, load)
120
+ .subscribe();
121
+ return () => {
122
+ cancelled = true;
123
+ supabase.removeChannel(channel);
124
+ };
125
+ }, [tradeItemKey, productName, productId]);
126
+ return (_jsxs(Card, { children: [_jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 px-6 py-4", children: [_jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-full border border-primary/40 bg-primary/10 text-primary", children: _jsx(ClipboardList, { className: "h-4 w-4" }) }), _jsx("span", { className: "font-medium", children: "Bestelgeschiedenis" }), _jsx("span", { className: "text-xs text-muted-foreground tabular-nums", children: rows ? `${rows.length} bestelling${rows.length === 1 ? "" : "en"}` : "" })] }), _jsxs(CardContent, { className: "pt-0", children: [error && (_jsxs("div", { className: "text-sm text-destructive", children: ["Kon bestelgeschiedenis niet laden: ", error] })), !rows && !error && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Bestellingen laden\u2026"] })), rows && rows.length === 0 && !error && (_jsx("div", { className: "text-sm text-muted-foreground", children: "Nog geen bestellingen voor dit artikel." })), rows && rows.length > 0 && (_jsx("div", { className: "overflow-x-auto rounded-md border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-xs uppercase text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-3 py-2 text-left", children: "Ordernummer" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Klant" }), _jsx("th", { className: "px-3 py-2 text-right", children: "Fusten" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Besteldatum" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Status" }), _jsx("th", { className: "px-3 py-2" })] }) }), _jsx("tbody", { children: rows.map((r) => {
127
+ const label = normalizeStatus(r.status);
128
+ const tone = STATUS_TONE[label.toLowerCase()] ??
129
+ "bg-slate-100 text-slate-700 border-slate-200";
130
+ const href = `/floriday-verkoop/verkooporders/${r.order_id}`;
131
+ return (_jsxs("tr", { className: "border-t hover:bg-muted/40 cursor-pointer", onClick: () => { window.location.href = href; }, children: [_jsx("td", { className: "px-3 py-2 font-medium", children: _jsx("a", { href: href, className: "text-primary hover:underline", onClick: (e) => e.stopPropagation(), children: r.order_number }) }), _jsx("td", { className: "px-3 py-2", children: r.customer_name ?? "—" }), _jsxs("td", { className: "px-3 py-2 text-right tabular-nums", children: [r.quantity, r.unit ? _jsx("span", { className: "ml-1 text-xs text-muted-foreground", children: r.unit }) : null] }), _jsx("td", { className: "px-3 py-2", children: formatDate(r.order_date ?? r.created_at) }), _jsx("td", { className: "px-3 py-2", children: _jsx(Badge, { variant: "outline", className: `border ${tone}`, children: label }) }), _jsx("td", { className: "px-3 py-2 text-right text-muted-foreground", children: _jsx(ExternalLink, { className: "h-3.5 w-3.5 inline" }) })] }, r.order_id));
132
+ }) })] }) }))] })] }));
133
+ }
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ tradeItemId: string | null | undefined;
3
+ offerForSale: boolean;
4
+ };
5
+ export declare function PriceStatusBadge({ tradeItemId, offerForSale }: Props): import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
7
+ //# sourceMappingURL=PriceStatusBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PriceStatusBadge.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/PriceStatusBadge.tsx"],"names":[],"mappings":"AAGA,KAAK,KAAK,GAAG;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAeF,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,KAAK,kDAkEpE"}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CircleDollarSign, Clock, MinusCircle, Loader2 } from "lucide-react";
3
+ import { useTradeItemSupplyLine } from "../../hooks/useTradeItemSupplyLine";
4
+ function formatDate(iso) {
5
+ if (!iso)
6
+ return "—";
7
+ try {
8
+ return new Date(iso).toLocaleDateString("nl-NL", {
9
+ day: "2-digit",
10
+ month: "short",
11
+ year: "numeric",
12
+ });
13
+ }
14
+ catch {
15
+ return iso;
16
+ }
17
+ }
18
+ export function PriceStatusBadge({ tradeItemId, offerForSale }) {
19
+ const { data: supplyLine, isLoading } = useTradeItemSupplyLine(tradeItemId);
20
+ if (!tradeItemId)
21
+ return null;
22
+ if (isLoading) {
23
+ return (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), " Prijsstatus laden\u2026"] }));
24
+ }
25
+ const now = Date.now();
26
+ const endMs = supplyLine?.period_end ? new Date(supplyLine.period_end).getTime() : null;
27
+ const qty = supplyLine?.available_quantity ?? 0;
28
+ const isExpired = endMs !== null && endMs < now;
29
+ const isDrained = supplyLine !== null && qty <= 0;
30
+ let label;
31
+ let Icon = CircleDollarSign;
32
+ let cls = "";
33
+ let variant;
34
+ if (!supplyLine || !offerForSale) {
35
+ variant = "none";
36
+ label = "Geen prijs actief";
37
+ Icon = MinusCircle;
38
+ cls = "bg-muted text-muted-foreground";
39
+ }
40
+ else if (isExpired || isDrained) {
41
+ variant = "expired";
42
+ label = isExpired ? "Prijs verlopen" : "Voorraad op";
43
+ Icon = Clock;
44
+ cls = "bg-amber-100 text-amber-800";
45
+ }
46
+ else {
47
+ variant = "live";
48
+ label = "Prijs live in catalogus";
49
+ Icon = CircleDollarSign;
50
+ cls = "bg-emerald-100 text-emerald-700";
51
+ }
52
+ const title = supplyLine
53
+ ? [
54
+ `Prijs: ${supplyLine.price_per_piece != null
55
+ ? `${supplyLine.currency ?? "EUR"} ${supplyLine.price_per_piece.toFixed(2)} / stuk`
56
+ : "—"}`,
57
+ `Beschikbaar: ${qty}`,
58
+ `Periode: ${formatDate(supplyLine.period_start)} → ${formatDate(supplyLine.period_end)}`,
59
+ variant === "none" && !offerForSale
60
+ ? '"Te koop aanbieden" staat uit.'
61
+ : null,
62
+ ]
63
+ .filter(Boolean)
64
+ .join("\n")
65
+ : "Nog geen prijs naar Floriday-catalogus gepusht.";
66
+ return (_jsxs("span", { className: `inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full cursor-help ${cls}`, title: title, children: [_jsx(Icon, { className: "h-3 w-3" }), " ", label] }));
67
+ }
@@ -2,7 +2,8 @@ interface Props {
2
2
  connectionId: string | null;
3
3
  tradeItemId?: string | null;
4
4
  draftId?: string | null;
5
+ productId?: string | null;
5
6
  }
6
- export declare function VoorraadStockCard({ connectionId, tradeItemId, draftId }: Props): import("react/jsx-runtime").JSX.Element;
7
+ export declare function VoorraadStockCard({ connectionId, tradeItemId, draftId, productId }: Props): import("react/jsx-runtime").JSX.Element;
7
8
  export {};
8
9
  //# sourceMappingURL=VoorraadStockCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VoorraadStockCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadStockCard.tsx"],"names":[],"mappings":"AAaA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,KAAK,2CAoG9E"}
1
+ {"version":3,"file":"VoorraadStockCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadStockCard.tsx"],"names":[],"mappings":"AAaA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,2CAqGzF"}
@@ -2,10 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useEffect, useState } from "react";
3
3
  import { Button, Card, CardContent, Input, Label, Textarea, toast, } from "@flowselections/core";
4
4
  import { Loader2, Package, Check } from "lucide-react";
5
- import { useTradeItemStock, stockKeyFor } from "../../hooks/useTradeItemStock";
6
- export function VoorraadStockCard({ connectionId, tradeItemId, draftId }) {
7
- const key = stockKeyFor({ tradeItemId, draftId });
8
- const { row, loading, save } = useTradeItemStock(connectionId, key);
5
+ import { useTradeItemStock, stockKeysFor } from "../../hooks/useTradeItemStock";
6
+ export function VoorraadStockCard({ connectionId, tradeItemId, draftId, productId }) {
7
+ const keys = stockKeysFor({ tradeItemId, draftId, productId });
8
+ const key = keys[0] ?? null;
9
+ const { row, loading, save } = useTradeItemStock(connectionId, keys);
9
10
  const [values, setValues] = useState(row);
10
11
  const [saving, setSaving] = useState(false);
11
12
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"VoorraadTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadTable.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAW3D,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,2CA8GA"}
1
+ {"version":3,"file":"VoorraadTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadTable.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAW3D,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,2CAmHA"}
@@ -20,10 +20,15 @@ export function VoorraadTable({ items, loading, }) {
20
20
  }
21
21
  return (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-left", children: _jsxs("tr", { children: [_jsx("th", { className: "p-3 w-14" }), _jsx("th", { className: "p-3", children: "Product" }), _jsx("th", { className: "p-3", children: "Artikelnummer" }), columns.map((c) => (_jsx("th", { className: "p-3 text-right whitespace-nowrap", children: c.label }, c.key)))] }) }), _jsx("tbody", { children: items.map((item) => {
22
22
  const isLocal = !item.published;
23
+ const isErp = item.source === "erp";
23
24
  const low = !isLocal &&
24
25
  item.minQuantity > 0 &&
25
26
  item.availableQuantity < item.minQuantity;
26
- const linkId = isLocal ? item.localId : item.id;
27
+ const linkId = isErp
28
+ ? item.productId
29
+ : isLocal
30
+ ? item.localId
31
+ : item.id;
27
32
  const clickable = Boolean(linkId);
28
33
  const open = () => {
29
34
  if (linkId)
@@ -1 +1 @@
1
- {"version":3,"file":"useLocalTradeItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useLocalTradeItems.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAgCD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;EA+B7D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQrF;AAED,MAAM,WAAW,SAAS;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC;CACpC;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhF;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
1
+ {"version":3,"file":"useLocalTradeItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useLocalTradeItems.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAoCD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;EA+B7D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQrF;AAED,MAAM,WAAW,SAAS;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC;CACpC;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhF;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
@@ -2,11 +2,15 @@ import { useCallback, useEffect, useState } from "react";
2
2
  import { supabase } from "../integrations/supabase/client";
3
3
  function draftToTradeItem(row) {
4
4
  const d = row.data ?? {};
5
+ const linkedProductId = typeof d.linkedProductId === "string" ? d.linkedProductId : undefined;
5
6
  const firstImage = Array.isArray(d.images) && d.images.length > 0 ? d.images[0] : null;
6
7
  const imageUrl = (firstImage && (firstImage.url || firstImage.previewUrl)) ?? null;
7
8
  return {
8
9
  id: `local:${row.id}`,
9
10
  localId: row.id,
11
+ productId: linkedProductId,
12
+ tradeItemKey: linkedProductId ? `product:${linkedProductId}` : `draft:${row.id}`,
13
+ source: "draft",
10
14
  name: d.name || d.vbnName || "(naamloos)",
11
15
  articleNumber: d.articleCode || d.gtin || "",
12
16
  imageUrl,
@@ -9,8 +9,21 @@ export interface TradeItemStockRow {
9
9
  export declare function stockKeyFor(params: {
10
10
  tradeItemId?: string | null;
11
11
  draftId?: string | null;
12
+ productId?: string | null;
12
13
  }): string | null;
13
- export declare function useTradeItemStock(connectionId: string | null, key: string | null): {
14
+ /**
15
+ * Build the ordered list of candidate keys for one artikel. Wij zoeken op
16
+ * ALLE bekende varianten (tradeItemId, product:{id}, draft:{id}) omdat de
17
+ * voorraadrij historisch onder één van die keys kan zijn aangemaakt (bv.
18
+ * concept → gepubliceerd, of gelinkt aan een ERP-product). Bij opslaan
19
+ * gebruiken wij altijd de eerste (meest specifieke) key.
20
+ */
21
+ export declare function stockKeysFor(params: {
22
+ tradeItemId?: string | null;
23
+ draftId?: string | null;
24
+ productId?: string | null;
25
+ }): string[];
26
+ export declare function useTradeItemStock(connectionId: string | null, keyOrKeys: string | string[] | null): {
14
27
  row: TradeItemStockRow;
15
28
  loading: boolean;
16
29
  save: (values: TradeItemStockRow) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"useTradeItemStock.d.ts","sourceRoot":"","sources":["../../src/hooks/useTradeItemStock.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,MAAM,GAAG,IAAI,CAIhB;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;;;mBA4B9D,iBAAiB;EA2BnC;AAED,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAUzC"}
1
+ {"version":3,"file":"useTradeItemStock.d.ts","sourceRoot":"","sources":["../../src/hooks/useTradeItemStock.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,GAAG,IAAI,CAKhB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,EAAE,CAMX;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;;;mBA4ElB,iBAAiB;EA6BnC;AAED,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAUzC"}
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useState } from "react";
1
+ import { useCallback, useEffect, useMemo, useState } from "react";
2
2
  import { supabase } from "../integrations/supabase/client";
3
3
  const EMPTY = {
4
4
  physical_stock: 0,
@@ -12,37 +12,96 @@ export function stockKeyFor(params) {
12
12
  return params.tradeItemId;
13
13
  if (params.draftId)
14
14
  return `draft:${params.draftId}`;
15
+ if (params.productId)
16
+ return `product:${params.productId}`;
15
17
  return null;
16
18
  }
17
- export function useTradeItemStock(connectionId, key) {
19
+ /**
20
+ * Build the ordered list of candidate keys for one artikel. Wij zoeken op
21
+ * ALLE bekende varianten (tradeItemId, product:{id}, draft:{id}) omdat de
22
+ * voorraadrij historisch onder één van die keys kan zijn aangemaakt (bv.
23
+ * concept → gepubliceerd, of gelinkt aan een ERP-product). Bij opslaan
24
+ * gebruiken wij altijd de eerste (meest specifieke) key.
25
+ */
26
+ export function stockKeysFor(params) {
27
+ const keys = [];
28
+ if (params.tradeItemId)
29
+ keys.push(params.tradeItemId);
30
+ if (params.productId)
31
+ keys.push(`product:${params.productId}`);
32
+ if (params.draftId)
33
+ keys.push(`draft:${params.draftId}`);
34
+ return keys;
35
+ }
36
+ export function useTradeItemStock(connectionId, keyOrKeys) {
37
+ const keysKey = Array.isArray(keyOrKeys)
38
+ ? keyOrKeys.filter(Boolean).join("|")
39
+ : keyOrKeys ?? "";
40
+ const keys = useMemo(() => (keysKey ? keysKey.split("|") : []), [keysKey]);
41
+ const primaryKey = keys[0] ?? null;
18
42
  const [row, setRow] = useState(null);
19
43
  const [loading, setLoading] = useState(false);
44
+ const refetch = useCallback(async () => {
45
+ if (!connectionId || keys.length === 0)
46
+ return;
47
+ const { data } = await supabase
48
+ .from("trade_item_stock")
49
+ .select("trade_item_key,physical_stock,minimum_stock,reserved_stock,incoming_stock,notes,updated_at")
50
+ .eq("connection_id", connectionId)
51
+ .in("trade_item_key", keys);
52
+ const rows = (data ?? []);
53
+ // Kies de rij in volgorde van keys (meest specifiek eerst).
54
+ let picked = null;
55
+ for (const k of keys) {
56
+ const hit = rows.find((r) => r.trade_item_key === k);
57
+ if (hit) {
58
+ picked = hit;
59
+ break;
60
+ }
61
+ }
62
+ setRow(picked ?? { ...EMPTY });
63
+ }, [connectionId, keys]);
20
64
  useEffect(() => {
21
- if (!connectionId || !key) {
65
+ if (!connectionId || keys.length === 0) {
22
66
  setRow(null);
23
67
  return;
24
68
  }
25
69
  let cancelled = false;
26
70
  setLoading(true);
27
71
  (async () => {
28
- const { data } = await supabase
29
- .from("trade_item_stock")
30
- .select("physical_stock,minimum_stock,reserved_stock,incoming_stock,notes,updated_at")
31
- .eq("connection_id", connectionId)
32
- .eq("trade_item_key", key)
33
- .maybeSingle();
34
- if (cancelled)
35
- return;
36
- setRow(data ?? { ...EMPTY });
37
- setLoading(false);
72
+ await refetch();
73
+ if (!cancelled)
74
+ setLoading(false);
38
75
  })();
39
76
  return () => {
40
77
  cancelled = true;
41
78
  };
42
- }, [connectionId, key]);
79
+ }, [connectionId, keys, refetch]);
80
+ // Realtime: reflecteer elke externe mutatie (order-reservering,
81
+ // completion, bulk-import, wizard-save vanuit ander tabblad).
82
+ useEffect(() => {
83
+ if (!connectionId || keys.length === 0)
84
+ return;
85
+ const filter = `trade_item_key=in.(${keys.map((k) => `"${k}"`).join(",")})`;
86
+ const channel = supabase
87
+ .channel(`stock-${connectionId}-${primaryKey}`)
88
+ .on("postgres_changes", {
89
+ event: "*",
90
+ schema: "public",
91
+ table: "trade_item_stock",
92
+ filter,
93
+ }, () => {
94
+ refetch();
95
+ })
96
+ .subscribe();
97
+ return () => {
98
+ supabase.removeChannel(channel);
99
+ };
100
+ }, [connectionId, keys, primaryKey, refetch]);
43
101
  const save = useCallback(async (values) => {
44
- if (!connectionId || !key)
102
+ if (!connectionId || !primaryKey) {
45
103
  throw new Error("Ontbrekende connectie of artikel-key");
104
+ }
46
105
  const userRes = await supabase.auth.getUser();
47
106
  const userId = userRes.data.user?.id;
48
107
  if (!userId)
@@ -52,7 +111,7 @@ export function useTradeItemStock(connectionId, key) {
52
111
  .upsert({
53
112
  user_id: userId,
54
113
  connection_id: connectionId,
55
- trade_item_key: key,
114
+ trade_item_key: primaryKey,
56
115
  physical_stock: values.physical_stock,
57
116
  minimum_stock: values.minimum_stock,
58
117
  reserved_stock: values.reserved_stock,
@@ -62,7 +121,7 @@ export function useTradeItemStock(connectionId, key) {
62
121
  if (error)
63
122
  throw new Error(error.message);
64
123
  setRow(values);
65
- }, [connectionId, key]);
124
+ }, [connectionId, primaryKey]);
66
125
  return { row: row ?? EMPTY, loading, save };
67
126
  }
68
127
  export async function fetchStockMap(connectionId) {
@@ -0,0 +1,21 @@
1
+ export type TradeItemSupplyLine = {
2
+ id: string;
3
+ supply_line_id: string | null;
4
+ trade_item_id: string;
5
+ price_per_piece: number | null;
6
+ currency: string | null;
7
+ available_quantity: number | null;
8
+ period_start: string | null;
9
+ period_end: string | null;
10
+ packing_configuration_id: string | null;
11
+ endpoint_family: string | null;
12
+ year: number | null;
13
+ week: number | null;
14
+ updated_at: string;
15
+ };
16
+ /**
17
+ * Leest de meest recente supply-line voor een trade item en luistert realtime
18
+ * op wijzigingen zodat de UI direct meebeweegt na een push naar Floriday.
19
+ */
20
+ export declare function useTradeItemSupplyLine(tradeItemId: string | null | undefined): import("@tanstack/react-query").UseQueryResult<TradeItemSupplyLine | null, Error>;
21
+ //# sourceMappingURL=useTradeItemSupplyLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTradeItemSupplyLine.d.ts","sourceRoot":"","sources":["../../src/hooks/useTradeItemSupplyLine.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,qFA+C5E"}