@flowselections/floriday-voorraad 1.0.28 → 1.0.30
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 +2 -1
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +555 -316
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts +2 -1
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +3 -3
- package/dist-lib/components/voorraad/FustenPage.d.ts +2 -0
- package/dist-lib/components/voorraad/FustenPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/FustenPage.js +97 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.d.ts +2 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.js +54 -0
- package/dist-lib/components/voorraad/PublicatiesPage.d.ts +2 -0
- package/dist-lib/components/voorraad/PublicatiesPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublicatiesPage.js +60 -0
- package/dist-lib/components/voorraad/PublishProgressCard.d.ts +12 -0
- package/dist-lib/components/voorraad/PublishProgressCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublishProgressCard.js +30 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.d.ts +10 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.js +12 -0
- package/dist-lib/components/voorraad/StockSyncStatus.d.ts +2 -0
- package/dist-lib/components/voorraad/StockSyncStatus.d.ts.map +1 -0
- package/dist-lib/components/voorraad/StockSyncStatus.js +23 -0
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +5 -1
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +1 -1
- package/dist-lib/hooks/useFusten.d.ts +17 -0
- package/dist-lib/hooks/useFusten.d.ts.map +1 -0
- package/dist-lib/hooks/useFusten.js +81 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts +14 -4
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
- package/dist-lib/hooks/useLocalTradeItems.js +83 -5
- package/dist-lib/hooks/useLogisticsTasks.d.ts +13 -0
- package/dist-lib/hooks/useLogisticsTasks.d.ts.map +1 -0
- package/dist-lib/hooks/useLogisticsTasks.js +155 -0
- package/dist-lib/hooks/usePublishJob.d.ts +13 -0
- package/dist-lib/hooks/usePublishJob.d.ts.map +1 -0
- package/dist-lib/hooks/usePublishJob.js +67 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.d.ts +2 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.d.ts.map +1 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.js +31 -0
- package/dist-lib/hooks/useStockSyncHealth.d.ts +8 -0
- package/dist-lib/hooks/useStockSyncHealth.d.ts.map +1 -0
- package/dist-lib/hooks/useStockSyncHealth.js +42 -0
- package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -1
- package/dist-lib/hooks/useTradeItemStock.js +37 -1
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +5 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1849 -50
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1849 -50
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +1849 -50
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1870 -41
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/floricode-required-features.functions.d.ts +1849 -50
- package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.d.ts +1 -1
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +1 -2
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts +1849 -50
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-customer-offer.functions.js +14 -19
- package/dist-lib/lib/floriday-env.functions.d.ts +35712 -0
- package/dist-lib/lib/floriday-env.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-env.functions.js +16 -0
- package/dist-lib/lib/floriday-env.server.d.ts +12 -0
- package/dist-lib/lib/floriday-env.server.d.ts.map +1 -1
- package/dist-lib/lib/floriday-env.server.js +15 -2
- package/dist-lib/lib/floriday-gateway.functions.d.ts +26934 -82
- package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.functions.js +12 -3
- package/dist-lib/lib/floriday-readiness.server.d.ts +11 -0
- package/dist-lib/lib/floriday-readiness.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-readiness.server.js +43 -0
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts +3698 -100
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-warehouse.functions.d.ts +5442 -45
- package/dist-lib/lib/floriday-warehouse.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-warehouse.functions.js +3 -0
- package/dist-lib/lib/floriday-writes.functions.d.ts +3698 -100
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/fusten.d.ts +87 -0
- package/dist-lib/lib/fusten.d.ts.map +1 -0
- package/dist-lib/lib/fusten.js +389 -0
- package/dist-lib/lib/logistics-engine.d.ts +63 -0
- package/dist-lib/lib/logistics-engine.d.ts.map +1 -0
- package/dist-lib/lib/logistics-engine.js +57 -0
- package/dist-lib/lib/logistics-events.d.ts +18 -0
- package/dist-lib/lib/logistics-events.d.ts.map +1 -0
- package/dist-lib/lib/logistics-events.js +61 -0
- package/dist-lib/lib/module-runtime-config.functions.d.ts +14 -0
- package/dist-lib/lib/module-runtime-config.functions.d.ts.map +1 -0
- package/dist-lib/lib/module-runtime-config.functions.js +107 -0
- package/dist-lib/lib/publish-errors.d.ts +37 -0
- package/dist-lib/lib/publish-errors.d.ts.map +1 -0
- package/dist-lib/lib/publish-errors.js +183 -0
- package/dist-lib/lib/publish-pipeline.d.ts +91 -0
- package/dist-lib/lib/publish-pipeline.d.ts.map +1 -0
- package/dist-lib/lib/publish-pipeline.js +212 -0
- package/dist-lib/lib/publish-readiness.d.ts +42 -0
- package/dist-lib/lib/publish-readiness.d.ts.map +1 -0
- package/dist-lib/lib/publish-readiness.js +102 -0
- package/package.json +2 -2
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Publicatie-pijplijn: één publicatie = één opdracht met vaste deelstappen.
|
|
3
|
+
*
|
|
4
|
+
* Elke deelstap wordt apart vastgelegd (status, pogingen, begrijpelijke fout).
|
|
5
|
+
* Geslaagde stappen worden bij een nieuwe poging overgeslagen, tijdelijke
|
|
6
|
+
* storingen worden automatisch opnieuw geprobeerd.
|
|
7
|
+
*/
|
|
8
|
+
import { supabase } from "../integrations/supabase/client";
|
|
9
|
+
import { translatePublishError } from "./publish-errors";
|
|
10
|
+
export const PUBLISH_STEPS = [
|
|
11
|
+
{ key: "trade-item", label: "Productgegevens" },
|
|
12
|
+
{ key: "stock", label: "Voorraad" },
|
|
13
|
+
{ key: "offer", label: "Aanbod" },
|
|
14
|
+
{ key: "supply-line", label: "Prijs online" },
|
|
15
|
+
{ key: "prices", label: "Prijsafspraken" },
|
|
16
|
+
{ key: "verify", label: "Controle" },
|
|
17
|
+
];
|
|
18
|
+
const jobs = () => supabase.from("voorraad_publish_jobs");
|
|
19
|
+
const steps = () => supabase.from("voorraad_publish_steps");
|
|
20
|
+
export async function createPublishJob(input) {
|
|
21
|
+
const userRes = await supabase.auth.getUser();
|
|
22
|
+
const userId = userRes.data.user?.id;
|
|
23
|
+
if (!userId)
|
|
24
|
+
return null;
|
|
25
|
+
const { data, error } = await jobs()
|
|
26
|
+
.insert({
|
|
27
|
+
user_id: userId,
|
|
28
|
+
connection_id: input.connectionId,
|
|
29
|
+
environment: input.environment,
|
|
30
|
+
intent: input.intent,
|
|
31
|
+
title: input.title,
|
|
32
|
+
product_id: input.productId ?? null,
|
|
33
|
+
trade_item_id: input.tradeItemId ?? null,
|
|
34
|
+
trade_item_key: input.tradeItemKey ?? null,
|
|
35
|
+
snapshot: (input.snapshot ?? {}),
|
|
36
|
+
})
|
|
37
|
+
.select("*")
|
|
38
|
+
.single();
|
|
39
|
+
if (error || !data)
|
|
40
|
+
return null;
|
|
41
|
+
const job = data;
|
|
42
|
+
const active = input.activeSteps ?? PUBLISH_STEPS.map((s) => s.key);
|
|
43
|
+
const rows = PUBLISH_STEPS.map((s, i) => ({
|
|
44
|
+
job_id: job.id,
|
|
45
|
+
user_id: userId,
|
|
46
|
+
step_key: s.key,
|
|
47
|
+
label: s.label,
|
|
48
|
+
position: i,
|
|
49
|
+
status: active.includes(s.key) ? "pending" : "skipped",
|
|
50
|
+
}));
|
|
51
|
+
await steps().insert(rows);
|
|
52
|
+
return job;
|
|
53
|
+
}
|
|
54
|
+
export async function loadPublishJob(jobId) {
|
|
55
|
+
const [{ data: j }, { data: s }] = await Promise.all([
|
|
56
|
+
jobs().select("*").eq("id", jobId).maybeSingle(),
|
|
57
|
+
steps().select("*").eq("job_id", jobId).order("position"),
|
|
58
|
+
]);
|
|
59
|
+
return {
|
|
60
|
+
job: j ?? null,
|
|
61
|
+
steps: (s ?? []),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function patchStep(jobId, key, patch) {
|
|
65
|
+
await steps().update(patch).eq("job_id", jobId).eq("step_key", key);
|
|
66
|
+
}
|
|
67
|
+
export async function markStepSkipped(jobId, key) {
|
|
68
|
+
await patchStep(jobId, key, { status: "skipped", finished_at: new Date().toISOString() });
|
|
69
|
+
}
|
|
70
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
71
|
+
/**
|
|
72
|
+
* Voert één deelstap uit. Al geslaagde stappen worden overgeslagen zodat
|
|
73
|
+
* "opnieuw proberen" nooit dubbel publiceert. Tijdelijke storingen worden
|
|
74
|
+
* automatisch tot 3× herhaald met oplopende wachttijd.
|
|
75
|
+
*/
|
|
76
|
+
export async function runPublishStep(jobId, key, fn, opts) {
|
|
77
|
+
// Zonder job (bv. offline logboek) draaien we de stap gewoon uit.
|
|
78
|
+
if (jobId) {
|
|
79
|
+
const { data } = await steps()
|
|
80
|
+
.select("status")
|
|
81
|
+
.eq("job_id", jobId)
|
|
82
|
+
.eq("step_key", key)
|
|
83
|
+
.maybeSingle();
|
|
84
|
+
const status = data?.status;
|
|
85
|
+
if (status === "done")
|
|
86
|
+
return { ok: true, skipped: true };
|
|
87
|
+
await patchStep(jobId, key, {
|
|
88
|
+
status: "running",
|
|
89
|
+
started_at: new Date().toISOString(),
|
|
90
|
+
error_code: null,
|
|
91
|
+
error_message: null,
|
|
92
|
+
error_detail: null,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const maxAttempts = opts?.maxAttempts ?? 3;
|
|
96
|
+
let last;
|
|
97
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
98
|
+
try {
|
|
99
|
+
const value = await fn();
|
|
100
|
+
if (jobId) {
|
|
101
|
+
await patchStep(jobId, key, {
|
|
102
|
+
status: "done",
|
|
103
|
+
attempts: attempt,
|
|
104
|
+
finished_at: new Date().toISOString(),
|
|
105
|
+
result: sanitizeResult(value),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return { ok: true, value };
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
last = translatePublishError(e, {
|
|
112
|
+
characteristicLabels: opts?.characteristicLabels,
|
|
113
|
+
});
|
|
114
|
+
if (!last.retryable || attempt === maxAttempts)
|
|
115
|
+
break;
|
|
116
|
+
await sleep(attempt * 1500);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (jobId && last) {
|
|
120
|
+
await patchStep(jobId, key, {
|
|
121
|
+
status: "failed",
|
|
122
|
+
attempts: maxAttempts,
|
|
123
|
+
finished_at: new Date().toISOString(),
|
|
124
|
+
error_code: last.code,
|
|
125
|
+
error_message: last.message,
|
|
126
|
+
error_detail: last.detail?.slice(0, 4000) ?? null,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return { ok: false, error: last };
|
|
130
|
+
}
|
|
131
|
+
function sanitizeResult(value) {
|
|
132
|
+
if (value == null)
|
|
133
|
+
return null;
|
|
134
|
+
if (typeof value === "object") {
|
|
135
|
+
try {
|
|
136
|
+
const json = JSON.stringify(value);
|
|
137
|
+
return json.length > 4000 ? { truncated: true } : JSON.parse(json);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { value: String(value) };
|
|
144
|
+
}
|
|
145
|
+
export async function finishPublishJob(jobId, patch) {
|
|
146
|
+
const { data } = await steps().select("status, step_key").eq("job_id", jobId);
|
|
147
|
+
const rows = (data ?? []);
|
|
148
|
+
const failed = rows.filter((r) => r.status === "failed");
|
|
149
|
+
const coreFailed = failed.some((r) => r.step_key === "trade-item");
|
|
150
|
+
const status = coreFailed
|
|
151
|
+
? "failed"
|
|
152
|
+
: failed.length > 0
|
|
153
|
+
? "succeeded_with_warnings"
|
|
154
|
+
: "succeeded";
|
|
155
|
+
await jobs()
|
|
156
|
+
.update({
|
|
157
|
+
status,
|
|
158
|
+
finished_at: new Date().toISOString(),
|
|
159
|
+
...(patch?.tradeItemId ? { trade_item_id: patch.tradeItemId } : {}),
|
|
160
|
+
...(patch?.summary ? { summary: patch.summary } : {}),
|
|
161
|
+
})
|
|
162
|
+
.eq("id", jobId);
|
|
163
|
+
return status;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Onthoudt welke gegevens door de handelsomgeving zijn afgekeurd, zodat een
|
|
167
|
+
* volgend product hier vóór het publiceren al op gecontroleerd wordt.
|
|
168
|
+
*/
|
|
169
|
+
export async function rememberPublishRejection(input) {
|
|
170
|
+
if (!input.vbnCode || input.keys.length === 0)
|
|
171
|
+
return;
|
|
172
|
+
try {
|
|
173
|
+
for (const key of input.keys) {
|
|
174
|
+
const { data } = await supabase
|
|
175
|
+
.from("voorraad_publish_learnings")
|
|
176
|
+
.select("id, hits")
|
|
177
|
+
.eq("vbn_code", input.vbnCode)
|
|
178
|
+
.eq("scope", input.scope)
|
|
179
|
+
.eq("field_key", key)
|
|
180
|
+
.maybeSingle();
|
|
181
|
+
if (data?.id) {
|
|
182
|
+
await supabase
|
|
183
|
+
.from("voorraad_publish_learnings")
|
|
184
|
+
.update({
|
|
185
|
+
hits: (data.hits ?? 0) + 1,
|
|
186
|
+
last_error: input.lastError?.slice(0, 500) ?? null,
|
|
187
|
+
})
|
|
188
|
+
.eq("id", data.id);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
await supabase.from("voorraad_publish_learnings").insert({
|
|
192
|
+
vbn_code: input.vbnCode,
|
|
193
|
+
scope: input.scope,
|
|
194
|
+
field_key: key,
|
|
195
|
+
last_error: input.lastError?.slice(0, 500) ?? null,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Leren mag de publicatie nooit blokkeren.
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
export async function listPublishLearnings(vbnCode) {
|
|
205
|
+
if (!vbnCode)
|
|
206
|
+
return [];
|
|
207
|
+
const { data } = await supabase
|
|
208
|
+
.from("voorraad_publish_learnings")
|
|
209
|
+
.select("scope, field_key")
|
|
210
|
+
.eq("vbn_code", vbnCode);
|
|
211
|
+
return (data ?? []);
|
|
212
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controle vooraf: kan dit product veilig gepubliceerd worden?
|
|
3
|
+
*
|
|
4
|
+
* Levert een korte checklist op in gewone taal. Elke regel verwijst naar de
|
|
5
|
+
* stap in de wizard waar het opgelost kan worden.
|
|
6
|
+
*/
|
|
7
|
+
import type { WizardData } from "./floriday-payload";
|
|
8
|
+
import type { TradeItemSpec } from "../hooks/useTradeItemSpec";
|
|
9
|
+
export interface ReadinessItem {
|
|
10
|
+
key: string;
|
|
11
|
+
label: string;
|
|
12
|
+
ok: boolean;
|
|
13
|
+
/** Wizard-stap waar dit ingevuld wordt. */
|
|
14
|
+
stepKey?: string;
|
|
15
|
+
/** Blokkeert publiceren volledig. */
|
|
16
|
+
blocking: boolean;
|
|
17
|
+
hint?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ReadinessReport {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
items: ReadinessItem[];
|
|
22
|
+
blockers: ReadinessItem[];
|
|
23
|
+
}
|
|
24
|
+
export interface ReadinessInput {
|
|
25
|
+
data: WizardData;
|
|
26
|
+
spec?: TradeItemSpec | null;
|
|
27
|
+
/** Verbinding actief en omgeving bekend. */
|
|
28
|
+
connectionOk: boolean;
|
|
29
|
+
connectionLoading?: boolean;
|
|
30
|
+
environment?: string | null;
|
|
31
|
+
connectionMessage?: string | null;
|
|
32
|
+
/** Productgegevens uit de handelsomgeving zijn geladen. */
|
|
33
|
+
schemaReady: boolean;
|
|
34
|
+
/** Eerder afgekeurde eigenschapscodes voor deze productsoort. */
|
|
35
|
+
learnedCharacteristicCodes?: string[];
|
|
36
|
+
/** Labels bij eigenschapscodes voor leesbare meldingen. */
|
|
37
|
+
characteristicLabels?: Record<string, string>;
|
|
38
|
+
/** Wordt het product ook echt gepubliceerd (of alleen lokaal bewaard)? */
|
|
39
|
+
wantsPublish: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare function buildReadinessReport(input: ReadinessInput): ReadinessReport;
|
|
42
|
+
//# sourceMappingURL=publish-readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-readiness.d.ts","sourceRoot":"","sources":["../../src/lib/publish-readiness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,4CAA4C;IAC5C,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;IACrB,iEAAiE;IACjE,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;IACtC,2DAA2D;IAC3D,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,0EAA0E;IAC1E,YAAY,EAAE,OAAO,CAAC;CACvB;AAOD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAuG3E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
function labelFor(code, labels) {
|
|
2
|
+
const l = labels?.[code];
|
|
3
|
+
return l && l !== code ? `${l}` : code;
|
|
4
|
+
}
|
|
5
|
+
export function buildReadinessReport(input) {
|
|
6
|
+
const d = input.data;
|
|
7
|
+
const items = [];
|
|
8
|
+
if (input.wantsPublish) {
|
|
9
|
+
items.push({
|
|
10
|
+
key: "connection",
|
|
11
|
+
label: input.connectionLoading
|
|
12
|
+
? "Verbinding met de handelsomgeving controleren…"
|
|
13
|
+
: input.connectionOk
|
|
14
|
+
? `De ${input.environment === "live" ? "liveomgeving" : "testomgeving"} is klaar voor publiceren`
|
|
15
|
+
: input.connectionMessage ?? "De verbinding is nog niet klaar voor publiceren",
|
|
16
|
+
ok: Boolean(input.connectionOk),
|
|
17
|
+
blocking: true,
|
|
18
|
+
hint: input.connectionOk ? undefined : "Controleer de verbinding bij Instellingen.",
|
|
19
|
+
});
|
|
20
|
+
items.push({
|
|
21
|
+
key: "schema",
|
|
22
|
+
label: input.schemaReady
|
|
23
|
+
? "Productregels opgehaald"
|
|
24
|
+
: "Productregels nog niet opgehaald",
|
|
25
|
+
ok: input.schemaReady,
|
|
26
|
+
blocking: true,
|
|
27
|
+
hint: input.schemaReady ? undefined : "Wacht heel even en probeer opnieuw.",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
items.push({
|
|
31
|
+
key: "vbn",
|
|
32
|
+
label: "Productsoort gekozen",
|
|
33
|
+
ok: Boolean(d.vbnCode?.trim()),
|
|
34
|
+
stepKey: "vbn",
|
|
35
|
+
blocking: true,
|
|
36
|
+
});
|
|
37
|
+
items.push({
|
|
38
|
+
key: "name",
|
|
39
|
+
label: "Artikelnaam ingevuld",
|
|
40
|
+
ok: Boolean(d.name?.trim() && d.name.trim().length >= 2),
|
|
41
|
+
stepKey: "artikel",
|
|
42
|
+
blocking: true,
|
|
43
|
+
});
|
|
44
|
+
items.push({
|
|
45
|
+
key: "articleCode",
|
|
46
|
+
label: "Artikelcode aanwezig",
|
|
47
|
+
ok: Boolean(d.articleCode?.trim()),
|
|
48
|
+
stepKey: "artikel",
|
|
49
|
+
blocking: true,
|
|
50
|
+
});
|
|
51
|
+
items.push({
|
|
52
|
+
key: "packing",
|
|
53
|
+
label: "Belading ingesteld",
|
|
54
|
+
ok: Array.isArray(d.packingConfigurations) && d.packingConfigurations.length > 0,
|
|
55
|
+
stepKey: "belading",
|
|
56
|
+
blocking: true,
|
|
57
|
+
});
|
|
58
|
+
items.push({
|
|
59
|
+
key: "photos",
|
|
60
|
+
label: "Minimaal één foto toegevoegd",
|
|
61
|
+
ok: Array.isArray(d.images) && d.images.length > 0,
|
|
62
|
+
stepKey: "fotos",
|
|
63
|
+
blocking: false,
|
|
64
|
+
hint: "Zonder foto is het product minder goed vindbaar.",
|
|
65
|
+
});
|
|
66
|
+
// Verplichte eigenschappen uit de productregels + eerder afgekeurde velden.
|
|
67
|
+
const required = new Set([
|
|
68
|
+
...Array.from(input.spec?.requiredCharacteristicCodes ?? []),
|
|
69
|
+
...(input.learnedCharacteristicCodes ?? []),
|
|
70
|
+
]);
|
|
71
|
+
const filled = d.features ?? {};
|
|
72
|
+
const missing = Array.from(required).filter((code) => {
|
|
73
|
+
const v = filled[code];
|
|
74
|
+
return v == null || String(v).trim() === "";
|
|
75
|
+
});
|
|
76
|
+
if (required.size > 0) {
|
|
77
|
+
items.push({
|
|
78
|
+
key: "characteristics",
|
|
79
|
+
label: missing.length === 0
|
|
80
|
+
? "Alle verplichte eigenschappen ingevuld"
|
|
81
|
+
: `Nog invullen: ${missing
|
|
82
|
+
.slice(0, 4)
|
|
83
|
+
.map((c) => labelFor(c, input.characteristicLabels))
|
|
84
|
+
.join(", ")}${missing.length > 4 ? ` en ${missing.length - 4} meer` : ""}`,
|
|
85
|
+
ok: missing.length === 0,
|
|
86
|
+
stepKey: "eigenschappen",
|
|
87
|
+
blocking: true,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (d.offerForSale) {
|
|
91
|
+
items.push({
|
|
92
|
+
key: "price",
|
|
93
|
+
label: "Verkoopprijs ingevuld",
|
|
94
|
+
ok: Number(d.salePricePerPiece) > 0,
|
|
95
|
+
stepKey: "aanbieden",
|
|
96
|
+
blocking: true,
|
|
97
|
+
hint: "Zonder prijs kan het product niet worden aangeboden.",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const blockers = items.filter((i) => i.blocking && !i.ok);
|
|
101
|
+
return { ok: blockers.length === 0, items, blockers };
|
|
102
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowselections/floriday-voorraad",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist-lib/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@cloudflare/vite-plugin": "^1.25.5",
|
|
46
46
|
"@eslint/js": "^9.32.0",
|
|
47
47
|
"@flowselections/core": "1.0.16",
|
|
48
|
-
"@lovable.dev/vite-tanstack-config": "2.
|
|
48
|
+
"@lovable.dev/vite-tanstack-config": "2.8.5",
|
|
49
49
|
"@rsbuild/core": "^1.0.0",
|
|
50
50
|
"@tailwindcss/vite": "^4.2.1",
|
|
51
51
|
"@tanstack/router-plugin": "^1.167.10",
|