@flowselections/layout-maker 1.32.0 → 1.38.4
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/README.md +139 -139
- package/dist-lib/components/AfdrukKnop.d.ts +19 -19
- package/dist-lib/components/ComputersLijst.d.ts.map +1 -1
- package/dist-lib/components/ComputersLijst.js +5 -5
- package/dist-lib/components/DocumentenPage.d.ts.map +1 -1
- package/dist-lib/components/DocumentenPage.js +3 -2
- package/dist-lib/components/LayoutPrinterSelect.d.ts +8 -0
- package/dist-lib/components/LayoutPrinterSelect.d.ts.map +1 -0
- package/dist-lib/components/LayoutPrinterSelect.js +23 -0
- package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
- package/dist-lib/components/LayoutsPage.js +16 -3
- package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
- package/dist-lib/components/PaginaDocument.d.ts +4 -1
- package/dist-lib/components/PaginaDocument.d.ts.map +1 -1
- package/dist-lib/components/PaginaDocument.js +10 -5
- package/dist-lib/components/PakbonBuilderPage.d.ts.map +1 -1
- package/dist-lib/components/PakbonBuilderPage.js +6 -2
- package/dist-lib/components/PakbonPreview.d.ts +4 -2
- package/dist-lib/components/PakbonPreview.d.ts.map +1 -1
- package/dist-lib/components/PakbonPreview.js +55 -12
- package/dist-lib/components/PakbonSectiesPanel.d.ts +2 -2
- package/dist-lib/components/PakbonSectiesPanel.d.ts.map +1 -1
- package/dist-lib/components/PakbonSectiesPanel.js +7 -2
- package/dist-lib/components/PdfMapAutoSaver.d.ts +6 -0
- package/dist-lib/components/PdfMapAutoSaver.d.ts.map +1 -0
- package/dist-lib/components/PdfMapAutoSaver.js +12 -0
- package/dist-lib/components/PdfMapGlobaleBanner.d.ts +12 -0
- package/dist-lib/components/PdfMapGlobaleBanner.d.ts.map +1 -0
- package/dist-lib/components/PdfMapGlobaleBanner.js +30 -0
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts +7 -0
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts.map +1 -0
- package/dist-lib/components/PdfMapToestemmingBanner.js +139 -0
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +42 -3
- package/dist-lib/components/PrintenPage.d.ts.map +1 -1
- package/dist-lib/components/PrintenPage.js +3 -2
- package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
- package/dist-lib/components/PrinterSetupWizard.js +28 -5
- package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
- package/dist-lib/components/PrintersRedirectPage.js +14 -14
- package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekDetailPage.js +30 -4
- package/dist-lib/components/PrintplekWizard.d.ts.map +1 -1
- package/dist-lib/components/PrintplekWizard.js +81 -3
- package/dist-lib/components/ProductiebonBuilderPage.d.ts.map +1 -1
- package/dist-lib/components/ProductiebonBuilderPage.js +3 -1
- package/dist-lib/index.d.ts +10 -2
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +13 -2
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1396 -727
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +1396 -727
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +24008 -0
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/moduleClient.js +29 -0
- package/dist-lib/integrations/supabase/types.d.ts +1403 -750
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +1396 -727
- package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.server.js +9 -9
- package/dist-lib/lib/browserPrint.js +1 -1
- package/dist-lib/lib/code128.d.ts +5 -0
- package/dist-lib/lib/code128.d.ts.map +1 -0
- package/dist-lib/lib/code128.js +51 -0
- package/dist-lib/lib/htmlPdf.server.d.ts.map +1 -1
- package/dist-lib/lib/htmlPdf.server.js +101 -6
- package/dist-lib/lib/layoutPreview.d.ts.map +1 -1
- package/dist-lib/lib/layoutPreview.js +11 -8
- package/dist-lib/lib/orderData.server.d.ts.map +1 -1
- package/dist-lib/lib/orderData.server.js +123 -10
- package/dist-lib/lib/pakbonBuilder.d.ts +28 -2
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +69 -8
- package/dist-lib/lib/pakbonHtml.d.ts +14 -2
- package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
- package/dist-lib/lib/pakbonHtml.js +155 -63
- package/dist-lib/lib/pakbonScan.d.ts +44 -0
- package/dist-lib/lib/pakbonScan.d.ts.map +1 -0
- package/dist-lib/lib/pakbonScan.js +105 -0
- package/dist-lib/lib/pdfJobSaver.d.ts +20 -0
- package/dist-lib/lib/pdfJobSaver.d.ts.map +1 -0
- package/dist-lib/lib/pdfJobSaver.js +173 -0
- package/dist-lib/lib/pdfMap.d.ts +48 -0
- package/dist-lib/lib/pdfMap.d.ts.map +1 -0
- package/dist-lib/lib/pdfMap.js +219 -0
- package/dist-lib/lib/pdfPrinter.d.ts +9 -0
- package/dist-lib/lib/pdfPrinter.d.ts.map +1 -0
- package/dist-lib/lib/pdfPrinter.js +34 -0
- package/dist-lib/lib/previewPdf.d.ts.map +1 -1
- package/dist-lib/lib/previewPdf.js +41 -9
- package/dist-lib/lib/printApi.d.ts.map +1 -1
- package/dist-lib/lib/printApi.js +9 -1
- package/dist-lib/lib/printQueue.server.d.ts +7 -0
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/printQueue.server.js +346 -52
- package/dist-lib/lib/printService.functions.d.ts +5365 -2689
- package/dist-lib/lib/printService.functions.d.ts.map +1 -1
- package/dist-lib/lib/productiebonHtml.js +15 -15
- package/dist-lib/lib/profielHtml.js +18 -18
- package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
- package/dist-lib/lib/supabaseAdmin.server.js +43 -43
- package/dist-lib/lib/supabaseClient.d.ts +1 -3
- package/dist-lib/lib/supabaseClient.d.ts.map +1 -1
- package/dist-lib/lib/supabaseClient.js +4 -8
- package/dist-lib/lib/testpagina.js +3 -3
- package/dist-lib/lib/testprint.js +4 -4
- package/dist-lib/lib/useDocumentData.d.ts +10 -0
- package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
- package/dist-lib/lib/useDocumentData.js +19 -0
- package/dist-lib/lib/voorbeeldPrint.d.ts +4 -0
- package/dist-lib/lib/voorbeeldPrint.d.ts.map +1 -1
- package/dist-lib/lib/voorbeeldPrint.js +13 -2
- package/package.json +151 -151
|
@@ -212,7 +212,7 @@ export const SECTIE_REGISTER = [
|
|
|
212
212
|
{
|
|
213
213
|
type: "pickmethode",
|
|
214
214
|
label: "Pickmethode",
|
|
215
|
-
omschrijving: "Bepaalt
|
|
215
|
+
omschrijving: "Bepaalt of orders per kar, per fust of op beide manieren worden gepickt.",
|
|
216
216
|
opties: [
|
|
217
217
|
{
|
|
218
218
|
key: "methode",
|
|
@@ -222,8 +222,9 @@ export const SECTIE_REGISTER = [
|
|
|
222
222
|
opties: [
|
|
223
223
|
{ value: "kar", label: "Order picken per kar" },
|
|
224
224
|
{ value: "fusten", label: "Order picken per fusten (zelf karindeling maken)" },
|
|
225
|
+
{ value: "beide", label: "Order picken per kar én per fusten (karren + verzamellijst)" },
|
|
225
226
|
],
|
|
226
|
-
hint: "Bij picken per fusten vervallen de blokken Karren, Lagen, Producten en Fusten
|
|
227
|
+
hint: "Bij picken per fusten vervallen de blokken Karren, Lagen, Producten en Fusten. Bij de gecombineerde keuze bepaalt de Engine per opdracht: full_cart toont de karindeling, partial_order alleen de te verzamelen fusten.",
|
|
227
228
|
},
|
|
228
229
|
{
|
|
229
230
|
key: "kop",
|
|
@@ -249,6 +250,14 @@ export const SECTIE_REGISTER = [
|
|
|
249
250
|
},
|
|
250
251
|
{ key: "toonFusthoogte", label: "Fusthoogte en belading tonen", type: "schakelaar", standaard: true },
|
|
251
252
|
{ key: "toonTotaal", label: "Totaal aantal fusten tonen", type: "schakelaar", standaard: true },
|
|
253
|
+
{
|
|
254
|
+
key: "toonBarcode",
|
|
255
|
+
label: "Barcode voor afleverbrief tonen",
|
|
256
|
+
type: "schakelaar",
|
|
257
|
+
standaard: true,
|
|
258
|
+
hint: "De barcode wordt uitsluitend overgenomen uit de Engine-opdracht.",
|
|
259
|
+
},
|
|
260
|
+
{ key: "barcodeHoogte", label: "Barcodehoogte (mm)", type: "getal", standaard: 15 },
|
|
252
261
|
],
|
|
253
262
|
},
|
|
254
263
|
{
|
|
@@ -498,9 +507,9 @@ export const SECTIE_REGISTER = [
|
|
|
498
507
|
{
|
|
499
508
|
type: "barcode",
|
|
500
509
|
label: "Barcode",
|
|
501
|
-
omschrijving: "
|
|
510
|
+
omschrijving: "Scanbare barcode. Bij Engine-pakbonnen komt de waarde uit de opdracht.",
|
|
502
511
|
opties: [
|
|
503
|
-
{ key: "waarde", label: "Inhoud", type: "tekst", standaard: "{{
|
|
512
|
+
{ key: "waarde", label: "Inhoud", type: "tekst", standaard: "{{barcode}}" },
|
|
504
513
|
{ key: "hoogte", label: "Hoogte (mm)", type: "getal", standaard: 15 },
|
|
505
514
|
],
|
|
506
515
|
},
|
|
@@ -572,11 +581,20 @@ function migreerPickmethode(secties) {
|
|
|
572
581
|
const karIndex = secties.findIndex((s) => s.type === "karren");
|
|
573
582
|
const oud = karIndex >= 0 ? String(secties[karIndex].opties?.["pickmethode"] ?? "kar") : "kar";
|
|
574
583
|
const blok = nieuweSectie("pickmethode");
|
|
575
|
-
blok.opties["methode"] = oud === "fusten"
|
|
584
|
+
blok.opties["methode"] = oud === "fusten" || oud === "beide" ? oud : "kar";
|
|
576
585
|
const kopie = [...secties];
|
|
577
586
|
kopie.splice(karIndex >= 0 ? karIndex : kopie.length, 0, blok);
|
|
578
587
|
return kopie;
|
|
579
588
|
}
|
|
589
|
+
/** Normaliseert alleen de twee varianten uit het gedeelde Engine-contract. */
|
|
590
|
+
export function pakbonLayoutVariant(value) {
|
|
591
|
+
const variant = String(value ?? "").trim().toLowerCase();
|
|
592
|
+
if (variant === "full_cart")
|
|
593
|
+
return "full_cart";
|
|
594
|
+
if (variant === "partial_order")
|
|
595
|
+
return "partial_order";
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
580
598
|
/** Actieve pickmethode van een pakbonconfiguratie. */
|
|
581
599
|
export function pickMethode(secties) {
|
|
582
600
|
const lijst = Array.isArray(secties) ? secties : [];
|
|
@@ -584,13 +602,31 @@ export function pickMethode(secties) {
|
|
|
584
602
|
const waarde = blok
|
|
585
603
|
? String(blok.opties?.["methode"] ?? "kar")
|
|
586
604
|
: String(lijst.find((s) => s.type === "karren")?.opties?.["pickmethode"] ?? "kar");
|
|
587
|
-
|
|
605
|
+
if (waarde === "fusten")
|
|
606
|
+
return "fusten";
|
|
607
|
+
if (waarde === "beide")
|
|
608
|
+
return "beide";
|
|
609
|
+
return "kar";
|
|
588
610
|
}
|
|
589
611
|
const KAR_SECTIES = ["karren", "lagen", "producten", "fusten"];
|
|
590
612
|
/** Blokken die bij de gekozen pickmethode niet van toepassing zijn. */
|
|
591
613
|
export function sectieOnderdrukt(type, methode) {
|
|
592
614
|
return methode === "fusten" && KAR_SECTIES.includes(type);
|
|
593
615
|
}
|
|
616
|
+
/**
|
|
617
|
+
* Blokken die de Engine-variant weglaat. Zonder variant blijft de editor/het
|
|
618
|
+
* losse voorbeeld compleet; een echte Engine-opdracht wordt in de wachtrij
|
|
619
|
+
* geblokkeerd totdat de variant aanwezig is.
|
|
620
|
+
*/
|
|
621
|
+
export function sectieOnderdruktVoorVariant(type, methode, variant) {
|
|
622
|
+
if (sectieOnderdrukt(type, methode))
|
|
623
|
+
return true;
|
|
624
|
+
if (methode !== "beide" || !variant)
|
|
625
|
+
return false;
|
|
626
|
+
if (variant === "full_cart")
|
|
627
|
+
return type === "pickmethode";
|
|
628
|
+
return type === "pickmethode" ? false : [...KAR_SECTIES, "orderregels"].includes(type);
|
|
629
|
+
}
|
|
594
630
|
const p = (nr, naam, potmaat, aantal, locatie, groep, kleur) => ({
|
|
595
631
|
artikelnummer: nr,
|
|
596
632
|
artikelnaam: naam,
|
|
@@ -651,6 +687,7 @@ export const DEMO_ORDER = {
|
|
|
651
687
|
karren: [
|
|
652
688
|
{
|
|
653
689
|
karnummer: 5,
|
|
690
|
+
barcode: "VOORBEELD-KAR-05",
|
|
654
691
|
route: "Route Zuid",
|
|
655
692
|
chauffeur: "J. Bakker",
|
|
656
693
|
gewicht: "142 kg",
|
|
@@ -687,6 +724,7 @@ export const DEMO_ORDER = {
|
|
|
687
724
|
// ze samengevoegd tot één blok met "Deze kar 3× pakken".
|
|
688
725
|
...[6, 7, 8].map((nr) => ({
|
|
689
726
|
karnummer: nr,
|
|
727
|
+
barcode: `VOORBEELD-KAR-${String(nr).padStart(2, "0")}`,
|
|
690
728
|
route: "Route Zuid",
|
|
691
729
|
chauffeur: "J. Bakker",
|
|
692
730
|
gewicht: "118 kg",
|
|
@@ -813,8 +851,10 @@ function laagVingerafdruk(l) {
|
|
|
813
851
|
return [l.belading, l.potmaat, l.gewicht, l.opmerking, producten, fusten].join("#");
|
|
814
852
|
}
|
|
815
853
|
function karVingerafdruk(k) {
|
|
816
|
-
// karnummer bewust niet meegenomen: alleen de indeling telt
|
|
817
|
-
|
|
854
|
+
// karnummer bewust niet meegenomen: alleen de indeling telt. Een kar met een
|
|
855
|
+
// eigen barcode of cart_id van de Engine is wél uniek en wordt nooit gebundeld.
|
|
856
|
+
const uniek = String(k.barcode ?? "") || String(k.cart_id ?? "") || String(k.cart_label ?? "");
|
|
857
|
+
return [uniek, k.route, k.chauffeur, k.gewicht, k.gedeeld ? "gedeeld" : "", (k.lagen ?? []).map(laagVingerafdruk).join("~")].join("#");
|
|
818
858
|
}
|
|
819
859
|
/** Groepeert identieke karren. Bij `aan = false` blijft elke kar los. */
|
|
820
860
|
export function groepeerIdentiekeKarren(karren, aan) {
|
|
@@ -928,3 +968,24 @@ export function fustVerzamellijst(karren) {
|
|
|
928
968
|
}
|
|
929
969
|
return [...map.values()].sort((a, b) => a.fusttype.localeCompare(b.fusttype));
|
|
930
970
|
}
|
|
971
|
+
/**
|
|
972
|
+
* Voorbeeld van een deelkar (niet-volle kar): alleen een deel van de fusten,
|
|
973
|
+
* zonder karindeling. Uitsluitend bedoeld voor het voorbeeld in de builder —
|
|
974
|
+
* echte opdrachten krijgen hun gegevens van de Logistics Engine.
|
|
975
|
+
*/
|
|
976
|
+
export function deelkarVoorbeeldOrder(order = DEMO_ORDER) {
|
|
977
|
+
const eerste = order.karren[0];
|
|
978
|
+
const laag = eerste?.lagen?.[0];
|
|
979
|
+
if (!eerste || !laag)
|
|
980
|
+
return order;
|
|
981
|
+
return {
|
|
982
|
+
...order,
|
|
983
|
+
karren: [
|
|
984
|
+
{
|
|
985
|
+
...eerste,
|
|
986
|
+
gedeeld: true,
|
|
987
|
+
lagen: [{ ...laag, producten: laag.producten.slice(0, 1), fusten: laag.fusten?.slice(0, 1) ?? [] }],
|
|
988
|
+
},
|
|
989
|
+
],
|
|
990
|
+
};
|
|
991
|
+
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { type DemoOrder, type PakbonConfig } from "./pakbonBuilder.js";
|
|
2
|
-
/** Gegevensvorm van een pakbon.
|
|
3
|
-
export type PakbonOrder = DemoOrder
|
|
2
|
+
/** Gegevensvorm van een pakbon. Engine-metadata blijft naast ordergegevens beschikbaar. */
|
|
3
|
+
export type PakbonOrder = DemoOrder & {
|
|
4
|
+
barcode?: string;
|
|
5
|
+
cart?: {
|
|
6
|
+
cart_label?: string;
|
|
7
|
+
cart_index?: number;
|
|
8
|
+
cart_total?: number;
|
|
9
|
+
cart_id?: string;
|
|
10
|
+
cart_items?: unknown[];
|
|
11
|
+
barcode?: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
4
14
|
export interface PakbonLogo {
|
|
5
15
|
id: string;
|
|
6
16
|
naam?: string;
|
|
@@ -20,6 +30,8 @@ export interface PakbonRenderOpties {
|
|
|
20
30
|
logos?: PakbonLogo[];
|
|
21
31
|
/** Documentlogo: gebruikt wanneer een logoblok zelf geen logo heeft. */
|
|
22
32
|
logoId?: string | null;
|
|
33
|
+
/** Variant die uitsluitend door de Logistics Engine wordt bepaald. */
|
|
34
|
+
layoutVariant?: string | null;
|
|
23
35
|
}
|
|
24
36
|
export declare function esc(v: unknown): string;
|
|
25
37
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pakbonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/pakbonHtml.ts"],"names":[],"mappings":"AAUA,OAAO,
|
|
1
|
+
{"version":3,"file":"pakbonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/pakbonHtml.ts"],"names":[],"mappings":"AAUA,OAAO,EAoBL,KAAK,SAAS,EAEd,KAAK,YAAY,EAGlB,MAAM,iBAAiB,CAAC;AAKzB,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;CAC/B;AAWD,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAKtC;AAyBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAiF3D;AAgrBD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CA+CR;AAgBD,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,GAAG,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,kBAAuB,GAC9B,MAAM,CAoER;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"}
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
// layoutconfiguratie en de echte ordergegevens. Zo tonen het live voorbeeld en
|
|
8
8
|
// de afdruk altijd exact dezelfde secties — inclusief de orderregels.
|
|
9
9
|
// ============================================================================
|
|
10
|
-
import { DEMO_ORDER, conditieContext, groepeerIdentiekeKarren, groepeerIdentiekeLagen, karBundelTekst, fustVerzamellijst, pickMethode, productVeldBreedtes,
|
|
10
|
+
import { DEMO_ORDER, conditieContext, groepeerIdentiekeKarren, groepeerIdentiekeLagen, karBundelTekst, fustVerzamellijst, pickMethode, pakbonLayoutVariant, productVeldBreedtes, sectieOnderdruktVoorVariant, laagBundelTekst, leesPakbonConfig, sectieZichtbaar, sorteerProducten, totalen, vulVeldcodes, } from "./pakbonBuilder.js";
|
|
11
11
|
import { haalPrintLogos } from "./logoLibrary.js";
|
|
12
|
+
import { code128BarsHtml } from "./code128.js";
|
|
12
13
|
// --- kleine hulpjes ---------------------------------------------------------
|
|
13
14
|
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
14
15
|
const opt = (s, key, fallback) => s.opties?.[key] ?? fallback;
|
|
@@ -24,6 +25,24 @@ const cel = (p, veld) => {
|
|
|
24
25
|
return "";
|
|
25
26
|
return String(p[veld] ?? "");
|
|
26
27
|
};
|
|
28
|
+
/** Rendert uitsluitend een bestaande barcodewaarde uit de Engine-payload. */
|
|
29
|
+
function barcodeHtml(value, hoogteMm = 15) {
|
|
30
|
+
const tekst = String(value ?? "").trim();
|
|
31
|
+
if (!tekst)
|
|
32
|
+
return "";
|
|
33
|
+
const hoogte = Number.isFinite(hoogteMm) && hoogteMm > 0 ? hoogteMm : 15;
|
|
34
|
+
return `<div class="barcode"><div class="barcode-bars" data-barcode="${esc(tekst)}" style="height:${hoogte}mm">${code128BarsHtml(tekst)}</div><div>${esc(tekst)}</div></div>`;
|
|
35
|
+
}
|
|
36
|
+
/** Barcode van één pakbon; bij één geselecteerde kar mag diens Engine-barcode worden gebruikt. */
|
|
37
|
+
function pakbonBarcode(order) {
|
|
38
|
+
const direct = String(order.barcode ?? order.cart?.barcode ?? "").trim();
|
|
39
|
+
if (direct)
|
|
40
|
+
return direct;
|
|
41
|
+
const karren = Array.isArray(order.karren) ? order.karren : [];
|
|
42
|
+
if (karren.length !== 1)
|
|
43
|
+
return undefined;
|
|
44
|
+
return String(karren[0]?.barcode ?? "").trim() || undefined;
|
|
45
|
+
}
|
|
27
46
|
/**
|
|
28
47
|
* Vult ontbrekende onderdelen aan met veilige lege waarden, zodat een module
|
|
29
48
|
* die maar een deel van de gegevens heeft nooit een lege of stukke pakbon
|
|
@@ -38,11 +57,19 @@ export function maakPakbonOrder(input) {
|
|
|
38
57
|
out[v] = b[v] === undefined || b[v] === null ? "" : String(b[v]);
|
|
39
58
|
return out;
|
|
40
59
|
};
|
|
60
|
+
const cart = (bron["cart"] && typeof bron["cart"] === "object" ? bron["cart"] : {});
|
|
61
|
+
const topBarcode = String(bron["barcode"] ?? cart["barcode"] ?? "").trim();
|
|
41
62
|
const karren = arr(bron["karren"]).map((k, i) => ({
|
|
42
63
|
karnummer: Number(k["karnummer"] ?? i + 1),
|
|
64
|
+
barcode: String(k["barcode"] ?? "").trim() || undefined,
|
|
43
65
|
route: String(k["route"] ?? ""),
|
|
44
66
|
chauffeur: String(k["chauffeur"] ?? ""),
|
|
45
67
|
gewicht: String(k["gewicht"] ?? ""),
|
|
68
|
+
cart_label: String(k["cart_label"] ?? cart["cart_label"] ?? "").trim() || undefined,
|
|
69
|
+
cart_index: Number(k["cart_index"] ?? cart["cart_index"] ?? 0) || undefined,
|
|
70
|
+
cart_total: Number(k["cart_total"] ?? cart["cart_total"] ?? 0) || undefined,
|
|
71
|
+
cart_id: String(k["cart_id"] ?? cart["cart_id"] ?? "").trim() || undefined,
|
|
72
|
+
cart_items: Array.isArray(k["cart_items"] ?? cart["cart_items"]) ? (k["cart_items"] ?? cart["cart_items"]) : undefined,
|
|
46
73
|
gedeeld: k["gedeeld"] === true,
|
|
47
74
|
lagen: arr(k["lagen"]).map((l, j) => ({
|
|
48
75
|
laagnummer: Number(l["laagnummer"] ?? j + 1),
|
|
@@ -89,6 +116,15 @@ export function maakPakbonOrder(input) {
|
|
|
89
116
|
afleveradres: groep("afleveradres", ["naam", "adres", "plaats", "land"]),
|
|
90
117
|
factuuradres: groep("factuuradres", ["naam", "adres", "plaats", "land"]),
|
|
91
118
|
transport: groep("transport", ["transporteur", "route", "chauffeur", "track"]),
|
|
119
|
+
barcode: topBarcode || undefined,
|
|
120
|
+
cart: Object.keys(cart).length ? {
|
|
121
|
+
cart_label: String(cart["cart_label"] ?? "").trim() || undefined,
|
|
122
|
+
cart_index: Number(cart["cart_index"] ?? 0) || undefined,
|
|
123
|
+
cart_total: Number(cart["cart_total"] ?? 0) || undefined,
|
|
124
|
+
cart_id: String(cart["cart_id"] ?? "").trim() || undefined,
|
|
125
|
+
cart_items: Array.isArray(cart["cart_items"]) ? cart["cart_items"] : undefined,
|
|
126
|
+
barcode: String(cart["barcode"] ?? "").trim() || undefined,
|
|
127
|
+
} : undefined,
|
|
92
128
|
karren,
|
|
93
129
|
};
|
|
94
130
|
}
|
|
@@ -323,6 +359,14 @@ function karKop(s, kar, velden, bundelTekst = "") {
|
|
|
323
359
|
info.push(kar.route);
|
|
324
360
|
if (kar.gedeeld)
|
|
325
361
|
info.push("gedeelde kar");
|
|
362
|
+
const cartLabel = kar.cart_label ||
|
|
363
|
+
(kar.cart_index && kar.cart_total ? `Kar ${kar.cart_index} van ${kar.cart_total}` : "");
|
|
364
|
+
if (cartLabel)
|
|
365
|
+
info.push(cartLabel);
|
|
366
|
+
if (kar.cart_id)
|
|
367
|
+
info.push(`ID ${kar.cart_id}`);
|
|
368
|
+
if (kar.cart_items?.length)
|
|
369
|
+
info.push(`${kar.cart_items.length} karregels`);
|
|
326
370
|
const toonNummer = velden.includes("karnummer");
|
|
327
371
|
if (!toonNummer && !info.length && !bundelTekst)
|
|
328
372
|
return "";
|
|
@@ -344,6 +388,28 @@ function karKop(s, kar, velden, bundelTekst = "") {
|
|
|
344
388
|
.map((t) => `<span>${esc(t)}</span>`)
|
|
345
389
|
.join("")}</span></div>`;
|
|
346
390
|
}
|
|
391
|
+
function cartRegelsHtml(kar) {
|
|
392
|
+
const regels = arr(kar.cart_items);
|
|
393
|
+
if (!regels.length)
|
|
394
|
+
return "";
|
|
395
|
+
const velden = [
|
|
396
|
+
["artikelnummer", "Artikel"],
|
|
397
|
+
["artikelnaam", "Omschrijving"],
|
|
398
|
+
["omschrijving", "Omschrijving"],
|
|
399
|
+
["aantal", "Aantal"],
|
|
400
|
+
["eenheid", "Eenheid"],
|
|
401
|
+
];
|
|
402
|
+
const rijen = regels.map((regel) => {
|
|
403
|
+
const waarden = velden
|
|
404
|
+
.map(([sleutel]) => String(regel[sleutel] ?? "").trim())
|
|
405
|
+
.filter(Boolean);
|
|
406
|
+
const tekst = waarden.length
|
|
407
|
+
? waarden.map((waarde) => `<span>${esc(waarde)}</span>`).join(" ")
|
|
408
|
+
: Object.values(regel).map((waarde) => `<span>${esc(String(waarde ?? ""))}</span>`).join(" ");
|
|
409
|
+
return `<div class="cartregel">${tekst}</div>`;
|
|
410
|
+
});
|
|
411
|
+
return `<div class="cartregels"><div class="vet">Karregels</div>${rijen.join("")}</div>`;
|
|
412
|
+
}
|
|
347
413
|
function laagKop(s, laag, velden, compact, bundelTekst = "") {
|
|
348
414
|
const tekst = optS(s, "koptekst", "Laag {laag}").replace(/\{laag\}/g, String(laag.laagnummer));
|
|
349
415
|
const info = [];
|
|
@@ -367,14 +433,16 @@ function bundelMelding(tekst) {
|
|
|
367
433
|
return `<div class="bundel">${esc(tekst)}</div>`;
|
|
368
434
|
}
|
|
369
435
|
function karBlok(s, kar, lagen, zoek, omkaderd, aantal = 1) {
|
|
370
|
-
//
|
|
371
|
-
|
|
436
|
+
// Alleen bij écht samengevoegde karren vervalt het unieke karnummer; een
|
|
437
|
+
// losse kar (bijv. met eigen Engine-barcode) houdt zijn eigen gegevens.
|
|
438
|
+
const bundelt = opt(s, "bundel_identiek", true) !== false && aantal > 1;
|
|
372
439
|
const velden = lijst(s, "velden").filter((v) => !(bundelt && (v === "karnummer" || v === "barcode" || v === "qrcode")));
|
|
373
440
|
const lagenSectie = zoek("lagen");
|
|
374
441
|
const productSectie = zoek("producten");
|
|
375
442
|
const fustSectie = zoek("fusten");
|
|
376
443
|
const lagenModus = lagenSectie ? optS(lagenSectie, "modus", "apart") : "geen";
|
|
377
444
|
let inhoud = karKop(s, kar, velden, karBundelTekst(aantal));
|
|
445
|
+
inhoud += cartRegelsHtml(kar);
|
|
378
446
|
if (lagen.length && lagenSectie && lagenModus !== "geen") {
|
|
379
447
|
const lVelden = lijst(lagenSectie, "velden");
|
|
380
448
|
const toonProducten = lagenModus !== "nummer" && lagenModus !== "regel";
|
|
@@ -392,6 +460,10 @@ function karBlok(s, kar, lagen, zoek, omkaderd, aantal = 1) {
|
|
|
392
460
|
}
|
|
393
461
|
if (fustSectie && optS(fustSectie, "modus", "totaal") === "kar")
|
|
394
462
|
inhoud += fustTabel(lijst(fustSectie, "velden"), lagen.flatMap((l) => l.fusten), `Fusten kar ${kar.karnummer}`);
|
|
463
|
+
// Een volle-karpakbon kan meerdere karren/pagina's bevatten. De barcode
|
|
464
|
+
// hoort daarom in het eigen karblok en niet één keer onderaan de serie.
|
|
465
|
+
if (kar.barcode)
|
|
466
|
+
inhoud += barcodeHtml(kar.barcode);
|
|
395
467
|
return `<div class="karblok${omkaderd ? " omkaderd" : ""}">${inhoud}</div>`;
|
|
396
468
|
}
|
|
397
469
|
const FUST_KOLOM_LABELS = {
|
|
@@ -558,7 +630,7 @@ function sectieHtml(s, order, zoek, opties) {
|
|
|
558
630
|
return titelHtml(s) + body;
|
|
559
631
|
}
|
|
560
632
|
case "pickmethode":
|
|
561
|
-
if (optS(s, "methode", "kar")
|
|
633
|
+
if (optS(s, "methode", "kar") === "kar")
|
|
562
634
|
return "";
|
|
563
635
|
return fustVerzamellijstHtml(order, s);
|
|
564
636
|
case "karren":
|
|
@@ -591,8 +663,11 @@ function sectieHtml(s, order, zoek, opties) {
|
|
|
591
663
|
return `<div class="${opt(s, "kader", false) ? "kader" : ""}" style="font-size:${Number(opt(s, "fontgrootte", 9))}pt">${esc(vulVeldcodes(optS(s, "tekst", ""), order))}</div>`;
|
|
592
664
|
case "qrcode":
|
|
593
665
|
return `<div><div class="qr" style="width:${Number(opt(s, "grootte", 25))}mm;height:${Number(opt(s, "grootte", 25))}mm"></div><div class="klein">${esc(vulVeldcodes(optS(s, "waarde", ""), order))}</div></div>`;
|
|
594
|
-
case "barcode":
|
|
595
|
-
|
|
666
|
+
case "barcode": {
|
|
667
|
+
// Alleen de Engine-waarde mag op de pakbon komen; nooit een lokaal
|
|
668
|
+
// gegenereerde orderwaarde of een layout-default als barcode gebruiken.
|
|
669
|
+
return barcodeHtml(pakbonBarcode(order), Number(opt(s, "hoogte", 15)));
|
|
670
|
+
}
|
|
596
671
|
case "afbeelding": {
|
|
597
672
|
const url = optS(s, "url", "");
|
|
598
673
|
return url
|
|
@@ -610,20 +685,36 @@ export function renderPakbonBody(config, order, opties = {}) {
|
|
|
610
685
|
const ctx = conditieContext(order);
|
|
611
686
|
const alleSecties = arr(cfg.secties);
|
|
612
687
|
const methode = pickMethode(alleSecties);
|
|
613
|
-
const
|
|
688
|
+
const variant = pakbonLayoutVariant(opties.layoutVariant);
|
|
689
|
+
const secties = alleSecties.filter((s) => sectieZichtbaar(s, ctx) && !sectieOnderdruktVoorVariant(s.type, methode, variant));
|
|
690
|
+
const heeftKarBarcodes = secties.some((s) => s.type === "karren") &&
|
|
691
|
+
(Array.isArray(order.karren) ? order.karren : []).some((kar) => Boolean(String(kar.barcode ?? "").trim()));
|
|
614
692
|
const zoek = (t) => secties.find((s) => s.type === t);
|
|
615
693
|
const opts = { ...opties, logoId: opties.logoId ?? cfg.logo?.logoId ?? null };
|
|
616
|
-
const
|
|
694
|
+
const variantKop = variant
|
|
695
|
+
? `<div class="pakbonvariant">${variant === "full_cart" ? "HELE KAR" : "DEELKAR"}</div>`
|
|
696
|
+
: "";
|
|
697
|
+
const kop = variantKop + documentLogoHtml(cfg.logo, opts);
|
|
617
698
|
const totalenSectie = zoek("totalen");
|
|
618
699
|
const totalenElkePagina = !!totalenSectie && opt(totalenSectie, "elke_pagina", false) === true;
|
|
619
700
|
const inhoud = secties
|
|
620
701
|
.filter((s) => !(s.type === "totalen" && totalenElkePagina))
|
|
702
|
+
.filter((s) => !(s.type === "barcode" && heeftKarBarcodes))
|
|
621
703
|
.map((s) => s.type === "karren" ? karrenHtml(s, order, zoek) : blokFrame(s, sectieHtml(s, order, zoek, opts)))
|
|
622
704
|
.join("");
|
|
705
|
+
const pickSectie = alleSecties.find((s) => s.type === "pickmethode");
|
|
706
|
+
const pickInstellingen = pickSectie ?? alleSecties[0];
|
|
707
|
+
// Elke pakbon krijgt de Engine-barcode wanneer die is aangeleverd. Een
|
|
708
|
+
// expliciet barcodeblok rendert hem zelf; anders voegen we hem één keer
|
|
709
|
+
// automatisch toe. Zonder Engine-barcode wordt nooit een waarde verzonnen.
|
|
710
|
+
const automatischeBarcode = !heeftKarBarcodes && !secties.some((s) => s.type === "barcode");
|
|
711
|
+
const barcode = automatischeBarcode
|
|
712
|
+
? barcodeHtml(pakbonBarcode(order), Number(pickInstellingen ? opt(pickInstellingen, "barcodeHoogte", 15) : 15))
|
|
713
|
+
: "";
|
|
623
714
|
const voet = totalenElkePagina && totalenSectie
|
|
624
715
|
? `<div class="paginavoet">${sectieHtml(totalenSectie, order, zoek, opts)}</div>`
|
|
625
716
|
: "";
|
|
626
|
-
return kop + inhoud + voet;
|
|
717
|
+
return kop + inhoud + (barcode ? `<div class="blok">${barcode}</div>` : "") + voet;
|
|
627
718
|
}
|
|
628
719
|
/** Het documentlogo bovenaan de pakbon. */
|
|
629
720
|
function documentLogoHtml(logoCfg, opties) {
|
|
@@ -647,60 +738,61 @@ export function renderPakbonDocument(config, order, opties = {}) {
|
|
|
647
738
|
// leest dit uit de meta, zodat de wachtrij niets extra hoeft door te geven.
|
|
648
739
|
const totalen = arr(leesPakbonConfig(config).secties).find((s) => s.type === "totalen");
|
|
649
740
|
const paginanummers = !!totalen && opt(totalen, "toon_paginanummer", false) === true;
|
|
650
|
-
return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
|
|
651
|
-
<meta name="pdf-paginanummers" content="${paginanummers ? "ja" : "nee"}" />
|
|
652
|
-
<title>${esc(opties.titel ?? "Pakbon")}</title>
|
|
653
|
-
|
|
654
|
-
<style>
|
|
655
|
-
@page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
|
|
656
|
-
* { box-sizing: border-box; }
|
|
657
|
-
html, body { margin: 0; padding: 0; }
|
|
658
|
-
body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
|
|
659
|
-
.
|
|
660
|
-
.
|
|
661
|
-
.
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
.
|
|
665
|
-
.kv
|
|
666
|
-
.kv .
|
|
667
|
-
.
|
|
668
|
-
.
|
|
669
|
-
|
|
670
|
-
table.regels
|
|
671
|
-
table.regels.vast
|
|
672
|
-
table.regels
|
|
673
|
-
table.regels th
|
|
674
|
-
.
|
|
675
|
-
.
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
.
|
|
679
|
-
.
|
|
680
|
-
.
|
|
681
|
-
.
|
|
682
|
-
.
|
|
683
|
-
.karblok
|
|
684
|
-
.
|
|
685
|
-
.
|
|
686
|
-
.
|
|
687
|
-
.
|
|
688
|
-
.laagkop
|
|
689
|
-
.
|
|
690
|
-
.
|
|
691
|
-
.
|
|
692
|
-
.
|
|
693
|
-
.
|
|
694
|
-
.lijnveld
|
|
695
|
-
.
|
|
696
|
-
.
|
|
697
|
-
.
|
|
698
|
-
.
|
|
699
|
-
.
|
|
700
|
-
.
|
|
701
|
-
.
|
|
702
|
-
|
|
703
|
-
|
|
741
|
+
return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
|
|
742
|
+
<meta name="pdf-paginanummers" content="${paginanummers ? "ja" : "nee"}" />
|
|
743
|
+
<title>${esc(opties.titel ?? "Pakbon")}</title>
|
|
744
|
+
|
|
745
|
+
<style>
|
|
746
|
+
@page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
|
|
747
|
+
* { box-sizing: border-box; }
|
|
748
|
+
html, body { margin: 0; padding: 0; }
|
|
749
|
+
body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
|
|
750
|
+
.pakbonvariant { border-top: 0.6mm solid #111827; border-bottom: 0.6mm solid #111827; padding: 2mm 1mm; margin-bottom: 2mm; text-align: center; font-size: 15pt; font-weight: 800; line-height: 1.1; }
|
|
751
|
+
.blok { margin-bottom: 2mm; }
|
|
752
|
+
.sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
|
|
753
|
+
.fustgroepkop { display: flex; justify-content: space-between; font-weight: 600; color: #111827; border-bottom: 0.45mm solid #111827; padding-bottom: 0.5mm; margin-bottom: 0.6mm; }
|
|
754
|
+
|
|
755
|
+
.vet { font-weight: 600; }
|
|
756
|
+
.kv { display: flex; justify-content: space-between; gap: 3mm; }
|
|
757
|
+
.kv .k { color: #6b7280; }
|
|
758
|
+
.kv .v { font-weight: 500; }
|
|
759
|
+
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
|
|
760
|
+
.kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
761
|
+
table.regels { width: 100%; border-collapse: collapse; }
|
|
762
|
+
table.regels.vast { table-layout: fixed; }
|
|
763
|
+
table.regels.vast td, table.regels.vast th { overflow-wrap: anywhere; }
|
|
764
|
+
table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
|
|
765
|
+
table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
|
|
766
|
+
.rand { border: 0.2mm solid #d1d5db; }
|
|
767
|
+
.onder { border-bottom: 0.2mm solid #d1d5db; }
|
|
768
|
+
table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
|
|
769
|
+
tr.zebra td { background: #f3f4f6; }
|
|
770
|
+
.plijst { margin: 0; padding-left: 4mm; }
|
|
771
|
+
.groep { margin-bottom: 1.5mm; }
|
|
772
|
+
.regelrij { display: flex; gap: 2mm; }
|
|
773
|
+
.tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
|
|
774
|
+
.karblok { margin-bottom: 2mm; }
|
|
775
|
+
.karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
776
|
+
.karkop { display: flex; justify-content: space-between; align-items: center; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; }
|
|
777
|
+
.bundel { display: inline-block; border: 0.3mm dashed #6b7280; border-radius: 1mm; padding: 0.4mm 1.5mm; margin-bottom: 1mm; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2mm; font-size: 90%; }
|
|
778
|
+
.laag { margin-bottom: 1.5mm; }
|
|
779
|
+
.laagkop { display: flex; justify-content: space-between; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; }
|
|
780
|
+
.laagkop.compact { border-bottom: none; }
|
|
781
|
+
.meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
|
|
782
|
+
.totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
|
|
783
|
+
.paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-top: 0.35mm solid #9ca3af; padding-top: 1mm; }
|
|
784
|
+
.handtekening { margin-top: 3mm; }
|
|
785
|
+
.lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
|
|
786
|
+
.lijnveld.hoog { padding-bottom: 10mm; }
|
|
787
|
+
.lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
|
|
788
|
+
.balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
|
|
789
|
+
.qr { border: 0.25mm dashed #9ca3af; }
|
|
790
|
+
.barcode { display:flex; flex-direction:column; align-items:center; gap:0.8mm; } .barcode-bars { width:45mm; display:flex; background:#fff; }
|
|
791
|
+
.klein { font-size: 85%; color: #6b7280; }
|
|
792
|
+
.breekvoor { break-before: page; page-break-before: always; }
|
|
793
|
+
.heelhouden { break-inside: avoid; page-break-inside: avoid; }
|
|
794
|
+
img { max-width: 100%; }
|
|
795
|
+
</style></head>
|
|
704
796
|
<body>${body}</body></html>`;
|
|
705
797
|
}
|
|
706
798
|
/** Handig voor testen: het document met de voorbeeldgegevens. */
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type PakbonLayoutVariant } from "./pakbonBuilder.js";
|
|
2
|
+
export interface PakbonScanRegel {
|
|
3
|
+
artikelnummer: string;
|
|
4
|
+
artikelnaam: string;
|
|
5
|
+
potmaat: string;
|
|
6
|
+
kleur: string;
|
|
7
|
+
fustsoort: string;
|
|
8
|
+
planten_per_fust: number;
|
|
9
|
+
aantal: number;
|
|
10
|
+
fust_aantal: number;
|
|
11
|
+
}
|
|
12
|
+
export interface PakbonScanInhoud {
|
|
13
|
+
barcode: string;
|
|
14
|
+
order_ref: string | null;
|
|
15
|
+
order_nummer: string | null;
|
|
16
|
+
klant_naam: string | null;
|
|
17
|
+
klant_nummer: string | null;
|
|
18
|
+
cart_id: string | null;
|
|
19
|
+
cart_label: string | null;
|
|
20
|
+
cart_index: number | null;
|
|
21
|
+
cart_total: number | null;
|
|
22
|
+
layout_variant: PakbonLayoutVariant | null;
|
|
23
|
+
layout_id: string | null;
|
|
24
|
+
print_job_id: string | null;
|
|
25
|
+
is_herprint: boolean;
|
|
26
|
+
regels: PakbonScanRegel[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Bouwt de scanregel uit de order zoals die op de pakbon is gerenderd.
|
|
30
|
+
* Bij een deelkar (`partial_order`) staan uitsluitend de fusten van die
|
|
31
|
+
* deelkar op de pakbon, dus ook uitsluitend die regels in de registratie.
|
|
32
|
+
*/
|
|
33
|
+
export declare function bouwPakbonScanInhoud(order: unknown, opties: {
|
|
34
|
+
barcode: unknown;
|
|
35
|
+
layoutVariant?: PakbonLayoutVariant | null;
|
|
36
|
+
layoutId?: string | null;
|
|
37
|
+
printJobId?: string | null;
|
|
38
|
+
isHerprint?: boolean;
|
|
39
|
+
}): PakbonScanInhoud | null;
|
|
40
|
+
/** Slaat de scaninhoud op; een herprint werkt dezelfde barcode bij. */
|
|
41
|
+
export declare function bewaarPakbonScanInhoud(db: {
|
|
42
|
+
from: (tabel: string) => any;
|
|
43
|
+
}, inhoud: PakbonScanInhoud | null): Promise<void>;
|
|
44
|
+
//# sourceMappingURL=pakbonScan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pakbonScan.d.ts","sourceRoot":"","sources":["../../src/lib/pakbonScan.ts"],"names":[],"mappings":"AASA,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAWD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE;IACN,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GACA,gBAAgB,GAAG,IAAI,CA8EzB;AAED,uEAAuE;AACvE,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE;IAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAA;CAAE,EACpC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAC9B,OAAO,CAAC,IAAI,CAAC,CAMf"}
|