@flowselections/floriday-voorraad 1.0.82 → 1.0.86
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 +53 -10
- package/dist-lib/components/voorraad/FloridayTakeoverPanel.d.ts +7 -0
- package/dist-lib/components/voorraad/FloridayTakeoverPanel.d.ts.map +1 -0
- package/dist-lib/components/voorraad/FloridayTakeoverPanel.js +186 -0
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +2 -1
- package/dist-lib/hooks-entry.d.ts +1 -0
- package/dist-lib/hooks-entry.d.ts.map +1 -1
- package/dist-lib/hooks-entry.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +773 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.d.ts +5 -0
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +59 -50
- package/dist-lib/lib/floriday-takeover.functions.d.ts +49 -0
- package/dist-lib/lib/floriday-takeover.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-takeover.functions.js +185 -0
- package/dist-lib/lib/publish-readiness.js +2 -2
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.d.ts +2 -0
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.d.ts.map +1 -0
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.js +19 -0
- package/dist-lib/server-hooks/floriday-stock-reconcile.d.ts.map +1 -1
- package/dist-lib/server-hooks/floriday-stock-reconcile.js +5 -1
- package/dist-lib/server-hooks/guard.d.ts.map +1 -1
- package/dist-lib/server-hooks/guard.js +26 -3
- package/dist-lib/server-hooks/trade-item-photo.d.ts +13 -0
- package/dist-lib/server-hooks/trade-item-photo.d.ts.map +1 -0
- package/dist-lib/server-hooks/trade-item-photo.js +354 -0
- package/package.json +10 -1
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { PackingConfigurationInput } from "./floriday-payload.js";
|
|
2
2
|
import type { FloridayInfo } from "./floriday-info.js";
|
|
3
|
+
/** Fout bij foto-upload: `message` is voor de gebruiker, `adminDetail` voor "Details voor beheer". */
|
|
4
|
+
export declare class PhotoUploadError extends Error {
|
|
5
|
+
adminDetail: string;
|
|
6
|
+
constructor(message: string, adminDetail: string);
|
|
7
|
+
}
|
|
3
8
|
export interface PrimaryPackingSummary {
|
|
4
9
|
packagingType: string;
|
|
5
10
|
unitsPerPackage: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floriday-client.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"floriday-client.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { supabase } from "../integrations/supabase/client.js";
|
|
2
2
|
import { publishTradeItem, updateTradeItemFn } from "./floriday-writes.functions.js";
|
|
3
|
+
/** Fout bij foto-upload: `message` is voor de gebruiker, `adminDetail` voor "Details voor beheer". */
|
|
4
|
+
export class PhotoUploadError extends Error {
|
|
5
|
+
constructor(message, adminDetail) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.adminDetail = adminDetail;
|
|
8
|
+
this.name = "PhotoUploadError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
3
11
|
function summarizePayload(payload) {
|
|
4
12
|
if (!payload || typeof payload !== "object")
|
|
5
13
|
return {};
|
|
@@ -203,9 +211,8 @@ export const floriday = {
|
|
|
203
211
|
// Geef het bestand een naam mee — anders krijgt server "blob".
|
|
204
212
|
const fname = filename ?? file.name ?? `photo-${Date.now()}.jpg`;
|
|
205
213
|
form.append("file", file, fname);
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
// we de server-message meteen aan de gebruiker — geen retry.
|
|
214
|
+
// Alleen bij serverfouten (5xx) of netwerkfouten stil opnieuw proberen.
|
|
215
|
+
// 404, 401 of een afgekeurde foto meteen met de echte reden tonen.
|
|
209
216
|
const GENERIC = "Foto kon niet worden geüpload. Probeer het later opnieuw.";
|
|
210
217
|
const backoffs = [0, 300, 900];
|
|
211
218
|
let lastErr = null;
|
|
@@ -213,63 +220,65 @@ export const floriday = {
|
|
|
213
220
|
if (backoffs[attempt] > 0) {
|
|
214
221
|
await new Promise((r) => setTimeout(r, backoffs[attempt]));
|
|
215
222
|
}
|
|
223
|
+
let res;
|
|
216
224
|
try {
|
|
217
|
-
|
|
225
|
+
res = await fetch("/api/trade-item-photo", {
|
|
218
226
|
method: "POST",
|
|
219
227
|
headers: { Authorization: `Bearer ${token}` },
|
|
220
228
|
body: form,
|
|
221
229
|
});
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (!res.ok) {
|
|
234
|
-
const base = parsed?.message || parsed?.error || GENERIC;
|
|
235
|
-
const withDetail = parsed?.detail ? `${base} (${parsed.detail})` : base;
|
|
236
|
-
const withStatus = parsed?.gatewayStatus
|
|
237
|
-
? `${withDetail} [status ${parsed.gatewayStatus}]`
|
|
238
|
-
: withDetail;
|
|
239
|
-
lastErr = new Error(withStatus);
|
|
240
|
-
if (res.status >= 500 && attempt < backoffs.length - 1)
|
|
241
|
-
continue;
|
|
242
|
-
throw lastErr;
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
lastErr = new PhotoUploadError("Floriday is even niet bereikbaar. Probeer het zo opnieuw.", `netwerkfout: ${e?.message ?? String(e)}`);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
236
|
+
const text = await res.text().catch(() => "");
|
|
237
|
+
let parsed = null;
|
|
238
|
+
if (ct.toLowerCase().includes("application/json") && text) {
|
|
239
|
+
try {
|
|
240
|
+
parsed = JSON.parse(text);
|
|
243
241
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const withDetail = parsed.detail ? `${base} (${parsed.detail})` : base;
|
|
247
|
-
const withStatus = parsed.gatewayStatus
|
|
248
|
-
? `${withDetail} [status ${parsed.gatewayStatus}]`
|
|
249
|
-
: withDetail;
|
|
250
|
-
lastErr = new Error(withStatus);
|
|
251
|
-
if (parsed.retryable && attempt < backoffs.length - 1)
|
|
252
|
-
continue;
|
|
253
|
-
throw lastErr;
|
|
242
|
+
catch {
|
|
243
|
+
/* ignore */
|
|
254
244
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
245
|
+
}
|
|
246
|
+
const adminDetail = [
|
|
247
|
+
`POST /api/trade-item-photo → HTTP ${res.status}`,
|
|
248
|
+
parsed?.reason ? `reden: ${parsed.reason}` : null,
|
|
249
|
+
parsed?.gatewayStatus ? `gateway-status: ${parsed.gatewayStatus}` : null,
|
|
250
|
+
parsed?.detail ? `detail: ${parsed.detail}` : null,
|
|
251
|
+
!parsed && text ? `antwoord: ${text.slice(0, 160)}` : null,
|
|
252
|
+
]
|
|
253
|
+
.filter(Boolean)
|
|
254
|
+
.join(" · ");
|
|
255
|
+
if (res.status === 404 || (!parsed && res.ok)) {
|
|
256
|
+
throw new PhotoUploadError("Deze functie ontbreekt in de installatie. Vraag de beheerder de Shell bij te werken.", adminDetail);
|
|
257
|
+
}
|
|
258
|
+
if (res.status === 401 || res.status === 403) {
|
|
259
|
+
throw new PhotoUploadError(parsed?.message ?? "Je bent uitgelogd. Log opnieuw in en probeer het nog eens.", adminDetail);
|
|
260
|
+
}
|
|
261
|
+
if (res.status >= 500) {
|
|
262
|
+
lastErr = new PhotoUploadError(parsed?.message ?? GENERIC, adminDetail);
|
|
263
|
+
if (parsed?.reason === "config_missing")
|
|
259
264
|
throw lastErr;
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
ok: true,
|
|
263
|
-
imageId: (parsed.imageId ?? parsed.mediaId ?? null),
|
|
264
|
-
mediaId: parsed.mediaId ?? parsed.imageId ?? null,
|
|
265
|
-
url: parsed.url,
|
|
266
|
-
};
|
|
265
|
+
continue;
|
|
267
266
|
}
|
|
268
|
-
|
|
269
|
-
lastErr =
|
|
270
|
-
if (
|
|
271
|
-
|
|
267
|
+
if (!res.ok || parsed?.ok === false) {
|
|
268
|
+
lastErr = new PhotoUploadError(parsed?.message ?? GENERIC, adminDetail);
|
|
269
|
+
if (parsed?.retryable)
|
|
270
|
+
continue;
|
|
271
|
+
throw lastErr;
|
|
272
272
|
}
|
|
273
|
+
if (!parsed?.url) {
|
|
274
|
+
throw new PhotoUploadError(GENERIC, adminDetail);
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
ok: true,
|
|
278
|
+
imageId: (parsed.imageId ?? parsed.mediaId ?? null),
|
|
279
|
+
mediaId: parsed.mediaId ?? parsed.imageId ?? null,
|
|
280
|
+
url: parsed.url,
|
|
281
|
+
};
|
|
273
282
|
}
|
|
274
283
|
throw lastErr instanceof Error ? lastErr : new Error(GENERIC);
|
|
275
284
|
},
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type TakeoverRow = {
|
|
2
|
+
tradeItemId: string;
|
|
3
|
+
name: string;
|
|
4
|
+
articleCode: string | null;
|
|
5
|
+
gtin: string | null;
|
|
6
|
+
vbnCode: string | null;
|
|
7
|
+
productId: string | null;
|
|
8
|
+
productName: string | null;
|
|
9
|
+
action: "bijwerken" | "aanmaken" | "niet";
|
|
10
|
+
reason: string | null;
|
|
11
|
+
suggestion: string | null;
|
|
12
|
+
erpStock: number | null;
|
|
13
|
+
erpPrice: number | null;
|
|
14
|
+
floridayStock: number | null;
|
|
15
|
+
stockSource: string | null;
|
|
16
|
+
supplyLinePrice: number | null;
|
|
17
|
+
catalogPrice: number | null;
|
|
18
|
+
floridayPrice: number | null;
|
|
19
|
+
priceSource: string | null;
|
|
20
|
+
priceDiffers: boolean;
|
|
21
|
+
forms: {
|
|
22
|
+
continuous: boolean;
|
|
23
|
+
continuousAvailable: boolean | null;
|
|
24
|
+
weekly: boolean;
|
|
25
|
+
weeks: Array<{
|
|
26
|
+
year: number;
|
|
27
|
+
week: number;
|
|
28
|
+
pieces: number;
|
|
29
|
+
available: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
supply_lines: number;
|
|
32
|
+
customer_offers: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare const getFloridayTakeoverPreview: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
36
|
+
supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
|
|
37
|
+
userId: string;
|
|
38
|
+
claims: import("@supabase/auth-js").JwtPayload;
|
|
39
|
+
}, undefined, undefined, undefined>], undefined, Promise<{
|
|
40
|
+
connectionId: string;
|
|
41
|
+
environment: any;
|
|
42
|
+
weeks: {
|
|
43
|
+
year: number;
|
|
44
|
+
week: number;
|
|
45
|
+
}[];
|
|
46
|
+
weekError: string | null;
|
|
47
|
+
rows: TakeoverRow[];
|
|
48
|
+
}>>;
|
|
49
|
+
//# sourceMappingURL=floriday-takeover.functions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floriday-takeover.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-takeover.functions.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE;QACL,UAAU,EAAE,OAAO,CAAC;QACpB,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;QACpC,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACjF,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAmBF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;GA8InC,CAAC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proefrapport "Overnemen uit Floriday". Leest alleen: niets wordt geschreven
|
|
3
|
+
* en niets gaat naar Floriday. Het daadwerkelijk overnemen gebeurt via de
|
|
4
|
+
* databasefunctie `floriday_takeover_apply` (één transactie, terug te draaien).
|
|
5
|
+
*
|
|
6
|
+
* Floriday (Suppliers API 2026v1), alleen lezen via de leesroute van de
|
|
7
|
+
* Floriday-authenticatiemodule:
|
|
8
|
+
* - GET /trade-items/base-supply?year&week → WeeklyBaseSupply { tradeItemId, numberOfPieces, isAvailable, basePricePerPiece { currency, value } }
|
|
9
|
+
* Daarnaast de lokaal bijgehouden Floriday-gegevens van deze koppeling:
|
|
10
|
+
* - trade items (TradeItemBase: tradeItemId, supplierArticleCode, articleGtin, vbnProductCode, tradeItemName)
|
|
11
|
+
* - doorlopende voorraad (GET /trade-items/{id}/continuous-stock, door de ophaaltaak bewaard)
|
|
12
|
+
* - catalogusprijzen en aanbodregels (supply lines), incl. klantspecifieke aanbiedingen (alleen tonen)
|
|
13
|
+
*/
|
|
14
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
15
|
+
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
|
|
16
|
+
function isoWeek(d) {
|
|
17
|
+
const t = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
|
|
18
|
+
const day = t.getUTCDay() || 7;
|
|
19
|
+
t.setUTCDate(t.getUTCDate() + 4 - day);
|
|
20
|
+
const y = t.getUTCFullYear();
|
|
21
|
+
const w = Math.ceil(((t.getTime() - Date.UTC(y, 0, 1)) / 86400000 + 1) / 7);
|
|
22
|
+
return { year: y, week: w };
|
|
23
|
+
}
|
|
24
|
+
function nameOf(data) {
|
|
25
|
+
const n = data?.tradeItemName;
|
|
26
|
+
if (typeof n === "string")
|
|
27
|
+
return n;
|
|
28
|
+
return String(n?.nl ?? n?.en ?? Object.values(n ?? {})[0] ?? "").trim();
|
|
29
|
+
}
|
|
30
|
+
const norm = (v) => String(v ?? "").trim().toLowerCase();
|
|
31
|
+
export const getFloridayTakeoverPreview = createServerFn({ method: "POST" })
|
|
32
|
+
.middleware([requireSupabaseAuth])
|
|
33
|
+
.handler(async ({ context }) => {
|
|
34
|
+
const { data: canWrite } = await context.supabase.rpc("voorraad_can_write");
|
|
35
|
+
if (canWrite !== true)
|
|
36
|
+
throw new Error("Je hebt geen rechten om voorraad over te nemen.");
|
|
37
|
+
const { resolveActiveFloridayConnection } = await import("./floriday-env.server.js");
|
|
38
|
+
const conn = await resolveActiveFloridayConnection(context.supabase);
|
|
39
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
|
|
40
|
+
const admin = supabaseAdmin;
|
|
41
|
+
const [items, products, stock, cont, catalog, lines] = await Promise.all([
|
|
42
|
+
admin.from("floriday_trade_items_cache").select("floriday_id, data").eq("connection_id", conn.id).eq("is_deleted", false).limit(5000),
|
|
43
|
+
admin.from("products").select("id, product, barcode, article_number, floriday_trade_item_id, sale_price").limit(10000),
|
|
44
|
+
admin.from("trade_item_stock").select("trade_item_key, physical_stock").eq("connection_id", conn.id).limit(20000),
|
|
45
|
+
admin.from("floriday_continuous_stock_cache").select("trade_item_id, number_of_pieces").eq("connection_id", conn.id).limit(5000),
|
|
46
|
+
admin.from("floriday_catalog_prices_cache").select("trade_item_id, price, updated_at").eq("connection_id", conn.id).eq("is_deleted", false).order("updated_at", { ascending: false }).limit(20000),
|
|
47
|
+
admin.from("trade_item_supply_lines").select("trade_item_id, supply_type, price_per_piece, updated_at").eq("connection_id", conn.id).order("updated_at", { ascending: false }).limit(20000),
|
|
48
|
+
]);
|
|
49
|
+
for (const r of [items, products, stock, cont, catalog, lines])
|
|
50
|
+
if (r.error)
|
|
51
|
+
throw new Error(r.error.message);
|
|
52
|
+
// Weekaanbod: huidige en twee komende weken, live gelezen (1 per seconde).
|
|
53
|
+
const now = new Date();
|
|
54
|
+
const weeks = [0, 1, 2].map((i) => isoWeek(new Date(now.getTime() + i * 7 * 86400000)));
|
|
55
|
+
let weekError = null;
|
|
56
|
+
const weekly = new Map();
|
|
57
|
+
try {
|
|
58
|
+
const { readBaseSupplyWeeks } = await import("./base-supply-reader.server.js");
|
|
59
|
+
const out = await readBaseSupplyWeeks(weeks);
|
|
60
|
+
if (out.error)
|
|
61
|
+
weekError = out.error;
|
|
62
|
+
for (const w of out.results) {
|
|
63
|
+
if (!w.ok) {
|
|
64
|
+
weekError = weekError ?? w.error;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
for (const r of w.rows) {
|
|
68
|
+
const arr = weekly.get(r.tradeItemId) ?? [];
|
|
69
|
+
arr.push({ year: w.year, week: w.week, pieces: r.numberOfPieces, available: r.isAvailable, price: r.basePricePerPiece });
|
|
70
|
+
weekly.set(r.tradeItemId, arr);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
weekError = e?.message ?? String(e);
|
|
76
|
+
}
|
|
77
|
+
const byFid = new Map();
|
|
78
|
+
const unlinked = [];
|
|
79
|
+
for (const p of products.data ?? []) {
|
|
80
|
+
if (p.floriday_trade_item_id)
|
|
81
|
+
byFid.set(String(p.floriday_trade_item_id).toLowerCase(), p);
|
|
82
|
+
else
|
|
83
|
+
unlinked.push(p);
|
|
84
|
+
}
|
|
85
|
+
const stockBy = new Map();
|
|
86
|
+
for (const s of stock.data ?? [])
|
|
87
|
+
stockBy.set(String(s.trade_item_key), Number(s.physical_stock ?? 0));
|
|
88
|
+
const contBy = new Map();
|
|
89
|
+
for (const c of cont.data ?? [])
|
|
90
|
+
contBy.set(String(c.trade_item_id), Number(c.number_of_pieces ?? 0));
|
|
91
|
+
const catBy = new Map();
|
|
92
|
+
for (const c of catalog.data ?? []) {
|
|
93
|
+
const k = String(c.trade_item_id);
|
|
94
|
+
if (!catBy.has(k) && Number(c.price) > 0)
|
|
95
|
+
catBy.set(k, Number(c.price));
|
|
96
|
+
}
|
|
97
|
+
const lineBy = new Map();
|
|
98
|
+
for (const l of lines.data ?? []) {
|
|
99
|
+
const k = String(l.trade_item_id);
|
|
100
|
+
const cur = lineBy.get(k) ?? { price: null, count: 0, customer: 0 };
|
|
101
|
+
const isCustomer = /customer/i.test(String(l.supply_type ?? ""));
|
|
102
|
+
if (isCustomer)
|
|
103
|
+
cur.customer++;
|
|
104
|
+
else {
|
|
105
|
+
cur.count++;
|
|
106
|
+
if (cur.price == null && Number(l.price_per_piece) > 0)
|
|
107
|
+
cur.price = Number(l.price_per_piece);
|
|
108
|
+
}
|
|
109
|
+
lineBy.set(k, cur);
|
|
110
|
+
}
|
|
111
|
+
const cur = weeks[0];
|
|
112
|
+
const rows = (items.data ?? []).map((it) => {
|
|
113
|
+
const fid = String(it.floriday_id).toLowerCase();
|
|
114
|
+
const d = it.data ?? {};
|
|
115
|
+
const p = byFid.get(fid) ?? null;
|
|
116
|
+
const w = (weekly.get(fid) ?? []).sort((a, b) => a.year - b.year || a.week - b.week);
|
|
117
|
+
const contRaw = contBy.has(fid) ? contBy.get(fid) : null;
|
|
118
|
+
const line = lineBy.get(fid) ?? { price: null, count: 0, customer: 0 };
|
|
119
|
+
// Aanbodvorm uit Floriday zelf: staat er een doorlopende-voorraadrecord, dan is dat de vorm; anders weekaanbod huidige week.
|
|
120
|
+
let floridayStock = null;
|
|
121
|
+
let stockSource = null;
|
|
122
|
+
if (contRaw != null) {
|
|
123
|
+
floridayStock = contRaw;
|
|
124
|
+
stockSource = "Doorlopende voorraad";
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const now = w.find((x) => x.year === cur.year && x.week === cur.week);
|
|
128
|
+
if (now) {
|
|
129
|
+
floridayStock = now.pieces;
|
|
130
|
+
stockSource = `Weekaanbod week ${now.week}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Prijs: aanbodregel gaat voor op catalogusprijs.
|
|
134
|
+
const weekPrice = w.find((x) => x.price != null && x.price > 0)?.price ?? null;
|
|
135
|
+
const supplyLinePrice = line.price ?? weekPrice;
|
|
136
|
+
const catalogPrice = catBy.get(fid) ?? null;
|
|
137
|
+
const floridayPrice = supplyLinePrice ?? catalogPrice;
|
|
138
|
+
const priceSource = supplyLinePrice != null ? "Aanbodregel" : catalogPrice != null ? "Catalogusprijs" : null;
|
|
139
|
+
let suggestion = null;
|
|
140
|
+
if (!p) {
|
|
141
|
+
const gtin = norm(d.articleGtin), code = norm(d.supplierArticleCode), nm = norm(nameOf(d));
|
|
142
|
+
const hit = unlinked.find((u) => (gtin && norm(u.barcode) === gtin) || (code && norm(u.article_number) === code) || (nm && norm(u.product) === nm));
|
|
143
|
+
if (hit)
|
|
144
|
+
suggestion = `Lijkt op bestaand artikel "${hit.product}" (niet automatisch gekoppeld)`;
|
|
145
|
+
}
|
|
146
|
+
const erpStock = p
|
|
147
|
+
? stockBy.get(fid) ?? stockBy.get(`product:${p.id}`) ?? stockBy.get(String(p.id)) ?? null
|
|
148
|
+
: null;
|
|
149
|
+
const name = nameOf(d) || String(d.supplierArticleCode ?? fid);
|
|
150
|
+
let action = p ? "bijwerken" : "aanmaken";
|
|
151
|
+
let reason = null;
|
|
152
|
+
if (floridayStock == null && floridayPrice == null) {
|
|
153
|
+
action = p ? "niet" : "aanmaken";
|
|
154
|
+
reason = "Geen aantal en geen prijs gevonden in Floriday";
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
tradeItemId: fid, name,
|
|
158
|
+
articleCode: d.supplierArticleCode ?? null,
|
|
159
|
+
gtin: d.articleGtin ?? null,
|
|
160
|
+
vbnCode: d.vbnProductCode != null ? String(d.vbnProductCode) : null,
|
|
161
|
+
productId: p?.id ?? null, productName: p?.product ?? null,
|
|
162
|
+
action, reason, suggestion,
|
|
163
|
+
erpStock, erpPrice: p?.sale_price != null ? Number(p.sale_price) : null,
|
|
164
|
+
floridayStock, stockSource,
|
|
165
|
+
supplyLinePrice, catalogPrice, floridayPrice, priceSource,
|
|
166
|
+
priceDiffers: supplyLinePrice != null && catalogPrice != null && Math.abs(supplyLinePrice - catalogPrice) > 0.0001,
|
|
167
|
+
forms: {
|
|
168
|
+
continuous: contRaw != null && contRaw > 0,
|
|
169
|
+
continuousAvailable: contRaw == null ? null : contRaw > 0,
|
|
170
|
+
weekly: w.length > 0,
|
|
171
|
+
weeks: w.map(({ year, week, pieces, available }) => ({ year, week, pieces, available })),
|
|
172
|
+
supply_lines: line.count,
|
|
173
|
+
customer_offers: line.customer,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
rows.sort((a, b) => a.name.localeCompare(b.name, "nl"));
|
|
178
|
+
return {
|
|
179
|
+
connectionId: conn.id,
|
|
180
|
+
environment: conn.environment ?? null,
|
|
181
|
+
weeks,
|
|
182
|
+
weekError,
|
|
183
|
+
rows,
|
|
184
|
+
};
|
|
185
|
+
});
|
|
@@ -60,8 +60,8 @@ export function buildReadinessReport(input) {
|
|
|
60
60
|
label: "Minimaal één foto toegevoegd",
|
|
61
61
|
ok: Array.isArray(d.images) && d.images.length > 0,
|
|
62
62
|
stepKey: "fotos",
|
|
63
|
-
blocking:
|
|
64
|
-
hint: "
|
|
63
|
+
blocking: true,
|
|
64
|
+
hint: "Floriday vraagt minstens één foto. Opslaan als concept kan zonder foto.",
|
|
65
65
|
});
|
|
66
66
|
// Verplichte eigenschappen uit de productregels + eerder afgekeurde velden.
|
|
67
67
|
const required = new Set([
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade-item-photo.test.d.ts","sourceRoot":"","sources":["../../../src/server-hooks/__tests__/trade-item-photo.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { checkImage } from "../trade-item-photo.js";
|
|
3
|
+
function png(w, h) {
|
|
4
|
+
const b = new Uint8Array(32);
|
|
5
|
+
b.set([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], 0);
|
|
6
|
+
const dv = new DataView(b.buffer);
|
|
7
|
+
dv.setUint32(16, w);
|
|
8
|
+
dv.setUint32(20, h);
|
|
9
|
+
return b;
|
|
10
|
+
}
|
|
11
|
+
function jpg(w, h) {
|
|
12
|
+
return new Uint8Array([0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08, h >> 8, h & 255, w >> 8, w & 255, 3, 0, 0, 0, 0]);
|
|
13
|
+
}
|
|
14
|
+
describe("foto-controle op de server", () => {
|
|
15
|
+
it("accepteert jpg van 800x1200", () => expect(checkImage(jpg(800, 1200), 400000)).toBeNull());
|
|
16
|
+
it("weigert kleiner dan 640x640", () => expect(checkImage(png(639, 800), 1000)?.reason).toBe("image_too_small"));
|
|
17
|
+
it("weigert groter dan 5 MB", () => expect(checkImage(png(800, 800), 5 * 1024 * 1024 + 1)?.reason).toBe("image_too_large"));
|
|
18
|
+
it("weigert ander bestandstype", () => expect(checkImage(new TextEncoder().encode("GIF89a-----"), 100)?.reason).toBe("unsupported_type"));
|
|
19
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floriday-stock-reconcile.d.ts","sourceRoot":"","sources":["../../src/server-hooks/floriday-stock-reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"floriday-stock-reconcile.d.ts","sourceRoot":"","sources":["../../src/server-hooks/floriday-stock-reconcile.ts"],"names":[],"mappings":"AA2PA,wHAAwH;AACxH,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEtF"}
|
|
@@ -117,7 +117,7 @@ async function handle(request) {
|
|
|
117
117
|
}
|
|
118
118
|
const { data: settings, error: setErr } = await admin
|
|
119
119
|
.from("floriday_inventory_settings")
|
|
120
|
-
.select("id, connection_id, product_id, floriday_trade_item_id, desired_quantity, desired_availability, stock_mode, sync_status")
|
|
120
|
+
.select("id, connection_id, product_id, floriday_trade_item_id, desired_quantity, desired_availability, stock_mode, sync_status, erp_leading")
|
|
121
121
|
.eq("connection_id", connection.id)
|
|
122
122
|
.not("floriday_trade_item_id", "is", null);
|
|
123
123
|
if (setErr)
|
|
@@ -180,6 +180,10 @@ async function handle(request) {
|
|
|
180
180
|
.eq("id", s.id);
|
|
181
181
|
if (status === "DRIFT") {
|
|
182
182
|
drift++;
|
|
183
|
+
// Alleen melden, tenzij het ERP leidend is (erp_leading true, of NULL =
|
|
184
|
+
// artikel van vóór 1.0.84). Floriday-leidende artikelen nooit corrigeren.
|
|
185
|
+
if (s.erp_leading === false)
|
|
186
|
+
continue;
|
|
183
187
|
await admin.rpc("floriday_recompute_inventory", {
|
|
184
188
|
p_connection_id: s.connection_id,
|
|
185
189
|
p_product_id: s.product_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/server-hooks/guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/server-hooks/guard.ts"],"names":[],"mappings":"AA4DA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhE;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC/C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
|
|
@@ -13,8 +13,31 @@ const CORS = {
|
|
|
13
13
|
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
14
14
|
"Access-Control-Allow-Headers": "content-type, apikey, x-api-key, authorization",
|
|
15
15
|
};
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Deze verwerkers staan zonder expliciete instelling alleen aan zolang er
|
|
18
|
+
* minstens één ERP-leidend artikel is (erp_leading = true, of een artikel van
|
|
19
|
+
* vóór 1.0.84 met een andere modus dan Uit). Anders uit: een Shell die alles
|
|
20
|
+
* uit Floriday overneemt, verstuurt dan niets.
|
|
21
|
+
*/
|
|
22
|
+
const DEFAULT_ON_IF_ERP_LEADING = new Set(["floriday_base_supply", "logistics_tasks"]);
|
|
23
|
+
async function hasErpLeadingArticle(admin) {
|
|
24
|
+
const lead = await admin
|
|
25
|
+
.from("floriday_inventory_settings")
|
|
26
|
+
.select("id", { count: "exact", head: true })
|
|
27
|
+
.eq("erp_leading", true);
|
|
28
|
+
if (lead.error)
|
|
29
|
+
return false; // fail closed
|
|
30
|
+
if ((lead.count ?? 0) > 0)
|
|
31
|
+
return true;
|
|
32
|
+
const legacy = await admin
|
|
33
|
+
.from("floriday_inventory_settings")
|
|
34
|
+
.select("id", { count: "exact", head: true })
|
|
35
|
+
.is("erp_leading", null)
|
|
36
|
+
.neq("stock_mode", "DISABLED");
|
|
37
|
+
if (legacy.error)
|
|
38
|
+
return false;
|
|
39
|
+
return (legacy.count ?? 0) > 0;
|
|
40
|
+
}
|
|
18
41
|
function json(body, status = 200) {
|
|
19
42
|
return new Response(JSON.stringify(body), {
|
|
20
43
|
status,
|
|
@@ -40,7 +63,7 @@ export async function hookEnabled(name) {
|
|
|
40
63
|
.eq("key", `voorraad_hook_enabled.${name}`)
|
|
41
64
|
.maybeSingle();
|
|
42
65
|
if (!data)
|
|
43
|
-
return
|
|
66
|
+
return DEFAULT_ON_IF_ERP_LEADING.has(name) && (await hasErpLeadingArticle(admin));
|
|
44
67
|
return String(data.value).trim().toLowerCase() === "true";
|
|
45
68
|
}
|
|
46
69
|
export async function runGuardedHook(request, name, handle, label) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type UploadReason = "image_too_small" | "image_too_large" | "unsupported_type" | "invalid_payload" | "network" | "not_logged_in" | "not_connected" | "config_missing" | "unknown";
|
|
2
|
+
/** Breedte/hoogte uit PNG-IHDR of JPEG-SOF-marker. */
|
|
3
|
+
export declare function imageSize(b: Uint8Array): {
|
|
4
|
+
w: number;
|
|
5
|
+
h: number;
|
|
6
|
+
} | null;
|
|
7
|
+
export declare function checkImage(head: Uint8Array, size: number): {
|
|
8
|
+
reason: UploadReason;
|
|
9
|
+
detail: string;
|
|
10
|
+
} | null;
|
|
11
|
+
export declare function handleTradeItemPhoto(request: Request): Promise<Response>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=trade-item-photo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade-item-photo.d.ts","sourceRoot":"","sources":["../../src/server-hooks/trade-item-photo.ts"],"names":[],"mappings":"AAqBA,KAAK,YAAY,GACb,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,SAAS,GACT,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,SAAS,CAAC;AAgFd,sDAAsD;AACtD,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBxE;AAKD,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASjD;AAMD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA+P9E"}
|