@flowselections/layout-maker 1.69.10 → 1.69.13

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 (73) hide show
  1. package/dist-lib/components/A4StickervelKaart.d.ts +5 -0
  2. package/dist-lib/components/A4StickervelKaart.d.ts.map +1 -0
  3. package/dist-lib/components/A4StickervelKaart.js +123 -0
  4. package/dist-lib/components/KlaarOmTePrintenBlok.d.ts.map +1 -1
  5. package/dist-lib/components/KlaarOmTePrintenBlok.js +50 -7
  6. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  7. package/dist-lib/components/PrintQueuePage.js +2 -1
  8. package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
  9. package/dist-lib/components/PrintplekDetailPage.js +3 -1
  10. package/dist-lib/components/PrintplekkenPage.d.ts.map +1 -1
  11. package/dist-lib/components/PrintplekkenPage.js +2 -1
  12. package/dist-lib/components/StickerRouteTestKaart.d.ts +5 -0
  13. package/dist-lib/components/StickerRouteTestKaart.d.ts.map +1 -0
  14. package/dist-lib/components/StickerRouteTestKaart.js +75 -0
  15. package/dist-lib/components/UitwijkRegel.d.ts +5 -0
  16. package/dist-lib/components/UitwijkRegel.d.ts.map +1 -0
  17. package/dist-lib/components/UitwijkRegel.js +17 -0
  18. package/dist-lib/components/UitwijkTekening.d.ts +19 -0
  19. package/dist-lib/components/UitwijkTekening.d.ts.map +1 -0
  20. package/dist-lib/components/UitwijkTekening.js +21 -0
  21. package/dist-lib/index.d.ts +12 -0
  22. package/dist-lib/index.d.ts.map +1 -1
  23. package/dist-lib/index.js +14 -0
  24. package/dist-lib/integrations/supabase/types.d.ts +3227 -22
  25. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  26. package/dist-lib/lib/belading.d.ts +10 -0
  27. package/dist-lib/lib/belading.d.ts.map +1 -0
  28. package/dist-lib/lib/belading.js +49 -0
  29. package/dist-lib/lib/eigenDocumenten.d.ts +2 -0
  30. package/dist-lib/lib/eigenDocumenten.d.ts.map +1 -1
  31. package/dist-lib/lib/eigenDocumenten.js +22 -0
  32. package/dist-lib/lib/installCheck.d.ts +36 -0
  33. package/dist-lib/lib/installCheck.d.ts.map +1 -0
  34. package/dist-lib/lib/installCheck.js +65 -0
  35. package/dist-lib/lib/klaarOmTePrinten.d.ts +15 -1
  36. package/dist-lib/lib/klaarOmTePrinten.d.ts.map +1 -1
  37. package/dist-lib/lib/klaarOmTePrinten.js +19 -1
  38. package/dist-lib/lib/orderData.server.d.ts.map +1 -1
  39. package/dist-lib/lib/orderData.server.js +20 -17
  40. package/dist-lib/lib/pakbonBuilder.d.ts +6 -0
  41. package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
  42. package/dist-lib/lib/pakbonBuilder.js +18 -5
  43. package/dist-lib/lib/pakbonContent.d.ts.map +1 -1
  44. package/dist-lib/lib/pakbonContent.js +4 -1
  45. package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
  46. package/dist-lib/lib/pakbonHtml.js +5 -2
  47. package/dist-lib/lib/pakbonPresentation.d.ts +3 -1
  48. package/dist-lib/lib/pakbonPresentation.d.ts.map +1 -1
  49. package/dist-lib/lib/pakbonPresentation.js +13 -6
  50. package/dist-lib/lib/printQueue.server.d.ts +11 -0
  51. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  52. package/dist-lib/lib/printQueue.server.js +158 -13
  53. package/dist-lib/lib/printService.server.d.ts.map +1 -1
  54. package/dist-lib/lib/printService.server.js +3 -2
  55. package/dist-lib/lib/standaardLayouts.server.d.ts +6 -0
  56. package/dist-lib/lib/standaardLayouts.server.d.ts.map +1 -1
  57. package/dist-lib/lib/standaardLayouts.server.js +13 -0
  58. package/dist-lib/lib/stickerPlaatsing.d.ts +37 -0
  59. package/dist-lib/lib/stickerPlaatsing.d.ts.map +1 -0
  60. package/dist-lib/lib/stickerPlaatsing.js +122 -0
  61. package/dist-lib/lib/stickerUitwijk.d.ts +197 -0
  62. package/dist-lib/lib/stickerUitwijk.d.ts.map +1 -0
  63. package/dist-lib/lib/stickerUitwijk.js +311 -0
  64. package/dist-lib/lib/testprint.d.ts +13 -0
  65. package/dist-lib/lib/testprint.d.ts.map +1 -1
  66. package/dist-lib/lib/testprint.js +38 -0
  67. package/dist-lib/lib/useDocumentData.js +1 -1
  68. package/dist-lib/lib/versie.generated.d.ts +1 -1
  69. package/dist-lib/lib/versie.generated.js +1 -1
  70. package/dist-lib/lib/vroegeWaarschuwing.d.ts +21 -0
  71. package/dist-lib/lib/vroegeWaarschuwing.d.ts.map +1 -0
  72. package/dist-lib/lib/vroegeWaarschuwing.js +15 -0
  73. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { telwoord } from "./pakbonBuilder.js";
1
2
  /**
2
3
  * Canonieke zichtbare metadata van een kar. Zowel het live voorbeeld als de
3
4
  * print-renderer gebruiken deze lijst, zodat geen van beide zelf regels kan
@@ -5,8 +6,10 @@
5
6
  */
