@kreiseck/kasseneck-api 0.10.0 → 0.12.0
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/CHANGELOG.md +94 -1
- package/README.md +41 -0
- package/dist/cjs/client/receipts.d.ts +8 -0
- package/dist/cjs/client/receipts.js +18 -0
- package/dist/cjs/printing/escpos.d.ts +85 -1
- package/dist/cjs/printing/escpos.js +140 -4
- package/dist/cjs/printing/index.d.ts +2 -1
- package/dist/cjs/printing/index.js +13 -1
- package/dist/cjs/printing/qr-groesse.d.ts +122 -0
- package/dist/cjs/printing/qr-groesse.js +126 -0
- package/dist/cjs/receipt/epos.d.ts +42 -1
- package/dist/cjs/receipt/epos.js +66 -5
- package/dist/cjs/receipt/index.d.ts +2 -2
- package/dist/cjs/receipt/index.js +3 -1
- package/dist/cjs/receipt/layout-escpos.d.ts +50 -2
- package/dist/cjs/receipt/layout-escpos.js +59 -2
- package/dist/esm/client/receipts.d.ts +8 -0
- package/dist/esm/client/receipts.js +18 -0
- package/dist/esm/printing/escpos.d.ts +85 -1
- package/dist/esm/printing/escpos.js +138 -4
- package/dist/esm/printing/index.d.ts +2 -1
- package/dist/esm/printing/index.js +2 -1
- package/dist/esm/printing/qr-groesse.d.ts +122 -0
- package/dist/esm/printing/qr-groesse.js +120 -0
- package/dist/esm/receipt/epos.d.ts +42 -1
- package/dist/esm/receipt/epos.js +65 -5
- package/dist/esm/receipt/index.d.ts +2 -2
- package/dist/esm/receipt/index.js +2 -2
- package/dist/esm/receipt/layout-escpos.d.ts +50 -2
- package/dist/esm/receipt/layout-escpos.js +59 -3
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/oberflaeche.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { PosPaperSize, QrSize } from './escpos.js';
|
|
2
|
+
/**
|
|
3
|
+
* Die Rechenregel fuer die Modulgroesse des Beleg-QR — rein, ohne Drucker.
|
|
4
|
+
* Zwilling von `kasseneck_api/lib/src/printing/qr_groesse.dart` (Flutter).
|
|
5
|
+
*
|
|
6
|
+
* Vorgeschichte: der native QR-Befehl bekommt eine feste Modulgroesse in
|
|
7
|
+
* Druckpunkten mit und rechnet nicht nach, ob das Symbol aufs Papier passt.
|
|
8
|
+
* Ein Beleg-QR mit realer RKSV-Nutzlast hat 57 Module, mit Ruhezone also
|
|
9
|
+
* (57 + 8) Module breit; bei sechs Punkten je Modul sind das 390 Druckpunkte,
|
|
10
|
+
* und ein 58-mm-Kopf hat 384. Zu breit heisst bei den meisten Geraeten nicht
|
|
11
|
+
* "abgeschnitten", sondern **gar kein QR** — auf einem Pflichtbeleg der
|
|
12
|
+
* schlechteste aller Ausgaenge. (Im Flutter-Zwilling war genau das der
|
|
13
|
+
* belegte Fehler; dieses Paket druckt seit jeher mit vier Punkten und blieb
|
|
14
|
+
* darum verschont. Die Regel ist trotzdem dieselbe: sie deckelt auch eine
|
|
15
|
+
* ausdruecklich gewaehlte groessere Modulgroesse gegen den Papierrand ab.)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Wie gross die Module des Beleg-QR werden duerfen — ein **Deckel**, keine
|
|
19
|
+
* Vorgabe: gedruckt wird immer die groesste Groesse, die noch aufs Papier
|
|
20
|
+
* passt, hoechstens aber diese hier.
|
|
21
|
+
*
|
|
22
|
+
* `auto` und `klein` decken beide bei 4 — das ist kein Versehen. 4 ist der
|
|
23
|
+
* Wert, den der native Weg dieses Pakets seit jeher druckt
|
|
24
|
+
* (`qrCodeBytes(..., size ?? 4)`); ohne diesen Deckel bekaeme jedes Geraet ab
|
|
25
|
+
* sofort ungefragt einen groesseren QR als gestern. `auto` heisst also
|
|
26
|
+
* "rechne, aber aendere den Bestand nicht".
|
|
27
|
+
*
|
|
28
|
+
* **Abweichung zum Flutter-Zwilling, bewusst:** dort deckelt `auto` bei 6,
|
|
29
|
+
* weil dort 6 der Bestandswert ist. Die Regel ist in beiden Paketen
|
|
30
|
+
* dieselbe — "so gross wie moeglich, hoechstens der Bestandswert" —, nur der
|
|
31
|
+
* Bestandswert unterscheidet sich. `mittel` (6) und `gross` (8) sind in
|
|
32
|
+
* beiden Paketen gleich; sie waehlt ein Mensch.
|
|
33
|
+
*/
|
|
34
|
+
export type QrModulGroesse = 'auto' | 'klein' | 'mittel' | 'gross';
|
|
35
|
+
/** Groesste Modulgroesse in Druckpunkten, die der jeweilige Deckel zulaesst. */
|
|
36
|
+
export declare const QR_MODUL_DECKEL: Readonly<Record<QrModulGroesse, number>>;
|
|
37
|
+
/**
|
|
38
|
+
* Ergebnis der Modulgroessen-Rechnung.
|
|
39
|
+
*
|
|
40
|
+
* Traegt bewusst mehr als die Zahl: ob ueberhaupt etwas passt (`passt`), ob
|
|
41
|
+
* nur unter der Mindestgroesse (`unterMindestmass`) und wie breit das Symbol
|
|
42
|
+
* wird (`breitePunkte`). Eine blosse Zahl haette die Ausnahme verschwiegen.
|
|
43
|
+
*/
|
|
44
|
+
export interface QrGroesse {
|
|
45
|
+
/**
|
|
46
|
+
* Modulgroesse in Druckpunkten, `null` wenn das Symbol auch mit der
|
|
47
|
+
* Ausnahmegroesse nicht aufs Papier passt.
|
|
48
|
+
*/
|
|
49
|
+
readonly punkte: QrSize | null;
|
|
50
|
+
/** Modulanzahl des Symbols (ohne Ruhezone). */
|
|
51
|
+
readonly module: number;
|
|
52
|
+
/** Gesamtbreite inklusive Ruhezone in Druckpunkten; 0, wenn nichts passt. */
|
|
53
|
+
readonly breitePunkte: number;
|
|
54
|
+
/**
|
|
55
|
+
* Gedruckt wird unter `QR_MINDEST_PUNKTE`. Erlaubt, aber eine Ausnahme, von
|
|
56
|
+
* der der Aufrufer erfahren muss — billige Thermodrucker und Handykameras
|
|
57
|
+
* tun sich damit schwer, besonders auf gewelltem Papier.
|
|
58
|
+
*/
|
|
59
|
+
readonly unterMindestmass: boolean;
|
|
60
|
+
/** Kurz fuer `punkte !== null`. */
|
|
61
|
+
readonly passt: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Ruhezone je Seite, in Modulen (QR-Norm). */
|
|
64
|
+
export declare const QR_RUHEZONE_MODULE = 4;
|
|
65
|
+
/** Untergrenze: 4 Punkte sind bei 203 dpi rund 0,5 mm je Modul. */
|
|
66
|
+
export declare const QR_MINDEST_PUNKTE = 4;
|
|
67
|
+
/** Ausnahme, wenn `QR_MINDEST_PUNKTE` nicht passt — gemeldet, nicht still. */
|
|
68
|
+
export declare const QR_AUSNAHME_PUNKTE = 3;
|
|
69
|
+
/** Obergrenze des Druckbefehls in diesem Stack (`GS ( k` Funktion 167: 1..8). */
|
|
70
|
+
export declare const QR_HOECHST_PUNKTE = 8;
|
|
71
|
+
/**
|
|
72
|
+
* Druckbreite des Kopfes in Punkten (203 dpi): 58 mm = 384, 80 mm = 576 —
|
|
73
|
+
* Zwilling von `KeckPaperSize.druckPunkte`.
|
|
74
|
+
*
|
|
75
|
+
* Nicht dasselbe wie die Spaltenbreite in `escpos.ts` (372/558): die stammt
|
|
76
|
+
* aus `EscPaperSize.width` und laesst absichtlich Rand fuer die
|
|
77
|
+
* Textpositionierung. Wer rechnet, ob ein Symbol aufs Papier passt, braucht
|
|
78
|
+
* die echte Kopfbreite — ein QR, der auch nur einen Punkt zu breit ist, wird
|
|
79
|
+
* von den meisten Geraeten gar nicht gedruckt.
|
|
80
|
+
*/
|
|
81
|
+
export declare const QR_DRUCK_PUNKTE: Readonly<Record<PosPaperSize, number>>;
|
|
82
|
+
/**
|
|
83
|
+
* Modulanzahl, die `nutzlast` bei Fehlerkorrektur **M** braucht.
|
|
84
|
+
*
|
|
85
|
+
* Warum M, obwohl der native Befehl mit L druckt: M braucht bei gleicher
|
|
86
|
+
* Nutzlast gleich viele oder mehr Module als L. Wer mit M rechnet und mit L
|
|
87
|
+
* druckt, druckt nie breiter als gerechnet — die Rechnung ist konservativ,
|
|
88
|
+
* nie knapp. Umgekehrt waere sie eine Rechnung, die aufgeht, und ein Symbol,
|
|
89
|
+
* das ueber den Papierrand laeuft. Dasselbe gilt fuer die Byte-Zaehlung: hier
|
|
90
|
+
* zaehlt UTF-8 (wie im Flutter-Zwilling), waehrend `qrCodeBytes` die Nutzlast
|
|
91
|
+
* als Latin-1 sendet — UTF-8 ist nie kuerzer, die Rechnung also nie zu klein.
|
|
92
|
+
*
|
|
93
|
+
* Wirft, wenn die Nutzlast in keine Version passt — wie `qrCodeBytes` bei zu
|
|
94
|
+
* langem Inhalt. Ein still zurueckgegebenes "passt nicht" haette den
|
|
95
|
+
* Datenfehler als Papierfehler getarnt.
|
|
96
|
+
*/
|
|
97
|
+
export declare function qrModulAnzahl(nutzlast: string): number;
|
|
98
|
+
/**
|
|
99
|
+
* Groesste Modulgroesse, mit der `moduleAnzahl` Module **samt Ruhezone** in
|
|
100
|
+
* `papierbreitePunkte` passen, gedeckelt durch `groesse`.
|
|
101
|
+
*
|
|
102
|
+
* Wirft bei sinnlosen Eingaben: eine Papierbreite von 0 oder ein Symbol ohne
|
|
103
|
+
* Module ist ein Programmierfehler, und ein still zurueckgegebenes "passt
|
|
104
|
+
* nicht" haette ihn als Druckerproblem getarnt.
|
|
105
|
+
*/
|
|
106
|
+
export declare function qrGroesseBerechnen(options: {
|
|
107
|
+
papierbreitePunkte: number;
|
|
108
|
+
moduleAnzahl: number;
|
|
109
|
+
groesse?: QrModulGroesse;
|
|
110
|
+
}): QrGroesse;
|
|
111
|
+
/**
|
|
112
|
+
* Wie `qrGroesseBerechnen`, nur mit der Modulanzahl aus `nutzlast`.
|
|
113
|
+
*
|
|
114
|
+
* Eine leere Nutzlast ergibt kein Symbol — sie "passt nicht", statt zu
|
|
115
|
+
* werfen: der Aufrufer behandelt den Fall ohnehin schon (leerer QR am Beleg
|
|
116
|
+
* ist ein Datenfehler, kein Papierfehler).
|
|
117
|
+
*/
|
|
118
|
+
export declare function qrGroesseFuer(options: {
|
|
119
|
+
nutzlast: string;
|
|
120
|
+
papierbreitePunkte: number;
|
|
121
|
+
groesse?: QrModulGroesse;
|
|
122
|
+
}): QrGroesse;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QR_DRUCK_PUNKTE = exports.QR_HOECHST_PUNKTE = exports.QR_AUSNAHME_PUNKTE = exports.QR_MINDEST_PUNKTE = exports.QR_RUHEZONE_MODULE = exports.QR_MODUL_DECKEL = void 0;
|
|
4
|
+
exports.qrModulAnzahl = qrModulAnzahl;
|
|
5
|
+
exports.qrGroesseBerechnen = qrGroesseBerechnen;
|
|
6
|
+
exports.qrGroesseFuer = qrGroesseFuer;
|
|
7
|
+
/** Groesste Modulgroesse in Druckpunkten, die der jeweilige Deckel zulaesst. */
|
|
8
|
+
exports.QR_MODUL_DECKEL = {
|
|
9
|
+
auto: 4,
|
|
10
|
+
klein: 4,
|
|
11
|
+
mittel: 6,
|
|
12
|
+
gross: 8,
|
|
13
|
+
};
|
|
14
|
+
// --------------------------------------------------------------- Konstanten
|
|
15
|
+
/** Ruhezone je Seite, in Modulen (QR-Norm). */
|
|
16
|
+
exports.QR_RUHEZONE_MODULE = 4;
|
|
17
|
+
/** Untergrenze: 4 Punkte sind bei 203 dpi rund 0,5 mm je Modul. */
|
|
18
|
+
exports.QR_MINDEST_PUNKTE = 4;
|
|
19
|
+
/** Ausnahme, wenn `QR_MINDEST_PUNKTE` nicht passt — gemeldet, nicht still. */
|
|
20
|
+
exports.QR_AUSNAHME_PUNKTE = 3;
|
|
21
|
+
/** Obergrenze des Druckbefehls in diesem Stack (`GS ( k` Funktion 167: 1..8). */
|
|
22
|
+
exports.QR_HOECHST_PUNKTE = 8;
|
|
23
|
+
/**
|
|
24
|
+
* Druckbreite des Kopfes in Punkten (203 dpi): 58 mm = 384, 80 mm = 576 —
|
|
25
|
+
* Zwilling von `KeckPaperSize.druckPunkte`.
|
|
26
|
+
*
|
|
27
|
+
* Nicht dasselbe wie die Spaltenbreite in `escpos.ts` (372/558): die stammt
|
|
28
|
+
* aus `EscPaperSize.width` und laesst absichtlich Rand fuer die
|
|
29
|
+
* Textpositionierung. Wer rechnet, ob ein Symbol aufs Papier passt, braucht
|
|
30
|
+
* die echte Kopfbreite — ein QR, der auch nur einen Punkt zu breit ist, wird
|
|
31
|
+
* von den meisten Geraeten gar nicht gedruckt.
|
|
32
|
+
*/
|
|
33
|
+
exports.QR_DRUCK_PUNKTE = { mm58: 384, mm80: 576 };
|
|
34
|
+
/**
|
|
35
|
+
* Nutzlast in Byte, die eine QR-Version 1..40 bei Fehlerkorrektur **M** im
|
|
36
|
+
* Byte-Modus aufnimmt (ISO/IEC 18004, Tabelle 7).
|
|
37
|
+
*
|
|
38
|
+
* Byte-Modus, weil die RKSV-Nutzlast beliebige Zeichen traegt; Ziffern- oder
|
|
39
|
+
* Alphanumerik-Modus waere enger gefasst und wuerde fuer denselben Text
|
|
40
|
+
* weniger Module ergeben — also zu klein rechnen.
|
|
41
|
+
*/
|
|
42
|
+
const BYTE_KAPAZITAET_M = [
|
|
43
|
+
14, 26, 42, 62, 84, 106, 122, 152, 180, 213,
|
|
44
|
+
251, 287, 331, 362, 412, 450, 504, 560, 624, 666,
|
|
45
|
+
711, 779, 857, 911, 997, 1059, 1125, 1190, 1264, 1370,
|
|
46
|
+
1452, 1538, 1628, 1722, 1809, 1911, 1989, 2099, 2213, 2331,
|
|
47
|
+
];
|
|
48
|
+
// ------------------------------------------------------------- oeffentlich
|
|
49
|
+
/**
|
|
50
|
+
* Modulanzahl, die `nutzlast` bei Fehlerkorrektur **M** braucht.
|
|
51
|
+
*
|
|
52
|
+
* Warum M, obwohl der native Befehl mit L druckt: M braucht bei gleicher
|
|
53
|
+
* Nutzlast gleich viele oder mehr Module als L. Wer mit M rechnet und mit L
|
|
54
|
+
* druckt, druckt nie breiter als gerechnet — die Rechnung ist konservativ,
|
|
55
|
+
* nie knapp. Umgekehrt waere sie eine Rechnung, die aufgeht, und ein Symbol,
|
|
56
|
+
* das ueber den Papierrand laeuft. Dasselbe gilt fuer die Byte-Zaehlung: hier
|
|
57
|
+
* zaehlt UTF-8 (wie im Flutter-Zwilling), waehrend `qrCodeBytes` die Nutzlast
|
|
58
|
+
* als Latin-1 sendet — UTF-8 ist nie kuerzer, die Rechnung also nie zu klein.
|
|
59
|
+
*
|
|
60
|
+
* Wirft, wenn die Nutzlast in keine Version passt — wie `qrCodeBytes` bei zu
|
|
61
|
+
* langem Inhalt. Ein still zurueckgegebenes "passt nicht" haette den
|
|
62
|
+
* Datenfehler als Papierfehler getarnt.
|
|
63
|
+
*/
|
|
64
|
+
function qrModulAnzahl(nutzlast) {
|
|
65
|
+
const laenge = new TextEncoder().encode(nutzlast).length;
|
|
66
|
+
for (let i = 0; i < BYTE_KAPAZITAET_M.length; i++) {
|
|
67
|
+
if (laenge <= BYTE_KAPAZITAET_M[i])
|
|
68
|
+
return 17 + 4 * (i + 1);
|
|
69
|
+
}
|
|
70
|
+
throw new Error('QR-Inhalt ist zu lang');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Groesste Modulgroesse, mit der `moduleAnzahl` Module **samt Ruhezone** in
|
|
74
|
+
* `papierbreitePunkte` passen, gedeckelt durch `groesse`.
|
|
75
|
+
*
|
|
76
|
+
* Wirft bei sinnlosen Eingaben: eine Papierbreite von 0 oder ein Symbol ohne
|
|
77
|
+
* Module ist ein Programmierfehler, und ein still zurueckgegebenes "passt
|
|
78
|
+
* nicht" haette ihn als Druckerproblem getarnt.
|
|
79
|
+
*/
|
|
80
|
+
function qrGroesseBerechnen(options) {
|
|
81
|
+
const { papierbreitePunkte, moduleAnzahl } = options;
|
|
82
|
+
const groesse = options.groesse ?? 'auto';
|
|
83
|
+
if (!Number.isInteger(papierbreitePunkte) || papierbreitePunkte <= 0) {
|
|
84
|
+
throw new Error('papierbreitePunkte muss eine Ganzzahl > 0 sein');
|
|
85
|
+
}
|
|
86
|
+
if (!Number.isInteger(moduleAnzahl) || moduleAnzahl <= 0) {
|
|
87
|
+
throw new Error('moduleAnzahl muss eine Ganzzahl > 0 sein');
|
|
88
|
+
}
|
|
89
|
+
const roh = exports.QR_MODUL_DECKEL[groesse];
|
|
90
|
+
if (roh === undefined) {
|
|
91
|
+
throw new Error(`Unbekannte QR-Modulgroesse: ${String(groesse)}`);
|
|
92
|
+
}
|
|
93
|
+
const gesamtModule = moduleAnzahl + exports.QR_RUHEZONE_MODULE * 2;
|
|
94
|
+
const passend = Math.floor(papierbreitePunkte / gesamtModule);
|
|
95
|
+
if (passend < exports.QR_AUSNAHME_PUNKTE) {
|
|
96
|
+
return { punkte: null, module: moduleAnzahl, breitePunkte: 0, unterMindestmass: false, passt: false };
|
|
97
|
+
}
|
|
98
|
+
const deckel = Math.min(Math.max(roh, exports.QR_AUSNAHME_PUNKTE), exports.QR_HOECHST_PUNKTE);
|
|
99
|
+
const punkte = passend < exports.QR_MINDEST_PUNKTE ? exports.QR_AUSNAHME_PUNKTE : Math.min(passend, deckel);
|
|
100
|
+
return {
|
|
101
|
+
punkte: punkte,
|
|
102
|
+
module: moduleAnzahl,
|
|
103
|
+
breitePunkte: gesamtModule * punkte,
|
|
104
|
+
unterMindestmass: punkte < exports.QR_MINDEST_PUNKTE,
|
|
105
|
+
passt: true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Wie `qrGroesseBerechnen`, nur mit der Modulanzahl aus `nutzlast`.
|
|
110
|
+
*
|
|
111
|
+
* Eine leere Nutzlast ergibt kein Symbol — sie "passt nicht", statt zu
|
|
112
|
+
* werfen: der Aufrufer behandelt den Fall ohnehin schon (leerer QR am Beleg
|
|
113
|
+
* ist ein Datenfehler, kein Papierfehler).
|
|
114
|
+
*/
|
|
115
|
+
function qrGroesseFuer(options) {
|
|
116
|
+
if (options.nutzlast === '') {
|
|
117
|
+
return { punkte: null, module: 0, breitePunkte: 0, unterMindestmass: false, passt: false };
|
|
118
|
+
}
|
|
119
|
+
const weiter = {
|
|
120
|
+
papierbreitePunkte: options.papierbreitePunkte,
|
|
121
|
+
moduleAnzahl: qrModulAnzahl(options.nutzlast),
|
|
122
|
+
};
|
|
123
|
+
if (options.groesse !== undefined)
|
|
124
|
+
weiter.groesse = options.groesse;
|
|
125
|
+
return qrGroesseBerechnen(weiter);
|
|
126
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReceiptLayout } from './layout.js';
|
|
2
2
|
import type { PosPaperSize } from '../printing/escpos.js';
|
|
3
|
+
import { type QrModulGroesse } from '../printing/index.js';
|
|
3
4
|
/**
|
|
4
5
|
* ePOS-Print XML (Epson TM-Drucker: Server Direct Print, ePOS-Print ueber
|
|
5
6
|
* HTTP) -- **aus dem Zeichenraster**: jede Rasterzeile wird eine <text>-Zeile
|
|
@@ -14,13 +15,49 @@ import type { PosPaperSize } from '../printing/escpos.js';
|
|
|
14
15
|
export interface EposPrintXmlOptions {
|
|
15
16
|
/** Zeichen je Zeile; Vorgabe nach `layout.paperSize` (32/48). */
|
|
16
17
|
zeichen?: number;
|
|
17
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* **Feste** QR-Modulgroesse (Epson `width` 3..16). Gesetzt schaltet sie die
|
|
20
|
+
* Rechnung ab -- dann passt der Aufrufer selbst auf, dass das Symbol samt
|
|
21
|
+
* Ruhezone auf die Rolle geht.
|
|
22
|
+
*/
|
|
18
23
|
qrBreite?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Deckel fuer die gerechnete QR-Modulgroesse; Vorgabe `mittel`.
|
|
26
|
+
*
|
|
27
|
+
* Warum `mittel` und nicht `auto`: `auto` deckelt beim Bestandswert des
|
|
28
|
+
* **ESC/POS**-Befehls dieses Pakets (4), dieser Weg druckt aber seit jeher
|
|
29
|
+
* mit 6. Die Vorgabe nennt den Bestandswert dieses Wegs also ausdruecklich,
|
|
30
|
+
* damit ohne Wahl kein Byte anders herauskommt.
|
|
31
|
+
*/
|
|
32
|
+
qrGroesse?: QrModulGroesse;
|
|
19
33
|
/** Papierschnitt am Ende, Vorgabe true. */
|
|
20
34
|
cut?: boolean;
|
|
21
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Das XML **samt** dem, was dem QR unterwegs zugestossen ist -- dieselbe
|
|
38
|
+
* Buchfuehrung wie `EscPosLayoutErgebnis` am ESC/POS-Weg.
|
|
39
|
+
*/
|
|
40
|
+
export interface EposPrintErgebnis {
|
|
41
|
+
xml: string;
|
|
42
|
+
/** Der Beleg ging ohne QR hinaus; das Symbol passt auch mit 3 Punkten nicht. */
|
|
43
|
+
qrFehler: string | null;
|
|
44
|
+
/** Der QR steht da, aber unter der Mindest-Modulgroesse. */
|
|
45
|
+
qrAusweich: string | null;
|
|
46
|
+
}
|
|
22
47
|
export declare function eposXmlEscape(text: string): string;
|
|
48
|
+
/** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
|
|
23
49
|
export declare function eposPrintXml(layout: ReceiptLayout, options?: EposPrintXmlOptions): string;
|
|
50
|
+
/**
|
|
51
|
+
* Wie [eposPrintXml], gibt aber zusaetzlich zurueck, was dem QR zugestossen
|
|
52
|
+
* ist.
|
|
53
|
+
*
|
|
54
|
+
* **Die QR-Modulgroesse wird gerechnet.** Vorher stand hier fest 6, unabhaengig
|
|
55
|
+
* von der Papierbreite: ein Beleg-QR mit realer RKSV-Nutzlast hat 57 Module,
|
|
56
|
+
* mit Ruhezone 65, bei sechs Punkten also 390 Druckpunkte -- und ein
|
|
57
|
+
* 58-mm-Kopf hat 384. Der Epson schneidet ein zu breites Symbol nicht ab, er
|
|
58
|
+
* laesst es weg; genau daran fehlte am echten Beleg der QR.
|
|
59
|
+
*/
|
|
60
|
+
export declare function eposPrintXmlErgebnis(layout: ReceiptLayout, options?: EposPrintXmlOptions): EposPrintErgebnis;
|
|
24
61
|
/**
|
|
25
62
|
* Epson-Drucker mit ePOS-Print direkt aus dem Browser ansprechen (ohne
|
|
26
63
|
* Server-Umweg): POST an `https://<ip>/cgi-bin/epos/service.cgi`. Der Drucker
|
|
@@ -36,6 +73,10 @@ export interface EposDirectOptions {
|
|
|
36
73
|
devid?: string;
|
|
37
74
|
/** Papier des Druckers -- bestimmt das Raster; Vorgabe: das des Layouts. */
|
|
38
75
|
papier?: PosPaperSize;
|
|
76
|
+
/** Feste QR-Modulgroesse; siehe [EposPrintXmlOptions.qrBreite]. */
|
|
77
|
+
qrBreite?: number;
|
|
78
|
+
/** Deckel fuer die gerechnete QR-Modulgroesse; siehe [EposPrintXmlOptions.qrGroesse]. */
|
|
79
|
+
qrGroesse?: QrModulGroesse;
|
|
39
80
|
timeoutMs?: number;
|
|
40
81
|
}
|
|
41
82
|
export interface EposResponse {
|
package/dist/cjs/receipt/epos.js
CHANGED
|
@@ -3,19 +3,71 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.EposConnectionError = void 0;
|
|
4
4
|
exports.eposXmlEscape = eposXmlEscape;
|
|
5
5
|
exports.eposPrintXml = eposPrintXml;
|
|
6
|
+
exports.eposPrintXmlErgebnis = eposPrintXmlErgebnis;
|
|
6
7
|
exports.eposServiceUrl = eposServiceUrl;
|
|
7
8
|
exports.eposSoapEnvelope = eposSoapEnvelope;
|
|
8
9
|
exports.eposParseResponse = eposParseResponse;
|
|
9
10
|
exports.eposDirectPrint = eposDirectPrint;
|
|
10
11
|
exports.eposDirectStatus = eposDirectStatus;
|
|
12
|
+
const index_js_1 = require("../printing/index.js");
|
|
11
13
|
const grid_js_1 = require("./grid.js");
|
|
12
14
|
function eposXmlEscape(text) {
|
|
13
15
|
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
14
16
|
}
|
|
15
17
|
const NS = 'http://www.epson-pos.com/schemas/2011/03/epos-print';
|
|
18
|
+
/** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
|
|
16
19
|
function eposPrintXml(layout, options = {}) {
|
|
20
|
+
return eposPrintXmlErgebnis(layout, options).xml;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Wie [eposPrintXml], gibt aber zusaetzlich zurueck, was dem QR zugestossen
|
|
24
|
+
* ist.
|
|
25
|
+
*
|
|
26
|
+
* **Die QR-Modulgroesse wird gerechnet.** Vorher stand hier fest 6, unabhaengig
|
|
27
|
+
* von der Papierbreite: ein Beleg-QR mit realer RKSV-Nutzlast hat 57 Module,
|
|
28
|
+
* mit Ruhezone 65, bei sechs Punkten also 390 Druckpunkte -- und ein
|
|
29
|
+
* 58-mm-Kopf hat 384. Der Epson schneidet ein zu breites Symbol nicht ab, er
|
|
30
|
+
* laesst es weg; genau daran fehlte am echten Beleg der QR.
|
|
31
|
+
*/
|
|
32
|
+
function eposPrintXmlErgebnis(layout, options = {}) {
|
|
17
33
|
const grid = (0, grid_js_1.renderReceiptGrid)(layout, { zeichen: options.zeichen ?? grid_js_1.ZEICHEN_JE_PAPIER[layout.paperSize] });
|
|
18
|
-
const
|
|
34
|
+
const deckel = options.qrGroesse ?? 'mittel';
|
|
35
|
+
const fest = options.qrBreite === undefined
|
|
36
|
+
? null
|
|
37
|
+
: Math.min(16, Math.max(3, Math.floor(options.qrBreite)));
|
|
38
|
+
let qrFehler = null;
|
|
39
|
+
let qrAusweich = null;
|
|
40
|
+
/**
|
|
41
|
+
* Die Breite fuer eine QR-Zeile, oder `null` -- dann geht **kein** Symbol
|
|
42
|
+
* hinaus: ein Element, von dem man weiss, dass der Drucker es weglaesst,
|
|
43
|
+
* taeuscht nur einen Ausdruck vor.
|
|
44
|
+
*
|
|
45
|
+
* Eine leere Nutzlast geht unveraendert den Bestandsweg (Deckel), wie am
|
|
46
|
+
* ESC/POS-Befehl: sie ist ein Datenfehler, kein Papierfehler.
|
|
47
|
+
*/
|
|
48
|
+
const qrBreiteFuer = (nutzlast) => {
|
|
49
|
+
if (fest !== null)
|
|
50
|
+
return fest;
|
|
51
|
+
if (nutzlast === '')
|
|
52
|
+
return index_js_1.QR_MODUL_DECKEL[deckel];
|
|
53
|
+
const mass = (0, index_js_1.qrGroesseFuer)({
|
|
54
|
+
nutzlast,
|
|
55
|
+
papierbreitePunkte: index_js_1.QR_DRUCK_PUNKTE[layout.paperSize],
|
|
56
|
+
groesse: deckel,
|
|
57
|
+
});
|
|
58
|
+
if (!mass.passt) {
|
|
59
|
+
qrFehler =
|
|
60
|
+
`QR mit ${mass.module} Modulen ist fuer ${layout.paperSize === 'mm58' ? 58 : 80} mm ` +
|
|
61
|
+
`(${index_js_1.QR_DRUCK_PUNKTE[layout.paperSize]} Punkte) zu breit`;
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (mass.unterMindestmass) {
|
|
65
|
+
qrAusweich =
|
|
66
|
+
`QR mit ${mass.module} Modulen passt nur mit ${String(mass.punkte)} Punkten ` +
|
|
67
|
+
`je Modul -- unter dem Mindestmass von ${index_js_1.QR_MINDEST_PUNKTE}`;
|
|
68
|
+
}
|
|
69
|
+
return mass.punkte;
|
|
70
|
+
};
|
|
19
71
|
const out = [];
|
|
20
72
|
out.push(`<epos-print xmlns="${NS}">`);
|
|
21
73
|
out.push('<text lang="de"/>');
|
|
@@ -27,11 +79,15 @@ function eposPrintXml(layout, options = {}) {
|
|
|
27
79
|
case 'space':
|
|
28
80
|
out.push('<feed line="1"/>');
|
|
29
81
|
break;
|
|
30
|
-
case 'qr':
|
|
82
|
+
case 'qr': {
|
|
83
|
+
const breite = qrBreiteFuer(z.qr ?? '');
|
|
84
|
+
if (breite === null)
|
|
85
|
+
break;
|
|
31
86
|
out.push('<text align="center"/>');
|
|
32
|
-
out.push(`<symbol type="qrcode_model_2" level="level_m" width="${
|
|
87
|
+
out.push(`<symbol type="qrcode_model_2" level="level_m" width="${breite}" height="0" size="0">${eposXmlEscape(z.qr ?? '')}</symbol>`);
|
|
33
88
|
out.push('<text align="left"/>');
|
|
34
89
|
break;
|
|
90
|
+
}
|
|
35
91
|
case 'banner':
|
|
36
92
|
out.push(`<text width="1" height="2" reverse="${z.ton === 'warnung' ? 'true' : 'false'}" em="true">${eposXmlEscape(z.text)} </text>`);
|
|
37
93
|
out.push('<text width="1" height="1" reverse="false" em="false"/>');
|
|
@@ -51,7 +107,7 @@ function eposPrintXml(layout, options = {}) {
|
|
|
51
107
|
out.push('<cut type="feed"/>');
|
|
52
108
|
}
|
|
53
109
|
out.push('</epos-print>');
|
|
54
|
-
return out.join('\n');
|
|
110
|
+
return { xml: out.join('\n'), qrFehler, qrAusweich };
|
|
55
111
|
}
|
|
56
112
|
const EPOS_DEVID_VORGABE = 'local_printer';
|
|
57
113
|
function eposServiceUrl(ip, devid = EPOS_DEVID_VORGABE, timeoutMs = 10000) {
|
|
@@ -159,7 +215,12 @@ async function eposDirectSend(innerXml, o, fetchFn) {
|
|
|
159
215
|
/** Beleg direkt drucken; wirft bei Netz-/Zertifikatsproblemen, sonst die Drucker-Antwort. */
|
|
160
216
|
function eposDirectPrint(layout, o, fetchFn = fetch) {
|
|
161
217
|
const papier = o.papier ?? layout.paperSize;
|
|
162
|
-
|
|
218
|
+
const xmlOptionen = { zeichen: grid_js_1.ZEICHEN_JE_PAPIER[papier] };
|
|
219
|
+
if (o.qrBreite !== undefined)
|
|
220
|
+
xmlOptionen.qrBreite = o.qrBreite;
|
|
221
|
+
if (o.qrGroesse !== undefined)
|
|
222
|
+
xmlOptionen.qrGroesse = o.qrGroesse;
|
|
223
|
+
return eposDirectSend(eposPrintXml({ ...layout, paperSize: papier }, xmlOptionen), o, fetchFn);
|
|
163
224
|
}
|
|
164
225
|
/** Verbindungstest: leeres Dokument, druckt nichts, liefert den Druckerstatus. */
|
|
165
226
|
function eposDirectStatus(o, fetchFn = fetch) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { type LayoutAlign, type LayoutColumn, type LayoutTextLine, type LayoutColumnsLine, type LayoutRuleLine, type LayoutSpaceLine, type LayoutQrLine, type LayoutLine, type ReceiptLayout, type BuildReceiptLayoutOptions, buildReceiptLayout, receiptSignatureFailed, receiptSignatureIsTest, receiptIsZero, receiptAmountsAreZero, receiptIsSmallBusinessConsistent, receiptZdaText, type Pruefangaben, AKTUELLES_REGELWERK, type LayoutBannerLine, type LayoutRegelwerk, SMALL_BUSINESS_NOTICE, formatCents, } from './layout.js';
|
|
2
|
-
export { type EscPosLayoutOptions, escPosLayoutBytes } from './layout-escpos.js';
|
|
2
|
+
export { type EscPosLayoutOptions, type EscPosLayoutErgebnis, type QrPrintMode, escPosLayoutBytes, escPosLayoutErgebnis, } from './layout-escpos.js';
|
|
3
3
|
export { type GridLine, type GridLineKind, type ReceiptGrid, type RenderReceiptGridOptions, renderReceiptGrid, gridSpaltenBreiten, gridAlsText, ZEICHEN_JE_PAPIER, } from './grid.js';
|
|
4
|
-
export { type EposPrintXmlOptions, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposXmlEscape, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
4
|
+
export { type EposPrintXmlOptions, type EposPrintErgebnis, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlErgebnis, eposXmlEscape, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposXmlEscape = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutBytes = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
3
|
+
exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposXmlEscape = exports.eposPrintXmlErgebnis = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutErgebnis = exports.escPosLayoutBytes = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
4
4
|
var layout_js_1 = require("./layout.js");
|
|
5
5
|
Object.defineProperty(exports, "buildReceiptLayout", { enumerable: true, get: function () { return layout_js_1.buildReceiptLayout; } });
|
|
6
6
|
Object.defineProperty(exports, "receiptSignatureFailed", { enumerable: true, get: function () { return layout_js_1.receiptSignatureFailed; } });
|
|
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "SMALL_BUSINESS_NOTICE", { enumerable: true, get:
|
|
|
14
14
|
Object.defineProperty(exports, "formatCents", { enumerable: true, get: function () { return layout_js_1.formatCents; } });
|
|
15
15
|
var layout_escpos_js_1 = require("./layout-escpos.js");
|
|
16
16
|
Object.defineProperty(exports, "escPosLayoutBytes", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutBytes; } });
|
|
17
|
+
Object.defineProperty(exports, "escPosLayoutErgebnis", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutErgebnis; } });
|
|
17
18
|
var grid_js_1 = require("./grid.js");
|
|
18
19
|
Object.defineProperty(exports, "renderReceiptGrid", { enumerable: true, get: function () { return grid_js_1.renderReceiptGrid; } });
|
|
19
20
|
Object.defineProperty(exports, "gridSpaltenBreiten", { enumerable: true, get: function () { return grid_js_1.gridSpaltenBreiten; } });
|
|
@@ -22,6 +23,7 @@ Object.defineProperty(exports, "ZEICHEN_JE_PAPIER", { enumerable: true, get: fun
|
|
|
22
23
|
var epos_js_1 = require("./epos.js");
|
|
23
24
|
Object.defineProperty(exports, "EposConnectionError", { enumerable: true, get: function () { return epos_js_1.EposConnectionError; } });
|
|
24
25
|
Object.defineProperty(exports, "eposPrintXml", { enumerable: true, get: function () { return epos_js_1.eposPrintXml; } });
|
|
26
|
+
Object.defineProperty(exports, "eposPrintXmlErgebnis", { enumerable: true, get: function () { return epos_js_1.eposPrintXmlErgebnis; } });
|
|
25
27
|
Object.defineProperty(exports, "eposXmlEscape", { enumerable: true, get: function () { return epos_js_1.eposXmlEscape; } });
|
|
26
28
|
Object.defineProperty(exports, "eposServiceUrl", { enumerable: true, get: function () { return epos_js_1.eposServiceUrl; } });
|
|
27
29
|
Object.defineProperty(exports, "eposSoapEnvelope", { enumerable: true, get: function () { return epos_js_1.eposSoapEnvelope; } });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrSize } from '../printing/index.js';
|
|
1
|
+
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrMatrix, type QrModulGroesse, type QrSize } from '../printing/index.js';
|
|
2
2
|
import type { ReceiptLayout } from './layout.js';
|
|
3
3
|
/**
|
|
4
4
|
* Bruecke vom Layout-Modell zu ESC/POS-Bytes — der Bondrucker-Ausgabeweg.
|
|
@@ -14,6 +14,20 @@ import type { ReceiptLayout } from './layout.js';
|
|
|
14
14
|
* ein unerwartetes Zeichen darin soll darum auffallen und nicht still
|
|
15
15
|
* verfaelscht werden.
|
|
16
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* Wie der Beleg-QR auf das Papier kommt — Zwilling von `QrPrintMode`
|
|
19
|
+
* (kasseneck_api/lib/enums/qr_print_mode.dart).
|
|
20
|
+
*
|
|
21
|
+
* - `native` — der Druckbefehl `GS ( k`; der Drucker zeichnet selbst.
|
|
22
|
+
* Ohne Modellbefehl, also byteidentisch zum Bestand.
|
|
23
|
+
* - `nativeModel1` — derselbe Befehl mit ausdruecklicher Wahl von **Modell 1**
|
|
24
|
+
* (`GS ( k 04 00 31 41 31 00`). Fuer guenstige Geraete, die
|
|
25
|
+
* nur diesen aelteren Symboltyp beherrschen; belegt ist
|
|
26
|
+
* eines, das bei Modell 2 unter dem Code eine "0" ausgibt.
|
|
27
|
+
* - `imageRaster` — der QR als Rasterbild. Braucht ein Raster vom Aufrufer
|
|
28
|
+
* (`qrMatrix`), weil dieses Paket keine QR-Codes rechnet.
|
|
29
|
+
*/
|
|
30
|
+
export type QrPrintMode = 'native' | 'nativeModel1' | 'imageRaster';
|
|
17
31
|
export interface EscPosLayoutOptions {
|
|
18
32
|
/** Papierbreite; Vorgabe ist die des Layouts (dessen Spaltenbreiten daran haengen). */
|
|
19
33
|
paperSize?: PosPaperSize;
|
|
@@ -21,10 +35,38 @@ export interface EscPosLayoutOptions {
|
|
|
21
35
|
codeTable?: PosCodeTable | null;
|
|
22
36
|
/** Papierschnitt am Ende: `true` (voll), `'partial'` oder `false`. Vorgabe `true`. */
|
|
23
37
|
cut?: boolean | PosCutMode;
|
|
24
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Feste Modulgroesse des QR-Codes. Gesetzt schaltet sie die Rechnung ab —
|
|
40
|
+
* dann passt der Aufrufer selbst auf, dass das Symbol aufs Papier geht.
|
|
41
|
+
*/
|
|
25
42
|
qrSize?: QrSize;
|
|
26
43
|
/** Fehlerkorrekturstufe des QR-Codes. */
|
|
27
44
|
qrCorrection?: QrCorrection;
|
|
45
|
+
/** Deckel fuer die gerechnete Modulgroesse; Vorgabe `auto`. */
|
|
46
|
+
qrGroesse?: QrModulGroesse;
|
|
47
|
+
/** Druckweg des QR; Vorgabe `native` (der Bestandsweg). */
|
|
48
|
+
qrModus?: QrPrintMode;
|
|
49
|
+
/**
|
|
50
|
+
* Raster fuer den Bildweg — ohne das gibt es keinen Notausgang.
|
|
51
|
+
*
|
|
52
|
+
* Dieses Paket rechnet keine QR-Codes und verarbeitet keine Bilder (siehe
|
|
53
|
+
* Kopf von `layout.ts`); der Aufrufer bringt das fertige Raster mit, etwa
|
|
54
|
+
* aus der QR-Bibliothek, die er ohnehin fuer den Bildschirm benutzt.
|
|
55
|
+
*/
|
|
56
|
+
qrMatrix?: (nutzlast: string) => QrMatrix;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Der Bytestrom **samt** dem, was dem QR unterwegs zugestossen ist.
|
|
60
|
+
*
|
|
61
|
+
* Zwilling von `KeckPrintResult`: `qrFehler` heisst "Beleg ohne QR,
|
|
62
|
+
* nachdrucken oder elektronisch ausgeben", `qrAusweich` heisst "gedruckt,
|
|
63
|
+
* aber der eingestellte Weg taugt fuer dieses Geraet nicht" — das eine gehoert
|
|
64
|
+
* dem Kunden gesagt, das andere dem Chef.
|
|
65
|
+
*/
|
|
66
|
+
export interface EscPosLayoutErgebnis {
|
|
67
|
+
bytes: Uint8Array;
|
|
68
|
+
qrFehler: string | null;
|
|
69
|
+
qrAusweich: string | null;
|
|
28
70
|
}
|
|
29
71
|
/**
|
|
30
72
|
* Bytes fuer den Bondrucker -- **aus dem Zeichenraster** ([renderReceiptGrid]):
|
|
@@ -33,3 +75,9 @@ export interface EscPosLayoutOptions {
|
|
|
33
75
|
* zeigt, druckt der Drucker (Monospace, Font A: 32/48 Zeichen).
|
|
34
76
|
*/
|
|
35
77
|
export declare function escPosLayoutBytes(layout: ReceiptLayout, options?: EscPosLayoutOptions): Uint8Array;
|
|
78
|
+
/**
|
|
79
|
+
* Wie [escPosLayoutBytes], gibt aber zusaetzlich zurueck, was dem QR
|
|
80
|
+
* zugestossen ist. Die Bytes sind dieselben; wer die Meldungen braucht, nimmt
|
|
81
|
+
* diesen Weg.
|
|
82
|
+
*/
|
|
83
|
+
export declare function escPosLayoutErgebnis(layout: ReceiptLayout, options?: EscPosLayoutOptions): EscPosLayoutErgebnis;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.escPosLayoutBytes = escPosLayoutBytes;
|
|
4
|
+
exports.escPosLayoutErgebnis = escPosLayoutErgebnis;
|
|
4
5
|
const index_js_1 = require("../printing/index.js");
|
|
5
6
|
const grid_js_1 = require("./grid.js");
|
|
6
7
|
/**
|
|
@@ -29,6 +30,14 @@ function druckbaresLayout(layout) {
|
|
|
29
30
|
* zeigt, druckt der Drucker (Monospace, Font A: 32/48 Zeichen).
|
|
30
31
|
*/
|
|
31
32
|
function escPosLayoutBytes(layout, options = {}) {
|
|
33
|
+
return escPosLayoutErgebnis(layout, options).bytes;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Wie [escPosLayoutBytes], gibt aber zusaetzlich zurueck, was dem QR
|
|
37
|
+
* zugestossen ist. Die Bytes sind dieselben; wer die Meldungen braucht, nimmt
|
|
38
|
+
* diesen Weg.
|
|
39
|
+
*/
|
|
40
|
+
function escPosLayoutErgebnis(layout, options = {}) {
|
|
32
41
|
const paperSize = options.paperSize ?? layout.paperSize;
|
|
33
42
|
const dokumentOptionen = { paperSize };
|
|
34
43
|
if (options.codeTable !== undefined) {
|
|
@@ -36,11 +45,59 @@ function escPosLayoutBytes(layout, options = {}) {
|
|
|
36
45
|
}
|
|
37
46
|
const doc = (0, index_js_1.createEscPosDocument)(dokumentOptionen);
|
|
38
47
|
(0, index_js_1.escPosReset)(doc);
|
|
48
|
+
const modus = options.qrModus ?? 'native';
|
|
39
49
|
const qrOptionen = { align: 'center' };
|
|
40
50
|
if (options.qrSize !== undefined)
|
|
41
51
|
qrOptionen.size = options.qrSize;
|
|
42
52
|
if (options.qrCorrection !== undefined)
|
|
43
53
|
qrOptionen.correction = options.qrCorrection;
|
|
54
|
+
if (options.qrGroesse !== undefined)
|
|
55
|
+
qrOptionen.groesse = options.qrGroesse;
|
|
56
|
+
if (modus === 'nativeModel1')
|
|
57
|
+
qrOptionen.modell1 = true;
|
|
58
|
+
if (modus === 'imageRaster' && options.qrMatrix === undefined) {
|
|
59
|
+
throw new Error("qrModus 'imageRaster' braucht ein qrMatrix -- dieses Paket rastert nicht selbst");
|
|
60
|
+
}
|
|
61
|
+
const rasterOptionen = { align: 'center' };
|
|
62
|
+
if (options.qrGroesse !== undefined)
|
|
63
|
+
rasterOptionen.groesse = options.qrGroesse;
|
|
64
|
+
/**
|
|
65
|
+
* Eine QR-Zeile des Rasters. Hier sitzt der **Notausgang**: passt das Symbol
|
|
66
|
+
* nativ auch mit der Ausnahmegroesse nicht aufs Papier, druckt der Drucker
|
|
67
|
+
* es GAR NICHT -- er schneidet nicht ab, er laesst weg. Ein Pflichtbeleg
|
|
68
|
+
* ohne QR ist der schlechteste aller Ausgaenge, also geht der QR dann als
|
|
69
|
+
* Bild hinaus, und der Aufrufer erfaehrt es ueber `qrAusweich`.
|
|
70
|
+
*
|
|
71
|
+
* Ohne `qrMatrix` gibt es diesen Weg nicht -- dann bleibt nur die Meldung
|
|
72
|
+
* `qrFehler` aus `escPosQrCode`, und der Beleg geht ohne QR hinaus.
|
|
73
|
+
*/
|
|
74
|
+
const qrZeile = (nutzlast) => {
|
|
75
|
+
const raster = options.qrMatrix;
|
|
76
|
+
if (nutzlast !== '' && raster !== undefined) {
|
|
77
|
+
if (modus === 'imageRaster') {
|
|
78
|
+
(0, index_js_1.escPosQrRaster)(doc, raster(nutzlast), rasterOptionen);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Feste `qrSize` heisst: der Aufrufer weiss, was er tut -- dann wird
|
|
82
|
+
// weder gerechnet noch ausgewichen.
|
|
83
|
+
if (options.qrSize === undefined) {
|
|
84
|
+
const mass = (0, index_js_1.qrGroesseFuer)({
|
|
85
|
+
nutzlast,
|
|
86
|
+
papierbreitePunkte: index_js_1.QR_DRUCK_PUNKTE[paperSize],
|
|
87
|
+
groesse: options.qrGroesse ?? 'auto',
|
|
88
|
+
});
|
|
89
|
+
if (!mass.passt) {
|
|
90
|
+
doc.qrAusweich =
|
|
91
|
+
`QR mit ${mass.module} Modulen passt nativ nicht auf ` +
|
|
92
|
+
`${paperSize === 'mm58' ? 58 : 80} mm (${index_js_1.QR_DRUCK_PUNKTE[paperSize]} Punkte) ` +
|
|
93
|
+
`-- als Bild gedruckt`;
|
|
94
|
+
(0, index_js_1.escPosQrRaster)(doc, raster(nutzlast), rasterOptionen);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
(0, index_js_1.escPosQrCode)(doc, nutzlast, qrOptionen);
|
|
100
|
+
};
|
|
44
101
|
const grid = (0, grid_js_1.renderReceiptGrid)(druckbaresLayout(layout), { zeichen: grid_js_1.ZEICHEN_JE_PAPIER[paperSize] });
|
|
45
102
|
for (const zeile of grid.lines) {
|
|
46
103
|
switch (zeile.kind) {
|
|
@@ -48,7 +105,7 @@ function escPosLayoutBytes(layout, options = {}) {
|
|
|
48
105
|
(0, index_js_1.escPosFeed)(doc, 1);
|
|
49
106
|
break;
|
|
50
107
|
case 'qr':
|
|
51
|
-
(
|
|
108
|
+
qrZeile(zeile.qr ?? '');
|
|
52
109
|
break;
|
|
53
110
|
case 'banner': {
|
|
54
111
|
// Belegart/Warnung: fett zwischen zwei Volllinien — derselbe Rahmen-
|
|
@@ -68,5 +125,5 @@ function escPosLayoutBytes(layout, options = {}) {
|
|
|
68
125
|
if (options.cut !== false) {
|
|
69
126
|
(0, index_js_1.escPosCut)(doc, options.cut === 'partial' ? 'partial' : 'full');
|
|
70
127
|
}
|
|
71
|
-
return (0, index_js_1.escPosBytes)(doc);
|
|
128
|
+
return { bytes: (0, index_js_1.escPosBytes)(doc), qrFehler: doc.qrFehler, qrAusweich: doc.qrAusweich };
|
|
72
129
|
}
|
|
@@ -117,6 +117,14 @@ export type CancelReceiptOptions = {
|
|
|
117
117
|
note?: string;
|
|
118
118
|
/** Rueckzahlweg; ohne Angabe die Zahlungsart des stornierten Belegs. */
|
|
119
119
|
paymentMethod?: KeckPaymentMethod | KeckPaymentMethodKey;
|
|
120
|
+
/**
|
|
121
|
+
* Kartendaten der ERSTATTUNG (Gutschrift oder Aufhebung am Terminal) fuer
|
|
122
|
+
* den Kartenblock am Storno-Bon -- nur bei Rueckzahlweg Karte. Beschreiben
|
|
123
|
+
* nie die Originalzahlung; das Backend uebernimmt sie nicht vom Original.
|
|
124
|
+
*/
|
|
125
|
+
creditCardProvider?: CreditCardProvider;
|
|
126
|
+
cardPaymentId?: string;
|
|
127
|
+
cardPaymentData?: Record<string, unknown>;
|
|
120
128
|
} & ({
|
|
121
129
|
receipt: Receipt;
|
|
122
130
|
cashregisterId?: string;
|