@flowselections/logistiek-engine 1.0.174 → 1.0.177

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.
Files changed (31) hide show
  1. package/db/schema/logistiek-engine.sql +1262 -0
  2. package/dist-lib/components/BeheerPage.d.ts.map +1 -1
  3. package/dist-lib/components/BeheerPage.js +2 -1
  4. package/dist-lib/components/DocumentkeuzeCard.d.ts +2 -0
  5. package/dist-lib/components/DocumentkeuzeCard.d.ts.map +1 -0
  6. package/dist-lib/components/DocumentkeuzeCard.js +18 -0
  7. package/dist-lib/index.d.ts +1 -0
  8. package/dist-lib/index.d.ts.map +1 -1
  9. package/dist-lib/index.js +1 -0
  10. package/dist-lib/integrations/supabase/types.d.ts +239 -15
  11. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  12. package/dist-lib/lib/controlScan.server.js +1 -1
  13. package/dist-lib/lib/layoutPrint.server.d.ts +10 -1
  14. package/dist-lib/lib/layoutPrint.server.d.ts.map +1 -1
  15. package/dist-lib/lib/layoutPrint.server.js +19 -1
  16. package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
  17. package/dist-lib/lib/modulePrompts.js +157 -0
  18. package/dist-lib/lib/moduleVersion.d.ts +1 -1
  19. package/dist-lib/lib/moduleVersion.js +1 -1
  20. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
  21. package/dist-lib/lib/ruleEngineSchema.js +4 -38
  22. package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -1
  23. package/dist-lib/lib/ruleEngineWizard.js +0 -2
  24. package/dist-lib/lib/shippingNoteQueue.server.js +1 -1
  25. package/dist-lib/lib/stickerQueue.server.d.ts +25 -0
  26. package/dist-lib/lib/stickerQueue.server.d.ts.map +1 -1
  27. package/dist-lib/lib/stickerQueue.server.js +62 -22
  28. package/dist-lib/lib/stickerRules.d.ts +17 -0
  29. package/dist-lib/lib/stickerRules.d.ts.map +1 -1
  30. package/dist-lib/lib/stickerRules.js +30 -0
  31. package/package.json +1 -1
@@ -226,7 +226,7 @@ export async function runControlScanQueue(sb, options = {}) {
226
226
  continue;
227
227
  }
228
228
  // Layout op id: de actieve Floriday-afleverbrief (bij meerdere de standaard).
