@flowselections/layout-maker 1.58.1 → 1.59.1

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 (43) hide show
  1. package/dist-lib/components/ComputersLijst.d.ts +1 -0
  2. package/dist-lib/components/ComputersLijst.d.ts.map +1 -1
  3. package/dist-lib/components/ComputersLijst.js +9 -5
  4. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  5. package/dist-lib/components/PrintQueuePage.js +8 -5
  6. package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
  7. package/dist-lib/components/PrintplekDetailPage.js +4 -2
  8. package/dist-lib/components/PrintplekkenPage.d.ts.map +1 -1
  9. package/dist-lib/components/PrintplekkenPage.js +10 -2
  10. package/dist-lib/components/TestprintDialog.d.ts.map +1 -1
  11. package/dist-lib/components/TestprintDialog.js +5 -1
  12. package/dist-lib/components/WerkplekkenTab.d.ts.map +1 -1
  13. package/dist-lib/components/WerkplekkenTab.js +4 -3
  14. package/dist-lib/integrations/supabase/types.d.ts +108 -0
  15. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  16. package/dist-lib/lib/orderData.server.d.ts.map +1 -1
  17. package/dist-lib/lib/orderData.server.js +26 -3
  18. package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
  19. package/dist-lib/lib/pakbonHtml.js +6 -1
  20. package/dist-lib/lib/printQueue.server.d.ts +6 -0
  21. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  22. package/dist-lib/lib/printQueue.server.js +25 -2
  23. package/dist-lib/lib/printRoutering.d.ts +3 -1
  24. package/dist-lib/lib/printRoutering.d.ts.map +1 -1
  25. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  26. package/dist-lib/lib/printService.functions.js +3 -1
  27. package/dist-lib/lib/printnodeStatus.d.ts.map +1 -1
  28. package/dist-lib/lib/printnodeStatus.js +4 -0
  29. package/dist-lib/lib/printnodeWebhook.d.ts +2 -0
  30. package/dist-lib/lib/printnodeWebhook.d.ts.map +1 -1
  31. package/dist-lib/lib/printnodeWebhook.js +31 -1
  32. package/dist-lib/lib/printnodeWebhookBeheer.server.d.ts +2 -0
  33. package/dist-lib/lib/printnodeWebhookBeheer.server.d.ts.map +1 -1
  34. package/dist-lib/lib/printnodeWebhookBeheer.server.js +12 -2
  35. package/dist-lib/lib/productiebonHtml.d.ts.map +1 -1
  36. package/dist-lib/lib/productiebonHtml.js +7 -1
  37. package/dist-lib/lib/testprint.d.ts +5 -1
  38. package/dist-lib/lib/testprint.d.ts.map +1 -1
  39. package/dist-lib/lib/testprint.js +55 -11
  40. package/dist-lib/lib/waaromPrinter.d.ts +2 -0
  41. package/dist-lib/lib/waaromPrinter.d.ts.map +1 -1
  42. package/dist-lib/lib/waaromPrinter.js +13 -0
  43. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"orderData.server.d.ts","sourceRoot":"","sources":["../../src/lib/orderData.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE/B,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAwBtD,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKvD;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG;IACrD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAgCA;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG;IAC7C,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAMA;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,OAAO,EACX,MAAM,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC7E,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CA+arB;AAyFD;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAGhG"}
