@flowselections/layout-maker 1.69.10 → 1.69.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/A4StickervelKaart.d.ts +5 -0
- package/dist-lib/components/A4StickervelKaart.d.ts.map +1 -0
- package/dist-lib/components/A4StickervelKaart.js +123 -0
- package/dist-lib/components/KlaarOmTePrintenBlok.d.ts.map +1 -1
- package/dist-lib/components/KlaarOmTePrintenBlok.js +50 -7
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +4 -6
- package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekDetailPage.js +3 -1
- package/dist-lib/components/PrintplekkenPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekkenPage.js +2 -1
- package/dist-lib/components/StickerRouteTestKaart.d.ts +5 -0
- package/dist-lib/components/StickerRouteTestKaart.d.ts.map +1 -0
- package/dist-lib/components/StickerRouteTestKaart.js +75 -0
- package/dist-lib/components/UitwijkRegel.d.ts +5 -0
- package/dist-lib/components/UitwijkRegel.d.ts.map +1 -0
- package/dist-lib/components/UitwijkRegel.js +17 -0
- package/dist-lib/components/UitwijkTekening.d.ts +19 -0
- package/dist-lib/components/UitwijkTekening.d.ts.map +1 -0
- package/dist-lib/components/UitwijkTekening.js +21 -0
- package/dist-lib/index.d.ts +12 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +14 -0
- package/dist-lib/integrations/supabase/types.d.ts +3714 -25
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +1 -0
- package/dist-lib/lib/belading.d.ts +10 -0
- package/dist-lib/lib/belading.d.ts.map +1 -0
- package/dist-lib/lib/belading.js +49 -0
- package/dist-lib/lib/codelijstCache.d.ts +11 -0
- package/dist-lib/lib/codelijstCache.d.ts.map +1 -0
- package/dist-lib/lib/codelijstCache.js +117 -0
- package/dist-lib/lib/documentTypes.d.ts +1 -1
- package/dist-lib/lib/documentTypes.d.ts.map +1 -1
- package/dist-lib/lib/documentTypes.js +2 -1
- package/dist-lib/lib/eigenDocumenten.d.ts +2 -0
- package/dist-lib/lib/eigenDocumenten.d.ts.map +1 -1
- package/dist-lib/lib/eigenDocumenten.js +22 -0
- package/dist-lib/lib/installCheck.d.ts +36 -0
- package/dist-lib/lib/installCheck.d.ts.map +1 -0
- package/dist-lib/lib/installCheck.js +65 -0
- package/dist-lib/lib/kiesFormaat.d.ts +11 -0
- package/dist-lib/lib/kiesFormaat.d.ts.map +1 -0
- package/dist-lib/lib/kiesFormaat.js +32 -0
- package/dist-lib/lib/klaarOmTePrinten.d.ts +15 -1
- package/dist-lib/lib/klaarOmTePrinten.d.ts.map +1 -1
- package/dist-lib/lib/klaarOmTePrinten.js +19 -1
- package/dist-lib/lib/orderData.server.d.ts.map +1 -1
- package/dist-lib/lib/orderData.server.js +25 -31
- package/dist-lib/lib/pakbonBuilder.d.ts +6 -0
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +18 -5
- package/dist-lib/lib/pakbonContent.d.ts.map +1 -1
- package/dist-lib/lib/pakbonContent.js +4 -1
- package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
- package/dist-lib/lib/pakbonHtml.js +5 -2
- package/dist-lib/lib/pakbonPresentation.d.ts +3 -1
- package/dist-lib/lib/pakbonPresentation.d.ts.map +1 -1
- package/dist-lib/lib/pakbonPresentation.js +13 -6
- package/dist-lib/lib/printQueue.server.d.ts +16 -2
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/printQueue.server.js +305 -59
- package/dist-lib/lib/printService.server.d.ts.map +1 -1
- package/dist-lib/lib/printService.server.js +3 -2
- package/dist-lib/lib/printerKeuze.d.ts +15 -0
- package/dist-lib/lib/printerKeuze.d.ts.map +1 -0
- package/dist-lib/lib/printerKeuze.js +32 -0
- package/dist-lib/lib/queueTick.d.ts.map +1 -1
- package/dist-lib/lib/queueTick.js +9 -1
- package/dist-lib/lib/runnerRegistry.server.d.ts +10 -0
- package/dist-lib/lib/runnerRegistry.server.d.ts.map +1 -1
- package/dist-lib/lib/runnerRegistry.server.js +55 -0
- package/dist-lib/lib/standaardLayouts.server.d.ts +6 -0
- package/dist-lib/lib/standaardLayouts.server.d.ts.map +1 -1
- package/dist-lib/lib/standaardLayouts.server.js +13 -0
- package/dist-lib/lib/stickerPlaatsing.d.ts +37 -0
- package/dist-lib/lib/stickerPlaatsing.d.ts.map +1 -0
- package/dist-lib/lib/stickerPlaatsing.js +122 -0
- package/dist-lib/lib/stickerUitwijk.d.ts +197 -0
- package/dist-lib/lib/stickerUitwijk.d.ts.map +1 -0
- package/dist-lib/lib/stickerUitwijk.js +311 -0
- package/dist-lib/lib/testprint.d.ts +13 -0
- package/dist-lib/lib/testprint.d.ts.map +1 -1
- package/dist-lib/lib/testprint.js +38 -0
- package/dist-lib/lib/useDocumentData.js +1 -1
- package/dist-lib/lib/versie.generated.d.ts +1 -1
- package/dist-lib/lib/versie.generated.js +1 -1
- package/dist-lib/lib/vroegeWaarschuwing.d.ts +21 -0
- package/dist-lib/lib/vroegeWaarschuwing.d.ts.map +1 -0
- package/dist-lib/lib/vroegeWaarschuwing.js +15 -0
- package/package.json +1 -1
- package/sql/print-schema.sql +1 -0
|
@@ -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,15 @@ 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";
|
|
19
|
+
import { neemCodelijstMeldingen, startCodelijstRonde, stopCodelijstRonde } from "./codelijstCache.js";
|
|
20
|
+
import { kiesFormaat, testprintHoudtFormaat } from "./kiesFormaat.js";
|
|
18
21
|
import { OPMAAK_LIMIET_MS, OpmaakTeLangFout, metTijdslimiet } from "./opmaakLimiet.js";
|
|
19
22
|
import { stuurPdfNaarPrinter, opdrachtStatusDetail, vervaltijdVoor } from "./printService.server.js";
|
|
20
23
|
import { kiesPapier } from "./papierFormaten.js";
|
|
21
24
|
import { waaromDezePrinter } from "./waaromPrinter.js";
|
|
22
|
-
import { etiketPast, leesGeladenEtiket, pdfPaginaMm } from "./etiketControle.js";
|
|
25
|
+
import { etiketPast, leesGeladenEtiket, maatNl, pdfPaginaMm } from "./etiketControle.js";
|
|
26
|
+
import { a4VelVoor, kiesUitwijkroute, leesA4StickervelWaarde, leesStickerInstellingenStrikt, uitwijkVoorPickschermen } from "./stickerUitwijk.js";
|
|
23
27
|
import { documentTypeLabel as documentTypeLabelVoor } from "./documentTypes.js";
|
|
24
28
|
import { PAPIERFORMATEN } from "./documentTypes.js";
|
|
25
29
|
const MAX_POGINGEN = 3;
|
|
@@ -46,7 +50,10 @@ export async function controleerClient(db) {
|
|
|
46
50
|
/** Fase met tijd en details in het logboek, zodat een vastloper nooit stil is. */
|
|
47
51
|
async function faseLog(db, jobId, fase, detail) {
|
|
48
52
|
try {
|
|
49
|
-
|
|
53
|
+
const op = new Date().toISOString();
|
|
54
|
+
await log(db, String(jobId), "fase", JSON.stringify({ fase, op, ...detail }));
|
|
55
|
+
// Vrijgave per fase (layouts_vrijgeven_vastgelopen) meet vanaf de laatste fase.
|
|
56
|
+
await db.from("print_jobs").update({ fase_gestart_op: op }).eq("id", String(jobId)).eq("status", "bezig");
|
|
50
57
|
}
|
|
51
58
|
catch {
|
|
52
59
|
/* loggen mag het printen nooit blokkeren */
|
|
@@ -269,7 +276,7 @@ function isEngineOpdracht(job) {
|
|
|
269
276
|
return bron.includes("logistic") || bron.includes("engine");
|
|
270
277
|
}
|
|
271
278
|
/** Stickers: altijd kant-en-klare PDF op een labelprinter. */
|
|
272
|
-
const ETIKET_PDF_SOORTEN = new Set(["sticker", "traysticker"]);
|
|
279
|
+
const ETIKET_PDF_SOORTEN = new Set(["sticker", "traysticker", "eigen_sticker"]);
|
|
273
280
|
/** Testprint: alleen de eigen testvlag telt (geen kar, geen barcode). */
|
|
274
281
|
export function isTestprintJob(job) {
|
|
275
282
|
const p = (job.payload ?? {});
|
|
@@ -458,7 +465,21 @@ async function zoekLayout(db, job) {
|
|
|
458
465
|
.order("is_standaard", { ascending: false })
|
|
459
466
|
.order("updated_at", { ascending: false })
|
|
460
467
|
.limit(1);
|
|
461
|
-
|
|
468
|
+
let gevonden = (arr(data)[0] ?? null);
|
|
469
|
+
if (!gevonden && documenttype === "eigen_sticker") {
|
|
470
|
+
// Engine 1.0.194: soort eigen_sticker. Bestaande eigen-stickerlayout
|
|
471
|
+
// (soort sticker + fs.eigen_sticker) blijft werken; niets gekopieerd.
|
|
472
|
+
const { data: oud } = await db
|
|
473
|
+
.from("document_layouts")
|
|
474
|
+
.select("*")
|
|
475
|
+
.eq("documenttype", "sticker")
|
|
476
|
+
.eq("actief", true)
|
|
477
|
+
.not("config->eigen_sticker", "is", null)
|
|
478
|
+
.order("is_standaard", { ascending: false })
|
|
479
|
+
.order("updated_at", { ascending: false })
|
|
480
|
+
.limit(1);
|
|
481
|
+
gevonden = (arr(oud)[0] ?? null);
|
|
482
|
+
}
|
|
462
483
|
if (!gevonden && !job.render_html) {
|
|
463
484
|
throw new GeenDocumentFout(`Geen layout gevonden voor documenttype '${documenttype}'. ` +
|
|
464
485
|
"Maak een layout aan en zet die op actief.");
|
|
@@ -756,7 +777,14 @@ async function zoekPrinter(db, job, layout) {
|
|
|
756
777
|
// Alleen een printer die nog echt aan de plek gekoppeld én actief is telt.
|
|
757
778
|
const plekPrinter = async (plek) => {
|
|
758
779
|
const { data } = await db.rpc("printplek_printer", { _plek: plek, _documenttype: type });
|
|
759
|
-
|
|
780
|
+
if (typeof data === "string")
|
|
781
|
+
return data;
|
|
782
|
+
// Eigen sticker: dezelfde printerkeuze als de traysticker.
|
|
783
|
+
if (type === "eigen_sticker") {
|
|
784
|
+
const { data: tray } = await db.rpc("printplek_printer", { _plek: plek, _documenttype: "traysticker" });
|
|
785
|
+
return typeof tray === "string" ? tray : null;
|
|
786
|
+
}
|
|
787
|
+
return null;
|
|
760
788
|
};
|
|
761
789
|
if (explicietePlek) {
|
|
762
790
|
printer = await pak(await plekPrinter(explicietePlek));
|
|
@@ -786,11 +814,24 @@ async function zoekPrinter(db, job, layout) {
|
|
|
786
814
|
_papierformaat: layout?.papierformaat ?? null,
|
|
787
815
|
...(leesWerkplekId(job) ? { _werkplek_id: leesWerkplekId(job) } : {}),
|
|
788
816
|
});
|
|
789
|
-
|
|
817
|
+
let routeRij = route;
|
|
818
|
+
if (!routeRij?.printer_id && type === "eigen_sticker") {
|
|
819
|
+
// Eigen sticker: dezelfde printerkeuze als de traysticker.
|
|
820
|
+
const { data: tray } = await db.rpc("printer_routering", {
|
|
821
|
+
_documenttype: "traysticker",
|
|
822
|
+
_print_plek_id: plekId || null,
|
|
823
|
+
_werkplek: werkplek || null,
|
|
824
|
+
_layout_id: layout?.id ?? null,
|
|
825
|
+
_papierformaat: layout?.papierformaat ?? null,
|
|
826
|
+
...(leesWerkplekId(job) ? { _werkplek_id: leesWerkplekId(job) } : {}),
|
|
827
|
+
});
|
|
828
|
+
routeRij = tray;
|
|
829
|
+
}
|
|
830
|
+
printer = await pak(routeRij?.printer_id);
|
|
790
831
|
if (printer) {
|
|
791
832
|
try {
|
|
792
833
|
const plekNaam = plekId ? await printplekNaamVoorJob(db, job) : null;
|
|
793
|
-
const r = (
|
|
834
|
+
const r = (routeRij ?? {});
|
|
794
835
|
await log(db, job.id, "waarom", waaromDezePrinter({ bron: r.bron, papierformaat: r.papierformaat ?? null, werkplek_naam: r.werkplek_naam, printer_rol: r.printer_rol, werkplek: r.werkplek }, String(printer.weergavenaam || printer.naam || "Printer"), plekNaam));
|
|
795
836
|
}
|
|
796
837
|
catch { /* uitleg is informatief */ }
|
|
@@ -986,7 +1027,7 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
|
|
|
986
1027
|
noteer("render_html");
|
|
987
1028
|
return meegestuurd;
|
|
988
1029
|
}
|
|
989
|
-
|
|
1030
|
+
let p = (job.payload ?? {});
|
|
990
1031
|
// Vervoerder: alleen carrier_label uit de Engine. Ontbreekt hij → wachten.
|
|
991
1032
|
const carrierLabel = await bepaalVervoerder(db, job, p, layout);
|
|
992
1033
|
const liggend = String(layout.orientatie ?? "portrait") === "landscape";
|
|
@@ -1008,6 +1049,9 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
|
|
|
1008
1049
|
}
|
|
1009
1050
|
// Eigen traysticker (fs.eigen_traysticker): één sticker per tray.
|
|
1010
1051
|
if (cfg.eigen_traysticker && typeof cfg.eigen_traysticker === "object") {
|
|
1052
|
+
// Testprint: voorbeeldgegevens (voorbeeldorder, fusten, een samenstelling).
|
|
1053
|
+
if (isTestprintJob(job) && !trayProducten(p))
|
|
1054
|
+
p = { ...VOORBEELD_TRAY_PAYLOAD, ...p };
|
|
1011
1055
|
if (!trayProducten(p))
|
|
1012
1056
|
throw new WachtOpLayoutFout(TRAYSTICKER_GEEN_INDELING);
|
|
1013
1057
|
const inst = await bedrijfsInstelling(db).catch(() => null);
|
|
@@ -1053,6 +1097,7 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
|
|
|
1053
1097
|
? ((await laadPakbonData(db, { scope: "cart", id: cartId })) ??
|
|
1054
1098
|
(await laadOrderVanuitDatabase(db, p)))
|
|
1055
1099
|
: await laadOrderVanuitDatabase(db, p);
|
|
1100
|
+
await faseLog(db, job.id, "gegevens_geladen", { uit_database: !!uitDb });
|
|
1056
1101
|
const bron = uitDb ??
|
|
1057
1102
|
(p.voorbeeld === true && !heeftOrderInhoud(orderBron)
|
|
1058
1103
|
? voorbeeldPakbonOrder()
|
|
@@ -1123,6 +1168,7 @@ export async function bouwHtml(db, job, keuze, uitkomst) {
|
|
|
1123
1168
|
? ((await laadPakbonData(db, { scope: "cart", id: engineCartId })) ??
|
|
1124
1169
|
(await laadOrderVanuitDatabase(db, p)))
|
|
1125
1170
|
: await laadOrderVanuitDatabase(db, p);
|
|
1171
|
+
await faseLog(db, job.id, "gegevens_geladen", { uit_database: !!uitDb });
|
|
1126
1172
|
// Een voorbeeldafdruk zonder ordergegevens krijgt een voorbeeldorder, zodat
|
|
1127
1173
|
// je ziet hoe het document er in de praktijk uitziet.
|
|
1128
1174
|
const bron = uitDb ??
|
|
@@ -1617,7 +1663,7 @@ async function verwerkJob(db, job) {
|
|
|
1617
1663
|
}
|
|
1618
1664
|
const keuze = klaar ? { layout: null, ontwerpWint: false } : await zoekLayout(db, job);
|
|
1619
1665
|
klok.markeer("layout_resolved");
|
|
1620
|
-
|
|
1666
|
+
let layout = keuze.layout;
|
|
1621
1667
|
// Klantsticker/traysticker: maat vaststellen (Floriday-formaat, anders de
|
|
1622
1668
|
// PDF). Onbekend = niet printen. De maat kiest ook de printer via de
|
|
1623
1669
|
// formaatregels, zodat een sticker op een etiket komt dat groot genoeg is.
|
|
@@ -1685,8 +1731,20 @@ async function verwerkJob(db, job) {
|
|
|
1685
1731
|
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
1732
|
return "mislukt";
|
|
1687
1733
|
}
|
|
1734
|
+
// Eigen sticker/traysticker: variant op de maat van het geladen etiket,
|
|
1735
|
+
// opgebouwd uit dezelfde velden. Een eigen ontwerp wordt nooit geschaald
|
|
1736
|
+
// en de opgeslagen layout wordt niet gewijzigd (alleen deze opmaak).
|
|
1737
|
+
if (label?.etiket && layout && eigenEtiketVariantNodig(layout, label.etiket)) {
|
|
1738
|
+
const e = label.etiket;
|
|
1739
|
+
layout = { ...layout, breedte_mm: e.breedte_mm, hoogte_mm: e.hoogte_mm, orientatie: e.breedte_mm > e.hoogte_mm ? "landscape" : "portrait" };
|
|
1740
|
+
keuze.layout = layout;
|
|
1741
|
+
await log(db, job.id, "etiket", `Eigen ontwerp opgebouwd op de etiketmaat ${maatNl(e.breedte_mm, e.hoogte_mm)} (variant, niet geschaald).`);
|
|
1742
|
+
}
|
|
1688
1743
|
const isTest = (job.payload ?? {})["is_testprint"] === true;
|
|
1689
|
-
|
|
1744
|
+
// Testprint per uitwijkroute (1.69.12): de voorbeeldsticker houdt zijn
|
|
1745
|
+
// eigen maat, zodat de echte uitwijkroute zichtbaar wordt.
|
|
1746
|
+
const routeTest = (job.payload ?? {})["uitwijk_test"] === true;
|
|
1747
|
+
if (label && isTest && label.etiket && !routeTest) {
|
|
1690
1748
|
// Een testprint gebruikt het formaat dat echt in de printer zit.
|
|
1691
1749
|
const p = (job.payload ?? {});
|
|
1692
1750
|
p["voorbeeld_formaat"] = {
|
|
@@ -1705,7 +1763,10 @@ async function verwerkJob(db, job) {
|
|
|
1705
1763
|
const opmaakStart = Date.now();
|
|
1706
1764
|
await faseLog(db, job.id, "opmaken_gestart", { layout_id: layout?.id ?? null });
|
|
1707
1765
|
pdfBase64 = await metTijdslimiet(OPMAAK_LIMIET_MS, async () => {
|
|
1766
|
+
await faseLog(db, job.id, "gegevens_laden_gestart", {});
|
|
1708
1767
|
const html = await bouwHtml(db, job, keuze, uitkomst);
|
|
1768
|
+
for (const m of neemCodelijstMeldingen())
|
|
1769
|
+
await faseLog(db, job.id, String(m["fase"] ?? "codelijst"), m);
|
|
1709
1770
|
await faseLog(db, job.id, "html_klaar", { ms: Date.now() - opmaakStart, tekens: html.length });
|
|
1710
1771
|
if (!heeftZichtbareInhoud(html)) {
|
|
1711
1772
|
throw new GeenDocumentFout("Het document was leeg: er zijn geen gegevens gevonden om af te drukken. " +
|
|
@@ -1715,12 +1776,12 @@ async function verwerkJob(db, job) {
|
|
|
1715
1776
|
// ontwerp is leidend), maar geeft wél het papierformaat van de bewerkte
|
|
1716
1777
|
// layout mee. Zonder dit zou het voorbeeld altijd op A4 uitkomen.
|
|
1717
1778
|
const vf = (job.payload ?? {})["voorbeeld_formaat"];
|
|
1718
|
-
const liggend = String(layout
|
|
1779
|
+
const liggend = String(kiesFormaat(job, layout).orientatie ?? "portrait") === "landscape";
|
|
1719
1780
|
const pdf = await htmlNaarPdfServer({
|
|
1720
1781
|
html,
|
|
1721
|
-
breedteMm:
|
|
1722
|
-
hoogteMm:
|
|
1723
|
-
margeMm: Number(layout?.marge_boven ?? vf?.["marge_boven"] ?? 10),
|
|
1782
|
+
breedteMm: kiesFormaat(job, layout).breedte_mm ?? 210,
|
|
1783
|
+
hoogteMm: kiesFormaat(job, layout).hoogte_mm ?? 297,
|
|
1784
|
+
margeMm: Number(testprintHoudtFormaat(job) ? (vf?.["marge_boven"] ?? 10) : (layout?.marge_boven ?? vf?.["marge_boven"] ?? 10)),
|
|
1724
1785
|
landschap: liggend,
|
|
1725
1786
|
bijOvergeslagen: (src, reden) => {
|
|
1726
1787
|
void faseLog(db, job.id, "afbeelding_weggelaten", { bron: src.split("?")[0]?.slice(0, 200), reden });
|
|
@@ -1737,23 +1798,47 @@ async function verwerkJob(db, job) {
|
|
|
1737
1798
|
}
|
|
1738
1799
|
const formaten = await zorgVoorFormaten(db, printer);
|
|
1739
1800
|
const vfPapier = (job.payload ?? {})["voorbeeld_formaat"];
|
|
1740
|
-
|
|
1741
|
-
const
|
|
1801
|
+
void vfPapier;
|
|
1802
|
+
const breedteMm = kiesFormaat(job, layout).breedte_mm ?? standaardMaat(printer).breedte;
|
|
1803
|
+
const hoogteMm = kiesFormaat(job, layout).hoogte_mm ?? standaardMaat(printer).hoogte;
|
|
1804
|
+
let doelPrinter = printer;
|
|
1805
|
+
let uitwijk = null;
|
|
1806
|
+
const fitToPage = false;
|
|
1807
|
+
let kopieenNaarPrinter = Number(job.kopieen ?? 1);
|
|
1742
1808
|
let papier = kiesPapier(formaten, breedteMm, hoogteMm);
|
|
1743
1809
|
if (label) {
|
|
1744
1810
|
const maat = stickerMaat ?? (klaar ? pdfPaginaMm(pdfBase64) : null) ?? { breedte_mm: breedteMm, hoogte_mm: hoogteMm };
|
|
1745
1811
|
const uit = etiketPast({ ...maat, soortLabel: stickerCache?.sticker_type ? stickerTypeLabel(stickerCache.sticker_type) : documentTypeLabelVoor(String(job.documenttype ?? "Document")) }, label.etiket, label.naam, !!stickerMaat);
|
|
1746
|
-
if (
|
|
1812
|
+
if (label.etiket && ETIKET_PDF_SOORTEN.has(String(job.documenttype ?? "")) && (uit.ok || uit.code === "FORMAAT_PAST_NIET")) {
|
|
1813
|
+
// 1.69.12: elke sticker via de uitwijkroute (vaste volgorde), papier
|
|
1814
|
+
// op afmeting gekozen; draaien/centreren/verkleinen in de PDF zelf.
|
|
1815
|
+
const keuzeUitwijk = await bepaalUitwijk(db, job, layout, !!floriday, !!klaar, maat, label, printer, formaten);
|
|
1816
|
+
if (!keuzeUitwijk) {
|
|
1817
|
+
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.`);
|
|
1818
|
+
return "mislukt";
|
|
1819
|
+
}
|
|
1820
|
+
uitwijk = keuzeUitwijk.uitkomst;
|
|
1821
|
+
if (keuzeUitwijk.a4)
|
|
1822
|
+
doelPrinter = keuzeUitwijk.a4;
|
|
1823
|
+
const geplaatst = await voerUitwijkUit(pdfBase64, uitwijk, maat, Number(job.kopieen ?? 1));
|
|
1824
|
+
pdfBase64 = geplaatst.pdfBase64;
|
|
1825
|
+
kopieenNaarPrinter = geplaatst.kopieen;
|
|
1826
|
+
papier = { paper: uitwijk.paper || null, rotate: 0, uitleg: uitwijk.reden };
|
|
1827
|
+
await log(db, job.id, "uitwijk", `${uitwijk.reden} (${uitwijk.printerNaam}).`);
|
|
1828
|
+
}
|
|
1829
|
+
else if (!uit.ok) {
|
|
1747
1830
|
await geweigerd(db, job, uit.code, uit.bericht);
|
|
1748
1831
|
return "mislukt";
|
|
1749
1832
|
}
|
|
1750
|
-
|
|
1751
|
-
|
|
1833
|
+
else {
|
|
1834
|
+
papier = { paper: uit.paper, rotate: uit.rotate, uitleg: uit.uitleg };
|
|
1835
|
+
await log(db, job.id, "etiket", `Labelprinter ${label.naam}: ${uit.uitleg}.`);
|
|
1836
|
+
}
|
|
1752
1837
|
}
|
|
1753
1838
|
const verloopt = vervaltijdVoor(String(job.documenttype ?? ""));
|
|
1754
1839
|
// Eén fysieke printer via meerdere computers: probeer de routes op
|
|
1755
1840
|
// volgorde; valt de eerste weg, dan automatisch de volgende.
|
|
1756
|
-
const routes = await printerRoutes(db, String(
|
|
1841
|
+
const routes = await printerRoutes(db, String(doelPrinter.id), String(doelPrinter.extern_printer_id));
|
|
1757
1842
|
let externJobId = "";
|
|
1758
1843
|
let laatsteFout = null;
|
|
1759
1844
|
for (const [i, route] of routes.entries()) {
|
|
@@ -1764,9 +1849,9 @@ async function verwerkJob(db, job) {
|
|
|
1764
1849
|
externPrinterId: route.extern,
|
|
1765
1850
|
documentnaam: String(job.documentnaam ?? "Document"),
|
|
1766
1851
|
pdfBase64,
|
|
1767
|
-
kopieen:
|
|
1852
|
+
kopieen: kopieenNaarPrinter,
|
|
1768
1853
|
documenttype: String(job.documenttype ?? ""),
|
|
1769
|
-
opties: { paper: papier.paper, rotate: papier.rotate, fitToPage
|
|
1854
|
+
opties: { paper: papier.paper, rotate: papier.rotate, fitToPage },
|
|
1770
1855
|
});
|
|
1771
1856
|
if (i > 0) {
|
|
1772
1857
|
await log(db, job.id, "route", `Verstuurd via computer ${route.computer ?? "andere route"}: de eerste computer was niet bereikbaar.`);
|
|
@@ -1791,13 +1876,14 @@ async function verwerkJob(db, job) {
|
|
|
1791
1876
|
const { data: gekoppeldeJob } = await db
|
|
1792
1877
|
.from("print_jobs")
|
|
1793
1878
|
.update({
|
|
1794
|
-
printer_id:
|
|
1879
|
+
printer_id: doelPrinter.id,
|
|
1795
1880
|
// layout_id blijft de aangeleverde invoer en wordt bewust niet
|
|
1796
1881
|
// overschreven met de uitkomst.
|
|
1797
1882
|
// Bij Floriday 1-op-1 wordt de Floriday-layout vastgelegd (alleen nieuwe opdrachten).
|
|
1798
1883
|
gebruikte_layout_id: uitkomst.bron === "extern_pdf" ? null : (layout?.id ?? null),
|
|
1799
1884
|
gebruikte_bron: uitkomst.bron,
|
|
1800
1885
|
extern_job_id: externJobId,
|
|
1886
|
+
printer_keuze: await printerKeuzeVoor(db, job, doelPrinter, uitwijk),
|
|
1801
1887
|
printnode_status: "new",
|
|
1802
1888
|
printnode_status_op: new Date().toISOString(),
|
|
1803
1889
|
verloopt_na_s: verloopt,
|
|
@@ -1819,7 +1905,9 @@ async function verwerkJob(db, job) {
|
|
|
1819
1905
|
return "wachtend";
|
|
1820
1906
|
}
|
|
1821
1907
|
klok.markeer("submitted");
|
|
1822
|
-
|
|
1908
|
+
if (uitwijk)
|
|
1909
|
+
await legUitwijkVast(db, job, uitwijk);
|
|
1910
|
+
await log(db, job.id, "verstuurd", `Naar printer ${doelPrinter.naam ?? ""}. ${papier.uitleg} ${klok.samenvatting()}`);
|
|
1823
1911
|
return "verstuurd";
|
|
1824
1912
|
}
|
|
1825
1913
|
catch (e) {
|
|
@@ -1943,7 +2031,7 @@ async function synchroniseerStatussen(db) {
|
|
|
1943
2031
|
* runner draait niet meer) -> na 10 minuten terug naar 'wachtend'.
|
|
1944
2032
|
* Beide draaien in elke ronde, ook als er niets te claimen viel.
|
|
1945
2033
|
*/
|
|
1946
|
-
async function vervalControle(db) {
|
|
2034
|
+
async function vervalControle(db, houder = null) {
|
|
1947
2035
|
const nu = Date.now();
|
|
1948
2036
|
const grensVerstuurd = new Date(nu - VERVAL_BEZIG_MIN * 60000).toISOString();
|
|
1949
2037
|
const grensClaim = new Date(nu - VERVAL_CLAIM_MIN * 60000).toISOString();
|
|
@@ -1977,6 +2065,12 @@ async function vervalControle(db) {
|
|
|
1977
2065
|
await log(db, job.id, "vervallen", reden);
|
|
1978
2066
|
aantal++;
|
|
1979
2067
|
}
|
|
2068
|
+
// Vrijgave per fase (standaard 90 s), alleen als geen levende andere ronde
|
|
2069
|
+
// de lease houdt. Lukt de functie niet, dan het oude vangnet van 10 minuten.
|
|
2070
|
+
const { data: vrij, error: vrijFout } = await db.rpc("layouts_vrijgeven_vastgelopen", { p_houder: houder });
|
|
2071
|
+
if (!vrijFout)
|
|
2072
|
+
return aantal + Number(vrij ?? 0);
|
|
2073
|
+
console.warn(`[printwachtrij] vrijgeven per fase mislukt: ${vrijFout.message}`);
|
|
1980
2074
|
const { data: vastgelopen } = await db
|
|
1981
2075
|
.from("print_jobs")
|
|
1982
2076
|
.select("id, pogingen")
|
|
@@ -2007,7 +2101,10 @@ async function vervalControle(db) {
|
|
|
2007
2101
|
return aantal;
|
|
2008
2102
|
}
|
|
2009
2103
|
/** Hoeveel opdrachten tegelijk worden gerenderd binnen één ronde. */
|
|
2010
|
-
const JOB_PARALLEL =
|
|
2104
|
+
const JOB_PARALLEL = 1;
|
|
2105
|
+
/** Na deze looptijd pakt een ronde geen nieuwe opdracht meer (lopende wordt afgemaakt). */
|
|
2106
|
+
export const RONDE_BUDGET_MS = 20000;
|
|
2107
|
+
void JOB_PARALLEL;
|
|
2011
2108
|
/** Zo lang mag één ronde het slot houden; daarna is hij vanzelf herstelbaar. */
|
|
2012
2109
|
const LEASE_SECONDEN = 120;
|
|
2013
2110
|
const LEASE_NAAM = "print-queue-worker";
|
|
@@ -2017,7 +2114,7 @@ const VERVOLG_COOLDOWN_MS = 1500;
|
|
|
2017
2114
|
* Wekt de wachtrij opnieuw, maar uitsluitend wanneer er aantoonbaar wachtend
|
|
2018
2115
|
* werk overblijft. Het adres van de runner staat in de database, nooit in code.
|
|
2019
2116
|
*/
|
|
2020
|
-
async function wekVervolgRonde(db) {
|
|
2117
|
+
async function wekVervolgRonde(db, origin = null) {
|
|
2021
2118
|
const { count } = await db
|
|
2022
2119
|
.from("print_jobs")
|
|
2023
2120
|
.select("id", { count: "exact", head: true })
|
|
@@ -2025,13 +2122,32 @@ async function wekVervolgRonde(db) {
|
|
|
2025
2122
|
.or(`volgende_poging.is.null,volgende_poging.lte.${new Date().toISOString()}`);
|
|
2026
2123
|
if (!count)
|
|
2027
2124
|
return;
|
|
2028
|
-
|
|
2125
|
+
void VERVOLG_COOLDOWN_MS;
|
|
2126
|
+
// Eerst direct vanaf de server (geen pg_net-wachtrij); pg_net is het vangnet.
|
|
2127
|
+
const { wekEigenRonde } = await import("./runnerRegistry.server.js");
|
|
2128
|
+
const direct = await wekEigenRonde(db, origin);
|
|
2129
|
+
if (direct.ok)
|
|
2130
|
+
return;
|
|
2131
|
+
console.warn(`[printwachtrij] direct wekken niet gelukt (${direct.reden}); vangnet wake_print_queue.`);
|
|
2029
2132
|
const { error } = await db.rpc("wake_print_queue", { _min_interval_ms: 1000 });
|
|
2030
2133
|
if (error)
|
|
2031
2134
|
console.warn(`[printwachtrij] vervolgronde wekken mislukt: ${error.message}`);
|
|
2032
2135
|
}
|
|
2033
2136
|
/** Eén ronde: vastgelopen opdrachten opruimen, afdrukken en statussen bijwerken. */
|
|
2034
|
-
|
|
2137
|
+
async function claimEen(db) {
|
|
2138
|
+
const { data: pdf, error: pdfError } = await db.rpc("claim_pdf_print_jobs", { _max: 1 });
|
|
2139
|
+
if (pdfError)
|
|
2140
|
+
throw new Error(pdfError.message);
|
|
2141
|
+
const p = arr(pdf)[0];
|
|
2142
|
+
if (p)
|
|
2143
|
+
return p;
|
|
2144
|
+
const { data, error } = await db.rpc("claim_cloud_print_jobs", { _max: 1 });
|
|
2145
|
+
if (error)
|
|
2146
|
+
throw new Error(error.message);
|
|
2147
|
+
return arr(data)[0] ?? null;
|
|
2148
|
+
}
|
|
2149
|
+
export async function verwerkWachtrij(db, max = 5, opties = {}) {
|
|
2150
|
+
const rondeStart = Date.now();
|
|
2035
2151
|
const leeg = {
|
|
2036
2152
|
opgepakt: 0,
|
|
2037
2153
|
verstuurd: 0,
|
|
@@ -2052,10 +2168,11 @@ export async function verwerkWachtrij(db, max = 5) {
|
|
|
2052
2168
|
if (slot !== true)
|
|
2053
2169
|
return { ...leeg, overgeslagen: "Er draait al een printronde." };
|
|
2054
2170
|
let vervolgNodig = false;
|
|
2171
|
+
startCodelijstRonde();
|
|
2055
2172
|
try {
|
|
2056
2173
|
// Eerst het vangnet: dit draait ook als er niets te claimen valt.
|
|
2057
2174
|
try {
|
|
2058
|
-
await vervalControle(db);
|
|
2175
|
+
await vervalControle(db, houder);
|
|
2059
2176
|
}
|
|
2060
2177
|
catch (e) {
|
|
2061
2178
|
console.warn(`[printwachtrij] vervalcontrole mislukt: ${e instanceof Error ? e.message : "onbekend"}`);
|
|
@@ -2068,47 +2185,48 @@ export async function verwerkWachtrij(db, max = 5) {
|
|
|
2068
2185
|
catch (e) {
|
|
2069
2186
|
console.warn(`[printwachtrij] webhook koppelen mislukt: ${e instanceof Error ? e.message : "onbekend"}`);
|
|
2070
2187
|
}
|
|
2071
|
-
//
|
|
2072
|
-
//
|
|
2073
|
-
//
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2188
|
+
// Eén opdracht tegelijk (JOB_PARALLEL = 1): claim er één, verwerk hem en
|
|
2189
|
+
// herhaal zolang de ronde jonger is dan RONDE_BUDGET_MS. Nooit vooraf
|
|
2190
|
+
// claimen, zodat wachtende opdrachten 'wachtend' blijven.
|
|
2191
|
+
// PDF-opdrachten hebben een eigen claimroute (eerst), daarna de cloud-route.
|
|
2192
|
+
const uitkomsten = [];
|
|
2193
|
+
let stopreden = "leeg";
|
|
2194
|
+
let opgepakt = 0;
|
|
2195
|
+
while (true) {
|
|
2196
|
+
if (opgepakt >= max) {
|
|
2197
|
+
stopreden = "max";
|
|
2198
|
+
break;
|
|
2199
|
+
}
|
|
2200
|
+
if (Date.now() - rondeStart >= RONDE_BUDGET_MS) {
|
|
2201
|
+
stopreden = "tijd";
|
|
2202
|
+
break;
|
|
2203
|
+
}
|
|
2204
|
+
const job = await claimEen(db);
|
|
2205
|
+
if (!job) {
|
|
2206
|
+
stopreden = "leeg";
|
|
2207
|
+
break;
|
|
2208
|
+
}
|
|
2209
|
+
opgepakt++;
|
|
2091
2210
|
try {
|
|
2092
2211
|
const { eigenBasisUrl } = await import("./runnerRegistry.server.js");
|
|
2093
2212
|
const { MODULE_VERSIE } = await import("./shellPoort.js");
|
|
2094
2213
|
await db
|
|
2095
2214
|
.from("print_jobs")
|
|
2096
2215
|
.update({ verwerkt_door_runner: eigenBasisUrl(), verwerkt_met_versie: MODULE_VERSIE })
|
|
2097
|
-
.
|
|
2216
|
+
.eq("id", job.id);
|
|
2098
2217
|
}
|
|
2099
2218
|
catch {
|
|
2100
2219
|
/* vastleggen mag het printen nooit blokkeren */
|
|
2101
2220
|
}
|
|
2102
|
-
}
|
|
2103
|
-
const uitkomsten = await metPool(jobs, JOB_PARALLEL, async (job) => {
|
|
2104
2221
|
try {
|
|
2105
|
-
|
|
2222
|
+
uitkomsten.push(await verwerkJob(db, job));
|
|
2106
2223
|
}
|
|
2107
2224
|
catch (e) {
|
|
2108
2225
|
console.error(`[printwachtrij] opdracht ${job.id} viel onverwacht uit: ${e instanceof Error ? e.message : "onbekend"}`);
|
|
2109
|
-
|
|
2226
|
+
uitkomsten.push("mislukt");
|
|
2110
2227
|
}
|
|
2111
|
-
}
|
|
2228
|
+
}
|
|
2229
|
+
const jobs = { length: opgepakt };
|
|
2112
2230
|
const resultaat = {
|
|
2113
2231
|
opgepakt: jobs.length,
|
|
2114
2232
|
verstuurd: uitkomsten.filter((u) => u === "verstuurd").length,
|
|
@@ -2118,10 +2236,12 @@ export async function verwerkWachtrij(db, max = 5) {
|
|
|
2118
2236
|
bijgewerkt: await synchroniseerStatussen(db),
|
|
2119
2237
|
};
|
|
2120
2238
|
// Alleen wanneer de batchlimiet vol zat kan er nog werk klaarstaan.
|
|
2121
|
-
vervolgNodig =
|
|
2239
|
+
vervolgNodig = stopreden !== "leeg";
|
|
2240
|
+
console.info(`[printwachtrij] ronde_klaar ${JSON.stringify({ opdrachten: opgepakt, ms: Date.now() - rondeStart, stopreden, eind: new Date().toISOString() })}`);
|
|
2122
2241
|
return resultaat;
|
|
2123
2242
|
}
|
|
2124
2243
|
finally {
|
|
2244
|
+
stopCodelijstRonde();
|
|
2125
2245
|
const { error } = await db.rpc("release_print_queue_lease", {
|
|
2126
2246
|
_naam: LEASE_NAAM,
|
|
2127
2247
|
_houder: houder,
|
|
@@ -2130,7 +2250,7 @@ export async function verwerkWachtrij(db, max = 5) {
|
|
|
2130
2250
|
console.warn(`[printwachtrij] slot vrijgeven mislukt: ${error.message}`);
|
|
2131
2251
|
if (vervolgNodig) {
|
|
2132
2252
|
try {
|
|
2133
|
-
await wekVervolgRonde(db);
|
|
2253
|
+
await wekVervolgRonde(db, opties.origin ?? null);
|
|
2134
2254
|
}
|
|
2135
2255
|
catch (fout) {
|
|
2136
2256
|
const melding = fout instanceof Error ? fout.message : "onbekend";
|
|
@@ -2172,6 +2292,132 @@ export async function bepaalDocumentKeuze(db, job) {
|
|
|
2172
2292
|
* een werkplek hem als labelprinter gebruikt. Alleen dan geldt de controle,
|
|
2173
2293
|
* zodat bestaande printers zonder werkplek precies blijven werken als nu.
|
|
2174
2294
|
*/
|
|
2295
|
+
/** Stickersoort voor de verkleininstelling (op configuratie en bron, nooit op naam). */
|
|
2296
|
+
export function stickerSoortVoor(documenttype, layout, floriday, klaar) {
|
|
2297
|
+
const cfg = (layout?.config ?? {});
|
|
2298
|
+
if (cfg.eigen_traysticker)
|
|
2299
|
+
return "eigen_traysticker";
|
|
2300
|
+
if (cfg.eigen_sticker || String(documenttype) === "eigen_sticker")
|
|
2301
|
+
return "eigen_sticker";
|
|
2302
|
+
const tray = String(documenttype) === "traysticker";
|
|
2303
|
+
if (floriday || (klaar && tray))
|
|
2304
|
+
return tray ? "floriday_traysticker" : "floriday_sticker";
|
|
2305
|
+
return "klantsticker";
|
|
2306
|
+
}
|
|
2307
|
+
/** Eigen ontwerp past niet op het geladen etiket: variant op de etiketmaat maken. */
|
|
2308
|
+
export function eigenEtiketVariantNodig(layout, etiket) {
|
|
2309
|
+
const cfg = (layout?.config ?? {});
|
|
2310
|
+
if (!cfg.eigen_traysticker && !cfg.eigen_sticker)
|
|
2311
|
+
return false;
|
|
2312
|
+
// Eigen sticker met geüploade afbeelding heeft een vaste maat: die volgt de uitwijkroute.
|
|
2313
|
+
if (cfg.eigen_sticker && !cfg.eigen_traysticker)
|
|
2314
|
+
return false;
|
|
2315
|
+
const b = Number(layout.breedte_mm ?? 0);
|
|
2316
|
+
const h = Number(layout.hoogte_mm ?? 0);
|
|
2317
|
+
if (!(b > 0) || !(h > 0))
|
|
2318
|
+
return false;
|
|
2319
|
+
return !etiketPast({ breedte_mm: b, hoogte_mm: h, soortLabel: "Traysticker" }, etiket, "").ok;
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Verkleininstelling via de databasefunctie (één bron met de vroege
|
|
2323
|
+
* waarschuwing; maakt de standaard aan als hij ontbreekt). null = niet
|
|
2324
|
+
* leesbaar: dan vervalt alleen de stap verkleinen, nooit wachten.
|
|
2325
|
+
*/
|
|
2326
|
+
async function leesStickerInstelling(db) {
|
|
2327
|
+
const { data, error } = await db.rpc("layouts_sticker_verkleinen");
|
|
2328
|
+
if (error)
|
|
2329
|
+
return null;
|
|
2330
|
+
return leesStickerInstellingenStrikt(data);
|
|
2331
|
+
}
|
|
2332
|
+
/** Uitwijkroute voor een sticker die niet op het geladen etiket past. */
|
|
2333
|
+
async function bepaalUitwijk(db, job, layout, floriday, klaar, maat, label, printer, formaten = null) {
|
|
2334
|
+
const instellingen = await leesStickerInstelling(db).catch(() => null);
|
|
2335
|
+
const soort = stickerSoortVoor(String(job.documenttype ?? ""), layout, floriday, klaar);
|
|
2336
|
+
const etiketten = label.etiket
|
|
2337
|
+
? [{ 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 }]
|
|
2338
|
+
: [];
|
|
2339
|
+
const plekId = leesPrintPlekId(job) || (await zoekPrintPlekId(db, job).catch(() => null));
|
|
2340
|
+
let a4 = null;
|
|
2341
|
+
if (plekId) {
|
|
2342
|
+
const { data: a4Id } = await db.rpc("printplek_printer", { _plek: plekId, _documenttype: "pakbon" });
|
|
2343
|
+
if (typeof a4Id === "string" && a4Id !== String(printer.id)) {
|
|
2344
|
+
const { data } = await db
|
|
2345
|
+
.from("printers")
|
|
2346
|
+
.select("id, naam, weergavenaam, extern_printer_id, actief, papierformaat, ondersteunde_formaten, geladen_etiket")
|
|
2347
|
+
.eq("id", a4Id)
|
|
2348
|
+
.maybeSingle();
|
|
2349
|
+
a4 = data && data.actief !== false && data.extern_printer_id ? data : null;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
// Ensure bij gebruik (eerste print): oude losse instelling overnemen.
|
|
2353
|
+
await db.rpc("layouts_zorg_voor_a4_stickervel").then(() => undefined, () => undefined);
|
|
2354
|
+
const vel = plekId ? await leesA4Stickervel(db, String(plekId)) : null;
|
|
2355
|
+
const velIndeling = a4VelVoor(vel, maat);
|
|
2356
|
+
const uitkomst = kiesUitwijkroute({
|
|
2357
|
+
sticker: maat,
|
|
2358
|
+
etiketten,
|
|
2359
|
+
a4Printer: a4 ? { naam: String(a4.weergavenaam || a4.naam || "A4-printer"), id: String(a4.id) } : null,
|
|
2360
|
+
a4VelIngesteld: !!velIndeling,
|
|
2361
|
+
a4VelIndeling: velIndeling,
|
|
2362
|
+
instelling: instellingen ? instellingen[soort] : null,
|
|
2363
|
+
});
|
|
2364
|
+
if (!uitkomst)
|
|
2365
|
+
return null;
|
|
2366
|
+
const naarA4 = uitkomst.uitwijkroute === "a4_vel" || uitkomst.uitwijkroute === "a4_snijlijnen";
|
|
2367
|
+
return { uitkomst, a4: naarA4 ? a4 : null };
|
|
2368
|
+
}
|
|
2369
|
+
/** A4-stickervel van de printplek (print_plekken.a4_stickervel, 1.69.12). */
|
|
2370
|
+
async function leesA4Stickervel(db, plekId) {
|
|
2371
|
+
const { data } = await db.from("print_plekken").select("a4_stickervel").eq("id", plekId).maybeSingle();
|
|
2372
|
+
return leesA4StickervelWaarde(data?.a4_stickervel);
|
|
2373
|
+
}
|
|
2374
|
+
/** Resolutie uit de PrintNode-gegevens; onbekend = null (de uitwijk neemt 203 dpi). */
|
|
2375
|
+
function printerDpi(printer) {
|
|
2376
|
+
const f = (printer?.ondersteunde_formaten ?? {});
|
|
2377
|
+
const d = Number(f?.dpi ?? (Array.isArray(f?.dpis) ? String(f.dpis[0]).split("x")[0] : NaN));
|
|
2378
|
+
return d > 0 ? d : null;
|
|
2379
|
+
}
|
|
2380
|
+
/**
|
|
2381
|
+
* Waarom deze printer, vastgelegd in dezelfde update als extern_job_id/status
|
|
2382
|
+
* (print_jobs.printer_keuze). Zo spreken status en uitleg elkaar nooit tegen.
|
|
2383
|
+
*/
|
|
2384
|
+
async function printerKeuzeVoor(db, job, printer, uitwijk) {
|
|
2385
|
+
let regels = [];
|
|
2386
|
+
try {
|
|
2387
|
+
const { data } = await db
|
|
2388
|
+
.from("print_job_logs")
|
|
2389
|
+
.select("detail")
|
|
2390
|
+
.eq("job_id", String(job.id))
|
|
2391
|
+
.in("gebeurtenis", ["waarom", "etiket", "route"])
|
|
2392
|
+
.order("created_at", { ascending: true });
|
|
2393
|
+
regels = arr(data).map((r) => String(r.detail ?? "")).filter(Boolean);
|
|
2394
|
+
}
|
|
2395
|
+
catch { /* uitleg is informatief */ }
|
|
2396
|
+
const naam = String(printer.weergavenaam || printer.naam || "Printer");
|
|
2397
|
+
if (uitwijk?.reden)
|
|
2398
|
+
regels.push(uitwijk.reden);
|
|
2399
|
+
if (!regels.length)
|
|
2400
|
+
regels.push(`Verstuurd naar ${naam}.`);
|
|
2401
|
+
return { printer_id: printer.id ?? null, printer_naam: naam, regels, vastgelegd_op: new Date().toISOString() };
|
|
2402
|
+
}
|
|
2403
|
+
/** Legt vast wat er met de sticker gebeurd is (veldnamen voor Pickschermen 1.0.61). */
|
|
2404
|
+
async function legUitwijkVast(db, job, u) {
|
|
2405
|
+
// Pickschermen 1.0.61 leest uitwijkroute/printerNaam/schaal/reden; de
|
|
2406
|
+
// overige velden zijn alleen voor het voorbeeld in de printwachtrij.
|
|
2407
|
+
const waarde = {
|
|
2408
|
+
...uitwijkVoorPickschermen(u),
|
|
2409
|
+
rotate: u.rotate,
|
|
2410
|
+
pagina_breedte_mm: u.pagina_breedte_mm,
|
|
2411
|
+
pagina_hoogte_mm: u.pagina_hoogte_mm,
|
|
2412
|
+
sticker_breedte_mm: u.sticker_breedte_mm,
|
|
2413
|
+
sticker_hoogte_mm: u.sticker_hoogte_mm,
|
|
2414
|
+
};
|
|
2415
|
+
const { error } = await db.from("print_jobs").update({ uitwijk: waarde }).eq("id", job.id);
|
|
2416
|
+
if (error)
|
|
2417
|
+
await faseLog(db, job.id, "uitwijk_niet_vastgelegd", { ...waarde, fout: error.message });
|
|
2418
|
+
else
|
|
2419
|
+
await faseLog(db, job.id, "uitwijk", waarde);
|
|
2420
|
+
}
|
|
2175
2421
|
async function labelControleVoorbereiden(db, printer) {
|
|
2176
2422
|
const etiket = leesGeladenEtiket(printer?.geladen_etiket);
|
|
2177
2423
|
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":"AAkBA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IAC1C,oDAAoD;IACpD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAWD,iFAAiF;AACjF,qBAAa,eAAgB,SAAQ,KAAK;;CAEzC;AAED,kFAAkF;AAClF,eAAO,MAAM,aAAa,gCAA2B,CAAC;AACtD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAEtE;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOvD,CAAC;AACF,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAE9E;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAE7E;AA4CD,6EAA6E;AAC7E,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAmBrE;AAED,gFAAgF;AAChF,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CASzE;AAED,2FAA2F;AAC3F,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
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
|
-
//
|
|
117
|
-
|
|
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;
|