6
7
  export function karMetadata(kar, velden) {
7
8
  const info = [];
8
- if (velden.includes("lagen"))
9
- info.push(`${kar.lagen.length} lagen`);
9
+ if (velden.includes("lagen")) {
10
+ const gevuld = kar.lagen.filter((l) => (l.producten?.length ?? 0) > 0).length;
11
+ info.push(telwoord(gevuld || kar.lagen.length, "laag", "lagen"));
12
+ }
10
13
  if (velden.includes("producten")) {
11
14
  const aantal = kar.lagen.reduce((totaal, laag) => totaal + laag.producten.reduce((som, product) => som + product.aantal, 0), 0);
12
15
  info.push(`${aantal} producten`);
@@ -21,9 +24,13 @@ export function karMetadata(kar, velden) {
21
24
  info.push("gedeelde kar");
22
25
  // De karstand hoort in de grote karkop (`KAR 2 van 2`), niet nogmaals in
23
26
  // deze metaregel. Anders verschijnt dezelfde telling op twee plekken.
24
- if (kar.cart_id)
25
- info.push(`ID ${kar.cart_id}`);
26
- if (kar.cart_items?.length)
27
- info.push(`${kar.cart_items.length} karregels`);
27
+ if (velden.includes("stickers"))
28
+ info.push(telwoord(aantalStickersBijKar(kar), "sticker", "stickers"));
29
+ // Geen technisch kar-id en geen interne regeltelling op papier: de barcode
30
+ // identificeert de kar.
28
31
  return info;
29
32
  }
33
+ /** Stickers bij deze kar: planten van regels waar een sticker bij hoort. */
34
+ export function aantalStickersBijKar(kar) {
35
+ return kar.lagen.reduce((n, l) => n + l.producten.reduce((m, p) => m + (String(p.sticker ?? "") === "Ja" ? Number(p.aantal || 0) : 0), 0), 0);
36
+ }
@@ -1,5 +1,7 @@
1
1
  import type { SupabaseClient } from "@supabase/supabase-js";
2
2
  import { type EigenStickerMaat } from "./eigenDocumenten.js";
3
+ import { type GeladenEtiket } from "./etiketControle.js";
4
+ import { type StickerSoort } from "./stickerUitwijk.js";
3
5
  type Job = Record<string, any>;
4
6
  /** De databaseclient die de shell aanlevert. De module maakt er zelf nooit een. */
5
7
  export type PrintDb = SupabaseClient<any, any, any>;
@@ -137,5 +139,14 @@ export declare function bepaalDocumentKeuze(db: PrintDb, job: Job): Promise<{
137
139
  keuze: LayoutKeuze;
138
140
  klaarPdf: string | null;
139
141
  }>;
142
+ /**
143
+ * Is dit een labelprinter? Ja als er een geladen etiket is ingesteld, of als
144
+ * een werkplek hem als labelprinter gebruikt. Alleen dan geldt de controle,
145
+ * zodat bestaande printers zonder werkplek precies blijven werken als nu.
146
+ */
147
+ /** Stickersoort voor de verkleininstelling (op configuratie en bron, nooit op naam). */
148
+ export declare function stickerSoortVoor(documenttype: string, layout: Job | null, floriday: boolean, klaar: boolean): StickerSoort;
149
+ /** Eigen ontwerp past niet op het geladen etiket: variant op de etiketmaat maken. */
150
+ export declare function eigenEtiketVariantNodig(layout: Job, etiket: GeladenEtiket): boolean;
140
151
  export {};
141
152
  //# sourceMappingURL=printQueue.server.d.ts.map
@@ -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":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA2B5D,OAAO,EAA+H,KAAK,gBAAgB,EAAkF,MAAM,mBAAmB,CAAC;AAMvQ,OAAO,EAAsD,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1G,OAAO,EAAkL,KAAK,YAAY,EAAwB,MAAM,kBAAkB,CAAC;AAQ3P,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE/B,mFAAmF;AACnF,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEpD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAW1E;AAiFD,2EAA2E;AAC3E,qBAAa,gBAAiB,SAAQ,KAAK;IAChC,IAAI,SAAsB;CACpC;AAED,+EAA+E;AAC/E,qBAAa,iBAAkB,SAAQ,KAAK;IACjC,IAAI,SAAuB;CACrC;AAED,oFAAoF;AACpF,qBAAa,qBAAsB,SAAQ,KAAK;IACrC,IAAI,SAA2B;CACzC;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBhH;AAED,kGAAkG;AAClG,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBjG;AAED,oFAAoF;AACpF,qBAAa,kBAAmB,SAAQ,gBAAgB;IAC7C,IAAI,SAAwB;CACtC;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvE,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CAAC;AAE5G,6EAA6E;AAC7E,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAcnD,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAI7D;AASD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAQnD;AAkCD,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAIlE;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAe7C;AA8ND;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQlH;AAWD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqClF;AA2UD;;;;GAIG;AACH,gEAAgE;AAChE,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMpG;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA4CtG;AAoBD,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,OAAO,EACX,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,WAAW,EAClB,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,MAAM,CAAC,CAqdjB;AAGD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAY1D;AAqBD,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAsCzG;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,GAAG,qBAAqB,EAAE,OAAO,EAAE,MAAM,iBAiBxH;AAED,mFAAmF;AACnF,wBAAsB,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,iBAiBpD;AA+aD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAOD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGlG;AAqID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA2BD,oFAAoF;AACpF,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,SAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8GtF;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,OAAO,EACX,GAAG,EAAE,GAAG,GACP,OAAO,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CA6B1D;AAGD;;;;GAIG;AACH,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,YAAY,CAO1H;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CASnF"}
@@ -3,6 +3,7 @@
3
3
  // Pakt wachtende opdrachten op, maakt er een PDF van en stuurt die stil naar
4
4
  // de juiste printer. Draait alleen op de server (cron / interne aanroep).
5
5
  // ============================================================================
6
+ import { voerUitwijkUit } from "./stickerPlaatsing.js";
6
7
  import { carrierUitPayload, carrierUitTransport, ENGINE_TE_OUD, geenVervoerderTekst, metVervoerder, VERVOERDER_DOCUMENTEN, voorbeeldVervoerder } from "./vervoerder.js";
7
8
  import { maakPakbonOrder, renderPakbonDocument, voorbeeldPakbonOrder, } from "./pakbonHtml.js";
8
9
  import { bouwPakbonScanInhoud, bewaarPakbonScanInhoud } from "./pakbonScan.js";
@@ -14,12 +15,13 @@ import { profielHeeftInhoud, renderProfielDocument } from "./profielHtml.js";
14
15
  import { bouwDocumentHtml, voorbeeldContext } from "./layoutPreview.js";
15
16
  import { AfbeeldingInhoudFout, htmlNaarPdfServer, PdfRenderFout } from "./htmlNaarPdf.server.js";
16
17
  import { bepaalStickerMaat, floridayStickerMaat, STICKER_MAAT_ONBEKEND, stickerFormaatCode, stickerIdUitPayload, stickerInfoUitCache, stickerNietNodig, stickerTypeLabel, STICKER_NIET_NODIG, FASE_NIET_NODIG } from "./stickerFormaat.js";
17
- import { controlelijstHtml, EIGEN_STICKER_MAAT_ONBEKEND, eigenStickerId, eigenStickerKlant, eigenStickerMaat, kiesTraystickerLogo, TRAYSTICKER_GEEN_INDELING, trayProducten, traystickerHtml } from "./eigenDocumenten.js";
18
+ import { controlelijstHtml, EIGEN_STICKER_MAAT_ONBEKEND, VOORBEELD_TRAY_PAYLOAD, eigenStickerId, eigenStickerKlant, eigenStickerMaat, kiesTraystickerLogo, TRAYSTICKER_GEEN_INDELING, trayProducten, traystickerHtml } from "./eigenDocumenten.js";
18
19
  import { OPMAAK_LIMIET_MS, OpmaakTeLangFout, metTijdslimiet } from "./opmaakLimiet.js";
19
20
  import { stuurPdfNaarPrinter, opdrachtStatusDetail, vervaltijdVoor } from "./printService.server.js";
20
21
  import { kiesPapier } from "./papierFormaten.js";
21
22
  import { waaromDezePrinter } from "./waaromPrinter.js";
22
- import { etiketPast, leesGeladenEtiket, pdfPaginaMm } from "./etiketControle.js";
23
+ import { etiketPast, leesGeladenEtiket, maatNl, pdfPaginaMm } from "./etiketControle.js";
24
+ import { a4VelVoor, kiesUitwijkroute, leesA4StickervelWaarde, leesStickerInstellingenStrikt, uitwijkVoorPickschermen } from "./stickerUitwijk.js";
23
25
  import { documentTypeLabel as documentTypeLabelVoor } from "./documentTypes.js";
24
26
  import { PAPIERFORMATEN } from "./documentTypes.js";
25
27
  const MAX_POGINGEN = 3;
@@ -986,7 +988,7 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
986
988
  noteer("render_html");
987
989
  return meegestuurd;
988
990
  }
