@flowselections/floriday-voorraad 1.0.27 → 1.0.28
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/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +21 -8
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +3 -2
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.d.ts +5 -0
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.js +65 -0
- package/dist-lib/components/voorraad/StockBulkButtons.d.ts.map +1 -1
- package/dist-lib/components/voorraad/StockBulkButtons.js +65 -2
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ValidationOverviewTable.js +8 -2
- package/dist-lib/components/voorraad/VoorraadDashboard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadDashboard.js +4 -1
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +10 -2
- package/dist-lib/components/voorraad/VoorraadVeldenCard.d.ts +2 -0
- package/dist-lib/components/voorraad/VoorraadVeldenCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadVeldenCard.js +97 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts +4 -4
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
- package/dist-lib/hooks/useLocalTradeItems.js +59 -35
- package/dist-lib/hooks/useVoorraadCustomFields.d.ts +9 -0
- package/dist-lib/hooks/useVoorraadCustomFields.d.ts.map +1 -0
- package/dist-lib/hooks/useVoorraadCustomFields.js +26 -0
- package/dist-lib/index.d.ts +2 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +4 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +2358 -177
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +2358 -177
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +2358 -177
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +2428 -174
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +49 -0
- package/dist-lib/lib/floricode-required-features.functions.d.ts +2358 -177
- package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts +2358 -177
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.functions.d.ts +49617 -38712
- package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts +13843 -9481
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-warehouse.functions.d.ts +25719 -19176
- package/dist-lib/lib/floriday-warehouse.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-writes.functions.d.ts +13826 -9464
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/voorraad-custom-fields.d.ts +22 -0
- package/dist-lib/lib/voorraad-custom-fields.d.ts.map +1 -0
- package/dist-lib/lib/voorraad-custom-fields.js +71 -0
- package/package.json +1 -1
|
@@ -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":"AAgLA,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,+BA0mDrE"}
|
|
@@ -78,6 +78,11 @@ function warehouseSubLabel(raw) {
|
|
|
78
78
|
const city = addr.city ?? "";
|
|
79
79
|
return [line, city].filter(Boolean).join(", ") || undefined;
|
|
80
80
|
}
|
|
81
|
+
function asPlainRecord(value) {
|
|
82
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
83
|
+
? value
|
|
84
|
+
: {};
|
|
85
|
+
}
|
|
81
86
|
async function lookupProductGroupForVbn(vbnCode) {
|
|
82
87
|
const code = String(vbnCode ?? "").trim();
|
|
83
88
|
if (!code)
|
|
@@ -257,7 +262,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
257
262
|
try {
|
|
258
263
|
const { data: product, error } = await supabase
|
|
259
264
|
.from("products")
|
|
260
|
-
.select("id,product,barcode,article_number,quantity,
|
|
265
|
+
.select("id,product,barcode,article_number,quantity,image_url,plants_per_crate,crates_per_layer,layers_per_cart,trade_item_key,floriday_trade_item_id,custom_fields")
|
|
261
266
|
.eq("id", productId)
|
|
262
267
|
.maybeSingle();
|
|
263
268
|
if (cancelled)
|
|
@@ -274,9 +279,15 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
274
279
|
const ppc = Number(product.plants_per_crate) || 0;
|
|
275
280
|
const cpl = Number(product.crates_per_layer) || 0;
|
|
276
281
|
const lpc = Number(product.layers_per_cart) || 0;
|
|
277
|
-
const
|
|
278
|
-
const
|
|
279
|
-
const
|
|
282
|
+
const customFields = asPlainRecord(product.custom_fields);
|
|
283
|
+
const payload = asPlainRecord(customFields.floriday_payload);
|
|
284
|
+
const productTradeItemKey = String(product.trade_item_key ?? "");
|
|
285
|
+
const fid = ((product.floriday_trade_item_id ??
|
|
286
|
+
customFields.floriday_id ??
|
|
287
|
+
(productTradeItemKey && !productTradeItemKey.startsWith("product:")
|
|
288
|
+
? productTradeItemKey
|
|
289
|
+
: null)) || null);
|
|
290
|
+
const fActive = Boolean(fid);
|
|
280
291
|
// Floriday-cache + warehouse-voorkeur parallel ophalen wanneer we een
|
|
281
292
|
// gekoppeld trade-item hebben. Missing cache blokkeert de wizard niet;
|
|
282
293
|
// dan valt hij terug op wat er lokaal is opgeslagen.
|
|
@@ -402,17 +413,19 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
402
413
|
: validGtin
|
|
403
414
|
? barcode
|
|
404
415
|
: (payload.gtin ?? ""),
|
|
405
|
-
salePricePerPiece: Number(
|
|
416
|
+
salePricePerPiece: Number(customFields.sale_price ?? customFields.salePrice ?? payload.salePricePerPiece) || 0,
|
|
406
417
|
// Voorkeur: werkelijke voorraad uit trade_item_stock.
|
|
407
418
|
// Fallback: opgeslagen payload-waarde. `products.quantity` wordt
|
|
408
419
|
// bewust NIET meer gelezen — die staat structureel op 0.
|
|
409
420
|
saleStockPieces: physical > 0
|
|
410
421
|
? physical
|
|
411
422
|
: Number(payload.saleStockPieces ?? 0) || 0,
|
|
412
|
-
vatRate:
|
|
413
|
-
? Number(
|
|
423
|
+
vatRate: customFields.vat_rate !== null && customFields.vat_rate !== undefined
|
|
424
|
+
? Number(customFields.vat_rate)
|
|
414
425
|
: (payload.vatRate ?? null),
|
|
415
|
-
vatCode:
|
|
426
|
+
vatCode: (customFields.vat_code ?? customFields.vatCode) ??
|
|
427
|
+
payload.vatCode ??
|
|
428
|
+
null,
|
|
416
429
|
warehouseId: warehousePref ||
|
|
417
430
|
cacheWarehouseId ||
|
|
418
431
|
payloadWarehouseId ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"AAYA,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,+BAmFrD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Card } from "@flowselections/core";
|
|
4
4
|
import { Loader2 } from "lucide-react";
|
|
5
5
|
import { ArtikelWizard } from "./ArtikelWizard";
|
|
6
|
+
import { ProductCustomFieldsCard } from "./ProductCustomFieldsCard";
|
|
6
7
|
import { supabase } from "../../integrations/supabase/client";
|
|
7
8
|
export function EditArtikelPage({ id }) {
|
|
8
9
|
const [resolved, setResolved] = useState(null);
|
|
@@ -62,7 +63,7 @@ export function EditArtikelPage({ id }) {
|
|
|
62
63
|
return (_jsx("main", { className: "p-6", children: _jsxs(Card, { className: "p-6 text-sm space-y-1", children: [_jsx("div", { children: "Artikel niet gevonden." }), resolved.reason && (_jsx("div", { className: "text-muted-foreground", children: resolved.reason }))] }) }));
|
|
63
64
|
}
|
|
64
65
|
if (resolved.kind === "product") {
|
|
65
|
-
return _jsx(ArtikelWizard, { productId: resolved.id });
|
|
66
|
+
return (_jsxs(_Fragment, { children: [_jsx(ArtikelWizard, { productId: resolved.id }), _jsx("div", { className: "p-6 pt-0", children: _jsx(ProductCustomFieldsCard, { productId: resolved.id }) })] }));
|
|
66
67
|
}
|
|
67
68
|
return _jsx(ArtikelWizard, { tradeItemId: resolved.id });
|
|
68
69
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Eigen voorraadvelden met `show_in_detail`, tonen en bewerken op de productpagina. */
|
|
2
|
+
export declare function ProductCustomFieldsCard({ productId }: {
|
|
3
|
+
productId: string;
|
|
4
|
+
}): import("react").JSX.Element | null;
|
|
5
|
+
//# sourceMappingURL=ProductCustomFieldsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductCustomFieldsCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductCustomFieldsCard.tsx"],"names":[],"mappings":"AAyBA,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,sCA6H3E"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast, } from "@flowselections/core";
|
|
4
|
+
import { Loader2, Save } from "lucide-react";
|
|
5
|
+
import { useVoorraadCustomFields } from "../../hooks/useVoorraadCustomFields";
|
|
6
|
+
import { fetchProductCustomValues, saveProductCustomValues, } from "../../lib/voorraad-custom-fields";
|
|
7
|
+
/** Eigen voorraadvelden met `show_in_detail`, tonen en bewerken op de productpagina. */
|
|
8
|
+
export function ProductCustomFieldsCard({ productId }) {
|
|
9
|
+
const { fields, loading } = useVoorraadCustomFields();
|
|
10
|
+
const [values, setValues] = useState({});
|
|
11
|
+
const [loadingValues, setLoadingValues] = useState(true);
|
|
12
|
+
const [saving, setSaving] = useState(false);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
let cancelled = false;
|
|
15
|
+
setLoadingValues(true);
|
|
16
|
+
fetchProductCustomValues(productId)
|
|
17
|
+
.then((v) => {
|
|
18
|
+
if (!cancelled)
|
|
19
|
+
setValues(v);
|
|
20
|
+
})
|
|
21
|
+
.catch(() => {
|
|
22
|
+
if (!cancelled)
|
|
23
|
+
setValues({});
|
|
24
|
+
})
|
|
25
|
+
.finally(() => {
|
|
26
|
+
if (!cancelled)
|
|
27
|
+
setLoadingValues(false);
|
|
28
|
+
});
|
|
29
|
+
return () => {
|
|
30
|
+
cancelled = true;
|
|
31
|
+
};
|
|
32
|
+
}, [productId]);
|
|
33
|
+
const detailFields = fields.filter((f) => f.show_in_detail);
|
|
34
|
+
if (loading || loadingValues) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (detailFields.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
const set = (key, value) => setValues((prev) => ({ ...prev, [key]: value }));
|
|
40
|
+
const save = async () => {
|
|
41
|
+
setSaving(true);
|
|
42
|
+
try {
|
|
43
|
+
await saveProductCustomValues(productId, Object.fromEntries(detailFields.map((f) => [f.field_key, values[f.field_key] ?? null])));
|
|
44
|
+
toast.success("Eigen velden opgeslagen");
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
toast.error(`Opslaan mislukt: ${e.message}`);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
setSaving(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Eigen velden" }), _jsx(CardDescription, { children: "Extra voorraadvelden zoals ingesteld bij Instellingen \u2192 Voorraadvelden." })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsx("div", { className: "grid gap-4 sm:grid-cols-2", children: detailFields.map((f) => {
|
|
54
|
+
const v = values[f.field_key];
|
|
55
|
+
return (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: `cf-${f.field_key}`, children: f.field_label }), f.field_type === "boolean" ? (_jsx("div", { className: "pt-1", children: _jsx(Checkbox, { id: `cf-${f.field_key}`, checked: v === true, onCheckedChange: (c) => set(f.field_key, c === true) }) })) : f.field_type === "select" ? (_jsxs(Select, { value: typeof v === "string" ? v : "", onValueChange: (val) => set(f.field_key, val), children: [_jsx(SelectTrigger, { id: `cf-${f.field_key}`, children: _jsx(SelectValue, { placeholder: "Kies\u2026" }) }), _jsx(SelectContent, { children: f.options.map((o) => (_jsx(SelectItem, { value: o, children: o }, o))) })] })) : (_jsx(Input, { id: `cf-${f.field_key}`, type: f.field_type === "number"
|
|
56
|
+
? "number"
|
|
57
|
+
: f.field_type === "date"
|
|
58
|
+
? "date"
|
|
59
|
+
: "text", value: v === null || v === undefined ? "" : String(v), onChange: (e) => set(f.field_key, f.field_type === "number"
|
|
60
|
+
? e.target.value === ""
|
|
61
|
+
? null
|
|
62
|
+
: Number(e.target.value)
|
|
63
|
+
: e.target.value) }))] }, f.id));
|
|
64
|
+
}) }), _jsxs(Button, { onClick: save, disabled: saving, children: [saving ? (_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" })) : (_jsx(Save, { className: "mr-2 h-4 w-4" })), "Eigen velden opslaan"] })] })] }));
|
|
65
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StockBulkButtons.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/StockBulkButtons.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"StockBulkButtons.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/StockBulkButtons.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsF3D,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,kBAAkB,EAClB,UAAU,GACX,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC,+BAmoBA"}
|
|
@@ -9,6 +9,8 @@ import { upsertLocalTradeItem, updateDraftMeta } from "../../hooks/useLocalTrade
|
|
|
9
9
|
import { validateDraftForPublish } from "../../lib/floriday-import-validator";
|
|
10
10
|
import { floriday } from "../../lib/floriday-client";
|
|
11
11
|
import { ensureArticleCodes } from "../../lib/ensure-article-codes";
|
|
12
|
+
import { useVoorraadCustomFields } from "../../hooks/useVoorraadCustomFields";
|
|
13
|
+
import { saveProductCustomValues } from "../../lib/voorraad-custom-fields";
|
|
12
14
|
const COLUMNS = [
|
|
13
15
|
"Artikelcode",
|
|
14
16
|
"Artikelnaam",
|
|
@@ -61,6 +63,34 @@ export function StockBulkButtons({ items, activeConnectionId, onImported, }) {
|
|
|
61
63
|
const [autoPublish, setAutoPublish] = useState(false);
|
|
62
64
|
const [result, setResult] = useState(null);
|
|
63
65
|
const [pastRuns, setPastRuns] = useState([]);
|
|
66
|
+
const { fields: customFields } = useVoorraadCustomFields();
|
|
67
|
+
const templateFields = customFields.filter((f) => f.show_in_template);
|
|
68
|
+
/**
|
|
69
|
+
* Leest de waarde van een eigen veld uit een Excel-rij. Kolomkoppen worden
|
|
70
|
+
* tolerant gematcht: op label óf key, hoofdletter- en spatie-ongevoelig.
|
|
71
|
+
*/
|
|
72
|
+
const readCustomValues = useCallback((row) => {
|
|
73
|
+
const norm = (s) => s.toLowerCase().replace(/[\s_-]+/g, "");
|
|
74
|
+
const lookup = new Map();
|
|
75
|
+
for (const [k, v] of Object.entries(row))
|
|
76
|
+
lookup.set(norm(k), v);
|
|
77
|
+
const patch = {};
|
|
78
|
+
for (const f of customFields) {
|
|
79
|
+
const raw = lookup.get(norm(f.field_label)) ?? lookup.get(norm(f.field_key));
|
|
80
|
+
if (raw === undefined)
|
|
81
|
+
continue;
|
|
82
|
+
const str = String(raw ?? "").trim();
|
|
83
|
+
patch[f.field_key] =
|
|
84
|
+
str === ""
|
|
85
|
+
? null
|
|
86
|
+
: f.field_type === "number"
|
|
87
|
+
? Number(str.replace(",", "."))
|
|
88
|
+
: f.field_type === "boolean"
|
|
89
|
+
? ["ja", "true", "1", "yes"].includes(str.toLowerCase())
|
|
90
|
+
: str;
|
|
91
|
+
}
|
|
92
|
+
return patch;
|
|
93
|
+
}, [customFields]);
|
|
64
94
|
const loadPastRuns = useCallback(async () => {
|
|
65
95
|
const { data, error } = await supabase
|
|
66
96
|
.from("stock_import_runs")
|
|
@@ -115,6 +145,12 @@ export function StockBulkButtons({ items, activeConnectionId, onImported, }) {
|
|
|
115
145
|
const generatedCount = exportItems.filter((i, idx) => i.articleNumber !== items[idx].articleNumber).length;
|
|
116
146
|
const rows = exportItems.map((i) => {
|
|
117
147
|
const d = i.raw?.data;
|
|
148
|
+
const cf = (i.raw?.custom_fields ?? {});
|
|
149
|
+
const extra = {};
|
|
150
|
+
for (const f of templateFields) {
|
|
151
|
+
const v = cf[f.field_key];
|
|
152
|
+
extra[f.field_label] = v === null || v === undefined ? "" : v;
|
|
153
|
+
}
|
|
118
154
|
return {
|
|
119
155
|
Artikelcode: i.articleNumber,
|
|
120
156
|
Artikelnaam: i.name,
|
|
@@ -126,10 +162,12 @@ export function StockBulkButtons({ items, activeConnectionId, onImported, }) {
|
|
|
126
162
|
"Minimum voorraad": i.minQuantity,
|
|
127
163
|
"Gereserveerde voorraad": i.reservedQuantity,
|
|
128
164
|
"Inkomende voorraad": i.incomingQuantity,
|
|
165
|
+
...extra,
|
|
129
166
|
};
|
|
130
167
|
});
|
|
131
|
-
const
|
|
132
|
-
ws
|
|
168
|
+
const headers = [...COLUMNS, ...templateFields.map((f) => f.field_label)];
|
|
169
|
+
const ws = XLSX.utils.json_to_sheet(rows, { header: headers });
|
|
170
|
+
ws["!cols"] = headers.map((c) => ({
|
|
133
171
|
wch: c === "Artikelnaam" ? 40 : c === "Artikelcode" ? 18 : 20,
|
|
134
172
|
}));
|
|
135
173
|
const wb = XLSX.utils.book_new();
|
|
@@ -257,6 +295,19 @@ export function StockBulkButtons({ items, activeConnectionId, onImported, }) {
|
|
|
257
295
|
oldReserved: existing.reservedQuantity,
|
|
258
296
|
newReserved: applied.reserved_stock,
|
|
259
297
|
});
|
|
298
|
+
// Eigen voorraadvelden uit de template terugschrijven
|
|
299
|
+
const targetProductId = existing.productId ?? existing.localId ?? null;
|
|
300
|
+
if (targetProductId && customFields.length > 0) {
|
|
301
|
+
const patch = readCustomValues(row);
|
|
302
|
+
if (Object.keys(patch).length > 0) {
|
|
303
|
+
try {
|
|
304
|
+
await saveProductCustomValues(targetProductId, patch);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
/* eigen velden zijn niet blokkerend voor de voorraadimport */
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
260
311
|
updated++;
|
|
261
312
|
setProgress(Math.round(((idx + 1) / rows.length) * 100));
|
|
262
313
|
continue;
|
|
@@ -334,6 +385,18 @@ export function StockBulkButtons({ items, activeConnectionId, onImported, }) {
|
|
|
334
385
|
},
|
|
335
386
|
});
|
|
336
387
|
created++;
|
|
388
|
+
// Eigen voorraadvelden ook op nieuw aangemaakte producten zetten
|
|
389
|
+
if (customFields.length > 0) {
|
|
390
|
+
const patch = readCustomValues(row);
|
|
391
|
+
if (Object.keys(patch).length > 0) {
|
|
392
|
+
try {
|
|
393
|
+
await saveProductCustomValues(draftId, patch);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
/* niet blokkerend */
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
337
400
|
// Stock koppelen aan het nieuwe product (draftId is nu de product-uuid)
|
|
338
401
|
const anyStock = stockValues.physical_stock !== null ||
|
|
339
402
|
stockValues.minimum_stock !== null ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidationOverviewTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ValidationOverviewTable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAM3D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,YAAY,EACZ,SAAS,GACV,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,+
|
|
1
|
+
{"version":3,"file":"ValidationOverviewTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ValidationOverviewTable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAM3D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,YAAY,EACZ,SAAS,GACV,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,+BAmHA"}
|
|
@@ -19,7 +19,10 @@ export function ValidationOverviewTable({ items, connectionId, onChanged, }) {
|
|
|
19
19
|
const productId = item.productId ?? item.localId;
|
|
20
20
|
if (!productId || !connectionId)
|
|
21
21
|
return;
|
|
22
|
-
const payload = item.raw?.floriday_payload ??
|
|
22
|
+
const payload = item.raw?.custom_fields?.floriday_payload ??
|
|
23
|
+
item.raw?.floriday_payload ??
|
|
24
|
+
item.raw?.data ??
|
|
25
|
+
{};
|
|
23
26
|
const v = validateDraftForPublish(payload);
|
|
24
27
|
if (!v.ok) {
|
|
25
28
|
toast.error("Nog niet compleet: " + v.missing.join(", "));
|
|
@@ -47,7 +50,10 @@ export function ValidationOverviewTable({ items, connectionId, onChanged, }) {
|
|
|
47
50
|
return (_jsx("div", { className: "p-8 text-center text-sm text-muted-foreground", children: "Alle producten staan actief op Floriday." }));
|
|
48
51
|
}
|
|
49
52
|
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", children: "Artikelcode" }), _jsx("th", { className: "p-3", children: "Artikelnaam" }), _jsx("th", { className: "p-3", children: "Floriday-status" }), _jsx("th", { className: "p-3", children: "Ontbrekende Floriday-velden" }), _jsx("th", { className: "p-3 text-right", children: "Acties" })] }) }), _jsx("tbody", { children: rows.map((it) => {
|
|
50
|
-
const payload = it.raw?.floriday_payload ??
|
|
53
|
+
const payload = it.raw?.custom_fields?.floriday_payload ??
|
|
54
|
+
it.raw?.floriday_payload ??
|
|
55
|
+
it.raw?.data ??
|
|
56
|
+
{};
|
|
51
57
|
const v = validateDraftForPublish(payload);
|
|
52
58
|
return (_jsxs("tr", { className: "border-t align-top", children: [_jsx("td", { className: "p-3 font-mono text-xs", children: it.articleNumber || "—" }), _jsx("td", { className: "p-3", children: it.name }), _jsx("td", { className: "p-3", children: _jsx(Badge, { className: "bg-slate-500/15 text-slate-700 border-slate-500/30", children: "Niet actief op Floriday" }) }), _jsx("td", { className: "p-3", children: v.missing.length === 0 ? (_jsx("span", { className: "text-xs text-emerald-700", children: "Klaar om te activeren" })) : (_jsx("div", { className: "flex flex-wrap gap-1", children: v.missing.map((m) => (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: m }, m))) })) }), _jsx("td", { className: "p-3", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
53
59
|
const target = it.productId ?? it.localId ?? it.id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoorraadDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadDashboard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA4B3D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,YAAY,GACb,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,+
|
|
1
|
+
{"version":3,"file":"VoorraadDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadDashboard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA4B3D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,YAAY,GACb,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,+BA0DA"}
|
|
@@ -23,7 +23,10 @@ export function VoorraadDashboard({ items, connectionId, }) {
|
|
|
23
23
|
const missingFields = items.filter((i) => {
|
|
24
24
|
if (i.floridayActive)
|
|
25
25
|
return false;
|
|
26
|
-
const payload = i.raw?.floriday_payload ??
|
|
26
|
+
const payload = i.raw?.custom_fields?.floriday_payload ??
|
|
27
|
+
i.raw?.floriday_payload ??
|
|
28
|
+
i.raw?.data ??
|
|
29
|
+
{};
|
|
27
30
|
return !validateDraftForPublish(payload).ok;
|
|
28
31
|
}).length;
|
|
29
32
|
// Nieuw sinds laatste import
|
|
@@ -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;
|
|
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;AAmB3D,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,+BAyJA"}
|
|
@@ -2,6 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useNavigate } from "@tanstack/react-router";
|
|
3
3
|
import { Package } from "lucide-react";
|
|
4
4
|
import { Badge } from "@flowselections/core";
|
|
5
|
+
import { useVoorraadCustomFields } from "../../hooks/useVoorraadCustomFields";
|
|
6
|
+
import { formatCustomValue } from "../../lib/voorraad-custom-fields";
|
|
5
7
|
const columns = [
|
|
6
8
|
{ key: "quantity", label: "Liggend" },
|
|
7
9
|
{ key: "minQuantity", label: "Minimum" },
|
|
@@ -10,15 +12,21 @@ const columns = [
|
|
|
10
12
|
{ key: "incomingQuantity", label: "Inkomend" },
|
|
11
13
|
{ key: "economicQuantity", label: "Economisch" },
|
|
12
14
|
];
|
|
15
|
+
function customValue(item, key) {
|
|
16
|
+
const cf = item.raw?.custom_fields;
|
|
17
|
+
return cf && typeof cf === "object" ? cf[key] : undefined;
|
|
18
|
+
}
|
|
13
19
|
export function VoorraadTable({ items, loading, }) {
|
|
14
20
|
const navigate = useNavigate();
|
|
21
|
+
const { fields } = useVoorraadCustomFields();
|
|
22
|
+
const extraColumns = fields.filter((f) => f.show_in_columns);
|
|
15
23
|
if (loading) {
|
|
16
24
|
return _jsx("p", { className: "text-sm text-muted-foreground p-6", children: "Voorraad laden..." });
|
|
17
25
|
}
|
|
18
26
|
if (items.length === 0) {
|
|
19
27
|
return (_jsx("p", { className: "text-sm text-muted-foreground p-6", children: "Geen producten gevonden voor deze connectie." }));
|
|
20
28
|
}
|
|
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: "Type" }), _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) => {
|
|
29
|
+
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: "Type" }), _jsx("th", { className: "p-3", children: "Artikelnummer" }), columns.map((c) => (_jsx("th", { className: "p-3 text-right whitespace-nowrap", children: c.label }, c.key))), extraColumns.map((f) => (_jsx("th", { className: "p-3 whitespace-nowrap", children: f.field_label }, f.id)))] }) }), _jsx("tbody", { children: items.map((item) => {
|
|
22
30
|
const low = item.minQuantity > 0 &&
|
|
23
31
|
item.availableQuantity < item.minQuantity;
|
|
24
32
|
const linkId = item.productId ?? item.localId ?? item.id;
|
|
@@ -41,6 +49,6 @@ export function VoorraadTable({ items, loading, }) {
|
|
|
41
49
|
: "Niet online in Floriday", title: floriday
|
|
42
50
|
? "Online in Floriday"
|
|
43
51
|
: "Niet online in Floriday", className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-2 py-0.5 text-[11px] font-medium leading-none text-muted-foreground", children: [_jsx("span", { className: "h-1.5 w-1.5 rounded-full " +
|
|
44
|
-
(floriday ? "bg-emerald-500" : "bg-red-500"), "aria-hidden": true }), _jsx("span", { children: "Floriday" })] })] }), low && (_jsx("div", { className: "text-xs text-destructive", children: "onder minimumvoorraad" }))] }), _jsx("td", { className: "p-3", children: item.itemType === "productgroep" ? (_jsx(Badge, { className: "bg-indigo-500/15 text-indigo-700 border-indigo-500/30", children: "Productgroep" })) : item.itemType === "samenstelling" ? (_jsx(Badge, { className: "bg-emerald-500/15 text-emerald-700 border-emerald-500/30", children: "Samenstelling" })) : (_jsx(Badge, { variant: "secondary", children: "Artikel" })) }), _jsx("td", { className: "p-3 font-mono text-xs", children: item.articleNumber || "—" }), columns.map((c) => (_jsx("td", { className: "p-3 text-right tabular-nums text-muted-foreground", children: Number(item[c.key] ?? 0) }, c.key)))] }, item.id));
|
|
52
|
+
(floriday ? "bg-emerald-500" : "bg-red-500"), "aria-hidden": true }), _jsx("span", { children: "Floriday" })] })] }), low && (_jsx("div", { className: "text-xs text-destructive", children: "onder minimumvoorraad" }))] }), _jsx("td", { className: "p-3", children: item.itemType === "productgroep" ? (_jsx(Badge, { className: "bg-indigo-500/15 text-indigo-700 border-indigo-500/30", children: "Productgroep" })) : item.itemType === "samenstelling" ? (_jsx(Badge, { className: "bg-emerald-500/15 text-emerald-700 border-emerald-500/30", children: "Samenstelling" })) : (_jsx(Badge, { variant: "secondary", children: "Artikel" })) }), _jsx("td", { className: "p-3 font-mono text-xs", children: item.articleNumber || "—" }), columns.map((c) => (_jsx("td", { className: "p-3 text-right tabular-nums text-muted-foreground", children: Number(item[c.key] ?? 0) }, c.key))), extraColumns.map((f) => (_jsx("td", { className: "p-3 text-muted-foreground whitespace-nowrap", children: formatCustomValue(customValue(item, f.field_key)) }, f.id)))] }, item.id));
|
|
45
53
|
}) })] }) }));
|
|
46
54
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoorraadVeldenCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadVeldenCard.tsx"],"names":[],"mappings":"AAoCA,wBAAgB,kBAAkB,gCAqOjC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast, } from "@flowselections/core";
|
|
4
|
+
import { Loader2, Plus, Trash2 } from "lucide-react";
|
|
5
|
+
import { useVoorraadCustomFields } from "../../hooks/useVoorraadCustomFields";
|
|
6
|
+
import { createVoorraadCustomField, deleteVoorraadCustomField, slugifyFieldKey, updateVoorraadCustomField, } from "../../lib/voorraad-custom-fields";
|
|
7
|
+
const TYPE_LABELS = {
|
|
8
|
+
text: "Tekst",
|
|
9
|
+
number: "Getal",
|
|
10
|
+
date: "Datum",
|
|
11
|
+
select: "Keuzelijst",
|
|
12
|
+
boolean: "Ja / nee",
|
|
13
|
+
};
|
|
14
|
+
export function VoorraadVeldenCard() {
|
|
15
|
+
const { fields, loading, reload } = useVoorraadCustomFields();
|
|
16
|
+
const [label, setLabel] = useState("");
|
|
17
|
+
const [type, setType] = useState("text");
|
|
18
|
+
const [options, setOptions] = useState("");
|
|
19
|
+
const [inTemplate, setInTemplate] = useState(false);
|
|
20
|
+
const [inColumns, setInColumns] = useState(false);
|
|
21
|
+
const [inDetail, setInDetail] = useState(true);
|
|
22
|
+
const [saving, setSaving] = useState(false);
|
|
23
|
+
const add = async () => {
|
|
24
|
+
const trimmed = label.trim();
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
toast.error("Geef het veld een naam");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const key = slugifyFieldKey(trimmed);
|
|
30
|
+
if (!key) {
|
|
31
|
+
toast.error("Ongeldige veldnaam");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (fields.some((f) => f.field_key === key)) {
|
|
35
|
+
toast.error("Er bestaat al een veld met deze naam");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
setSaving(true);
|
|
39
|
+
try {
|
|
40
|
+
await createVoorraadCustomField({
|
|
41
|
+
field_key: key,
|
|
42
|
+
field_label: trimmed,
|
|
43
|
+
field_type: type,
|
|
44
|
+
options: type === "select"
|
|
45
|
+
? options
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((o) => o.trim())
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
: [],
|
|
50
|
+
show_in_template: inTemplate,
|
|
51
|
+
show_in_columns: inColumns,
|
|
52
|
+
show_in_detail: inDetail,
|
|
53
|
+
sort_order: fields.length,
|
|
54
|
+
});
|
|
55
|
+
setLabel("");
|
|
56
|
+
setOptions("");
|
|
57
|
+
setType("text");
|
|
58
|
+
setInTemplate(false);
|
|
59
|
+
setInColumns(false);
|
|
60
|
+
setInDetail(true);
|
|
61
|
+
await reload();
|
|
62
|
+
toast.success("Veld toegevoegd");
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
toast.error(`Toevoegen mislukt: ${e.message}`);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
setSaving(false);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const toggle = async (id, key, value) => {
|
|
72
|
+
try {
|
|
73
|
+
await updateVoorraadCustomField(id, { [key]: value });
|
|
74
|
+
await reload();
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
toast.error(`Opslaan mislukt: ${e.message}`);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const remove = async (id, name) => {
|
|
81
|
+
if (!confirm(`Veld "${name}" verwijderen? Ingevulde waarden blijven bewaard.`))
|
|
82
|
+
return;
|
|
83
|
+
try {
|
|
84
|
+
await deleteVoorraadCustomField(id);
|
|
85
|
+
await reload();
|
|
86
|
+
toast.success("Veld verwijderd");
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
toast.error(`Verwijderen mislukt: ${e.message}`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Voorraadvelden" }), _jsx(CardDescription, { children: "Maak eigen velden aan en bepaal per veld waar het zichtbaar is: in de Excel-template, als kolom in de voorraadlijst, en/of op de productpagina." })] }), _jsxs(CardContent, { className: "space-y-6", children: [_jsxs("div", { className: "grid gap-3 sm:grid-cols-[1fr_180px] items-end", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "veld-naam", children: "Veldnaam" }), _jsx(Input, { id: "veld-naam", value: label, onChange: (e) => setLabel(e.target.value), placeholder: "Bijv. Kweeklocatie" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "Type" }), _jsxs(Select, { value: type, onValueChange: (v) => setType(v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: Object.keys(TYPE_LABELS).map((t) => (_jsx(SelectItem, { value: t, children: TYPE_LABELS[t] }, t))) })] })] })] }), type === "select" && (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "veld-opties", children: "Keuzes (komma-gescheiden)" }), _jsx(Input, { id: "veld-opties", value: options, onChange: (e) => setOptions(e.target.value), placeholder: "Kas 1, Kas 2, Buiten" })] })), _jsxs("div", { className: "flex flex-wrap gap-6", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: inTemplate, onCheckedChange: (c) => setInTemplate(c === true) }), "In Excel-template"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: inColumns, onCheckedChange: (c) => setInColumns(c === true) }), "Als voorraadkolom"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: inDetail, onCheckedChange: (c) => setInDetail(c === true) }), "Op productpagina"] })] }), _jsxs(Button, { onClick: add, disabled: saving, children: [saving ? (_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" })) : (_jsx(Plus, { className: "mr-2 h-4 w-4" })), "Veld toevoegen"] }), _jsx("div", { className: "border-t pt-4", children: loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Velden laden\u2026" })) : fields.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen eigen voorraadvelden aangemaakt." })) : (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "text-left text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "py-2", children: "Veld" }), _jsx("th", { className: "py-2", children: "Type" }), _jsx("th", { className: "py-2 text-center", children: "Template" }), _jsx("th", { className: "py-2 text-center", children: "Kolom" }), _jsx("th", { className: "py-2 text-center", children: "Productpagina" }), _jsx("th", { className: "py-2" })] }) }), _jsx("tbody", { children: fields.map((f) => (_jsxs("tr", { className: "border-t", children: [_jsxs("td", { className: "py-2", children: [_jsx("div", { className: "font-medium text-foreground", children: f.field_label }), _jsx("div", { className: "font-mono text-xs text-muted-foreground", children: f.field_key })] }), _jsx("td", { className: "py-2", children: TYPE_LABELS[f.field_type] ?? f.field_type }), [
|
|
93
|
+
"show_in_template",
|
|
94
|
+
"show_in_columns",
|
|
95
|
+
"show_in_detail",
|
|
96
|
+
].map((k) => (_jsx("td", { className: "py-2 text-center", children: _jsx(Checkbox, { checked: f[k], onCheckedChange: (c) => toggle(f.id, k, c === true), "aria-label": `${f.field_label} – ${k}` }) }, k))), _jsx("td", { className: "py-2 text-right", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => remove(f.id, f.field_label), "aria-label": `Verwijder ${f.field_label}`, children: _jsx(Trash2, { className: "h-4 w-4 text-destructive" }) }) })] }, f.id))) })] }) })) })] })] }));
|
|
97
|
+
}
|
|
@@ -2,7 +2,7 @@ import type { WizardData } from "../lib/floriday-payload";
|
|
|
2
2
|
import { type FloridayLinkStatus, type TradeItem } from "../lib/floriday-client";
|
|
3
3
|
/**
|
|
4
4
|
* Concept/Draft is verwijderd. Alle "lokale trade items" leven nu als volwaardige rijen in
|
|
5
|
-
* `public.products` met de Floriday-velden in `floriday_payload`. Dit bestand behoudt de
|
|
5
|
+
* `public.products` met de Floriday-velden in `custom_fields.floriday_payload`. Dit bestand behoudt de
|
|
6
6
|
* oorspronkelijke API-namen zodat bestaande callers blijven werken, maar leest en schrijft
|
|
7
7
|
* uitsluitend op `products`. `trade_item_drafts` is read-only (trigger blokkeert writes).
|
|
8
8
|
*/
|
|
@@ -38,7 +38,7 @@ export interface DraftMeta {
|
|
|
38
38
|
source?: "manual" | "excel_import";
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
-
* Slaat Floriday-velden op in `products.floriday_payload`. Als `id` ontbreekt maken we een
|
|
41
|
+
* Slaat Floriday-velden op in `products.custom_fields.floriday_payload`. Als `id` ontbreekt maken we een
|
|
42
42
|
* nieuw product aan (met minimale ERP-velden uit de payload). Nooit een concept-rij.
|
|
43
43
|
*/
|
|
44
44
|
export declare function upsertLocalTradeItem(params: {
|
|
@@ -48,8 +48,8 @@ export declare function upsertLocalTradeItem(params: {
|
|
|
48
48
|
meta?: DraftMeta;
|
|
49
49
|
}): Promise<string>;
|
|
50
50
|
/**
|
|
51
|
-
* Legacy API. Alleen meta-velden die vandaag nog op `products` bestaan (`
|
|
52
|
-
* `
|
|
51
|
+
* Legacy API. Alleen meta-velden die vandaag nog op `products` bestaan (`floriday_trade_item_id`
|
|
52
|
+
* en `custom_fields.floriday_id`) worden gepersisteerd; overige velden worden stilzwijgend genegeerd
|
|
53
53
|
* omdat het draft-model verdwenen is.
|
|
54
54
|
*/
|
|
55
55
|
export declare function updateDraftMeta(id: string, meta: DraftMeta): Promise<void>;
|
|
@@ -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,EAAwB,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGvG;;;;;GAKG;AAEH,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;
|
|
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,EAAwB,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGvG;;;;;GAKG;AAEH,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;AAwED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;;;;EA0B9D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA4BrF;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;;;GAGG;AACH,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,CAyElB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhF;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
|