229
- const layout = await floridayLayout(sb, "afleverbrief");
229
+ const layout = await floridayLayout(sb, "afleverbrief", row.order_id);
230
230
  if (!layout.layoutId) {
231
231
  await sb.rpc("logistics_control_scan_finish", {
232
232
  _id: row.id,
@@ -31,7 +31,16 @@ export declare function bestaandOpdrachtId(...bronnen: unknown[]): string | null
31
31
  * Zoekt de actieve Floriday-layout voor een documentsoort op id (bij meerdere:
32
32
  * de standaard). Geeft null + leesbare reden als er geen eenduidige layout is.
33
33
  */
34
- export declare function floridayLayout(sb: SupabaseClient, documenttype: string): Promise<{
34
+ export declare function floridayLayout(sb: SupabaseClient, documenttype: string, orderId?: string | null): Promise<{
35
+ layoutId: string | null;
36
+ reden: string | null;
37
+ }>;
38
+ /**
39
+ * 1.0.176: centrale documentkeuze per order (logistics_document_for_order).
40
+ * Layouts beslist zodra layout_voor_document bestaat; anders de automatische standaard.
41
+ * Fail closed: geen layout = null + leesbare reden; alleen dít document wacht.
42
+ */
43
+ export declare function documentLayout(sb: SupabaseClient, orderId: string, documenttype: string): Promise<{
35
44
  layoutId: string | null;
36
45
  reden: string | null;
37
46
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"layoutPrint.server.d.ts","sourceRoot":"","sources":["../../src/lib/layoutPrint.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layoutPrint.server.d.ts","sourceRoot":"","sources":["../../src/lib/layoutPrint.server.ts"],"names":[],"mappings":"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"}
@@ -41,7 +41,9 @@ export function bestaandOpdrachtId(...bronnen) {
41
41
  * Zoekt de actieve Floriday-layout voor een documentsoort op id (bij meerdere:
42
42
  * de standaard). Geeft null + leesbare reden als er geen eenduidige layout is.
43
43
  */
44
- export async function floridayLayout(sb, documenttype) {
44
+ export async function floridayLayout(sb, documenttype, orderId) {
45
+ if (orderId)
46
+ return documentLayout(sb, orderId, documenttype);
45
47
  const { data, error } = await sb.rpc("logistics_floriday_layout_id", {
46
48
  p_documenttype: documenttype,
47
49
  });
@@ -51,6 +53,22 @@ export async function floridayLayout(sb, documenttype) {
51
53
  const id = typeof r["layout_id"] === "string" ? r["layout_id"] : null;
52
54
  return { layoutId: id, reden: id ? null : String(r["reden"] ?? "Geen actieve Floriday-layout gevonden.") };
53
55
  }
56
+ /**
57
+ * 1.0.176: centrale documentkeuze per order (logistics_document_for_order).
58
+ * Layouts beslist zodra layout_voor_document bestaat; anders de automatische standaard.
59
+ * Fail closed: geen layout = null + leesbare reden; alleen dít document wacht.
60
+ */
61
+ export async function documentLayout(sb, orderId, documenttype) {
62
+ const { data, error } = await sb.rpc("logistics_document_for_order", {
63
+ p_order_id: orderId,
64
+ p_documenttype: documenttype,
65
+ });
66
+ if (error)
67
+ return { layoutId: null, reden: `De documentkeuze kon niet worden bepaald: ${error.message}` };
68
+ const r = (data ?? {});
69
+ const id = r["ok"] !== false && typeof r["layout_id"] === "string" && r["layout_id"] ? r["layout_id"] : null;
70
+ return { layoutId: id, reden: id ? null : String(r["reden"] ?? `Maak of activeer een ${documenttype}layout in Layouts en printers.`) };
71
+ }
54
72
  /** Bucket uit een ondertekende opslaglink (/storage/v1/object/sign/<bucket>/<pad>). */
55
73
  export function bucketUitLink(url) {
56
74
  if (!url)
@@ -1 +1 @@
1
- {"version":3,"file":"modulePrompts.d.ts","sourceRoot":"","sources":["../../src/lib/modulePrompts.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;CAKvB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAw9LD,eAAO,MAAM,cAAc,EAAE,YAAY,EAUL,CAAC;AAErC,gEAAgE;AAChE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,oBAAoB,GAC7B,MAAM,CAmBR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,IAAI,MAAM,CAiB9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAIR"}
1
+ {"version":3,"file":"modulePrompts.d.ts","sourceRoot":"","sources":["../../src/lib/modulePrompts.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;CAKvB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAwnMD,eAAO,MAAM,cAAc,EAAE,YAAY,EAUL,CAAC;AAErC,gEAAgE;AAChE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,oBAAoB,GAC7B,MAAM,CAmBR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,IAAI,MAAM,CAiB9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAIR"}
@@ -1241,6 +1241,28 @@ CONTROLELIJST
1241
1241
  order: 2,
1242
1242
  summary: "Voert belading, controle, printen en transport uit volgens de taak-payload.",
1243
1243
  revisions: [
1244
+ {
1245
+ number: 28,
1246
+ title: "Geen layoutkeuze meer: document automatisch uit de order",
1247
+ date: "2026-10-21",
1248
+ summary: "Haal eigen layoutkeuzes weg; documenten en layout volgen uit de order via de centrale beslisregel.",
1249
+ body: `KOPPELPROMPT AFHANDELING – automatische documentkeuze (Engine 1.0.176)
1250
+
1251
+ 1. Haal in je eigen instellingen en herprintschermen elke keuze voor layout of
1252
+ documentsoort weg. Toon: "Het document wordt automatisch bepaald uit de order."
1253
+ 2. Bestaande opgeslagen keuzes niet verwijderen, wel negeren.
1254
+ 3. Print je zelf een document: vraag de layout op met
1255
+ rpc logistics_document_for_order(p_order_id, p_documenttype)
1256
+ (documenttype: pakbon, productiebon, verzenddocument, sticker, traysticker,
1257
+ eigen_sticker). ok=false: dat document niet printen, reden tonen; andere
1258
+ documenten van de order gaan door.
1259
+ 4. Verzenddocument: precies één per order. Floriday-order = wat Floriday levert;
1260
+ eigen order = afleverbrief (bron eigen).
1261
+ 5. Opnieuw afdrukken blijft altijd mogelijk; maak geen tweede actieve
1262
+ documentregistratie per order per soort.
1263
+ Wanneer een document vrijkomt (vrijgave, X uur vóór pickmoment, aanmeldmoment,
1264
+ voorraadopwaardering) verandert niet. Wijzig geen functies van de Engine.`,
1265
+ },
1244
1266
  {
1245
1267
  number: 1,
1246
1268
  title: "Basiskoppeling via de database",
@@ -2446,6 +2468,48 @@ CONTROLELIJST
2446
2468
  order: 3,
2447
2469
  summary: "Toont pick-taken op de door de Engine berekende starttijd.",
2448
2470
  revisions: [
2471
+ {
2472
+ number: 51,
2473
+ title: "Antwoord op 1.0.56: pakbon alleen via centrale documentkeuze",
2474
+ date: "2026-10-21",
2475
+ summary: "Beide pick_enqueue_print_job-varianten en logistics_resolve_pick_document negeren payload.layout_id en weigeren bij ok=false.",
2476
+ body: `KOPPELPROMPT PICKSCHERMEN – antwoord op 1.0.56 (Engine 1.0.176)
2477
+
2478
+ Verwerkt:
2479
+ - pick_enqueue_print_job (4 en 5 velden) en logistics_resolve_pick_document
2480
+ kiezen de layout alleen via logistics_document_for_order(order_id, documenttype).
2481
+ payload.layout_id en payload.layout worden genegeerd en niet meer doorgegeven.
2482
+ - Bij ok=false (en geen geleverde pdf) maakt pick_enqueue_print_job GEEN
2483
+ printopdracht en geeft een fout (SQLSTATE 23514) met de Nederlandse reden als
2484
+ tekst. Toon die tekst; andere documenten van de order gaan gewoon door.
2485
+ - logistics_resolve_pick_document geeft nu ook terug: ok (boolean), reden (tekst
2486
+ of null) en layout_keuze ('layouts' of 'automatisch'). Gebruik ok/reden voor het
2487
+ voorbeeld op het pickstation.
2488
+ - Rechten, beveiliging en parameters zijn ongewijzigd.
2489
+ Je hoeft niets aan de Engine aan te passen.`,
2490
+ },
2491
+ {
2492
+ number: 50,
2493
+ title: "Geen layoutkeuze meer: document automatisch uit de order",
2494
+ date: "2026-10-21",
2495
+ summary: "Haal de layout- en documentsoortkeuzes uit de pickstationinstellingen; het document volgt uit de order.",
2496
+ body: `KOPPELPROMPT PICKSCHERMEN – automatische documentkeuze (Engine 1.0.176)
2497
+
2498
+ 1. Haal in de pickstationinstellingen alle keuzelijsten voor layout en
2499
+ documentsoort weg. Toon op die plek: "Het document wordt automatisch bepaald uit de order."
2500
+ 2. Bestaande opgeslagen keuzes NIET verwijderen, maar negeren.
2501
+ 3. Een pakbon printen blijft via pick_enqueue_print_job (Engine). Die kiest de
2502
+ layout nu zelf via logistics_document_for_order(order_id, documenttype);
2503
+ een layout_id in de payload van de pickrij wordt genegeerd.
2504
+ 4. Wil je vooraf tonen welk document eruit komt: rpc
2505
+ logistics_document_for_order(p_order_id, p_documenttype) -> { ok, layout_id, reden }.
2506
+ Bij ok=false: toon de reden, druk alleen dát document niet af; de rest van de
2507
+ order gaat door.
2508
+ 5. Opnieuw afdrukken blijft altijd mogelijk (bestaande herprintknop).
2509
+ 6. Eigen stickers (HO/MO/AO, vinkje Sticker op de orderregel) komen vanzelf mee
2510
+ met de pakbon op de labelprinter van dezelfde plek; geen extra knop nodig.
2511
+ Wijzig geen functies van de Engine.`,
2512
+ },
2449
2513
  {
2450
2514
  number: 1,
2451
2515
  title: "Basiskoppeling via de database",
@@ -4795,6 +4859,31 @@ CONTROLELIJST
4795
4859
  order: 5,
4796
4860
  summary: "Reserveert voorraad op commando en meldt wijzigingen terug.",
4797
4861
  revisions: [
4862
+ {
4863
+ number: 8,
4864
+ title: "Antwoord op Voorraad 1.0.93: reserveringen zonder Floriday-leidende FO-orders",
4865
+ date: "2026-10-21",
4866
+ summary: "logistics_recompute_reserved_targeted telt FO-toewijzingen op Floriday-leidende sleutels niet meer mee; change_source blijft RESERVATION_RECOMPUTE.",
4867
+ body: `KOPPELPROMPT VOORRAAD – antwoord op 1.0.93 (Engine 1.0.176)
4868
+
4869
+ Verwerkt in de Engine:
4870
+ 1. logistics_recompute_reserved_targeted, recompute_reserved_stock en
4871
+ recompute_all_reserved_stock zetten vóór de UPDATE
4872
+ set_config('stock.change_source','RESERVATION_RECOMPUTE', true) en schrijven
4873
+ change_source = 'RESERVATION_RECOMPUTE' op de rij (stond al zo).
4874
+ 2. Alle drie tellen geen toewijzingen mee van orders met
4875
+ normalize_order_source(order_source) = 'FO' op een sleutel waarvoor
4876
+ voorraad_floriday_leads_key(trade_item_key) = true. Eigen orders tellen mee.
4877
+ De toewijzingen (logistics_reservation_allocations) blijven bestaan.
4878
+ Ontbreekt voorraad_floriday_leads_key: telling zoals vroeger + melding in de
4879
+ Engine-trace (errorClass 'afhankelijkheid').
4880
+
4881
+ Niet van de Engine en dus NIET aangepast – deze schrijven ook reserved_stock;
4882
+ controleer ze zelf op change_source en de FO-regel:
4883
+ apply_stock_reservation, apply_stock_consumption, promote_trade_item_key,
4884
+ canonicalize_trade_item_stock_key, _migrate_rewrite_stock_key,
4885
+ floriday_ingest_sales_orders.`,
4886
+ },
4798
4887
  {
4799
4888
  number: 1,
4800
4889
  title: "Basiskoppeling via de database",
@@ -5228,6 +5317,74 @@ Zelf rekenen doe je niet.
5228
5317
  order: 9,
5229
5318
  summary: "Levert de documentlayouts. Kiest zelf geen layout en geen printer: de Engine bepaalt welke layout en welke printplek bij een document horen.",
5230
5319
  revisions: [
5320
+ {
5321
+ number: 11,
5322
+ title: "Verzenddocument: de Engine bepaalt afleverbrief of veilingbrief",
5323
+ date: "2026-10-21",
5324
+ summary: "De Engine vertaalt 'verzenddocument' bij Floriday-orders naar 'afleverbrief' of 'veilingbrief' voordat layout_voor_document wordt gevraagd.",
5325
+ body: `KOPPELPROMPT LAYOUTS EN PRINTERS – verzenddocument (Engine 1.0.176)
5326
+
5327
+ Je ok=false voor 'verzenddocument' bij Floriday-orders (1.69.0) is juist. De Engine
5328
+ lost het op: logistics_document_for_order vertaalt 'verzenddocument' eerst naar het
5329
+ echte document en roept daarna layout_voor_document(order, 'afleverbrief' |
5330
+ 'veilingbrief') aan. Eigen orders: 'afleverbrief'. Je hoeft niets te wijzigen.
5331
+
5332
+ Wil je het zelf lezen: rpc logistics_floriday_shipping_document(p_order_id uuid)
5333
+ -> { ok, documenttype: 'afleverbrief'|'veilingbrief'|null, fulfillment_order_id, reden }.
5334
+
5335
+ Eenduidige bron:
5336
+ public.logistics_slip_shipping_note.fulfillment_order_id
5337
+ -> public.floriday_fulfillment_orders_cache.floriday_id (is_deleted niet true)
5338
+ velden: data->>'type', data->>'isReAuctioning', data->'deliveryNoteCodes'
5339
+ Regel: isReAuctioning = true, of type bevat CLOCK of AUCTION -> veilingbrief;
5340
+ type = DIRECT_SALES met minstens één deliveryNoteCode -> afleverbrief;
5341
+ anders ok=false met reden (niet gokken).`,
5342
+ },
5343
+ {
5344
+ number: 10,
5345
+ title: "Eén beslisregel: layout_voor_document(order, documenttype)",
5346
+ date: "2026-10-21",
5347
+ summary: "Layouts wordt eigenaar van de layoutkeuze per documentsoort en herkomst via één functie die de Engine en Pickschermen aanroepen.",
5348
+ body: `KOPPELPROMPT LAYOUTS EN PRINTERS – automatische documentkeuze (Engine 1.0.176)
5349
+
5350
+ Doel: de gebruiker kiest nergens meer een layout. De keuze welke layout bij een
5351
+ documentsoort en herkomst hoort, is van Layouts. Bouw één functie die alle
5352
+ modules aanroepen:
5353
+
5354
+ public.layout_voor_document(p_order_id uuid, p_documenttype text) RETURNS jsonb
5355
+ { "ok": boolean, "layout_id": uuid|null, "bron": "eigen"|"floriday",
5356
+ "documenttype": text, "breedte_mm": numeric|null, "hoogte_mm": numeric|null,
5357
+ "reden": text|null }
5358
+
5359
+ documenttype dat de Engine meestuurt: pakbon, productiebon, verzenddocument,
5360
+ afleverbrief, veilingbrief, sticker, traysticker, eigen_sticker.
5361
+
5362
+ Beslisregel:
5363
+ - pakbon / productiebon: altijd de standaardlayout van die soort met bron 'eigen'.
5364
+ - verzenddocument, precies één per order:
5365
+ - Floriday-order (orders.order_source = 'floriday'): het document dat Floriday
5366
+ echt gekoppeld heeft (afleverbrief/verzendbrief of veilingbrief) met de
5367
+ Floriday-systeemlayout van die soort.
5368
+ - eigen order (HO/MO/AO): afleverbrief, standaardlayout, bron 'eigen'.
5369
+ - Onduidelijk of ontbreekt: ok=false en een Nederlandse reden. Niet gokken.
5370
+ - sticker: Floriday-order -> Floriday-systeemlayout 'sticker'.
5371
+ - eigen_sticker: eigen order -> standaard stickerlayout bron 'eigen'. Die layout
5372
+ tekent de afbeelding uit payload.sticker_afbeelding = { bucket, pad }
5373
+ (Klanten-opslag van customer_product_stickers).
5374
+ - traysticker: Floriday-systeemlayout 'traysticker'.
5375
+ - Geen (eenduidige) layout: ok=false, reden zoals
5376
+ "Maak of activeer een pakbonlayout in Layouts en printers."
5377
+
5378
+ Spelregels:
5379
+ - STABLE, SECURITY DEFINER, search_path public; EXECUTE voor authenticated en service_role.
5380
+ - Geen omgevingswaarden, geen terugval op een andere soort.
5381
+ - Pas niets aan functies van de Engine aan. Zodra deze functie bestaat, gebruikt
5382
+ de Engine (logistics_document_for_order) alleen nog jouw antwoord; tot die tijd
5383
+ gebruikt de Engine de automatische standaardkeuze en toont Beheer
5384
+ "Layouts is nog niet bijgewerkt – automatische keuze gebruikt".
5385
+ - Opnieuw afdrukken blijft altijd mogelijk; geen tweede actieve origineel per
5386
+ order per soort (bestaande idempotentiesleutel).`,
5387
+ },
5231
5388
  {
5232
5389
  number: 1,
5233
5390
  title: "De Engine kiest de layout, de Layout maker maakt hem",
@@ -1,2 +1,2 @@
1
- export declare const MODULE_VERSION = "1.0.174";
1
+ export declare const MODULE_VERSION = "1.0.177";
2
2
  //# sourceMappingURL=moduleVersion.d.ts.map
@@ -1,2 +1,2 @@
1
1
  // Automatisch gegenereerd door prebuild:lib; niet handmatig aanpassen.
2
- export const MODULE_VERSION = "1.0.174";
2
+ export const MODULE_VERSION = "1.0.177";
@@ -1 +1 @@
1
- {"version":3,"file":"ruleEngineSchema.d.ts","sourceRoot":"","sources":["../../src/lib/ruleEngineSchema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ruleEngineSchema.d.ts","sourceRoot":"","sources":["../../src/lib/ruleEngineSchema.ts"],"names":[],"mappings":"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"}
@@ -737,19 +737,12 @@ export const RULE_STEPS = [
737
737
  ],
738
738
  },
739
739
  { key: "packing_slip_station", label: "Pickstation", type: "pickstation" },
740
- {
741
- key: "packing_slip_layout",
742
- label: "Pakbon layout",
743
- type: "layout",
744
- layoutTypes: ["pakbon"],
745
- description: "De pakbon-layout voor dit soort orders. Of gelijke karren gebundeld worden, of er een barcode op staat en hoe een volle kar en een deelkar eruitzien, stel je in de Layout maker in. Op \u201cAutomatisch\u201d pakt de Layout maker zijn eigen actieve layout. Levert Floriday een kant-en-klare pakbon als PDF, dan wordt die altijd gebruikt.",
746
- },
747
740
  {
748
741
  key: "packing_slip_help",
749
742
  label: "Waar stel ik dit in?",
750
743
  type: "guidance",
751
744
  guidance: {
752
- engine: "Hier bepaal je w\u00e1nneer de pakbon vrijkomt, naar welk pickstation hij gaat en welke layout bij dit soort orders hoort.",
745
+ engine: "Hier bepaal je w\u00e1nneer de pakbon vrijkomt, en naar welk pickstation hij gaat. Het document wordt automatisch bepaald uit de order.",
753
746
  layoutMaker: "In de Layout maker teken je de layout zelf, zet je er \u00e9\u00e9n op actief en koppel je printplekken aan computers en printers. Welke printer er print, bepaal je daar.",
754
747
  pickstations: "Op de pickschermen koppel je elk pickstation aan een printplek uit de Layout maker. Ontbreekt die koppeling, dan blijft de printopdracht wachten in plaats van op een willekeurige printer te belanden.",
755
748
  },
@@ -819,19 +812,12 @@ export const RULE_STEPS = [
819
812
  },
820
813
  ],
821
814
  },
822
- {
823
- key: "sticker_layout",
824
- label: "Welke layout voor dit soort orders?",
825
- type: "layout",
826
- layoutTypes: ["sticker", "etiket"],
827
- description: "Kies de layout die bij dit soort orders hoort. Op \u201cAutomatisch\u201d pakt de Layout maker zijn eigen actieve layout. Levert Floriday kant-en-klare stickers als PDF, dan worden die altijd gebruikt.",
828
- },
829
815
  {
830
816
  key: "sticker_help",
831
817
  label: "Waar stel ik dit in?",
832
818
  type: "guidance",
833
819
  guidance: {
834
- engine: "Hier bepaal je w\u00e1nneer de stickers vrijkomen, naar welk pickstation ze gaan en welke layout bij dit soort orders hoort.",
820
+ engine: "Hier bepaal je w\u00e1nneer de stickers vrijkomen, en naar welk pickstation ze gaan. Het document wordt automatisch bepaald uit de order.",
835
821
  layoutMaker: "In de Layout maker teken je de layout zelf, zet je er \u00e9\u00e9n op actief en koppel je printplekken aan computers en printers. Welke printer er print, bepaal je daar.",
836
822
  pickstations: "Op de pickschermen koppel je elk pickstation aan een printplek uit de Layout maker. Ontbreekt die koppeling, dan blijft de printopdracht wachten in plaats van op een willekeurige printer te belanden.",
837
823
  },
@@ -855,25 +841,12 @@ export const RULE_STEPS = [
855
841
  ],
856
842
  },
857
843
  { key: "shipping_note_station", label: "Pickstation", type: "pickstation" },
858
- {
859
- key: "shipping_note_layout",
860
- label: "Verzendbrief voor BVO orders",
861
- type: "layout",
862
- layoutTypes: [
863
- "verzendlabel",
864
- "transportdocument",
865
- "afleverbrief",
866
- "veilingbrief",
867
- "veilingbon",
868
- ],
869
- description: "\u00c9\u00e9n layout voor de verzend-, aflever- en veilingbrief van BVO orders. Op \u201cAutomatisch\u201d pakt de Layout maker zijn eigen actieve layout. Levert Floriday een kant-en-klare brief als PDF, dan wordt die altijd gebruikt.",
870
- },
871
844
  {
872
845
  key: "shipping_note_help",
873
846
  label: "Waar stel ik dit in?",
874
847
  type: "guidance",
875
848
  guidance: {
876
- engine: "Hier bepaal je w\u00e1nneer de verzendbrief vrijkomt, naar welk pickstation hij gaat en welke layout bij dit soort orders hoort.",
849
+ engine: "Hier bepaal je w\u00e1nneer de verzendbrief vrijkomt, en naar welk pickstation hij gaat. Het document wordt automatisch bepaald uit de order.",
877
850
  layoutMaker: "In de Layout maker teken je de layout zelf, zet je er \u00e9\u00e9n op actief en koppel je printplekken aan computers en printers. Welke printer er print, bepaal je daar.",
878
851
  pickstations: "Op de pickschermen koppel je elk pickstation aan een printplek uit de Layout maker. Ontbreekt die koppeling, dan blijft de printopdracht wachten in plaats van op een willekeurige printer te belanden.",
879
852
  },
@@ -903,19 +876,12 @@ export const RULE_STEPS = [
903
876
  ],
904
877
  },
905
878
  { key: "production_note_station", label: "Pickstation", type: "pickstation" },
906
- {
907
- key: "production_note_layout",
908
- label: "Welke layout voor dit soort orders?",
909
- type: "layout",
910
- layoutTypes: ["productiebon", "magazijnlijst"],
911
- description: "Kies de layout die bij dit soort orders hoort. Laat je dit op \u201cAutomatisch\u201d staan, dan pakt de Layout maker zijn eigen actieve layout.",
912
- },
913
879
  {
914
880
  key: "production_note_help",
915
881
  label: "Waar stel ik dit in?",
916
882
  type: "guidance",
917
883
  guidance: {
918
- engine: "Hier bepaal je w\u00e1nneer de productiebon vrijkomt, naar welk pickstation hij gaat en welke layout bij dit soort orders hoort.",
884
+ engine: "Hier bepaal je w\u00e1nneer de productiebon vrijkomt, en naar welk pickstation hij gaat. Het document wordt automatisch bepaald uit de order.",
919
885
  layoutMaker: "In de Layout maker teken je de layout zelf, zet je er \u00e9\u00e9n op actief en koppel je printplekken aan computers en printers. Welke printer er print, bepaal je daar.",
920
886
  pickstations: "Op de pickschermen koppel je elk pickstation aan een printplek uit de Layout maker. Ontbreekt die koppeling, dan blijft de printopdracht wachten in plaats van op een willekeurige printer te belanden.",
921
887
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ruleEngineWizard.d.ts","sourceRoot":"","sources":["../../src/lib/ruleEngineWizard.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAC;CACzB;AAeD,eAAO,MAAM,YAAY,EAAE,UAAU,EAsDpC,CAAC;AA+BF,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEzD;AAwED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE9D;AAyCD,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAStF"}
1
+ {"version":3,"file":"ruleEngineWizard.d.ts","sourceRoot":"","sources":["../../src/lib/ruleEngineWizard.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAC;CACzB;AAeD,eAAO,MAAM,YAAY,EAAE,UAAU,EAsDpC,CAAC;AA+BF,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEzD;AAoED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE9D;AAyCD,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAStF"}
@@ -137,13 +137,11 @@ const EXTRA_HELP = {
137
137
  packing_slip_release: "Bepaalt op welk moment de pakbon bij het pickstation verschijnt.",
138
138
  packing_slip_hours_before: "Zoveel uur vóór het picken staat de pakbon klaar.",
139
139
  packing_slip_station: "Het pickstation waar de pakbon uitgeprint wordt.",
140
- packing_slip_layout: "De layout die de Engine bij elke pakbon meestuurt. Bundelen van gelijke karren, de barcode en het verschil tussen een volle kar en een deelkar stel je in de Layout maker in.",
141
140
  sticker_release: "Bepaalt op welk moment de stickers bij het pickstation verschijnen. Kies \u201cgelijk met de bijbehorende pakbon\u201d als sticker en pakbon altijd samen uit de printer moeten komen.",
142
141
  sticker_hours_before: "Zoveel uur vóór het picken staan de stickers klaar.",
143
142
  sticker_station: "Het pickstation waar de stickers uitgeprint worden.",
144
143
  shipping_note_release: "Bepaalt op welk moment de verzendbrief beschikbaar komt.",
145
144
  shipping_note_station: "Het pickstation waar de verzendbrief uitgeprint wordt.",
146
- shipping_note_layout: "\u00c9\u00e9n layout voor de verzend-, aflever- en veilingbrief van BVO orders.",
147
145
  production_note_release: "Bepaalt op welk moment de productiebon beschikbaar komt.",
148
146
  production_note_station: "Het pickstation waar de productiebon uitgeprint wordt.",
149
147
  control_mode: "Hoe je controleert of de kar klopt voordat hij weggaat. Bij 'Scannen voor afmelden' is één pakbonscan genoeg en wordt de hele kar direct afgemeld.",
@@ -377,7 +377,7 @@ export async function runShippingNoteQueue(sb, options = {}) {
377
377
  const printPlekId = String(slipPayload["print_plek_id"] ?? "").trim() || null;
378
378
  const cartId = slipPayload["cart_id"] ?? row.cart_id;
379
379
  // Layout op id: de actieve Floriday-afleverbrief (bij meerdere de standaard).
380
- const layout = await floridayLayout(sb, "afleverbrief");
380
+ const layout = await floridayLayout(sb, "afleverbrief", row.order_id);
381
381
  if (!layout.layoutId) {
382
382
  await sb.rpc("logistics_slip_note_hold_layout", { _id: row.id, _reason: layout.reden });
383
383
  run.waiting++;
@@ -9,9 +9,34 @@ export interface StickerRun {
9
9
  warnings: number;
10
10
  errors: string[];
11
11
  }
12
+ interface Row {
13
+ id: string;
14
+ soort: "sticker" | "traysticker" | "eigen_sticker";
15
+ bron_id: string;
16
+ eigen_sticker_id?: string | null;
17
+ order_id: string | null;
18
+ order_number: string | null;
19
+ cart_id: string | null;
20
+ kopieen: number;
21
+ breedte_mm: number | null;
22
+ hoogte_mm: number | null;
23
+ print_plek_id: string | null;
24
+ fulfillment_order_id: string | null;
25
+ status: string;
26
+ attempts: number;
27
+ sticker_type?: string | null;
28
+ print_job_id?: string | null;
29
+ herprint_reden?: string | null;
30
+ herprint_requested_at?: string | null;
31
+ }
32
+ /** Opslag van eigen stickers (Klanten-module, customer_product_stickers). */
33
+ export declare const EIGEN_STICKER_BUCKET = "customer-stickers";
34
+ /** Documentsoort voor de centrale documentkeuze. */
35
+ export declare function documentSoort(soort: Row["soort"]): string;
12
36
  export declare function runStickerQueue(sb: SupabaseClient, opts?: {
13
37
  limit?: number;
14
38
  }): Promise<StickerRun>;
15
39
  /** Reden die de layoutkeuze geeft als er geen (eenduidige) Floriday-layout is. */
16
40
  export declare function isGeenLayoutReden(reden: unknown): boolean;
41
+ export {};
17
42
  //# sourceMappingURL=stickerQueue.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stickerQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/stickerQueue.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiB5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAoCD,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA8T5G;AAoGD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzD"}
1
+ {"version":3,"file":"stickerQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/stickerQueue.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiB5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,UAAU,GAAG;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,eAAe,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAKD,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AAExD,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,CAEzD;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA8V5G;AAoGD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzD"}
@@ -18,7 +18,13 @@ import { trace, newTraceId } from "./trace.server.js";
18
18
  import { printViaLayoutGecontroleerd, floridayLayout, bucketUitLink } from "./layoutPrint.server.js";
19
19
  import { getFlorydayDocument, getFlorydayFulfillmentStatus } from "./floridayDocuments.server.js";
20
20
  import { controleerEtiket, parseGeladenEtiketten, pdfFormaat, stickerBackoffMinuten, stickerKopieen, waarschuwingTekst, } from "./stickerRules.js";
21
- const COLS = "id, soort, bron_id, order_id, order_number, cart_id, kopieen, breedte_mm, hoogte_mm, print_plek_id, fulfillment_order_id, status, attempts, sticker_type, print_job_id, herprint_reden, herprint_requested_at";
21
+ const COLS = "id, soort, bron_id, order_id, order_number, cart_id, kopieen, breedte_mm, hoogte_mm, print_plek_id, fulfillment_order_id, status, attempts, sticker_type, print_job_id, herprint_reden, herprint_requested_at, eigen_sticker_id";
22
+ /** Opslag van eigen stickers (Klanten-module, customer_product_stickers). */
23
+ export const EIGEN_STICKER_BUCKET = "customer-stickers";
24
+ /** Documentsoort voor de centrale documentkeuze. */
25
+ export function documentSoort(soort) {
26
+ return soort === "eigen_sticker" ? "eigen_sticker" : soort;
27
+ }
22
28
  function formaat(r) {
23
29
  return r.breedte_mm && r.hoogte_mm ? { breedteMm: Number(r.breedte_mm), hoogteMm: Number(r.hoogte_mm) } : null;
24
30
  }
@@ -41,6 +47,12 @@ export async function runStickerQueue(sb, opts = {}) {
41
47
  run.errors.push(`sync: ${error.message}`);
42
48
  run.synced = data ?? null;
43
49
  }
50
+ // 1b. Eigen stickers (1.0.176): needs_sticker per orderregel, vrij met de pakbon.
51
+ {
52
+ const { error } = await sb.rpc("logistics_own_sticker_sync", { p_limit: 200 });
53
+ if (error)
54
+ run.errors.push(`eigen stickers: ${error.message}`);
55
+ }
44
56
  // 2. Tray-stickers: vrij na geaccepteerde belading.
45
57
  {
46
58
  const { data } = await sb
@@ -158,7 +170,7 @@ export async function runStickerQueue(sb, opts = {}) {
158
170
  phase: "stickers",
159
171
  actor: "logistiek-engine:stickerronde",
160
172
  };
161
- const label = r.soort === "sticker" ? "Sticker" : "Tray-stickers";
173
+ const label = r.soort === "sticker" ? "Sticker" : r.soort === "eigen_sticker" ? "Eigen sticker" : "Tray-stickers";
162
174
  const blokkeer = async (reden) => {
163
175
  if (isHerprint) {
164
176
  await zet(r.id, { herprint_requested_at: null, herprint_reden: `Herprint mislukt: ${reden}` });
@@ -202,7 +214,7 @@ export async function runStickerQueue(sb, opts = {}) {
202
214
  await blokkeer("Geen kar bekend voor deze sticker.");
203
215
  continue;
204
216
  }
205
- const kopieen = r.soort === "sticker" ? stickerKopieen(r.kopieen) : Math.max(1, Math.floor(Number(r.kopieen) || 1));
217
+ const kopieen = r.soort !== "traysticker" ? stickerKopieen(r.kopieen) : Math.max(1, Math.floor(Number(r.kopieen) || 1));
206
218
  if (kopieen === null) {
207
219
  await blokkeer(`Aantal afdrukken ongeldig (${String(r.kopieen)}).`);
208
220
  continue;
@@ -211,23 +223,48 @@ export async function runStickerQueue(sb, opts = {}) {
211
223
  await blokkeer("Geen printplek bekend (geen pakbon met printplek en geen pickstation in de werkwijze).");
212
224
  continue;
213
225
  }
214
- // Pdf ophalen via de Floriday-koppeling.
215
- const doc = (await getFlorydayDocument(sb, (r.soort === "sticker"
216
- ? { kind: "customer-sticker", stickerId: r.bron_id }
217
- : { kind: "tray-stickers", deliveryOrderId: r.bron_id })));
218
- if (!doc["ok"]) {
219
- await later(`Floriday: ${String(doc["error"] ?? "pdf niet beschikbaar")}`);
220
- continue;
226
+ const isEigen = r.soort === "eigen_sticker";
227
+ let url = null;
228
+ let b64 = null;
229
+ let doc = {};
230
+ let eigenOpslag = null;
231
+ if (isEigen) {
232
+ // Eigen sticker: afbeelding uit customer_product_stickers, getekend via de eigen stickerlayout.
233
+ if (!r.eigen_sticker_id) {
234
+ await blokkeer("Geen eigen sticker gekoppeld voor deze klant en dit product.");
235
+ continue;
236
+ }
237
+ const { data: s } = await sb
238
+ .from("customer_product_stickers")
239
+ .select("file_path")
240
+ .eq("id", r.eigen_sticker_id)
241
+ .maybeSingle();
242
+ const pad = String(s?.["file_path"] ?? "").trim();
243
+ if (!pad) {
244
+ await blokkeer("Het bestand van de eigen sticker ontbreekt. Voeg de sticker opnieuw toe bij de klant.");
245
+ continue;
246
+ }
247
+ eigenOpslag = { bucket: EIGEN_STICKER_BUCKET, pad };
221
248
  }
222
- const url = (doc["url"] ?? doc["pdfUrl"] ?? doc["documentUrl"] ?? null);
223
- const b64 = (doc["pdfBase64"] ?? doc["base64"] ?? doc["pdf"] ?? null);
224
- if (!url && !b64) {
225
- await later("Floriday gaf nog geen bruikbaar bestand terug.");
226
- continue;
249
+ else {
250
+ // Pdf ophalen via de Floriday-koppeling.
251
+ doc = (await getFlorydayDocument(sb, (r.soort === "sticker"
252
+ ? { kind: "customer-sticker", stickerId: r.bron_id }
253
+ : { kind: "tray-stickers", deliveryOrderId: r.bron_id })));
254
+ if (!doc["ok"]) {
255
+ await later(`Floriday: ${String(doc["error"] ?? "pdf niet beschikbaar")}`);
256
+ continue;
257
+ }
258
+ url = (doc["url"] ?? doc["pdfUrl"] ?? doc["documentUrl"] ?? null);
259
+ b64 = (doc["pdfBase64"] ?? doc["base64"] ?? doc["pdf"] ?? null);
260
+ if (!url && !b64) {
261
+ await later("Floriday gaf nog geen bruikbaar bestand terug.");
262
+ continue;
263
+ }
227
264
  }
228
- // Formaat: van Floriday (stickerSize), anders uit de pdf zelf.
265
+ // Formaat: van Floriday (stickerSize), anders uit de pdf zelf; eigen sticker: uit sticker of layout.
229
266
  let f = formaat(r);
230
- if (!f) {
267
+ if (!f && !isEigen) {
231
268
  try {
232
269
  const bytes = b64 ? base64NaarBytes(b64) : new Uint8Array(await (await fetch(url)).arrayBuffer());
233
270
  f = pdfFormaat(bytes);
@@ -239,16 +276,17 @@ export async function runStickerQueue(sb, opts = {}) {
239
276
  }
240
277
  }
241
278
  const lijst = await etiketten(r.print_plek_id);
242
- const controle = controleerEtiket(f, lijst, r.soort === "sticker" ? "sticker" : "tray-sticker");
279
+ const controle = controleerEtiket(f, lijst, r.soort === "traysticker" ? "tray-sticker" : "sticker");
243
280
  if (f && lijst !== null)
244
281
  await meld(r, f, controle.etiket, controle.ok);
245
282
  if (!controle.ok) {
246
283
  await blokkeer(controle.reden);
247
284
  continue;
248
285
  }
249
- const layout = await floridayLayout(sb, r.soort);
286
+ // 1.0.176: centrale documentkeuze per order; zonder order de Floriday-systeemlayout.
287
+ const layout = await floridayLayout(sb, documentSoort(r.soort), r.order_id);
250
288
  if (!layout.layoutId) {
251
- await blokkeer(layout.reden ?? `Geen actieve Floriday-layout voor ${r.soort}.`);
289
+ await blokkeer(layout.reden ?? `Geen actieve layout voor ${r.soort}.`);
252
290
  continue;
253
291
  }
254
292
  // Blijvende verwijzing naar de opgeslagen pdf (alleen bij precies één rij).
@@ -278,7 +316,7 @@ export async function runStickerQueue(sb, opts = {}) {
278
316
  pdfUrl: url,
279
317
  layoutId: layout.layoutId,
280
318
  printPlekId: r.print_plek_id,
281
- herkomst: "floriday",
319
+ herkomst: isEigen ? "eigen" : "floriday",
282
320
  isHerprint,
283
321
  kopieen,
284
322
  idempotentieSleutel: isHerprint
@@ -298,7 +336,9 @@ export async function runStickerQueue(sb, opts = {}) {
298
336
  ...(isHerprint ? { herprint_reden: r.herprint_reden ?? null } : {}),
299
337
  ...(r.soort === "sticker"
300
338
  ? { sticker_id: r.bron_id, floriday_sticker_id: String(r.bron_id), sticker_type: r.sticker_type ?? null }
301
- : { delivery_order_id: r.bron_id }),
339
+ : r.soort === "eigen_sticker"
340
+ ? { eigen_sticker_id: r.eigen_sticker_id ?? null, sticker_afbeelding: eigenOpslag }
341
+ : { delivery_order_id: r.bron_id }),
302
342
  fulfillment_order_id: r.fulfillment_order_id,
303
343
  sticker_formaat_mm: f ? { breedte: f.breedteMm, hoogte: f.hoogteMm } : null,
304
344
  ...(pdfOpslag ? { pdf_opslag: pdfOpslag } : {}),