1
+ {"version":3,"file":"orderData.server.d.ts","sourceRoot":"","sources":["../../src/lib/orderData.server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE/B,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAwBtD,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKvD;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG;IACrD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAgCA;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG;IAC7C,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAMA;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,OAAO,EACX,MAAM,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC7E,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CA+arB;AAkHD;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAGhG"}
@@ -437,15 +437,19 @@ async function vulKlantEnAdres(db, orders, kop) {
437
437
  return;
438
438
  const c = await veilig(() => db
439
439
  .from("customers")
440
- .select("customer_number, company_name, contact_person, phone, email, street, house_number, address, address_line1, postal_code, city, country")
440
+ .select("customer_number, company_name, commercial_name, contact_person, phone, email, street, house_number, address, address_line1, postal_code, city, country")
441
441
  .eq("id", ids[0])
442
442
  .maybeSingle());
443
+ await vulKlantReferentie(db, orders, kop);
443
444
  if (!c)
444
445
  return;
445
446
  const t = (v) => (v == null ? "" : String(v).trim());
446
447
  klant["nummer"] = t(c["customer_number"]);
447
- if (!t(klant["naam"]))
448
- klant["naam"] = t(c["company_name"]);
448
+ // Op pakbon, afleverbrief en productiebon: de handelsnaam, met de
449
+ // bedrijfsnaam als terugval. (De factuur blijft de bedrijfsnaam gebruiken.)
450
+ const weergave = t(c["commercial_name"]) || t(c["company_name"]);
451
+ if (weergave)
452
+ klant["naam"] = weergave;
449
453
  klant["contact"] = t(c["contact_person"]);
450
454
  const straat = t(c["street"]) ? [t(c["street"]), t(c["house_number"])].filter(Boolean).join(" ") : t(c["address_line1"]) || t(c["address"]);
451
455
  kop["afleveradres"] = {
@@ -455,6 +459,25 @@ async function vulKlantEnAdres(db, orders, kop) {
455
459
  land: t(c["country"]),
456
460
  };
457
461
  }
462
+ /**
463
+ * Klantreferentie: `customerOrderId` van de Floriday-verkooporder (Suppliers
464
+ * API SalesOrder), gekoppeld op orders.floriday_sales_order_id. Geen
465
+ * referentie bekend: leeg, zodat de regel verdwijnt (nooit het ordernummer).
466
+ */
467
+ async function vulKlantReferentie(db, orders, kop) {
468
+ const order = (kop["order"] ?? {});
469
+ const klant = (kop["klant"] ?? {});
470
+ order["referentie"] = "";
471
+ klant["referentie"] = "";
472
+ const fids = uniek(orders.map((o) => o["floriday_sales_order_id"]));
473
+ if (!fids.length)
474
+ return;
475
+ const rijen = await veilig(() => db.from("floriday_salesorders_cache").select("floriday_id, data").in("floriday_id", fids));
476
+ const refs = uniek((Array.isArray(rijen) ? rijen : []).map((r) => (r["data"] ?? {})["customerOrderId"]));
477
+ const tekst = refs.length > 4 ? `${refs.slice(0, 4).join(", ")} +${refs.length - 4}` : refs.join(", ");
478
+ order["referentie"] = tekst;
479
+ klant["referentie"] = tekst;
480
+ }
458
481
  /**
459
482
  * Kopsecties bij één of meerdere orders. Conservatief: bij meerdere orders
460
483
  * tonen we de klant (als die gelijk is) en géén willekeurig ordernummer.
@@ -1 +1 @@
1
- {"version":3,"file":"pakbonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/pakbonHtml.ts"],"names":[],"mappings":"AAUA,OAAO,EAyBL,KAAK,SAAS,EAEd,KAAK,YAAY,EAGlB,MAAM,iBAAiB,CAAC;AAMzB,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAWD,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAKtC;AAyBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAqF3D;AA4ED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAGlD;AAwoBD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CAyDR;AAgBD,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CAkFR;AAED,iEAAiE;AACjE,wBAAgB,oBAAoB,IAAI,WAAW,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,IAAI,CAsCN;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAUf"}
1
+ {"version":3,"file":"pakbonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/pakbonHtml.ts"],"names":[],"mappings":"AAUA,OAAO,EAyBL,KAAK,SAAS,EAEd,KAAK,YAAY,EAGlB,MAAM,iBAAiB,CAAC;AAMzB,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAWD,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAKtC;AAyBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAqF3D;AA4ED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAGlD;AAwoBD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CA8DR;AAgBD,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CAkFR;AAED,iEAAiE;AACjE,wBAAgB,oBAAoB,IAAI,WAAW,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,IAAI,CAsCN;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -709,7 +709,12 @@ export function renderPakbonBody(config, order, opties = {}) {
709
709
  const variantKop = variant
710
710
  ? `<div class="pakbonvariant">${variant === "full_cart" ? "HELE KAR" : "DEELKAR"}</div>`
711
711
  : "";
712
- const kop = variantKop + documentLogoHtml(cfg.logo, opts);
712
+ // Klantnaam (handelsnaam) groot bovenaan; leeg = niets tonen.
713
+ const klantNaam = zonderUuid(order.klant?.naam ?? "");
714
+ const klantKop = klantNaam
715
+ ? `<div class="blok" style="font-size:16pt;font-weight:800;line-height:1.15">${esc(klantNaam)}</div>`
716
+ : "";
717
+ const kop = variantKop + klantKop + documentLogoHtml(cfg.logo, opts);
713
718
  const totalenSectie = zoek("totalen");
714
719
  const totalenElkePagina = !!totalenSectie && opt(totalenSectie, "elke_pagina", false) === true;
715
720
  const inhoud = secties
@@ -79,6 +79,12 @@ export declare const MAX_WACHT_OP_LAYOUT = 3;
79
79
  * eindeloos blijft rondgaan en onder de gewone opschoning valt.
80
80
  */
81
81
  export declare function wachtOpLayout(db: PrintDb, job: Job, reden: string): Promise<"wachtend" | "mislukt">;
82
+ /**
83
+ * Blijvende weigering (formaat past niet, geen geladen etiket). Opnieuw
84
+ * proberen kan niet slagen, dus meteen een eindstatus: telt niet als wachtend
85
+ * en valt buiten "Alles annuleren". De foutcode bepaalt het label.
86
+ */
87
+ export declare function geweigerd(db: PrintDb, job: Job, code: "FORMAAT_PAST_NIET" | "GEEN_GELADEN_ETIKET", bericht: string): Promise<void>;
82
88
  /**
83
89
  * Verwerkt één stabiele PrintNode-status (uit /states of de webhook) op een
84
90
  * opdracht. Gedeeld door polling en webhook, zodat beide hetzelfde doen.
@@ -1 +1 @@
1
- {"version":3,"file":"printQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/printQueue.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"printQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/printQueue.server.ts"],"names":[],"mappings":"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"}
@@ -1197,6 +1197,29 @@ export async function wachtOpLayout(db, job, reden) {
1197
1197
  await log(db, job.id, "wacht_op_engine_layout", `${reden} (poging ${pogingen}/${MAX_WACHT_OP_LAYOUT})`);
1198
1198
  return "wachtend";
1199
1199
  }
1200
+ /**
1201
+ * Blijvende weigering (formaat past niet, geen geladen etiket). Opnieuw
1202
+ * proberen kan niet slagen, dus meteen een eindstatus: telt niet als wachtend
1203
+ * en valt buiten "Alles annuleren". De foutcode bepaalt het label.
1204
+ */
1205
+ export async function geweigerd(db, job, code, bericht) {
1206
+ const nu = new Date().toISOString();
1207
+ await db
1208
+ .from("print_jobs")
1209
+ .update({
1210
+ status: "mislukt",
1211
+ verwerkingsfase: "mislukt",
1212
+ fase_voltooid_op: nu,
1213
+ foutcode: code,
1214
+ foutmelding: `${code}: ${bericht}`.slice(0, 500),
1215
+ volgende_poging: null,
1216
+ voltooid_op: nu,
1217
+ updated_at: nu,
1218
+ })
1219
+ .eq("id", job.id)
1220
+ .neq("status", "geannuleerd");
1221
+ await log(db, job.id, "geweigerd", `${code}: ${bericht}`);
1222
+ }
1200
1223
  async function mislukt(db, job, reden, terugNaarWachtend) {
1201
1224
  const pogingen = Number(job.pogingen ?? 0);
1202
1225
  const opnieuw = terugNaarWachtend && pogingen < MAX_POGINGEN;
@@ -1345,7 +1368,7 @@ async function verwerkJob(db, job) {
1345
1368
  // Labelprinter: het geladen etiket is leidend (punt "geladen etiket").
1346
1369
  const label = await labelControleVoorbereiden(db, printer);
1347
1370
  if (!label && ETIKET_PDF_SOORTEN.has(String(job.documenttype ?? ""))) {
1348
- await mislukt(db, job, `GEEN_GELADEN_ETIKET: ${documentTypeLabelVoor(String(job.documenttype))} gaat alleen naar een labelprinter met een ingesteld geladen etiket; printer ${String(printer.naam ?? printer.id)} heeft er geen.`, true);
1371
+ await geweigerd(db, job, "GEEN_GELADEN_ETIKET", `${documentTypeLabelVoor(String(job.documenttype))} gaat alleen naar een labelprinter met een ingesteld geladen etiket; printer ${String(printer.naam ?? printer.id)} heeft er geen.`);
1349
1372
  return "mislukt";
1350
1373
  }
1351
1374
  const isTest = (job.payload ?? {})["is_testprint"] === true;
@@ -1397,7 +1420,7 @@ async function verwerkJob(db, job) {
1397
1420
  const maat = (klaar ? pdfPaginaMm(pdfBase64) : null) ?? { breedte_mm: breedteMm, hoogte_mm: hoogteMm };
1398
1421
  const uit = etiketPast({ ...maat, soortLabel: documentTypeLabelVoor(String(job.documenttype ?? "Document")) }, label.etiket, label.naam);
1399
1422
  if (!uit.ok) {
1400
- await mislukt(db, job, `${uit.code}: ${uit.bericht}`, true);
1423
+ await geweigerd(db, job, uit.code, uit.bericht);
1401
1424
  return "mislukt";
1402
1425
  }
1403
1426
  papier = { paper: uit.paper, rotate: uit.rotate, uitleg: uit.uitleg };
@@ -4,7 +4,7 @@ export interface OvergeslagenRegel {
4
4
  bron: Exclude<RouteringBron, "geen">;
5
5
  regel_id: string;
6
6
  printer_id: string | null;
7
- reden: "ontbreekt" | "inactief" | "niet_bruikbaar";
7
+ reden: "ontbreekt" | "inactief" | "niet_bruikbaar" | "geen_labelprinter";
8
8
  }
9
9
  export interface RouteringUitkomst {
10
10
  bron: RouteringBron;
@@ -20,6 +20,8 @@ export interface RouteringUitkomst {
20
20
  werkplek_naam?: string | null;
21
21
  printer_rol?: "a4" | "label" | null;
22
22
  formaat_klasse?: "a4" | "label" | null;
23
+ /** geen_etiketlayout | geen_labelprinter | meerdere_labelprinters */
24
+ melding?: string | null;
23
25
  }
24
26
  export interface RouteringInvoer {
25
27
  documenttype: string;
@@ -1 +1 @@
1
- {"version":3,"file":"printRoutering.d.ts","sourceRoot":"","sources":["../../src/lib/printRoutering.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,UAAU,GACV,kBAAkB,GAClB,oBAAoB,GACpB,QAAQ,GACR,WAAW,GACX,MAAM,CAAC;AAEX,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,gBAAgB,CAAC;CACpD;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAuBD,oFAAoF;AACpF,wBAAsB,aAAa,CACjC,MAAM,EAAE,eAAe,EACvB,EAAE,GAAE,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAwD,GACvF,OAAO,CAAC,iBAAiB,CAAC,CAW5B;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,EAAE;;;;EA+BpB;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,mFAAmF;AACnF,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GACrE,OAAO,CAAC,iBAAiB,CAAC,CAE5B"}
1
+ {"version":3,"file":"printRoutering.d.ts","sourceRoot":"","sources":["../../src/lib/printRoutering.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,UAAU,GACV,kBAAkB,GAClB,oBAAoB,GACpB,QAAQ,GACR,WAAW,GACX,MAAM,CAAC;AAEX,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;CAC1E;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAuBD,oFAAoF;AACpF,wBAAsB,aAAa,CACjC,MAAM,EAAE,eAAe,EACvB,EAAE,GAAE,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAwD,GACvF,OAAO,CAAC,iBAAiB,CAAC,CAW5B;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,EAAE;;;;EA+BpB;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,mFAAmF;AACnF,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GACrE,OAAO,CAAC,iBAAiB,CAAC,CAE5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"printService.functions.d.ts","sourceRoot":"","sources":["../../src/lib/printService.functions.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe;;;;;;;;;;;;GASxB,CAAC;AAEL,eAAO,MAAM,qBAAqB;;;;8CAER;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;;GAmBC,CAAC;AAEL,eAAO,MAAM,WAAW;;;;8CAEE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;GAU7C,CAAC;AAEL,eAAO,MAAM,uBAAuB;;;;+CAET;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;;;;;;;;;;GAqE5C,CAAC;AAEL,eAAO,MAAM,gBAAgB;;;;;;;;;;;;GAYzB,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;GAUnC,CAAC;AAEL,oFAAoF;AACpF,eAAO,MAAM,cAAc;;;;iFAevB,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;8CAED;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;GAyDvC,CAAC;AAEL,qDAAqD;AACrD,eAAO,MAAM,aAAa;;;;;;sBAYJ,MAAM;qBAAe,MAAM;iBAAW,MAAM,EAAE;uBAAiB,MAAM,EAAE;kBAAY,MAAM;uBAAiB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;GAMpI,CAAC;AAEL,qEAAqE;AACrE,eAAO,MAAM,sBAAsB;;;;;;;;;;GAoB/B,CAAC"}
1
+ {"version":3,"file":"printService.functions.d.ts","sourceRoot":"","sources":["../../src/lib/printService.functions.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe;;;;;;;;;;;;GASxB,CAAC;AAEL,eAAO,MAAM,qBAAqB;;;;8CAER;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;;GAmBC,CAAC;AAEL,eAAO,MAAM,WAAW;;;;8CAEE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;GAU7C,CAAC;AAEL,eAAO,MAAM,uBAAuB;;;;+CAET;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;;;;;;;;;;GAqE5C,CAAC;AAEL,eAAO,MAAM,gBAAgB;;;;;;;;;;;;GAYzB,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;GAUnC,CAAC;AAEL,oFAAoF;AACpF,eAAO,MAAM,cAAc;;;;iFAgBvB,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;8CAED;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;GAyDvC,CAAC;AAEL,qDAAqD;AACrD,eAAO,MAAM,aAAa;;;;;;sBAYJ,MAAM;qBAAe,MAAM;iBAAW,MAAM,EAAE;uBAAiB,MAAM,EAAE;kBAAY,MAAM;uBAAiB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;GAMpI,CAAC;AAEL,qEAAqE;AACrE,eAAO,MAAM,sBAAsB;;;;;;;;;;GAoB/B,CAAC"}
@@ -158,10 +158,12 @@ export const printTellingen = createServerFn({ method: "POST" })
158
158
  const statussen = ["wachtend", "bezig", "voltooid", "mislukt", "geannuleerd"];
159
159
  const uitkomst = {};
160
160
  await Promise.all(statussen.map(async (s) => {
161
- const { count } = await context.supabase
161
+ const { count, error } = await context.supabase
162
162
  .from("print_jobs")
163
163
  .select("id", { count: "exact", head: true })
164
164
  .eq("status", s);
165
+ if (error)
166
+ throw new Error(`Tellen mislukt (${s}): ${error.message}`);
165
167
  uitkomst[s] = count ?? 0;
166
168
  }));
167
169
  return uitkomst;
@@ -1 +1 @@
1
- {"version":3,"file":"printnodeStatus.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeStatus.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzD,CAAC;AAEF,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAW5D;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,aAAsD,CAAC;AAEpF,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CAI3F;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAI/G"}
1
+ {"version":3,"file":"printnodeStatus.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeStatus.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzD,CAAC;AAEF,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAa5D;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,aAAsD,CAAC;AAEpF,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CAI3F;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAI/G"}
@@ -17,6 +17,10 @@ export function printnodeStatusLabel(j) {
17
17
  return "Geannuleerd";
18
18
  if (j.foutcode === "AANLEVERING_MISLUKT")
19
19
  return "Mislukt — geen document";
20
+ if (j.foutcode === "FORMAAT_PAST_NIET")
21
+ return "Geweigerd – past niet";
22
+ if (j.foutcode === "GEEN_GELADEN_ETIKET")
23
+ return "Geweigerd – geen etiket geladen";
20
24
  const pn = String(j.printnode_status ?? "").toLowerCase();
21
25
  if (pn && PRINTNODE_STATUS_LABEL[pn])
22
26
  return PRINTNODE_STATUS_LABEL[pn];
@@ -9,6 +9,8 @@ export declare function controleerSecret(request: Request, secret: string, _veld
9
9
  };
10
10
  /** @deprecated gebruik controleerSecret */
11
11
  export declare function secretKlopt(request: Request, secret: string): boolean;
12
+ /** Details van een geweigerde aanroep. Bevat nooit (een deel van) het geheim. */
13
+ export declare function afwijzingDetails(request: Request): Promise<Record<string, unknown>>;
12
14
  /**
13
15
  * Afhandeling van een webhookaanroep. Het geheim komt uit de eigen
14
16
  * koppelingstabel (servicerol). `secretVoorTest` alleen voor tests.
@@ -1 +1 @@
1
- {"version":3,"file":"printnodeWebhook.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhook.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAWxC,8EAA8E;AAC9E,eAAO,MAAM,UAAU,+BAA+B,CAAC;AAEvD,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAGtC;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AA8BD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,EAAE,EACN,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,QAAQ,CAAC,CA4EnB;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrD"}
1
+ {"version":3,"file":"printnodeWebhook.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhook.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAWxC,8EAA8E;AAC9E,eAAO,MAAM,UAAU,+BAA+B,CAAC;AAEvD,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAGtC;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AA8BD,iFAAiF;AACjF,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CASzF;AASD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,EAAE,EACN,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,QAAQ,CAAC,CAmFnB;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrD"}
@@ -52,6 +52,29 @@ async function noteer(db, regel, bewaren) {
52
52
  }
53
53
  catch { /* vastleggen mag verwerking niet blokkeren */ }
54
54
  }
55
+ /** Details van een geweigerde aanroep. Bevat nooit (een deel van) het geheim. */
56
+ export async function afwijzingDetails(request) {
57
+ let lengte = 0;
58
+ try {
59
+ lengte = (await request.clone().text()).length;
60
+ }
61
+ catch { /* onleesbaar */ }
62
+ return {
63
+ secret_kop_aanwezig: request.headers.has(SECRET_KOP),
64
+ inhoud_lengte: lengte,
65
+ user_agent: (request.headers.get("user-agent") ?? "").slice(0, 120) || null,
66
+ content_type: (request.headers.get("content-type") ?? "").slice(0, 60) || null,
67
+ };
68
+ }
69
+ async function soortenUit(request) {
70
+ try {
71
+ const b = JSON.parse(await request.clone().text());
72
+ return Array.isArray(b) ? [...new Set(b.map((x) => String(x?.type ?? "").toLowerCase()).filter(Boolean))].slice(0, 5) : [];
73
+ }
74
+ catch {
75
+ return [];
76
+ }
77
+ }
55
78
  /**
56
79
  * Afhandeling van een webhookaanroep. Het geheim komt uit de eigen
57
80
  * koppelingstabel (servicerol). `secretVoorTest` alleen voor tests.
@@ -74,9 +97,16 @@ export async function behandelPrintNodeWebhook(request, db, secretVoorTest, opti
74
97
  return Response.json({ ok: false, fout: "Live printstatus is niet gekoppeld." }, { status: 503 });
75
98
  }
76
99
  if (!controleerSecret(request, secret).ok) {
77
- await noteer(db, { http_status: 401, antwoord: { fout: "Ongeldig secret" } }, uitTabel);
100
+ // Vastleggen wát er binnenkwam, zonder het geheim zelf: alleen of de kop er
101
+ // was, hoe lang de inhoud is en welke soort melding het was.
102
+ await noteer(db, { http_status: 401, soorten: await soortenUit(request), antwoord: { fout: "Ongeldig secret", details: await afwijzingDetails(request) } }, uitTabel);
78
103
  return Response.json({ ok: false, fout: "Ongeldig secret" }, { status: 401 });
79
104
  }
105
+ // Eigen zelftest (geheim klopt): 200 + OK-kop, maar geen bewijs van PrintNode.
106
+ if (request.headers.get("x-layouts-zelftest") === "1") {
107
+ await noteer(db, { http_status: 200, soorten: ["zelftest"], antwoord: { ok: true, zelftest: true } }, uitTabel);
108
+ return Response.json({ ok: true, zelftest: true }, { headers: OK_KOP });
109
+ }
80
110
  if (uitTabel) {
81
111
  try {
82
112
  await db.from("printnode_webhook_koppeling").update({
@@ -46,6 +46,8 @@ export type ZelftestUitkomst = "ja" | "nee" | "onbekend";
46
46
  * Beoordeelt het antwoord van de eigen webhookroute zonder geheim.
47
47
  * JSON (401/503) = route bestaat. Alleen een echte 404 = niet bereikbaar.
48
48
  */
49
+ /** Kop waarmee de eigen zelftest zich herkenbaar maakt. */
50
+ export declare const ZELFTEST_KOP = "x-layouts-zelftest";
49
51
  export declare function beoordeelZelftest(status: number, contentType: string | null): ZelftestUitkomst;
50
52
  /** Leest counts uit GET /webhooks (successfulRequests, failedRequests, receivedEvents, droppedEvents). */
51
53
  export declare function leesCounts(counts: unknown): {
@@ -1 +1 @@
1
- {"version":3,"file":"printnodeWebhookBeheer.server.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhookBeheer.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"printnodeWebhookBeheer.server.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhookBeheer.server.ts"],"names":[],"mappings":"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"}
@@ -64,9 +64,15 @@ export async function koppelWebhook(db, opties = {}) {
64
64
  throw new Error("PrintNode gaf de nieuwe webhook niet terug.");
65
65
  webhookId = Number(gevonden.webhookId);
66
66
  }
67
+ // Een tweede webhook naar hetzelfde adres heeft een oud geheim en geeft dus
68
+ // telkens 401. Niet zelf verwijderen: alleen zichtbaar melden (op webhookId).
69
+ const dubbel = alle.filter((w) => w.url === oordeel.url && Number(w.webhookId) !== webhookId);
70
+ const dubbelMelding = dubbel.length
71
+ ? `Let op: in PrintNode staan nog ${dubbel.length} andere webhook(s) naar dit adres (id ${dubbel.map((w) => Number(w.webhookId)).join(", ")}). Die hebben een oud geheim en krijgen 401. Verwijder ze in PrintNode.`
72
+ : null;
67
73
  await schrijf(db, {
68
74
  geheim, secret_veld: null, webhook_id: webhookId, url: oordeel.url, status: "aan",
69
- fout: null, melding: opties.melding ?? null, gekoppeld_op: nu, laatste_poging_op: nu,
75
+ fout: null, melding: dubbelMelding ?? opties.melding ?? null, gekoppeld_op: nu, laatste_poging_op: nu,
70
76
  });
71
77
  await controleerBereikbaarheid(db);
72
78
  return { ok: true, url: oordeel.url, bijgewerkt: !!bestaand };
@@ -113,6 +119,8 @@ const ZELFTEST_MS = 5000;
113
119
  * Beoordeelt het antwoord van de eigen webhookroute zonder geheim.
114
120
  * JSON (401/503) = route bestaat. Alleen een echte 404 = niet bereikbaar.
115
121
  */
122
+ /** Kop waarmee de eigen zelftest zich herkenbaar maakt. */
123
+ export const ZELFTEST_KOP = "x-layouts-zelftest";
116
124
  export function beoordeelZelftest(status, contentType) {
117
125
  const json = (contentType ?? "").toLowerCase().includes("application/json");
118
126
  if (json)
@@ -145,7 +153,9 @@ export async function controleerBereikbaarheid(db) {
145
153
  const t = setTimeout(() => ctl.abort(), ZELFTEST_MS);
146
154
  const r = await fetch(k.url, {
147
155
  method: "POST",
148
- headers: { "Content-Type": "application/json" },
156
+ // Eigen zelftest mét het geheim (server-side) en een eigen kenmerk, zodat
157
+ // hij niet meer als "401 · leeg" tussen de PrintNode-meldingen staat.
158
+ headers: { "Content-Type": "application/json", ...(k.geheim ? { "X-PrintNode-Webhook-Secret": k.geheim } : {}), [ZELFTEST_KOP]: "1" },
149
159
  body: "[]",
150
160
  signal: ctl.signal,
151
161
  }).finally(() => clearTimeout(t));
@@ -1 +1 @@
1
- {"version":3,"file":"productiebonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/productiebonHtml.ts"],"names":[],"mappings":"AAwBA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAI/B,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAgBxD;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAG9D;AA6HD,yDAAyD;AACzD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,wBAA6B,GACpC,MAAM,CAgCR"}
1
+ {"version":3,"file":"productiebonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/productiebonHtml.ts"],"names":[],"mappings":"AAwBA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAI/B,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAgBxD;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAG9D;AA6HD,yDAAyD;AACzD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,wBAA6B,GACpC,MAAM,CAsCR"}
@@ -147,6 +147,12 @@ export function renderProductiebonDocument(config, gegevens, opties = {}) {
147
147
  return inhoud ? `<div class="blok">${inhoud}</div>` : "";
148
148
  })
149
149
  .join("");
150
+ // Klantnaam groot bovenaan, alleen als de opdracht hem echt aanlevert.
151
+ const bronProduct = (gegevens?.["product"] ?? {});
152
+ const klantNaam = String(bronProduct["klantnaam"] ?? "").trim();
153
+ const klantKop = klantNaam
154
+ ? `<div class="blok" style="font-size:16pt;font-weight:800;line-height:1.15">${esc(klantNaam)}</div>`
155
+ : "";
150
156
  return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
151
157
  <title>${esc(opties.titel ?? "Productiebon")}</title>
152
158
  <style>
@@ -162,5 +168,5 @@ body { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color: #111827
162
168
  .tabel { width: 100%; border-collapse: collapse; table-layout: fixed; }
163
169
  .tabel th { text-align: left; font-weight: 600; }
164
170
  .regel { padding: 0.4mm 0; }
165
- </style></head><body>${body}</body></html>`;
171
+ </style></head><body>${klantKop}${body}</body></html>`;
166
172
  }
@@ -22,7 +22,11 @@ export declare function bepaalTestOverzicht(ctx: TestprintContext): Promise<Test
22
22
  * zodat een testvel nooit voor een echt document kan doorgaan. Bovenaan staat
23
23
  * waar hij vandaan komt.
24
24
  */
25
- export declare function testHtml(velden: Record<string, string>): string;
25
+ export declare function testHtml(velden: Record<string, string>, opts?: {
26
+ smal?: boolean;
27
+ }): string;
28
+ /** Smal etiket: kleinste zijde van het geladen etiket onder 40 mm. */
29
+ export declare function isSmalEtiket(etiket: unknown): boolean;
26
30
  export interface TestprintResultaat {
27
31
  jobId: string;
28
32
  printerId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"testprint.d.ts","sourceRoot":"","sources":["../../src/lib/testprint.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kDAAkD;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA4B1F;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAY/D;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,kBAAkB,CAAC,CAyC7B"}
1
+ {"version":3,"file":"testprint.d.ts","sourceRoot":"","sources":["../../src/lib/testprint.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kDAAkD;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA+B1F;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CA0B9F;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAMrD;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,kBAAkB,CAAC,CA6C7B"}
@@ -5,8 +5,22 @@
5
5
  // ============================================================================
6
6
  import { supabase } from "./supabaseClient.js";
7
7
  import { DOCUMENT_TYPES, documentTypeLabel } from "./documentTypes.js";
8
- import { printHtml, printerVoorDocumenttype } from "./printApi.js";
8
+ import { printHtml } from "./printApi.js";
9
+ import { routeringMeldingTekst } from "./waaromPrinter.js";
9
10
  import { printplekNaam } from "./printplekken.js";
11
+ import { routeringVoor } from "./printRoutering.js";
12
+ /** Naam van de werkplek: uit de routering (op id), anders de computernaam. */
13
+ async function werkplekNaamVoor(id, naam, computer) {
14
+ if (naam)
15
+ return naam;
16
+ if (id) {
17
+ const { data } = await supabase.from("print_werkplekken").select("naam").eq("id", id).maybeSingle();
18
+ const n = data?.naam;
19
+ if (n)
20
+ return n;
21
+ }
22
+ return computer;
23
+ }
10
24
  const arr = (v) => (Array.isArray(v) ? v : []);
11
25
  /**
12
26
  * Bepaalt voor elke documentsoort welke printer er volgens de instellingen
@@ -19,8 +33,11 @@ export async function bepaalTestOverzicht(ctx) {
19
33
  const namen = new Map(arr(data).map((p) => [p.id, p.naam]));
20
34
  const regels = await Promise.all(DOCUMENT_TYPES.map(async (d) => {
21
35
  let printerId = null;
36
+ let melding = null;
22
37
  try {
23
- printerId = await printerVoorDocumenttype(d.value, undefined, werkplek, printplekId);
38
+ const u = await routeringVoor({ documenttype: d.value, printplekId: printplekId ?? null, werkplek: werkplek ?? null });
39
+ printerId = u.printer_id;
40
+ melding = u.melding ?? null;
24
41
  }
25
42
  catch {
26
43
  printerId = null;
@@ -30,9 +47,9 @@ export async function bepaalTestOverzicht(ctx) {
30
47
  label: d.label,
31
48
  printerId,
32
49
  printerNaam: printerId ? (namen.get(printerId) ?? "Printer") : null,
33
- reden: printerId
50
+ reden: routeringMeldingTekst(melding) ?? (printerId
34
51
  ? null
35
- : "Nog geen printer ingesteld voor deze documentsoort op deze plek.",
52
+ : "Nog geen printer ingesteld voor deze documentsoort op deze plek."),
36
53
  };
37
54
  }));
38
55
  return regels;
@@ -42,16 +59,39 @@ export async function bepaalTestOverzicht(ctx) {
42
59
  * zodat een testvel nooit voor een echt document kan doorgaan. Bovenaan staat
43
60
  * waar hij vandaan komt.
44
61
  */
45
- export function testHtml(velden) {
62
+ export function testHtml(velden, opts = {}) {
63
+ // Nooit midden in een woord afbreken: alleen op spaties.
64
+ const geenAfbreken = "word-break:keep-all;overflow-wrap:normal;hyphens:none;-webkit-hyphens:none";
65
+ if (opts.smal) {
66
+ // Smal etiket (bijv. 25 mm): kleine letter, elk veld op een eigen regel.
67
+ const regels = Object.entries(velden)
68
+ .map(([k, v]) => `<div style="margin:0 0 0.4mm"><span style="color:#555">${k}:</span> <b>${v}</b></div>`)
69
+ .join("");
70
+ return `<div style="position:relative;min-height:100%;padding:1mm;font-family:Arial,Helvetica,sans-serif;font-size:5.5pt;line-height:1.2;overflow:hidden;${geenAfbreken}">
71
+ <div style="font-weight:800;font-size:6.5pt;margin:0 0 0.8mm;white-space:nowrap">TESTAFDRUK</div>
72
+ <div style="font-size:5pt;margin:0 0 0.8mm">niet gebruiken</div>
73
+ ${regels}
74
+ <div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) rotate(-60deg);white-space:nowrap;font-size:9pt;font-weight:900;color:#999;opacity:0.5;border:0.5mm solid #999;padding:0.3mm 1.5mm">TESTAFDRUK</div>
75
+ </div>`;
76
+ }
46
77
  const rijen = Object.entries(velden)
47
78
  .map(([k, v]) => `<tr><td style="padding:0.6mm 3mm 0.6mm 0;color:#555">${k}</td><td style="padding:0.6mm 0;font-weight:700">${v}</td></tr>`)
48
79
  .join("");
49
- return `<div style="position:relative;min-height:100%;padding:3mm;font-family:Arial,Helvetica,sans-serif;font-size:9pt;overflow:hidden">
80
+ return `<div style="position:relative;min-height:100%;padding:3mm;font-family:Arial,Helvetica,sans-serif;font-size:9pt;overflow:hidden;${geenAfbreken}">
50
81
  <div style="font-weight:800;font-size:11pt;margin:0 0 1.5mm">TESTAFDRUK — niet gebruiken</div>
51
82
  <table style="border-collapse:collapse">${rijen}</table>
52
83
  <div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) rotate(-35deg);white-space:nowrap;font-size:28pt;font-weight:900;color:#999;opacity:0.55;border:1.2mm solid #999;padding:1mm 4mm">TESTAFDRUK — niet gebruiken</div>
53
84
  </div>`;
54
85
  }
86
+ /** Smal etiket: kleinste zijde van het geladen etiket onder 40 mm. */
87
+ export function isSmalEtiket(etiket) {
88
+ const e = (etiket ?? null);
89
+ const b = Number(e?.breedte_mm);
90
+ const h = Number(e?.hoogte_mm);
91
+ if (!Number.isFinite(b) || !Number.isFinite(h) || b <= 0 || h <= 0)
92
+ return false;
93
+ return Math.min(b, h) < 40;
94
+ }
55
95
  /**
56
96
  * Verstuurt één testprint via de gewone printwachtrij, zodat exact dezelfde
57
97
  * routering en PrintNode-afhandeling worden gebruikt als bij echte documenten.
@@ -60,7 +100,9 @@ export async function verstuurTestprint(documenttype, ctx) {
60
100
  const printplekId = ctx.printplekId ?? undefined;
61
101
  const werkplek = ctx.werkplek ?? undefined;
62
102
  const plekNaam = printplekId ? await printplekNaam(printplekId) : null;
63
- const printerId = await printerVoorDocumenttype(documenttype, undefined, werkplek, printplekId);
103
+ // Dezelfde gedeelde routering als het echte printen.
104
+ const uitkomst = await routeringVoor({ documenttype, printplekId: printplekId ?? null, werkplek: werkplek ?? null });
105
+ const printerId = uitkomst.printer_id;
64
106
  if (!printerId) {
65
107
  throw new Error(plekNaam
66
108
  ? `Geen printer voor ${documentTypeLabel(documenttype)} op ${plekNaam} — stel dit in bij deze printplek.`
@@ -68,18 +110,20 @@ export async function verstuurTestprint(documenttype, ctx) {
68
110
  }
69
111
  const { data } = await supabase
70
112
  .from("printers")
71
- .select("naam")
113
+ .select("naam, geladen_etiket")
72
114
  .eq("id", printerId)
73
115
  .maybeSingle();
74
- const printerNaam = data?.naam ?? "Printer";
116
+ const pr = data;
117
+ const printerNaam = pr?.naam ?? "Printer";
118
+ const werkplekNaam = await werkplekNaamVoor(uitkomst.werkplek_id ?? null, uitkomst.werkplek_naam ?? null, werkplek ?? null);
75
119
  const testId = `test-${documenttype}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
76
120
  const html = testHtml({
77
121
  Documentsoort: documentTypeLabel(documenttype),
78
122
  Printplek: plekNaam ?? "—",
79
- Werkplek: werkplek ?? "—",
123
+ Werkplek: werkplekNaam ?? "—",
80
124
  Printer: printerNaam,
81
125
  Tijdstip: new Date().toLocaleString("nl-NL"),
82
- });
126
+ }, { smal: isSmalEtiket(pr?.geladen_etiket) });
83
127
  const { jobId } = await printHtml({
84
128
  documenttype,
85
129
  documentnaam: `Testprint ${documentTypeLabel(documenttype)}`,
@@ -4,4 +4,6 @@ import type { RouteringUitkomst } from "./printRoutering.js";
4
4
  * "Werkplek Kantoor → A4-printer XP-2200 (regel: papierformaat A4)".
5
5
  */
6
6
  export declare function waaromDezePrinter(u: Pick<RouteringUitkomst, "bron" | "papierformaat"> & Partial<Pick<RouteringUitkomst, "werkplek_naam" | "printer_rol" | "werkplek">>, printerNaam: string | null, plekNaam?: string | null, extra?: string | null): string;
7
+ /** Leesbare tekst bij de melding uit de gedeelde routering. */
8
+ export declare function routeringMeldingTekst(melding: string | null | undefined): string | null;
7
9
  //# sourceMappingURL=waaromPrinter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"waaromPrinter.d.ts","sourceRoot":"","sources":["../../src/lib/waaromPrinter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAYzE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,eAAe,CAAC,GAClD,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC,EAChF,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAkBR"}
1
+ {"version":3,"file":"waaromPrinter.d.ts","sourceRoot":"","sources":["../../src/lib/waaromPrinter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAYzE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,eAAe,CAAC,GAClD,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC,EAChF,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAkBR;AAGD,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAWvF"}
@@ -33,3 +33,16 @@ export function waaromDezePrinter(u, printerNaam, plekNaam, extra) {
33
33
  const regel = u.bron === "werkplek_formaat" ? `papierformaat${formaat}` : BRON_TEKST[u.bron];
34
34
  return `${wie} (regel: ${regel})${extra ? ` · ${extra}` : ""}`;
35
35
  }
36
+ /** Leesbare tekst bij de melding uit de gedeelde routering. */
37
+ export function routeringMeldingTekst(melding) {
38
+ switch (melding) {
39
+ case "geen_etiketlayout":
40
+ return "Deze soort heeft nog geen etiketlayout (layout staat op A4)";
41
+ case "geen_labelprinter":
42
+ return "Etiketsoort: geen labelprinter op deze werkplek of printplek — er wordt niets geprint.";
43
+ case "meerdere_labelprinters":
44
+ return "Etiketsoort: deze printplek heeft meerdere labelprinters — kies een werkplek; er wordt niets geprint.";
45
+ default:
46
+ return null;
47
+ }
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/layout-maker",
3
- "version": "1.58.1",
3
+ "version": "1.59.1",
4
4
  "flowselections": {
5
5
  "moduleId": "layout-maker",
6
6
  "pages": [
@@ -143,9 +143,9 @@
143
143
  "@rsbuild/core": "^1.0.0",
144
144
  "@tailwindcss/vite": "^4.2.1",
145
145
  "@tanstack/react-query": "^5.83.0",
146
- "@tanstack/react-router": "^1.168.0",
147
- "@tanstack/react-start": "^1.167.14",
148
- "@tanstack/router-plugin": "^1.167.10",
146
+ "@tanstack/react-router": "1.169.1",
147
+ "@tanstack/react-start": "1.167.63",
148
+ "@tanstack/router-plugin": "1.167.33",
149
149
  "@types/node": "^22.16.5",
150
150
  "@types/react": "^19.2.0",
151
151
  "@types/react-dom": "^19.2.0",