Receipt Layout
Layout
For printing a fiscal transaction the data has to be formatted, this is done using the HTML templating engine PUG (former JADE). Language details can be found on https://pugjs.org. For Hungarian fiscal printers the item description and additional text lines may be formatted freely, but referring amounts are printed in a fixed format by the printer.
Following rules occur for bbox eKasa fiscal receipts:
- all lines up to 48 characters
- barcodes may be printed in the footer
- paper is cut after print completion
You can start http://localhost:5618/peri/pugedit for layout configuration, it works as a WYSIWYG editor. In this case HTML acts as device independent meta language, the EFR renders the content as possible onto the line printer. Besides fiscal.pug different non-fiscal layout files can be provided on directory /EFR/rn/def/cfg, the file name is derived from the NF or DT tag: NF="Login" => "login.pug" (filename lowercase).
PUG Editor
Workflow:
- start http://localhost:5618/peri/pugedit with a browser
- [open] e.g. file /EFR/HU/cfg/fiscal.pug.template
- copy your sample transaction data into the textbox at the left side
- the right side box shows the transaction data transformed to HTML
- modifications in PUG code (center box) are shown immediately
- when finished [download] e.g. as fiscal.pug and copy it to /EFR/rn/def/cfg/
EFR now transforms every transaction into HTML and renders to the line printer. By their nature fiscal printers provide only very limited formatting functionality. At the moment the editor implementation is basic, but it is going to be evolved as base technique for transaction rendering and print layout.
Layout Example
/EFR/app/HU/cfg/fiscal.pug.template:
//- fiscal.pug - Layout for Fiscal Transactions
-
function fDec(dec) { return dec.replace(/\./,',') }
function fQty(Qty) { if (Qty || Qty===0) return fDec(Qty.toString()) }
function fAmt(Amt) { if (Amt || Amt===0) return fDec(Amt.replace?Amt:Amt.toFixed(2)) }
function fPrc(Prc) { return fDec((Prc+'%').replace(/%%$/,'%')) }
function fD(D) { return D.substr(8,2)+'-'+D.substr(5,2)+'-'+D.substr(2,2) }
function fTime(D) { return D.substr(11,8).replace(/^0/,'') }
mixin row(arr)
if arr
hr
each e in arr
div(class=e._)
if e.Qty
.Lin
.Dsc2= ' ' + fQty(e.Qty) + ' ' + (e.QtyU||'') + ' x ' + fAmt(e.Pri)
if e.TaxG
if e._!='Tax'
.Dsc= e.Dsc
else
.DscTax
.Prc= fPrc(e.Prc)
.Net= fAmt(e.Net)
.TAmt= fAmt(e.TAmt)
.TaxG= e.TaxG
else if e.Dsc
.Dsc2= e.Dsc
if !/^-*$/.test(e.LAmt)
.Amt= fAmt(e.LAmt||e.Amt)
else
.Amt
hr
mixin txt(arr)
if arr
br
each e, k in arr
if '_' !== k
.Txt= 'string'===typeof e ? e.replace(/\r/g, '') : 'Txt'===e._ ? e.value.replace(/\r/g, '') : unknown
html
head
title= ESR.DT||ESR.NF||'Receipt'
style(type='text/css').
body { font-family:Courier; width:48ch }
.Txt,.Disp { text-align:center; white-space:pre }
.Pos,.Mod,.Lin,.Tot,.Pay,.Tax
{ display:grid; grid-template-columns:39ch 1ch 8ch }
.Dsc { grid-column:1 }
.TaxG { }
.Dsc2 { grid-column:1/span2 }
.DscTax { width:90%; display:grid; grid-template-columns:4fr 10fr 10fr }
.Prc { }
.Net, .TAmt { text-align:right }
.Amt { text-align:right; grid-column:3 }
@media fiscal {
.Disp,.Tax,.Tot { display:none }}
body
hr
if Cfg && Cfg.Cmp && Cfg.Loc
.Disp= Cfg.Cmp.Nam
.Disp= Cfg.Loc.Adr + ' ' + Cfg.Loc.Zip + ' ' + Cfg.Loc.City
.Disp= 'TaxId: ' + Cfg.Cmp.TaxId
if ESR.OprN
.Txt= ESR.OprN
.Txt= Array(48 + 1).join('-')
+txt(ESR.Head)
+row(ESR.PosA)
+row([{ _: 'Tot', Dsc: 'TOTAL', Amt: ESR.T }])
+row(ESR.PayA)
+row(ESR.TaxA)
+txt(ESR.Foot)
hr
.Txt= 'Terminal: ' + ESR.TL + '/' + ESR.TT + ' ' + (ESR.NF||'Receipt') + ': ' + ESR.TN
.Txt= fD(ESR.D) + ' ' + fTime(ESR.D)
//div
// img(data-barcode="type=ean13" data-value="978020137962"
style="width:30ch;height:3ch")
Restrictions
The fiscal printer allows only layout of header and footer lines and item text, amounts are formatted by the printer. Although transaction data usually is provided with UTF-8 encoding, not all characters can be printed. E.g. printing of the Euro symbol is not allowed.
Barcode
To add a barcode to a fiscal or non-fiscal layout enter:
div
img(data-barcode="type=ean13" data-value="123456789012" style="width:30ch;height:3ch")
The data-barcode attribute defines barcode parameters, data-value the content. Style (local or CSS) is used for dimensioning.
data-barcode
type | character set (as regular expression) |
---|---|
upce | 0[0-9]11 |
ean13 | [0-9]13 |
ean8 | [0-9]8 |
code39 | [0-9A-Z $%*+-./]34 |
code128 | [\u0000-\u007f^{ |
code128c | [0-9]98 |
qr | .+ |
Optional further parameters
Parameter | default | description |
---|---|---|
pos | Center | Left, Center or Right |
hri | Below | human readable interface: None, Above, Below, BothPlaces |
Example of a very small barcode (code128):
div
img(data-value="This is a test" style="width:10ch")
data-value
The data-value can be set programmatically:
div
- var x = ESR.TL + ("0" + ESR.TT).slice(-2) + ("00000" + ESR.TN).slice(-6)
img(data-value=x style="width:30ch;height:3ch")
Transaction Time
The fiscal printer itself has a clock. Date and time printed on the receipt are printer time.
Example Response
XML Response
<TraC SQ="142">
<Result RC="OK"/>
<Fis D="2023-05-09T16:06:38" FN="NY/Y19600048/0015/00017" DN="00017" ZI="15" ID="Y19600048"/>
</TraC>
JSON Response
{
"TraC":{
"SQ":144,
"Result":{"RC":"OK"},
"Fis":{
"D":"2023-05-09T16:01:04",
"FN":"NY/Y19600048/0015/00015",
"DN":"00015",
"ZI":"15",
"ID":"Y19600048"
}
}
}