@flowselections/floriday-voorraad 1.0.12 → 1.0.14
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/assets/floriday-logo.png.asset.json +11 -0
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts +5 -0
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ArtikelWizard.js +1229 -0
- package/dist-lib/components/voorraad/ConnectionBadge.d.ts +6 -0
- package/dist-lib/components/voorraad/ConnectionBadge.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ConnectionBadge.js +12 -0
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts +4 -0
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/EditArtikelPage.js +51 -0
- package/dist-lib/components/voorraad/NieuwArtikelPage.d.ts +2 -0
- package/dist-lib/components/voorraad/NieuwArtikelPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/NieuwArtikelPage.js +5 -0
- package/dist-lib/components/voorraad/StockBulkButtons.d.ts +7 -0
- package/dist-lib/components/voorraad/StockBulkButtons.d.ts.map +1 -0
- package/dist-lib/components/voorraad/StockBulkButtons.js +356 -0
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts +7 -0
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ValidationOverviewTable.js +87 -0
- package/dist-lib/components/voorraad/ValidationPage.d.ts +2 -0
- package/dist-lib/components/voorraad/ValidationPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ValidationPage.js +12 -0
- package/dist-lib/components/voorraad/VoorraadDashboard.d.ts +6 -0
- package/dist-lib/components/voorraad/VoorraadDashboard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadDashboard.js +42 -0
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +78 -11
- package/dist-lib/components/voorraad/VoorraadPagination.d.ts +10 -0
- package/dist-lib/components/voorraad/VoorraadPagination.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadPagination.js +12 -0
- package/dist-lib/components/voorraad/VoorraadStockCard.d.ts +8 -0
- package/dist-lib/components/voorraad/VoorraadStockCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadStockCard.js +33 -0
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +21 -2
- package/dist-lib/hooks/useFloriday.d.ts +55 -0
- package/dist-lib/hooks/useFloriday.d.ts.map +1 -0
- package/dist-lib/hooks/useFloriday.js +298 -0
- package/dist-lib/hooks/useFloridayConnection.d.ts +9 -4
- package/dist-lib/hooks/useFloridayConnection.d.ts.map +1 -1
- package/dist-lib/hooks/useFloridayConnection.js +23 -23
- package/dist-lib/hooks/useFlorydayCustomers.d.ts +17 -0
- package/dist-lib/hooks/useFlorydayCustomers.d.ts.map +1 -0
- package/dist-lib/hooks/useFlorydayCustomers.js +65 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts +38 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -0
- package/dist-lib/hooks/useLocalTradeItems.js +144 -0
- package/dist-lib/hooks/useTradeItemSpec.d.ts +42 -0
- package/dist-lib/hooks/useTradeItemSpec.d.ts.map +1 -0
- package/dist-lib/hooks/useTradeItemSpec.js +448 -0
- package/dist-lib/hooks/useTradeItemStock.d.ts +19 -0
- package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -0
- package/dist-lib/hooks/useTradeItemStock.js +78 -0
- package/dist-lib/hooks/useVbnRegulatoryFeatures.d.ts +3 -0
- package/dist-lib/hooks/useVbnRegulatoryFeatures.d.ts.map +1 -0
- package/dist-lib/hooks/useVbnRegulatoryFeatures.js +19 -0
- package/dist-lib/hooks/useVoorraadData.d.ts +6 -0
- package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadData.js +65 -10
- package/dist-lib/index.d.ts +4 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +6 -5
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +9085 -1645
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +9085 -1645
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +9085 -1645
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +9298 -1655
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +20 -1
- package/dist-lib/lib/__tests__/floricode-required-features.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/floricode-required-features.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/floricode-required-features.test.js +186 -0
- package/dist-lib/lib/floricode-client.d.ts +15 -1
- package/dist-lib/lib/floricode-client.d.ts.map +1 -1
- package/dist-lib/lib/floricode-client.js +42 -4
- package/dist-lib/lib/floricode-required-features.functions.d.ts +10026 -0
- package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -0
- package/dist-lib/lib/floricode-required-features.functions.js +170 -0
- package/dist-lib/lib/floriday-client.d.ts +45 -19
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +236 -38
- package/dist-lib/lib/floriday-env.d.ts +29 -0
- package/dist-lib/lib/floriday-env.d.ts.map +1 -0
- package/dist-lib/lib/floriday-env.js +42 -0
- package/dist-lib/lib/floriday-env.server.d.ts +15 -0
- package/dist-lib/lib/floriday-env.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-env.server.js +13 -0
- package/dist-lib/lib/floriday-field-sources.d.ts +18 -0
- package/dist-lib/lib/floriday-field-sources.d.ts.map +1 -0
- package/dist-lib/lib/floriday-field-sources.js +45 -0
- package/dist-lib/lib/floriday-gateway-entities.d.ts +44 -0
- package/dist-lib/lib/floriday-gateway-entities.d.ts.map +1 -0
- package/dist-lib/lib/floriday-gateway-entities.js +51 -0
- package/dist-lib/lib/floriday-gateway.functions.d.ts +39999 -0
- package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-gateway.functions.js +68 -0
- package/dist-lib/lib/floriday-gateway.server.d.ts +122 -0
- package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-gateway.server.js +230 -0
- package/dist-lib/lib/floriday-import-validator.d.ts +26 -0
- package/dist-lib/lib/floriday-import-validator.d.ts.map +1 -0
- package/dist-lib/lib/floriday-import-validator.js +41 -0
- package/dist-lib/lib/floriday-payload.d.ts +47 -3
- package/dist-lib/lib/floriday-payload.d.ts.map +1 -1
- package/dist-lib/lib/floriday-payload.js +179 -7
- package/dist-lib/lib/floriday-schema-to-zod.d.ts +9 -0
- package/dist-lib/lib/floriday-schema-to-zod.d.ts.map +1 -0
- package/dist-lib/lib/floriday-schema-to-zod.js +53 -0
- package/dist-lib/lib/floriday-writes.functions.d.ts +19998 -0
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-writes.functions.js +74 -0
- package/dist-lib/lib/image-resize.d.ts +43 -0
- package/dist-lib/lib/image-resize.d.ts.map +1 -0
- package/dist-lib/lib/image-resize.js +212 -0
- package/dist-lib/lib/normalize-errors-middleware.d.ts +2 -0
- package/dist-lib/lib/normalize-errors-middleware.d.ts.map +1 -0
- package/dist-lib/lib/normalize-errors-middleware.js +24 -0
- package/dist-lib/lib/wizard-step-fields.d.ts +15 -0
- package/dist-lib/lib/wizard-step-fields.d.ts.map +1 -0
- package/dist-lib/lib/wizard-step-fields.js +51 -0
- package/package.json +29 -14
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { gatewaySchemaFn, gatewayCodeListFn, gatewayCachedListFn, } from "../lib/floriday-gateway.functions";
|
|
4
|
+
import { unmappedRequiredFields } from "../lib/wizard-step-fields";
|
|
5
|
+
import { useFloridayConnection } from "./useFloridayConnection";
|
|
6
|
+
import { normalizeFloridayEnvironment } from "../lib/floriday-env";
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function arrayFromCodeListValue(value) {
|
|
11
|
+
if (Array.isArray(value))
|
|
12
|
+
return value;
|
|
13
|
+
if (!isRecord(value))
|
|
14
|
+
return [];
|
|
15
|
+
const candidates = [
|
|
16
|
+
value.values,
|
|
17
|
+
value.items,
|
|
18
|
+
value.rows,
|
|
19
|
+
value.data,
|
|
20
|
+
value.payload,
|
|
21
|
+
value.entries,
|
|
22
|
+
];
|
|
23
|
+
for (const c of candidates) {
|
|
24
|
+
if (Array.isArray(c))
|
|
25
|
+
return c;
|
|
26
|
+
}
|
|
27
|
+
// Sommige gateway-implementaties geven een codelijst als dictionary terug:
|
|
28
|
+
// { "S62": { description: "..." }, "S98": "..." }. Maak daar alsnog
|
|
29
|
+
// entries van. Een object dat zelf één entry is (heeft code/id/value) laten
|
|
30
|
+
// we ongemoeid om dubbele parsing te voorkomen.
|
|
31
|
+
if (value.code != null || value.id != null || value.value != null)
|
|
32
|
+
return [value];
|
|
33
|
+
return Object.entries(value).map(([code, entry]) => isRecord(entry) ? { code, ...entry } : { code, label: entry });
|
|
34
|
+
}
|
|
35
|
+
function canonicalCodeListName(name) {
|
|
36
|
+
const kebab = name
|
|
37
|
+
.trim()
|
|
38
|
+
.replace(/_/g, "-")
|
|
39
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
40
|
+
.toLowerCase();
|
|
41
|
+
const aliases = {
|
|
42
|
+
vbnproductgroup: "vbn-product-group",
|
|
43
|
+
"vbn-productgroup": "vbn-product-group",
|
|
44
|
+
"vbn-product-groups": "vbn-product-group",
|
|
45
|
+
characteristics: "characteristic",
|
|
46
|
+
"characteristic-type": "characteristic",
|
|
47
|
+
"characteristic-types": "characteristic",
|
|
48
|
+
packagingtype: "packaging-type",
|
|
49
|
+
countryoforigin: "country-of-origin",
|
|
50
|
+
lengthunit: "length-unit",
|
|
51
|
+
};
|
|
52
|
+
return aliases[kebab] ?? aliases[kebab.replace(/-/g, "")] ?? kebab;
|
|
53
|
+
}
|
|
54
|
+
function pickCode(value) {
|
|
55
|
+
if (!isRecord(value))
|
|
56
|
+
return String(value ?? "").trim();
|
|
57
|
+
const payload = isRecord(value.payload) ? value.payload : isRecord(value.data) ? value.data : undefined;
|
|
58
|
+
const raw = value.code ??
|
|
59
|
+
value.id ??
|
|
60
|
+
value.value ??
|
|
61
|
+
value.vbnProductCode ??
|
|
62
|
+
value.productCode ??
|
|
63
|
+
value.vbnCode ??
|
|
64
|
+
value.record_id ??
|
|
65
|
+
payload?.code ??
|
|
66
|
+
payload?.id ??
|
|
67
|
+
payload?.vbnProductCode ??
|
|
68
|
+
payload?.productCode ??
|
|
69
|
+
payload?.vbnCode ??
|
|
70
|
+
payload?.record_id;
|
|
71
|
+
return String(raw ?? "").trim();
|
|
72
|
+
}
|
|
73
|
+
function pickLabel(value, code) {
|
|
74
|
+
if (!isRecord(value))
|
|
75
|
+
return code || String(value ?? "").trim() || null;
|
|
76
|
+
const payload = isRecord(value.payload) ? value.payload : isRecord(value.data) ? value.data : undefined;
|
|
77
|
+
const raw = value.label ??
|
|
78
|
+
value.description ??
|
|
79
|
+
value.name ??
|
|
80
|
+
value.displayName ??
|
|
81
|
+
value.title ??
|
|
82
|
+
payload?.label ??
|
|
83
|
+
payload?.description ??
|
|
84
|
+
payload?.name ??
|
|
85
|
+
payload?.displayName ??
|
|
86
|
+
payload?.title;
|
|
87
|
+
return raw == null ? (code || null) : String(raw);
|
|
88
|
+
}
|
|
89
|
+
function normalizeCodeListEntries(value) {
|
|
90
|
+
return arrayFromCodeListValue(value)
|
|
91
|
+
.map((entry) => {
|
|
92
|
+
const code = pickCode(entry);
|
|
93
|
+
if (!code)
|
|
94
|
+
return null;
|
|
95
|
+
const label = pickLabel(entry, code);
|
|
96
|
+
const payload = isRecord(entry)
|
|
97
|
+
? entry.payload ?? entry.data ?? entry
|
|
98
|
+
: entry;
|
|
99
|
+
return { code, label, description: label, payload };
|
|
100
|
+
})
|
|
101
|
+
.filter(Boolean);
|
|
102
|
+
}
|
|
103
|
+
function normalizeCodeLists(raw) {
|
|
104
|
+
const root = isRecord(raw) ? raw : {};
|
|
105
|
+
const data = isRecord(root.data) ? root.data : undefined;
|
|
106
|
+
const payload = isRecord(root.payload) ? root.payload : undefined;
|
|
107
|
+
const result = isRecord(root.result) ? root.result : undefined;
|
|
108
|
+
const included = isRecord(root.included) ? root.included : undefined;
|
|
109
|
+
const containers = [
|
|
110
|
+
root.codeLists,
|
|
111
|
+
root.code_lists,
|
|
112
|
+
root.includedCodeLists,
|
|
113
|
+
root.included_code_lists,
|
|
114
|
+
data?.codeLists,
|
|
115
|
+
data?.code_lists,
|
|
116
|
+
data?.includedCodeLists,
|
|
117
|
+
data?.included_code_lists,
|
|
118
|
+
isRecord(data?.payload) ? data?.payload?.codeLists ?? data?.payload?.code_lists : undefined,
|
|
119
|
+
payload?.codeLists,
|
|
120
|
+
payload?.code_lists,
|
|
121
|
+
result?.codeLists,
|
|
122
|
+
result?.code_lists,
|
|
123
|
+
included?.codeLists,
|
|
124
|
+
included?.code_lists,
|
|
125
|
+
];
|
|
126
|
+
const out = {};
|
|
127
|
+
for (const container of containers) {
|
|
128
|
+
if (Array.isArray(container)) {
|
|
129
|
+
for (const list of container) {
|
|
130
|
+
if (!isRecord(list))
|
|
131
|
+
continue;
|
|
132
|
+
const name = canonicalCodeListName(String(list.name ?? list.listName ?? list.key ?? list.resource ?? ""));
|
|
133
|
+
if (!name)
|
|
134
|
+
continue;
|
|
135
|
+
const entries = normalizeCodeListEntries(list.values ?? list.items ?? list.rows ?? list.data ?? list.payload);
|
|
136
|
+
if (entries.length)
|
|
137
|
+
out[name] = entries;
|
|
138
|
+
}
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (!isRecord(container))
|
|
142
|
+
continue;
|
|
143
|
+
for (const [name, value] of Object.entries(container)) {
|
|
144
|
+
const canonicalName = canonicalCodeListName(name);
|
|
145
|
+
const entries = normalizeCodeListEntries(value);
|
|
146
|
+
if (entries.length)
|
|
147
|
+
out[canonicalName] = entries;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return Object.keys(out).length ? out : undefined;
|
|
151
|
+
}
|
|
152
|
+
function normalizeSchemaResponse(raw) {
|
|
153
|
+
const root = isRecord(raw) ? raw : {};
|
|
154
|
+
const data = isRecord(root.data) ? root.data : undefined;
|
|
155
|
+
const payload = isRecord(root.payload) ? root.payload : undefined;
|
|
156
|
+
const source = data && (data.fields || data.requiredFields || data.schema || data.enums || data.codeLists || data.code_lists)
|
|
157
|
+
? data
|
|
158
|
+
: payload && (payload.fields || payload.requiredFields || payload.schema || payload.enums || payload.codeLists || payload.code_lists)
|
|
159
|
+
? payload
|
|
160
|
+
: root;
|
|
161
|
+
const rawSchema = source.schema ?? source.jsonSchema ?? source.openApiSchema ?? source.swaggerSchema;
|
|
162
|
+
const codeLists = normalizeCodeLists(raw);
|
|
163
|
+
return {
|
|
164
|
+
...source,
|
|
165
|
+
ok: Boolean(root.ok ?? source.ok),
|
|
166
|
+
resource: String(source.resource ?? root.resource ?? "trade-item"),
|
|
167
|
+
version: String(source.version ?? root.version ?? ""),
|
|
168
|
+
requiredFields: Array.isArray(source.requiredFields)
|
|
169
|
+
? source.requiredFields.map(String)
|
|
170
|
+
: Array.isArray(source.required)
|
|
171
|
+
? source.required.map(String)
|
|
172
|
+
: [],
|
|
173
|
+
fields: Array.isArray(source.fields) ? source.fields : [],
|
|
174
|
+
enums: isRecord(source.enums) ? source.enums : undefined,
|
|
175
|
+
schema: rawSchema,
|
|
176
|
+
codeLists,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Cache-segment per environment zodat een latere live/staging-switch geen
|
|
181
|
+
* stale data uit de andere environment toont. De server resolved de echte
|
|
182
|
+
* environment uit de actieve connectie; deze key is puur voor de query-cache.
|
|
183
|
+
*/
|
|
184
|
+
function useEnvKey() {
|
|
185
|
+
const { environment } = useFloridayConnection();
|
|
186
|
+
try {
|
|
187
|
+
return environment ? normalizeFloridayEnvironment(environment) : "unknown";
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return "unknown";
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export function useFloridaySchema(resource, params) {
|
|
194
|
+
const envKey = useEnvKey();
|
|
195
|
+
const paramsKey = params ? JSON.stringify(params) : "";
|
|
196
|
+
const q = useQuery({
|
|
197
|
+
queryKey: ["floriday-schema", resource, paramsKey, envKey],
|
|
198
|
+
queryFn: async () => (await gatewaySchemaFn({
|
|
199
|
+
data: { resource, ...(params ?? {}) },
|
|
200
|
+
})),
|
|
201
|
+
staleTime: 60 * 60 * 1000,
|
|
202
|
+
});
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
if (!q.data?.requiredFields)
|
|
205
|
+
return;
|
|
206
|
+
const missing = unmappedRequiredFields(q.data.requiredFields);
|
|
207
|
+
if (missing.length && import.meta.env.DEV) {
|
|
208
|
+
console.warn(`[floriday-schema] ${resource}: required fields zonder step-mapping:`, missing);
|
|
209
|
+
}
|
|
210
|
+
}, [q.data?.requiredFields, resource]);
|
|
211
|
+
return q;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* §15.2 — één HMAC-call die het `trade-item`-schema én alle voor het
|
|
215
|
+
* "Nieuw artikel"-formulier benodigde code-lists meelevert. Vervangt een
|
|
216
|
+
* losse `useFloridaySchema("trade-item")` + meerdere `useCodeList(...)`
|
|
217
|
+
* round-trips bij wizard-open.
|
|
218
|
+
*
|
|
219
|
+
* Fail-closed: gooit als de gateway geen `ok: true` teruggeeft.
|
|
220
|
+
*/
|
|
221
|
+
const TRADE_ITEM_INCLUDE_CODE_LISTS = [
|
|
222
|
+
"vbn-product-group",
|
|
223
|
+
"vbn-product-code",
|
|
224
|
+
"vbn-characteristic",
|
|
225
|
+
"vbn-characteristic-value",
|
|
226
|
+
"characteristic",
|
|
227
|
+
"packaging-type",
|
|
228
|
+
"country-of-origin",
|
|
229
|
+
"length-unit",
|
|
230
|
+
];
|
|
231
|
+
export function useTradeItemFormSchema() {
|
|
232
|
+
const envKey = useEnvKey();
|
|
233
|
+
const q = useQuery({
|
|
234
|
+
queryKey: ["floriday-trade-item-schema", envKey],
|
|
235
|
+
queryFn: async () => {
|
|
236
|
+
const raw = await gatewaySchemaFn({
|
|
237
|
+
data: {
|
|
238
|
+
resource: "trade-item",
|
|
239
|
+
environment: envKey === "live" ? "live" : "staging",
|
|
240
|
+
includeCodeLists: [...TRADE_ITEM_INCLUDE_CODE_LISTS],
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
const res = normalizeSchemaResponse(raw);
|
|
244
|
+
if (!res || res.ok !== true) {
|
|
245
|
+
throw new Error(res?.error ??
|
|
246
|
+
"Floriday trade-item schema niet beschikbaar (gateway gaf geen ok=true terug)");
|
|
247
|
+
}
|
|
248
|
+
const vbnList = res.codeLists?.["vbn-product-group"] ?? [];
|
|
249
|
+
if (vbnList.length === 0) {
|
|
250
|
+
throw new Error("Floriday schema-call is incompleet: codeLists['vbn-product-group'] ontbreekt. Daardoor kunnen VBN-specifieke karakteristieken niet betrouwbaar worden bepaald.");
|
|
251
|
+
}
|
|
252
|
+
return res;
|
|
253
|
+
},
|
|
254
|
+
staleTime: 60 * 60 * 1000,
|
|
255
|
+
});
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
if (!q.data?.requiredFields)
|
|
258
|
+
return;
|
|
259
|
+
const missing = unmappedRequiredFields(q.data.requiredFields);
|
|
260
|
+
if (missing.length && import.meta.env.DEV) {
|
|
261
|
+
console.warn(`[floriday-schema] trade-item: required fields zonder step-mapping:`, missing);
|
|
262
|
+
}
|
|
263
|
+
}, [q.data?.requiredFields]);
|
|
264
|
+
return q;
|
|
265
|
+
}
|
|
266
|
+
export function useCodeList(listName) {
|
|
267
|
+
const envKey = useEnvKey();
|
|
268
|
+
return useQuery({
|
|
269
|
+
queryKey: ["floriday-code-list", listName ?? "", envKey],
|
|
270
|
+
queryFn: async () => (await gatewayCodeListFn({ data: { listName: listName } })),
|
|
271
|
+
staleTime: 60 * 60 * 1000,
|
|
272
|
+
enabled: Boolean(listName),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
export function useCachedList(entity, limit = 1000) {
|
|
276
|
+
const envKey = useEnvKey();
|
|
277
|
+
return useQuery({
|
|
278
|
+
queryKey: ["floriday-cached-list", entity ?? "", limit, envKey],
|
|
279
|
+
queryFn: async () => (await gatewayCachedListFn({ data: { entity: entity, limit } })),
|
|
280
|
+
staleTime: 5 * 60 * 1000,
|
|
281
|
+
enabled: Boolean(entity),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Invalideert alle floriday-* queries wanneer de actieve connectie
|
|
286
|
+
* (en dus mogelijk de environment) wijzigt. Voorkomt cache-bleed
|
|
287
|
+
* tussen staging en live bij een toekomstige switcher.
|
|
288
|
+
*/
|
|
289
|
+
export function useInvalidateFloridayOnConnectionChange() {
|
|
290
|
+
const { activeId, environment } = useFloridayConnection();
|
|
291
|
+
const qc = useQueryClient();
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
qc.invalidateQueries({ queryKey: ["floriday-cached-list"] });
|
|
294
|
+
qc.invalidateQueries({ queryKey: ["floriday-code-list"] });
|
|
295
|
+
qc.invalidateQueries({ queryKey: ["floriday-schema"] });
|
|
296
|
+
qc.invalidateQueries({ queryKey: ["floriday-trade-item-schema"] });
|
|
297
|
+
}, [activeId, environment, qc]);
|
|
298
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FloridayActiveConnection } from "../lib/floriday-client";
|
|
2
|
+
/**
|
|
3
|
+
* Reads the single active Floriday connection for the currently selected
|
|
4
|
+
* environment (staging/live) via the Auth-module's
|
|
5
|
+
* `get_active_floriday_connection_public` RPC. No tokens or secrets are
|
|
6
|
+
* exposed.
|
|
7
|
+
*/
|
|
2
8
|
export declare function useFloridayConnection(): {
|
|
3
|
-
|
|
9
|
+
activeConnection: FloridayActiveConnection | null;
|
|
4
10
|
activeId: string | null;
|
|
5
|
-
|
|
6
|
-
activeConnection: FloridayConnection | null;
|
|
11
|
+
environment: string | null;
|
|
7
12
|
loading: boolean;
|
|
8
13
|
error: string | null;
|
|
9
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFloridayConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFloridayConnection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFloridayConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFloridayConnection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,qBAAqB;;;;;;EA+BpC"}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
/**
|
|
4
|
+
* Reads the single active Floriday connection for the currently selected
|
|
5
|
+
* environment (staging/live) via the Auth-module's
|
|
6
|
+
* `get_active_floriday_connection_public` RPC. No tokens or secrets are
|
|
7
|
+
* exposed.
|
|
8
|
+
*/
|
|
4
9
|
export function useFloridayConnection() {
|
|
5
|
-
const [
|
|
6
|
-
const [activeId, setActiveIdState] = useState(null);
|
|
10
|
+
const [activeConnection, setActive] = useState(null);
|
|
7
11
|
const [loading, setLoading] = useState(true);
|
|
8
12
|
const [error, setError] = useState(null);
|
|
9
13
|
useEffect(() => {
|
|
10
14
|
let mounted = true;
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
.then((rows) => {
|
|
15
|
+
(async () => {
|
|
16
|
+
const { data, error } = await supabase.rpc("get_active_floriday_connection_public");
|
|
14
17
|
if (!mounted)
|
|
15
18
|
return;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
if (error) {
|
|
20
|
+
setError(error.message);
|
|
21
|
+
setActive(null);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const row = (data ?? [])[0];
|
|
25
|
+
setActive(row && row.id ? row : null);
|
|
26
|
+
}
|
|
27
|
+
setLoading(false);
|
|
28
|
+
})();
|
|
23
29
|
return () => {
|
|
24
30
|
mounted = false;
|
|
25
31
|
};
|
|
26
32
|
}, []);
|
|
27
|
-
const setActiveId = (id) => {
|
|
28
|
-
setActiveIdState(id);
|
|
29
|
-
if (typeof window !== "undefined")
|
|
30
|
-
localStorage.setItem(STORAGE_KEY, id);
|
|
31
|
-
};
|
|
32
33
|
return {
|
|
33
|
-
|
|
34
|
-
activeId,
|
|
35
|
-
|
|
36
|
-
activeConnection: connections.find((c) => c.id === activeId) ?? null,
|
|
34
|
+
activeConnection,
|
|
35
|
+
activeId: activeConnection?.id ?? null,
|
|
36
|
+
environment: activeConnection?.active_environment ?? null,
|
|
37
37
|
loading,
|
|
38
38
|
error,
|
|
39
39
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FloridayCustomer {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
hasRealName: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reads buyer organisations from the shared `floriday_connections_cache`
|
|
8
|
+
* (which contains buyer org id + name per supplier connection).
|
|
9
|
+
* If `buyer_organization_name` is NULL (Auth-module hasn't synced names yet),
|
|
10
|
+
* we fall back to a short, readable label so the UI never shows a raw UUID.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useFlorydayCustomers(connectionId: string | null): {
|
|
13
|
+
customers: FloridayCustomer[];
|
|
14
|
+
loading: boolean;
|
|
15
|
+
error: string | null;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useFlorydayCustomers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFlorydayCustomers.d.ts","sourceRoot":"","sources":["../../src/hooks/useFlorydayCustomers.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;EAoD/D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
function shortId(id) {
|
|
4
|
+
return `Klant ${id.slice(0, 8)}…${id.slice(-4)}`;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reads buyer organisations from the shared `floriday_connections_cache`
|
|
8
|
+
* (which contains buyer org id + name per supplier connection).
|
|
9
|
+
* If `buyer_organization_name` is NULL (Auth-module hasn't synced names yet),
|
|
10
|
+
* we fall back to a short, readable label so the UI never shows a raw UUID.
|
|
11
|
+
*/
|
|
12
|
+
export function useFlorydayCustomers(connectionId) {
|
|
13
|
+
const [customers, setCustomers] = useState([]);
|
|
14
|
+
const [loading, setLoading] = useState(false);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
let mounted = true;
|
|
18
|
+
if (!connectionId) {
|
|
19
|
+
setCustomers([]);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
setLoading(true);
|
|
23
|
+
setError(null);
|
|
24
|
+
supabase
|
|
25
|
+
.from("floriday_connections_cache")
|
|
26
|
+
.select("buyer_organization_id,buyer_organization_name")
|
|
27
|
+
.eq("connection_id", connectionId)
|
|
28
|
+
.eq("is_deleted", false)
|
|
29
|
+
.then(({ data, error }) => {
|
|
30
|
+
if (!mounted)
|
|
31
|
+
return;
|
|
32
|
+
if (error) {
|
|
33
|
+
setError(error.message);
|
|
34
|
+
setCustomers([]);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const out = [];
|
|
39
|
+
for (const row of data ?? []) {
|
|
40
|
+
const id = row.buyer_organization_id;
|
|
41
|
+
if (!id || seen.has(id))
|
|
42
|
+
continue;
|
|
43
|
+
seen.add(id);
|
|
44
|
+
const real = (row.buyer_organization_name ?? "").trim();
|
|
45
|
+
out.push({
|
|
46
|
+
id,
|
|
47
|
+
name: real.length > 0 ? real : shortId(id),
|
|
48
|
+
hasRealName: real.length > 0,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Real names first (alphabetical), then fallback labels.
|
|
52
|
+
out.sort((a, b) => {
|
|
53
|
+
if (a.hasRealName !== b.hasRealName)
|
|
54
|
+
return a.hasRealName ? -1 : 1;
|
|
55
|
+
return a.name.localeCompare(b.name);
|
|
56
|
+
});
|
|
57
|
+
setCustomers(out);
|
|
58
|
+
})
|
|
59
|
+
.then(() => mounted && setLoading(false));
|
|
60
|
+
return () => {
|
|
61
|
+
mounted = false;
|
|
62
|
+
};
|
|
63
|
+
}, [connectionId]);
|
|
64
|
+
return { customers, loading, error };
|
|
65
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { WizardData } from "../lib/floriday-payload";
|
|
2
|
+
import type { FloridayLinkStatus, TradeItem } from "../lib/floriday-client";
|
|
3
|
+
export interface LocalTradeItemRow {
|
|
4
|
+
id: string;
|
|
5
|
+
connection_id: string | null;
|
|
6
|
+
data: WizardData;
|
|
7
|
+
updated_at: string;
|
|
8
|
+
created_at: string;
|
|
9
|
+
floriday_link_status?: FloridayLinkStatus;
|
|
10
|
+
floriday_id?: string | null;
|
|
11
|
+
floriday_link_error?: string | null;
|
|
12
|
+
missing_required_fields?: string[] | null;
|
|
13
|
+
last_floriday_sync_at?: string | null;
|
|
14
|
+
source?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export declare function useLocalTradeItems(connectionId: string | null): {
|
|
17
|
+
items: TradeItem[];
|
|
18
|
+
loading: boolean;
|
|
19
|
+
reload: () => Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
export declare function getLocalTradeItem(id: string): Promise<LocalTradeItemRow | null>;
|
|
22
|
+
export interface DraftMeta {
|
|
23
|
+
floridayLinkStatus?: FloridayLinkStatus;
|
|
24
|
+
floridayId?: string | null;
|
|
25
|
+
floridayLinkError?: string | null;
|
|
26
|
+
missingRequiredFields?: string[];
|
|
27
|
+
lastFloridaySyncAt?: string | null;
|
|
28
|
+
source?: "manual" | "excel_import";
|
|
29
|
+
}
|
|
30
|
+
export declare function upsertLocalTradeItem(params: {
|
|
31
|
+
id?: string;
|
|
32
|
+
connectionId: string;
|
|
33
|
+
data: WizardData;
|
|
34
|
+
meta?: DraftMeta;
|
|
35
|
+
}): Promise<string>;
|
|
36
|
+
export declare function updateDraftMeta(id: string, meta: DraftMeta): Promise<void>;
|
|
37
|
+
export declare function deleteLocalTradeItem(id: string): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=useLocalTradeItems.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
function draftToTradeItem(row) {
|
|
4
|
+
const d = row.data ?? {};
|
|
5
|
+
const firstImage = Array.isArray(d.images) && d.images.length > 0 ? d.images[0] : null;
|
|
6
|
+
const imageUrl = (firstImage && (firstImage.url || firstImage.previewUrl)) ?? null;
|
|
7
|
+
return {
|
|
8
|
+
id: `local:${row.id}`,
|
|
9
|
+
localId: row.id,
|
|
10
|
+
name: d.name || d.vbnName || "(naamloos)",
|
|
11
|
+
articleNumber: d.articleCode || d.gtin || "",
|
|
12
|
+
imageUrl,
|
|
13
|
+
quantity: 0,
|
|
14
|
+
minQuantity: 0,
|
|
15
|
+
reservedQuantity: 0,
|
|
16
|
+
availableQuantity: 0,
|
|
17
|
+
incomingQuantity: 0,
|
|
18
|
+
economicQuantity: 0,
|
|
19
|
+
raw: row,
|
|
20
|
+
published: false,
|
|
21
|
+
linkStatus: row.floriday_link_status ?? "unlinked",
|
|
22
|
+
missingFields: row.missing_required_fields ?? [],
|
|
23
|
+
linkError: row.floriday_link_error ?? null,
|
|
24
|
+
lastSyncAt: row.last_floriday_sync_at ?? null,
|
|
25
|
+
floridayId: row.floriday_id ?? null,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const SELECT_COLS = "id,connection_id,data,updated_at,created_at,floriday_link_status,floriday_id,floriday_link_error,missing_required_fields,last_floriday_sync_at,source";
|
|
29
|
+
export function useLocalTradeItems(connectionId) {
|
|
30
|
+
const [items, setItems] = useState([]);
|
|
31
|
+
const [loading, setLoading] = useState(false);
|
|
32
|
+
const load = useCallback(async () => {
|
|
33
|
+
if (!connectionId) {
|
|
34
|
+
setItems([]);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
setLoading(true);
|
|
38
|
+
try {
|
|
39
|
+
const { data, error } = await supabase
|
|
40
|
+
.from("trade_item_drafts")
|
|
41
|
+
.select(SELECT_COLS)
|
|
42
|
+
.eq("connection_id", connectionId)
|
|
43
|
+
.order("updated_at", { ascending: false })
|
|
44
|
+
.limit(1000);
|
|
45
|
+
if (error)
|
|
46
|
+
throw error;
|
|
47
|
+
setItems((data ?? []).map((r) => draftToTradeItem(r)));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
setItems([]);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
setLoading(false);
|
|
54
|
+
}
|
|
55
|
+
}, [connectionId]);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
load();
|
|
58
|
+
}, [load]);
|
|
59
|
+
return { items, loading, reload: load };
|
|
60
|
+
}
|
|
61
|
+
export async function getLocalTradeItem(id) {
|
|
62
|
+
const { data, error } = await supabase
|
|
63
|
+
.from("trade_item_drafts")
|
|
64
|
+
.select(SELECT_COLS)
|
|
65
|
+
.eq("id", id)
|
|
66
|
+
.maybeSingle();
|
|
67
|
+
if (error)
|
|
68
|
+
throw new Error(error.message);
|
|
69
|
+
return data ?? null;
|
|
70
|
+
}
|
|
71
|
+
export async function upsertLocalTradeItem(params) {
|
|
72
|
+
const userRes = await supabase.auth.getUser();
|
|
73
|
+
const userId = userRes.data.user?.id;
|
|
74
|
+
if (!userId)
|
|
75
|
+
throw new Error("Niet ingelogd");
|
|
76
|
+
const metaRow = {};
|
|
77
|
+
const m = params.meta;
|
|
78
|
+
if (m) {
|
|
79
|
+
if (m.floridayLinkStatus !== undefined)
|
|
80
|
+
metaRow.floriday_link_status = m.floridayLinkStatus;
|
|
81
|
+
if (m.floridayId !== undefined)
|
|
82
|
+
metaRow.floriday_id = m.floridayId;
|
|
83
|
+
if (m.floridayLinkError !== undefined)
|
|
84
|
+
metaRow.floriday_link_error = m.floridayLinkError;
|
|
85
|
+
if (m.missingRequiredFields !== undefined)
|
|
86
|
+
metaRow.missing_required_fields = m.missingRequiredFields;
|
|
87
|
+
if (m.lastFloridaySyncAt !== undefined)
|
|
88
|
+
metaRow.last_floriday_sync_at = m.lastFloridaySyncAt;
|
|
89
|
+
if (m.source !== undefined)
|
|
90
|
+
metaRow.source = m.source;
|
|
91
|
+
}
|
|
92
|
+
if (params.id) {
|
|
93
|
+
const patch = {
|
|
94
|
+
data: params.data,
|
|
95
|
+
connection_id: params.connectionId,
|
|
96
|
+
updated_at: new Date().toISOString(),
|
|
97
|
+
...metaRow,
|
|
98
|
+
};
|
|
99
|
+
const { error } = await supabase
|
|
100
|
+
.from("trade_item_drafts")
|
|
101
|
+
.update(patch)
|
|
102
|
+
.eq("id", params.id);
|
|
103
|
+
if (error)
|
|
104
|
+
throw new Error(error.message);
|
|
105
|
+
return params.id;
|
|
106
|
+
}
|
|
107
|
+
const insertRow = {
|
|
108
|
+
user_id: userId,
|
|
109
|
+
connection_id: params.connectionId,
|
|
110
|
+
data: params.data,
|
|
111
|
+
...metaRow,
|
|
112
|
+
};
|
|
113
|
+
const { data, error } = await supabase
|
|
114
|
+
.from("trade_item_drafts")
|
|
115
|
+
.insert(insertRow)
|
|
116
|
+
.select("id")
|
|
117
|
+
.single();
|
|
118
|
+
if (error)
|
|
119
|
+
throw new Error(error.message);
|
|
120
|
+
return data.id;
|
|
121
|
+
}
|
|
122
|
+
export async function updateDraftMeta(id, meta) {
|
|
123
|
+
const row = {};
|
|
124
|
+
if (meta.floridayLinkStatus !== undefined)
|
|
125
|
+
row.floriday_link_status = meta.floridayLinkStatus;
|
|
126
|
+
if (meta.floridayId !== undefined)
|
|
127
|
+
row.floriday_id = meta.floridayId;
|
|
128
|
+
if (meta.floridayLinkError !== undefined)
|
|
129
|
+
row.floriday_link_error = meta.floridayLinkError;
|
|
130
|
+
if (meta.missingRequiredFields !== undefined)
|
|
131
|
+
row.missing_required_fields = meta.missingRequiredFields;
|
|
132
|
+
if (meta.lastFloridaySyncAt !== undefined)
|
|
133
|
+
row.last_floriday_sync_at = meta.lastFloridaySyncAt;
|
|
134
|
+
if (Object.keys(row).length === 0)
|
|
135
|
+
return;
|
|
136
|
+
const { error } = await supabase.from("trade_item_drafts").update(row).eq("id", id);
|
|
137
|
+
if (error)
|
|
138
|
+
throw new Error(error.message);
|
|
139
|
+
}
|
|
140
|
+
export async function deleteLocalTradeItem(id) {
|
|
141
|
+
const { error } = await supabase.from("trade_item_drafts").delete().eq("id", id);
|
|
142
|
+
if (error)
|
|
143
|
+
throw new Error(error.message);
|
|
144
|
+
}
|