989
- const p = (job.payload ?? {});
991
+ let p = (job.payload ?? {});
990
992
  // Vervoerder: alleen carrier_label uit de Engine. Ontbreekt hij → wachten.
991
993
  const carrierLabel = await bepaalVervoerder(db, job, p, layout);
992
994
  const liggend = String(layout.orientatie ?? "portrait") === "landscape";
@@ -1008,6 +1010,9 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
1008
1010
  }
1009
1011
  // Eigen traysticker (fs.eigen_traysticker): één sticker per tray.
1010
1012
  if (cfg.eigen_traysticker && typeof cfg.eigen_traysticker === "object") {
1013
+ // Testprint: voorbeeldgegevens (voorbeeldorder, fusten, een samenstelling).
1014
+ if (isTestprintJob(job) && !trayProducten(p))
1015
+ p = { ...VOORBEELD_TRAY_PAYLOAD, ...p };
1011
1016
  if (!trayProducten(p))
1012
1017
  throw new WachtOpLayoutFout(TRAYSTICKER_GEEN_INDELING);
1013
1018
  const inst = await bedrijfsInstelling(db).catch(() => null);
@@ -1617,7 +1622,7 @@ async function verwerkJob(db, job) {
1617
1622
  }
1618
1623
  const keuze = klaar ? { layout: null, ontwerpWint: false } : await zoekLayout(db, job);
1619
1624
  klok.markeer("layout_resolved");
1620
- const layout = keuze.layout;
1625
+ let layout = keuze.layout;
1621
1626
  // Klantsticker/traysticker: maat vaststellen (Floriday-formaat, anders de
1622
1627
  // PDF). Onbekend = niet printen. De maat kiest ook de printer via de
1623
1628
  // formaatregels, zodat een sticker op een etiket komt dat groot genoeg is.
@@ -1685,8 +1690,20 @@ async function verwerkJob(db, job) {
1685
1690
  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.`);
1686
1691
  return "mislukt";
1687
1692
  }
1693
+ // Eigen sticker/traysticker: variant op de maat van het geladen etiket,
1694
+ // opgebouwd uit dezelfde velden. Een eigen ontwerp wordt nooit geschaald
1695
+ // en de opgeslagen layout wordt niet gewijzigd (alleen deze opmaak).
1696
+ if (label?.etiket && layout && eigenEtiketVariantNodig(layout, label.etiket)) {
1697
+ const e = label.etiket;
1698
+ layout = { ...layout, breedte_mm: e.breedte_mm, hoogte_mm: e.hoogte_mm, orientatie: e.breedte_mm > e.hoogte_mm ? "landscape" : "portrait" };
1699
+ keuze.layout = layout;
1700
+ await log(db, job.id, "etiket", `Eigen ontwerp opgebouwd op de etiketmaat ${maatNl(e.breedte_mm, e.hoogte_mm)} (variant, niet geschaald).`);
1701
+ }
1688
1702
  const isTest = (job.payload ?? {})["is_testprint"] === true;
1689
- if (label && isTest && label.etiket) {
1703
+ // Testprint per uitwijkroute (1.69.12): de voorbeeldsticker houdt zijn
1704
+ // eigen maat, zodat de echte uitwijkroute zichtbaar wordt.
1705
+ const routeTest = (job.payload ?? {})["uitwijk_test"] === true;
1706
+ if (label && isTest && label.etiket && !routeTest) {
1690
1707
  // Een testprint gebruikt het formaat dat echt in de printer zit.
1691
1708
  const p = (job.payload ?? {});
1692
1709
  p["voorbeeld_formaat"] = {
@@ -1739,21 +1756,44 @@ async function verwerkJob(db, job) {
1739
1756
  const vfPapier = (job.payload ?? {})["voorbeeld_formaat"];
1740
1757
  const breedteMm = Number(layout?.breedte_mm ?? vfPapier?.["breedte_mm"] ?? standaardMaat(printer).breedte);
1741
1758
  const hoogteMm = Number(layout?.hoogte_mm ?? vfPapier?.["hoogte_mm"] ?? standaardMaat(printer).hoogte);
1759
+ let doelPrinter = printer;
1760
+ let uitwijk = null;
1761
+ const fitToPage = false;
1762
+ let kopieenNaarPrinter = Number(job.kopieen ?? 1);
1742
1763
  let papier = kiesPapier(formaten, breedteMm, hoogteMm);
1743
1764
  if (label) {
1744
1765
  const maat = stickerMaat ?? (klaar ? pdfPaginaMm(pdfBase64) : null) ?? { breedte_mm: breedteMm, hoogte_mm: hoogteMm };
1745
1766
  const uit = etiketPast({ ...maat, soortLabel: stickerCache?.sticker_type ? stickerTypeLabel(stickerCache.sticker_type) : documentTypeLabelVoor(String(job.documenttype ?? "Document")) }, label.etiket, label.naam, !!stickerMaat);
1746
- if (!uit.ok) {
1767
+ if (label.etiket && ETIKET_PDF_SOORTEN.has(String(job.documenttype ?? "")) && (uit.ok || uit.code === "FORMAAT_PAST_NIET")) {
1768
+ // 1.69.12: elke sticker via de uitwijkroute (vaste volgorde), papier
1769
+ // op afmeting gekozen; draaien/centreren/verkleinen in de PDF zelf.
1770
+ const keuzeUitwijk = await bepaalUitwijk(db, job, layout, !!floriday, !!klaar, maat, label, printer, formaten);
1771
+ if (!keuzeUitwijk) {
1772
+ await geweigerd(db, job, "FORMAAT_PAST_NIET", `${uit.ok ? "Geen passende papiermaat." : uit.bericht} Er is op deze printplek ook geen A4-printer om op uit te wijken.`);
1773
+ return "mislukt";
1774
+ }
1775
+ uitwijk = keuzeUitwijk.uitkomst;
1776
+ if (keuzeUitwijk.a4)
1777
+ doelPrinter = keuzeUitwijk.a4;
1778
+ const geplaatst = await voerUitwijkUit(pdfBase64, uitwijk, maat, Number(job.kopieen ?? 1));
1779
+ pdfBase64 = geplaatst.pdfBase64;
1780
+ kopieenNaarPrinter = geplaatst.kopieen;
1781
+ papier = { paper: uitwijk.paper || null, rotate: 0, uitleg: uitwijk.reden };
1782
+ await log(db, job.id, "uitwijk", `${uitwijk.reden} (${uitwijk.printerNaam}).`);
1783
+ }
1784
+ else if (!uit.ok) {
1747
1785
  await geweigerd(db, job, uit.code, uit.bericht);
1748
1786
  return "mislukt";
1749
1787
  }
1750
- papier = { paper: uit.paper, rotate: uit.rotate, uitleg: uit.uitleg };
1751
- await log(db, job.id, "etiket", `Labelprinter ${label.naam}: ${uit.uitleg}.`);
1788
+ else {
1789
+ papier = { paper: uit.paper, rotate: uit.rotate, uitleg: uit.uitleg };
1790
+ await log(db, job.id, "etiket", `Labelprinter ${label.naam}: ${uit.uitleg}.`);
1791
+ }
1752
1792
  }
1753
1793
  const verloopt = vervaltijdVoor(String(job.documenttype ?? ""));
1754
1794
  // Eén fysieke printer via meerdere computers: probeer de routes op
1755
1795
  // volgorde; valt de eerste weg, dan automatisch de volgende.
1756
- const routes = await printerRoutes(db, String(printer.id), String(printer.extern_printer_id));
1796
+ const routes = await printerRoutes(db, String(doelPrinter.id), String(doelPrinter.extern_printer_id));
1757
1797
  let externJobId = "";
1758
1798
  let laatsteFout = null;
1759
1799
  for (const [i, route] of routes.entries()) {
@@ -1764,9 +1804,9 @@ async function verwerkJob(db, job) {
1764
1804
  externPrinterId: route.extern,
1765
1805
  documentnaam: String(job.documentnaam ?? "Document"),
1766
1806
  pdfBase64,
1767
- kopieen: Number(job.kopieen ?? 1),
1807
+ kopieen: kopieenNaarPrinter,
1768
1808
  documenttype: String(job.documenttype ?? ""),
1769
- opties: { paper: papier.paper, rotate: papier.rotate, fitToPage: false },
1809
+ opties: { paper: papier.paper, rotate: papier.rotate, fitToPage },
1770
1810
  });
1771
1811
  if (i > 0) {
1772
1812
  await log(db, job.id, "route", `Verstuurd via computer ${route.computer ?? "andere route"}: de eerste computer was niet bereikbaar.`);
@@ -1791,7 +1831,7 @@ async function verwerkJob(db, job) {
1791
1831
  const { data: gekoppeldeJob } = await db
1792
1832
  .from("print_jobs")
1793
1833
  .update({
1794
- printer_id: printer.id,
1834
+ printer_id: doelPrinter.id,
1795
1835
  // layout_id blijft de aangeleverde invoer en wordt bewust niet
1796
1836
  // overschreven met de uitkomst.
1797
1837
  // Bij Floriday 1-op-1 wordt de Floriday-layout vastgelegd (alleen nieuwe opdrachten).
@@ -1819,7 +1859,9 @@ async function verwerkJob(db, job) {
1819
1859
  return "wachtend";
1820
1860
  }
1821
1861
  klok.markeer("submitted");
1822
- await log(db, job.id, "verstuurd", `Naar printer ${printer.naam ?? ""}. ${papier.uitleg} ${klok.samenvatting()}`);
1862
+ if (uitwijk)
1863
+ await legUitwijkVast(db, job, uitwijk);
1864
+ await log(db, job.id, "verstuurd", `Naar printer ${doelPrinter.naam ?? ""}. ${papier.uitleg} ${klok.samenvatting()}`);
1823
1865
  return "verstuurd";
1824
1866
  }
1825
1867
  catch (e) {
@@ -2172,6 +2214,109 @@ export async function bepaalDocumentKeuze(db, job) {
2172
2214
  * een werkplek hem als labelprinter gebruikt. Alleen dan geldt de controle,
2173
2215
  * zodat bestaande printers zonder werkplek precies blijven werken als nu.
2174
2216
  */
2217
+ /** Stickersoort voor de verkleininstelling (op configuratie en bron, nooit op naam). */
2218
+ export function stickerSoortVoor(documenttype, layout, floriday, klaar) {
2219
+ const cfg = (layout?.config ?? {});
2220
+ if (cfg.eigen_traysticker)
2221
+ return "eigen_traysticker";
2222
+ if (cfg.eigen_sticker)
2223
+ return "eigen_sticker";
2224
+ const tray = String(documenttype) === "traysticker";
2225
+ if (floriday || (klaar && tray))
2226
+ return tray ? "floriday_traysticker" : "floriday_sticker";
2227
+ return "klantsticker";
2228
+ }
2229
+ /** Eigen ontwerp past niet op het geladen etiket: variant op de etiketmaat maken. */
2230
+ export function eigenEtiketVariantNodig(layout, etiket) {
2231
+ const cfg = (layout?.config ?? {});
2232
+ if (!cfg.eigen_traysticker && !cfg.eigen_sticker)
2233
+ return false;
2234
+ // Eigen sticker met geüploade afbeelding heeft een vaste maat: die volgt de uitwijkroute.
2235
+ if (cfg.eigen_sticker && !cfg.eigen_traysticker)
2236
+ return false;
2237
+ const b = Number(layout.breedte_mm ?? 0);
2238
+ const h = Number(layout.hoogte_mm ?? 0);
2239
+ if (!(b > 0) || !(h > 0))
2240
+ return false;
2241
+ return !etiketPast({ breedte_mm: b, hoogte_mm: h, soortLabel: "Traysticker" }, etiket, "").ok;
2242
+ }
2243
+ /**
2244
+ * Verkleininstelling via de databasefunctie (één bron met de vroege
2245
+ * waarschuwing; maakt de standaard aan als hij ontbreekt). null = niet
2246
+ * leesbaar: dan vervalt alleen de stap verkleinen, nooit wachten.
2247
+ */
2248
+ async function leesStickerInstelling(db) {
2249
+ const { data, error } = await db.rpc("layouts_sticker_verkleinen");
2250
+ if (error)
2251
+ return null;
2252
+ return leesStickerInstellingenStrikt(data);
2253
+ }
2254
+ /** Uitwijkroute voor een sticker die niet op het geladen etiket past. */
2255
+ async function bepaalUitwijk(db, job, layout, floriday, klaar, maat, label, printer, formaten = null) {
2256
+ const instellingen = await leesStickerInstelling(db).catch(() => null);
2257
+ const soort = stickerSoortVoor(String(job.documenttype ?? ""), layout, floriday, klaar);
2258
+ const etiketten = label.etiket
2259
+ ? [{ printerNaam: label.naam, printerId: String(printer.id), paper: label.etiket.standaard ? "" : label.etiket.naam, breedte_mm: label.etiket.breedte_mm, hoogte_mm: label.etiket.hoogte_mm, dpi: printerDpi(printer), formaten: formaten ? formaten : undefined }]
2260
+ : [];
2261
+ const plekId = leesPrintPlekId(job) || (await zoekPrintPlekId(db, job).catch(() => null));
2262
+ let a4 = null;
2263
+ if (plekId) {
2264
+ const { data: a4Id } = await db.rpc("printplek_printer", { _plek: plekId, _documenttype: "pakbon" });
2265
+ if (typeof a4Id === "string" && a4Id !== String(printer.id)) {
2266
+ const { data } = await db
2267
+ .from("printers")
2268
+ .select("id, naam, weergavenaam, extern_printer_id, actief, papierformaat, ondersteunde_formaten, geladen_etiket")
2269
+ .eq("id", a4Id)
2270
+ .maybeSingle();
2271
+ a4 = data && data.actief !== false && data.extern_printer_id ? data : null;
2272
+ }
2273
+ }
2274
+ // Ensure bij gebruik (eerste print): oude losse instelling overnemen.
2275
+ await db.rpc("layouts_zorg_voor_a4_stickervel").then(() => undefined, () => undefined);
2276
+ const vel = plekId ? await leesA4Stickervel(db, String(plekId)) : null;
2277
+ const velIndeling = a4VelVoor(vel, maat);
2278
+ const uitkomst = kiesUitwijkroute({
2279
+ sticker: maat,
2280
+ etiketten,
2281
+ a4Printer: a4 ? { naam: String(a4.weergavenaam || a4.naam || "A4-printer"), id: String(a4.id) } : null,
2282
+ a4VelIngesteld: !!velIndeling,
2283
+ a4VelIndeling: velIndeling,
2284
+ instelling: instellingen ? instellingen[soort] : null,
2285
+ });
2286
+ if (!uitkomst)
2287
+ return null;
2288
+ const naarA4 = uitkomst.uitwijkroute === "a4_vel" || uitkomst.uitwijkroute === "a4_snijlijnen";
2289
+ return { uitkomst, a4: naarA4 ? a4 : null };
2290
+ }
2291
+ /** A4-stickervel van de printplek (print_plekken.a4_stickervel, 1.69.12). */
2292
+ async function leesA4Stickervel(db, plekId) {
2293
+ const { data } = await db.from("print_plekken").select("a4_stickervel").eq("id", plekId).maybeSingle();
2294
+ return leesA4StickervelWaarde(data?.a4_stickervel);
2295
+ }
2296
+ /** Resolutie uit de PrintNode-gegevens; onbekend = null (de uitwijk neemt 203 dpi). */
2297
+ function printerDpi(printer) {
2298
+ const f = (printer?.ondersteunde_formaten ?? {});
2299
+ const d = Number(f?.dpi ?? (Array.isArray(f?.dpis) ? String(f.dpis[0]).split("x")[0] : NaN));
2300
+ return d > 0 ? d : null;
2301
+ }
2302
+ /** Legt vast wat er met de sticker gebeurd is (veldnamen voor Pickschermen 1.0.61). */
2303
+ async function legUitwijkVast(db, job, u) {
2304
+ // Pickschermen 1.0.61 leest uitwijkroute/printerNaam/schaal/reden; de
2305
+ // overige velden zijn alleen voor het voorbeeld in de printwachtrij.
2306
+ const waarde = {
2307
+ ...uitwijkVoorPickschermen(u),
2308
+ rotate: u.rotate,
2309
+ pagina_breedte_mm: u.pagina_breedte_mm,
2310
+ pagina_hoogte_mm: u.pagina_hoogte_mm,
2311
+ sticker_breedte_mm: u.sticker_breedte_mm,
2312
+ sticker_hoogte_mm: u.sticker_hoogte_mm,
2313
+ };
2314
+ const { error } = await db.from("print_jobs").update({ uitwijk: waarde }).eq("id", job.id);
2315
+ if (error)
2316
+ await faseLog(db, job.id, "uitwijk_niet_vastgelegd", { ...waarde, fout: error.message });
2317
+ else
2318
+ await faseLog(db, job.id, "uitwijk", waarde);
2319
+ }
2175
2320
  async function labelControleVoorbereiden(db, printer) {
2176
2321
  const etiket = leesGeladenEtiket(printer?.geladen_etiket);
2177
2322
  const naam = String(printer?.weergavenaam || printer?.naam || "onbekend");
@@ -1 +1 @@
1
- {"version":3,"file":"printService.server.d.ts","sourceRoot":"","sources":["../../src/lib/printService.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"printService.server.d.ts","sourceRoot":"","sources":["../../src/lib/printService.server.ts"],"names":[],"mappings":"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"}
@@ -113,8 +113,9 @@ export async function haalPrinterFormaten(externPrinterId) {
113
113
  export async function stuurPdfNaarPrinter(input) {
114
114
  const o = input.opties ?? {};
115
115
  const options = {
116
- // Bewust uit: anders schaalt de printer een etiket stilzwijgend naar A4.
117
- fit_to_page: o.fitToPage === true,
116
+ // Altijd uit (1.69.12): de printer of driver mag nooit zelf schalen;
117
+ // verkleinen/centreren gebeurt in de PDF.
118
+ fit_to_page: false,
118
119
  };
119
120
  if (o.paper)
120
121
  options["paper"] = o.paper;
@@ -28,5 +28,11 @@ export declare function zorgVoorStandaardLayoutsMetStatus(db: Db): Promise<{
28
28
  * (met de knop "Overnemen uit factuurgegevens"). Raakt de database niet.
29
29
  */
30
30
  export declare function zorgVoorBedrijfsgegevens(_db: Db): Promise<boolean>;
31
+ /**
32
+ * Ensure: zet de verkleininstelling per stickersoort in app_settings als die
33
+ * nog ontbreekt (gegevens reizen niet mee met de schemasync). Vult alleen
34
+ * ontbrekende soorten aan; een bestaande keuze wordt nooit overschreven.
35
+ */
36
+ export declare function zorgVoorStickerInstellingen(db: Db): Promise<boolean>;
31
37
  export {};
32
38
  //# sourceMappingURL=standaardLayouts.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"standaardLayouts.server.d.ts","sourceRoot":"","sources":["../../src/lib/standaardLayouts.server.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAExC,eAAO,MAAM,wBAAwB,2MACqK,CAAC;AAE3M,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAKrH;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAmBrG;AAED,kDAAkD;AAClD,wBAAsB,8BAA8B,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAsB,iCAAiC,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAOrH;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE"}
1
+ {"version":3,"file":"standaardLayouts.server.d.ts","sourceRoot":"","sources":["../../src/lib/standaardLayouts.server.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAExC,eAAO,MAAM,wBAAwB,2MACqK,CAAC;AAE3M,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAKrH;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAmBrG;AAED,kDAAkD;AAClD,wBAAsB,8BAA8B,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAsB,iCAAiC,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAQrH;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAK1E"}
@@ -55,6 +55,7 @@ export async function zorgVoorStandaardLayoutsMetStatus(db) {
55
55
  const aanvulling = await vulStandaardenAan(db);
56
56
  if (aanvulling.schemaOntbreekt)
57
57
  return { aantal: 0, schemaOntbreekt: true };
58
+ await zorgVoorStickerInstellingen(db).catch(() => false);
58
59
  const { data, error: rpcFout } = await db.rpc("layout_zorg_systeemlayouts");
59
60
  if (rpcFout)
60
61
  throw new Error(`Standaardlayouts controleren mislukt: ${rpcFout.message}`);
@@ -70,3 +71,15 @@ export async function zorgVoorStandaardLayoutsMetStatus(db) {
70
71
  export async function zorgVoorBedrijfsgegevens(_db) {
71
72
  return false;
72
73
  }
74
+ /**
75
+ * Ensure: zet de verkleininstelling per stickersoort in app_settings als die
76
+ * nog ontbreekt (gegevens reizen niet mee met de schemasync). Vult alleen
77
+ * ontbrekende soorten aan; een bestaande keuze wordt nooit overschreven.
78
+ */
79
+ export async function zorgVoorStickerInstellingen(db) {
80
+ // 1.69.12: de standaardwaarden staan alleen in de databasefunctie.
81
+ const { error } = await db.rpc("layouts_zorg_voor_sticker_verkleinen");
82
+ if (error)
83
+ throw new Error(`Stickerinstellingen aanvullen mislukt: ${error.message}`);
84
+ return true;
85
+ }
@@ -0,0 +1,37 @@
1
+ import type { UitwijkUitkomst } from "./stickerUitwijk.js";
2
+ import { type Velindeling as VelIndeling } from "./stickerUitwijk.js";
3
+ /** Rand rond het A4-vel met snijlijnen. */
4
+ export declare const SNIJ_MARGE_MM = 5;
5
+ export interface Plaatsing {
6
+ /** Linksonder van het vak (mm, PDF-assen). */
7
+ x_mm: number;
8
+ y_mm: number;
9
+ b_mm: number;
10
+ h_mm: number;
11
+ }
12
+ /** Positie van een sticker gecentreerd op een pagina, in mm (links, onder). */
13
+ export declare function centreer(paginaB: number, paginaH: number, stickerB: number, stickerH: number, schaal: number, rotate: 0 | 90): Plaatsing;
14
+ /** Vakken op een A4 voor deze maat: vaste velindeling, of zoveel als passen met snijlijnen. */
15
+ export declare function velVakken(stickerB: number, stickerH: number, vel: VelIndeling | null): {
16
+ vakken: Plaatsing[];
17
+ snijlijnen: boolean;
18
+ };
19
+ /**
20
+ * Voert de uitwijkroute uit. Etiketroutes: elke pagina wordt een etiketpagina
21
+ * (gedraaid/gecentreerd/verkleind). A4-routes: alle pagina's × kopieën worden
22
+ * 1-op-1 over één of meer vellen verdeeld; de opdracht gaat dan met qty 1.
23
+ */
24
+ export declare function voerUitwijkUit(pdfBase64: string, u: UitwijkUitkomst, sticker: {
25
+ breedte_mm: number;
26
+ hoogte_mm: number;
27
+ }, kopieen: number): Promise<{
28
+ pdfBase64: string;
29
+ kopieen: number;
30
+ paginas: number;
31
+ }>;
32
+ /**
33
+ * Testvel op gewoon A4 (1.69.12): de vakken van de velindeling met rand,
34
+ * 1-op-1, zodat de beheerder het echte stickervel ertegen kan houden.
35
+ */
36
+ export declare function testvelPdf(vel: VelIndeling): Promise<string>;
37
+ //# sourceMappingURL=stickerPlaatsing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stickerPlaatsing.d.ts","sourceRoot":"","sources":["../../src/lib/stickerPlaatsing.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAmB,KAAK,WAAW,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpF,2CAA2C;AAC3C,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,CAIxI;AAED,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,GAAG;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAgBnI;AAeD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,eAAe,EAClB,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAClD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAmClE;AAcD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CASlE"}
@@ -0,0 +1,122 @@
1
+ // ============================================================================
2
+ // src/lib/stickerPlaatsing.ts — de uitwijkroute zelf in de PDF uitvoeren
3
+ // (1.69.12). De printer krijgt altijd een pagina van precies het geladen
4
+ // etiket (of A4), fit_to_page uit en rotate 0: draaien, centreren en
5
+ // eventueel verkleinen gebeurt hier, nooit in de printer of driver.
6
+ // ============================================================================
7
+ import { PDFDocument, degrees, rgb } from "pdf-lib";
8
+ import { velindelingVoor } from "./stickerUitwijk.js";
9
+ const PT = 72 / 25.4;
10
+ const A4 = { b: 210, h: 297 };
11
+ /** Rand rond het A4-vel met snijlijnen. */
12
+ export const SNIJ_MARGE_MM = 5;
13
+ /** Positie van een sticker gecentreerd op een pagina, in mm (links, onder). */
14
+ export function centreer(paginaB, paginaH, stickerB, stickerH, schaal, rotate) {
15
+ const b = (rotate ? stickerH : stickerB) * schaal;
16
+ const h = (rotate ? stickerB : stickerH) * schaal;
17
+ return { x_mm: (paginaB - b) / 2, y_mm: (paginaH - h) / 2, b_mm: b, h_mm: h };
18
+ }
19
+ /** Vakken op een A4 voor deze maat: vaste velindeling, of zoveel als passen met snijlijnen. */
20
+ export function velVakken(stickerB, stickerH, vel) {
21
+ const kol = vel ? vel.kolommen : Math.max(1, Math.floor((A4.b - 2 * SNIJ_MARGE_MM + 1e-9) / stickerB));
22
+ const rij = vel ? vel.rijen : Math.max(1, Math.floor((A4.h - 2 * SNIJ_MARGE_MM + 1e-9) / stickerH));
23
+ const cb = vel ? vel.breedte_mm : stickerB;
24
+ const ch = vel ? vel.hoogte_mm : stickerH;
25
+ // Eigen vel: vaste randen en tussenruimtes vanaf linksboven. Anders gecentreerd.
26
+ const eigen = vel?.marge_links_mm !== undefined || vel?.marge_boven_mm !== undefined;
27
+ const th = eigen ? vel?.tussen_h_mm ?? 0 : 0;
28
+ const tv = eigen ? vel?.tussen_v_mm ?? 0 : 0;
29
+ const x0 = eigen ? vel?.marge_links_mm ?? 0 : (A4.b - kol * cb) / 2;
30
+ const yTop = eigen ? A4.h - (vel?.marge_boven_mm ?? 0) : A4.h - (A4.h - rij * ch) / 2;
31
+ const vakken = [];
32
+ for (let r = 0; r < rij; r++) {
33
+ for (let k = 0; k < kol; k++)
34
+ vakken.push({ x_mm: x0 + k * (cb + th), y_mm: yTop - (r + 1) * ch - r * tv, b_mm: cb, h_mm: ch });
35
+ }
36
+ return { vakken, snijlijnen: !vel };
37
+ }
38
+ function decodeer(b64) {
39
+ if (typeof atob === "function")
40
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ return new Uint8Array(globalThis.Buffer.from(b64, "base64"));
43
+ }
44
+ function codeer(bytes) {
45
+ let s = "";
46
+ for (let i = 0; i < bytes.length; i += 0x8000)
47
+ s += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
48
+ if (typeof btoa === "function")
49
+ return btoa(s);
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ return globalThis.Buffer.from(bytes).toString("base64");
52
+ }
53
+ /**
54
+ * Voert de uitwijkroute uit. Etiketroutes: elke pagina wordt een etiketpagina
55
+ * (gedraaid/gecentreerd/verkleind). A4-routes: alle pagina's × kopieën worden
56
+ * 1-op-1 over één of meer vellen verdeeld; de opdracht gaat dan met qty 1.
57
+ */
58
+ export async function voerUitwijkUit(pdfBase64, u, sticker, kopieen) {
59
+ const bron = await PDFDocument.load(decodeer(pdfBase64));
60
+ const doel = await PDFDocument.create();
61
+ const ingebed = await doel.embedPages(bron.getPages());
62
+ if (u.uitwijkroute === "a4_vel" || u.uitwijkroute === "a4_snijlijnen") {
63
+ const vel = u.uitwijkroute === "a4_vel" ? (u.velindeling ?? velindelingVoor(sticker.breedte_mm, sticker.hoogte_mm)) : null;
64
+ const { vakken, snijlijnen } = velVakken(sticker.breedte_mm, sticker.hoogte_mm, vel);
65
+ const reeks = Array.from({ length: Math.max(1, kopieen) }).flatMap(() => ingebed);
66
+ let pagina = null;
67
+ reeks.forEach((p, i) => {
68
+ const vak = vakken[i % vakken.length];
69
+ if (i % vakken.length === 0) {
70
+ pagina = doel.addPage([A4.b * PT, A4.h * PT]);
71
+ if (snijlijnen)
72
+ tekenSnijlijnen(pagina, vakken);
73
+ }
74
+ const pl = centreer(vak.b_mm, vak.h_mm, sticker.breedte_mm, sticker.hoogte_mm, 1, 0);
75
+ pagina.drawPage(p, { x: (vak.x_mm + pl.x_mm) * PT, y: (vak.y_mm + pl.y_mm) * PT, width: sticker.breedte_mm * PT, height: sticker.hoogte_mm * PT });
76
+ });
77
+ return { pdfBase64: codeer(await doel.save()), kopieen: 1, paginas: doel.getPageCount() };
78
+ }
79
+ for (const p of ingebed) {
80
+ const pagina = doel.addPage([u.pagina_breedte_mm * PT, u.pagina_hoogte_mm * PT]);
81
+ const pl = centreer(u.pagina_breedte_mm, u.pagina_hoogte_mm, sticker.breedte_mm, sticker.hoogte_mm, u.schaal, u.rotate);
82
+ const w = sticker.breedte_mm * u.schaal * PT;
83
+ const h = sticker.hoogte_mm * u.schaal * PT;
84
+ if (u.rotate === 90) {
85
+ // Gedraaid om linksonder: vak loopt van x-h tot x en van y tot y+w.
86
+ pagina.drawPage(p, { x: (pl.x_mm + pl.b_mm) * PT, y: pl.y_mm * PT, width: w, height: h, rotate: degrees(90) });
87
+ }
88
+ else {
89
+ pagina.drawPage(p, { x: pl.x_mm * PT, y: pl.y_mm * PT, width: w, height: h });
90
+ }
91
+ }
92
+ return { pdfBase64: codeer(await doel.save()), kopieen, paginas: doel.getPageCount() };
93
+ }
94
+ function tekenSnijlijnen(pagina, vakken) {
95
+ const kleur = rgb(0.6, 0.6, 0.6);
96
+ const xs = new Set();
97
+ const ys = new Set();
98
+ for (const v of vakken) {
99
+ xs.add(v.x_mm);
100
+ xs.add(v.x_mm + v.b_mm);
101
+ ys.add(v.y_mm);
102
+ ys.add(v.y_mm + v.h_mm);
103
+ }
104
+ for (const x of xs)
105
+ pagina.drawLine({ start: { x: x * PT, y: 0 }, end: { x: x * PT, y: A4.h * PT }, thickness: 0.3, color: kleur, dashArray: [3, 3] });
106
+ for (const y of ys)
107
+ pagina.drawLine({ start: { x: 0, y: y * PT }, end: { x: A4.b * PT, y: y * PT }, thickness: 0.3, color: kleur, dashArray: [3, 3] });
108
+ }
109
+ /**
110
+ * Testvel op gewoon A4 (1.69.12): de vakken van de velindeling met rand,
111
+ * 1-op-1, zodat de beheerder het echte stickervel ertegen kan houden.
112
+ */
113
+ export async function testvelPdf(vel) {
114
+ const doel = await PDFDocument.create();
115
+ const pagina = doel.addPage([A4.b * PT, A4.h * PT]);
116
+ const { vakken } = velVakken(vel.breedte_mm, vel.hoogte_mm, vel);
117
+ for (const v of vakken) {
118
+ pagina.drawRectangle({ x: v.x_mm * PT, y: v.y_mm * PT, width: v.b_mm * PT, height: v.h_mm * PT, borderColor: rgb(0, 0, 0), borderWidth: 0.5 });
119
+ }
120
+ pagina.drawText(`Testvel ${Math.round(vel.breedte_mm)}x${Math.round(vel.hoogte_mm)} mm, ${vel.kolommen}x${vel.rijen} per vel - houd het stickervel ertegen`, { x: 5 * PT, y: 2 * PT, size: 7 });
121
+ return codeer(await doel.save());
122
+ }