@flowselections/floriday-voorraad 1.0.20 → 1.0.22
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/voorraad/ArtikelCompositionCard.d.ts +7 -0
- package/dist-lib/components/voorraad/ArtikelCompositionCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ArtikelCompositionCard.js +196 -0
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts +2 -1
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +259 -26
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +28 -85
- package/dist-lib/components/voorraad/FloridayStatusBadge.d.ts +4 -0
- package/dist-lib/components/voorraad/FloridayStatusBadge.d.ts.map +1 -0
- package/dist-lib/components/voorraad/FloridayStatusBadge.js +8 -0
- package/dist-lib/components/voorraad/StockBulkButtons.js +7 -6
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts +5 -0
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ValidationOverviewTable.js +26 -56
- package/dist-lib/components/voorraad/VoorraadDashboard.d.ts +4 -0
- package/dist-lib/components/voorraad/VoorraadDashboard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadDashboard.js +14 -6
- package/dist-lib/components/voorraad/VoorraadStockCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadStockCard.js +11 -0
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +5 -12
- package/dist-lib/hooks/useFloridayContinuousStock.d.ts +13 -0
- package/dist-lib/hooks/useFloridayContinuousStock.d.ts.map +1 -0
- package/dist-lib/hooks/useFloridayContinuousStock.js +109 -0
- package/dist-lib/hooks/useFlorydayCustomers.d.ts +11 -4
- package/dist-lib/hooks/useFlorydayCustomers.d.ts.map +1 -1
- package/dist-lib/hooks/useFlorydayCustomers.js +85 -38
- package/dist-lib/hooks/useLocalTradeItems.d.ts +26 -2
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
- package/dist-lib/hooks/useLocalTradeItems.js +119 -79
- package/dist-lib/hooks/useVoorraadData.d.ts +5 -5
- package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadData.js +165 -50
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +662 -168
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +662 -168
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +662 -168
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +678 -163
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/floricode-required-features.functions.d.ts +662 -168
- package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.d.ts +29 -12
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +36 -0
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts +662 -168
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.functions.d.ts +3220 -750
- package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.server.d.ts +14 -0
- package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.server.js +3 -0
- package/dist-lib/lib/floriday-payload.d.ts.map +1 -1
- package/dist-lib/lib/floriday-payload.js +32 -8
- package/dist-lib/lib/floriday-warehouse.functions.d.ts +1932 -450
- package/dist-lib/lib/floriday-warehouse.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-writes.functions.d.ts +1333 -345
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/merge-products.d.ts +8 -0
- package/dist-lib/lib/merge-products.d.ts.map +1 -0
- package/dist-lib/lib/merge-products.js +17 -0
- package/package.json +2 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
productId: string | null;
|
|
3
|
+
floridayId: string | null;
|
|
4
|
+
}
|
|
5
|
+
export declare function ArtikelCompositionCard({ productId, floridayId }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=ArtikelCompositionCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArtikelCompositionCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelCompositionCard.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAqFD,wBAAgB,sBAAsB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,KAAK,kDAgNtE"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Badge } from "@flowselections/core";
|
|
4
|
+
import { Loader2, Package } from "lucide-react";
|
|
5
|
+
import { supabase } from "../../integrations/supabase/client";
|
|
6
|
+
async function resolveNames(productIds, floridayIds) {
|
|
7
|
+
const resolved = new Map();
|
|
8
|
+
const uuidLike = [...productIds, ...floridayIds].filter((v) => /^[0-9a-f-]{36}$/i.test(v));
|
|
9
|
+
const [prodRes, flRes, draftRes] = await Promise.all([
|
|
10
|
+
productIds.length
|
|
11
|
+
? supabase.from("products").select("id,product,barcode").in("id", productIds)
|
|
12
|
+
: Promise.resolve({ data: [] }),
|
|
13
|
+
floridayIds.length
|
|
14
|
+
? supabase
|
|
15
|
+
.from("floriday_trade_items_cache")
|
|
16
|
+
.select("floriday_id,data")
|
|
17
|
+
.in("floriday_id", floridayIds)
|
|
18
|
+
: Promise.resolve({ data: [] }),
|
|
19
|
+
uuidLike.length
|
|
20
|
+
? supabase
|
|
21
|
+
.from("trade_item_drafts")
|
|
22
|
+
.select("id,data,floriday_id")
|
|
23
|
+
.in("id", uuidLike)
|
|
24
|
+
: Promise.resolve({ data: [] }),
|
|
25
|
+
]);
|
|
26
|
+
(Array.isArray(prodRes.data) ? prodRes.data : []).forEach((p) => {
|
|
27
|
+
resolved.set(`product:${p.id}`, {
|
|
28
|
+
name: String(p.product ?? p.id),
|
|
29
|
+
code: p.barcode ? String(p.barcode) : undefined,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
(Array.isArray(flRes.data) ? flRes.data : []).forEach((n) => {
|
|
33
|
+
const nm = n.data?.tradeItemName?.nl ??
|
|
34
|
+
n.data?.tradeItemName?.en ??
|
|
35
|
+
Object.values(n.data?.tradeItemName ?? {})[0] ??
|
|
36
|
+
n.floriday_id;
|
|
37
|
+
const code = n.data?.supplierArticleCode ??
|
|
38
|
+
n.data?.articleCode ??
|
|
39
|
+
n.data?.gtin ??
|
|
40
|
+
undefined;
|
|
41
|
+
resolved.set(`floriday:${n.floriday_id}`, {
|
|
42
|
+
name: String(nm),
|
|
43
|
+
code: code ? String(code) : undefined,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
(Array.isArray(draftRes.data) ? draftRes.data : []).forEach((d) => {
|
|
47
|
+
const data = d.data ?? {};
|
|
48
|
+
const nm = data.name || data.vbnName || d.id;
|
|
49
|
+
const code = data.articleCode || data.gtin || undefined;
|
|
50
|
+
resolved.set(`draft:${d.id}`, {
|
|
51
|
+
name: String(nm),
|
|
52
|
+
code: code ? String(code) : undefined,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return { resolved };
|
|
56
|
+
}
|
|
57
|
+
export function ArtikelCompositionCard({ productId, floridayId }) {
|
|
58
|
+
const [loading, setLoading] = useState(true);
|
|
59
|
+
const [sections, setSections] = useState([]);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
let cancelled = false;
|
|
62
|
+
(async () => {
|
|
63
|
+
setLoading(true);
|
|
64
|
+
const out = [];
|
|
65
|
+
// ---- Productgroep ----
|
|
66
|
+
let groupQ = supabase
|
|
67
|
+
.from("product_groups")
|
|
68
|
+
.select("id,name,description")
|
|
69
|
+
.limit(1);
|
|
70
|
+
if (productId && floridayId) {
|
|
71
|
+
groupQ = groupQ.or(`head_product_id.eq.${productId},head_trade_item_floriday_id.eq.${floridayId}`);
|
|
72
|
+
}
|
|
73
|
+
else if (productId) {
|
|
74
|
+
groupQ = groupQ.eq("head_product_id", productId);
|
|
75
|
+
}
|
|
76
|
+
else if (floridayId) {
|
|
77
|
+
groupQ = groupQ.eq("head_trade_item_floriday_id", floridayId);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
groupQ = groupQ.eq("id", "00000000-0000-0000-0000-000000000000");
|
|
81
|
+
}
|
|
82
|
+
const groupRes = await groupQ.maybeSingle();
|
|
83
|
+
if (groupRes.data) {
|
|
84
|
+
const group = groupRes.data;
|
|
85
|
+
const { data: pgi } = await supabase
|
|
86
|
+
.from("product_group_items")
|
|
87
|
+
.select("id,trade_item_id,quantity,sort_order")
|
|
88
|
+
.eq("product_group_id", group.id)
|
|
89
|
+
.order("sort_order", { ascending: true });
|
|
90
|
+
const items = Array.isArray(pgi) ? pgi : [];
|
|
91
|
+
const tradeIds = items.map((i) => String(i.trade_item_id));
|
|
92
|
+
const uuidIds = tradeIds.filter((v) => /^[0-9a-f-]{36}$/i.test(v));
|
|
93
|
+
const nonUuidIds = tradeIds.filter((v) => !/^[0-9a-f-]{36}$/i.test(v));
|
|
94
|
+
// uuid → could be either product uuid or a floriday uuid. Look both up.
|
|
95
|
+
const { resolved } = await resolveNames(uuidIds, [...uuidIds, ...nonUuidIds]);
|
|
96
|
+
const rows = items.map((i) => {
|
|
97
|
+
const id = String(i.trade_item_id);
|
|
98
|
+
const r = resolved.get(`floriday:${id}`) ??
|
|
99
|
+
resolved.get(`product:${id}`) ??
|
|
100
|
+
resolved.get(`draft:${id}`);
|
|
101
|
+
return {
|
|
102
|
+
key: i.id,
|
|
103
|
+
refId: id,
|
|
104
|
+
name: r?.name ?? id,
|
|
105
|
+
code: r?.code,
|
|
106
|
+
quantity: i.quantity ?? undefined,
|
|
107
|
+
kind: "artikel",
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
out.push({
|
|
111
|
+
kind: "productgroep",
|
|
112
|
+
title: `Productgroep: ${group.name}`,
|
|
113
|
+
description: group.description || `${rows.length} artikelen in deze productgroep`,
|
|
114
|
+
rows,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// ---- Samenstelling (BOM) ----
|
|
118
|
+
let bomQ = supabase
|
|
119
|
+
.from("product_bom_items")
|
|
120
|
+
.select("id,component_product_id,component_trade_item_floriday_id,quantity,unit,notes,sort_order")
|
|
121
|
+
.order("sort_order", { ascending: true });
|
|
122
|
+
if (productId && floridayId) {
|
|
123
|
+
bomQ = bomQ.or(`parent_product_id.eq.${productId},parent_trade_item_floriday_id.eq.${floridayId}`);
|
|
124
|
+
}
|
|
125
|
+
else if (productId) {
|
|
126
|
+
bomQ = bomQ.eq("parent_product_id", productId);
|
|
127
|
+
}
|
|
128
|
+
else if (floridayId) {
|
|
129
|
+
bomQ = bomQ.eq("parent_trade_item_floriday_id", floridayId);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
bomQ = bomQ.eq("id", "00000000-0000-0000-0000-000000000000");
|
|
133
|
+
}
|
|
134
|
+
const bomRes = await bomQ;
|
|
135
|
+
const bomItems = Array.isArray(bomRes.data) ? bomRes.data : [];
|
|
136
|
+
if (bomItems.length > 0) {
|
|
137
|
+
const prodIds = bomItems
|
|
138
|
+
.map((r) => r.component_product_id)
|
|
139
|
+
.filter((v) => Boolean(v));
|
|
140
|
+
const flIds = bomItems
|
|
141
|
+
.map((r) => r.component_trade_item_floriday_id)
|
|
142
|
+
.filter((v) => Boolean(v));
|
|
143
|
+
const { resolved } = await resolveNames(prodIds, flIds);
|
|
144
|
+
const rows = bomItems.map((r) => {
|
|
145
|
+
if (r.component_product_id) {
|
|
146
|
+
const id = String(r.component_product_id);
|
|
147
|
+
const res = resolved.get(`product:${id}`) ?? resolved.get(`draft:${id}`);
|
|
148
|
+
return {
|
|
149
|
+
key: r.id,
|
|
150
|
+
refId: id,
|
|
151
|
+
name: res?.name ?? id,
|
|
152
|
+
code: res?.code,
|
|
153
|
+
quantity: r.quantity ?? undefined,
|
|
154
|
+
unit: r.unit ?? null,
|
|
155
|
+
detail: r.notes ?? undefined,
|
|
156
|
+
kind: "artikel",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const id = String(r.component_trade_item_floriday_id ?? "");
|
|
160
|
+
const res = resolved.get(`floriday:${id}`) ?? resolved.get(`draft:${id}`);
|
|
161
|
+
return {
|
|
162
|
+
key: r.id,
|
|
163
|
+
refId: id,
|
|
164
|
+
name: res?.name ?? id,
|
|
165
|
+
code: res?.code,
|
|
166
|
+
quantity: r.quantity ?? undefined,
|
|
167
|
+
unit: r.unit ?? null,
|
|
168
|
+
detail: r.notes ?? undefined,
|
|
169
|
+
kind: "artikel",
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
out.push({
|
|
173
|
+
kind: "samenstelling",
|
|
174
|
+
title: "Samenstelling",
|
|
175
|
+
description: `${rows.length} onderdelen in dit ontworpen product`,
|
|
176
|
+
rows,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (!cancelled) {
|
|
180
|
+
setSections(out);
|
|
181
|
+
setLoading(false);
|
|
182
|
+
}
|
|
183
|
+
})();
|
|
184
|
+
return () => {
|
|
185
|
+
cancelled = true;
|
|
186
|
+
};
|
|
187
|
+
}, [productId, floridayId]);
|
|
188
|
+
if (loading) {
|
|
189
|
+
return (_jsx(Card, { children: _jsxs(CardContent, { className: "flex items-center gap-2 py-4 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Samenstelling laden\u2026"] }) }));
|
|
190
|
+
}
|
|
191
|
+
if (sections.length === 0)
|
|
192
|
+
return null;
|
|
193
|
+
return (_jsx(_Fragment, { children: sections.map((s) => (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx(CardTitle, { children: s.title }), _jsx(Badge, { className: s.kind === "productgroep"
|
|
194
|
+
? "bg-indigo-500/15 text-indigo-700 border-indigo-500/30"
|
|
195
|
+
: "bg-emerald-500/15 text-emerald-700 border-emerald-500/30", children: s.kind === "productgroep" ? "Productgroep" : "Samenstelling" })] }), _jsx(CardDescription, { children: s.description })] }), _jsx(CardContent, { children: s.rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground py-4 text-center", children: "Nog geen onderdelen toegevoegd." })) : (_jsx("ul", { className: "divide-y", children: s.rows.map((r) => (_jsxs("li", { className: "flex items-center gap-3 py-2", children: [_jsx("div", { className: "h-8 w-8 rounded bg-muted flex items-center justify-center shrink-0", children: _jsx(Package, { className: "h-4 w-4 text-muted-foreground" }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "font-medium text-sm truncate", children: r.name }), r.code && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.code })), r.detail && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.detail }))] }), r.quantity !== undefined && r.quantity !== null && (_jsxs("div", { className: "text-sm tabular-nums text-muted-foreground shrink-0", children: [r.quantity, r.unit ? ` ${r.unit}` : ""] }))] }, r.key))) })) })] }, s.kind))) }));
|
|
196
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export declare function ArtikelWizard({ draftId: initialDraftId, tradeItemId, }?: {
|
|
1
|
+
export declare function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId, }?: {
|
|
2
2
|
draftId?: string;
|
|
3
3
|
tradeItemId?: string;
|
|
4
|
+
productId?: string;
|
|
4
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
5
6
|
//# sourceMappingURL=ArtikelWizard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"AAoJA,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,cAAc,EACvB,WAAW,EACX,SAAS,GACV,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,2CA8lCrE"}
|