Label printing reports aanpassen (ZPL, Zebra)
Waarschuwing: maak altijd een goede backup voordat je een van onderstaande stappen uitvoert.
Odoo kent verschillende 'standaard' opties om (Zebra) labels te printen. Er zijn geen aanpassingen die je via Studio kan doen, maar het is wel mogelijk om (in een kopie van) het standaard rapport aan te passen. Hiervoor is basiskennis van de code van Zebra labels nodig, die gelukkig niet erg ingewikkeld is.
Voorbeeld printerdialoog voor het printen van productlabels in Odoo vanuit met de mogelijkheid om een Zebra (ZPL) label te printen.
Standaard instellingen aanpassen
De standaardinstellingen van dit label kunnen worden aangepast via het Qweb tabblad van het achterliggende rapport.
Om dit aan te passen ga je in Developer mode vanuit het startscherm naar alle rapporten door /reports te typen
Kies voor Settings/Technical/Actions/Reports
Kies hier het juiste rapport dat je wilt bewerken, in dit geval Product Label (ZPL).
Na het openen zie je rechtsboven de link naar het Qweb deel van dit rapport. Deze Qweb code regelt de opmaak van het label.
ZPL-code label
Als je die view opent zie je op het tabblad architecture de code die hoort bij de huidige installatie en module-opties. Deze code kan hier aangepast worden.
Maar let op! Wijzigingen van de standaardlayout worden hoogstwaarschijnlijk overschreven bij een volgende update. We adviseren hiervoor een inherited view aan te maken. Dit valt echter buiten de scope van dit artikel. Voor het testen kan het wel handig zijn om het op deze manier snel aan te passen.
Ook handig om te weten is dat je een regel kan 'uitcommentariëren' (comment out) met een ; (puntkomma). Alles na een puntkomma op een regel wordt beschouwd als commentaar en zal worden genegeerd door de ZPL-interpreter.
Maak wel even een backup van de huidige code zodat je altijd terug kunt naar de standaard.
De code die je ziet kan er bijvoorbeeld als volgt uit zien:
<t t-name="stock.label_product_product_view">
<t t-foreach="quantity.items()" t-as="barcode_and_qty_by_product">
<t t-set="product" t-value="barcode_and_qty_by_product[0]"/>
<t t-foreach="barcode_and_qty_by_product[1]" t-as="barcode_and_qty">
<t t-set="barcode" t-value="barcode_and_qty[0]"/>
<t t-foreach="range(barcode_and_qty[1])" t-as="qty">
<t t-translation="off">
^XA
^FT100,80^A0N,40,30^FD<t t-esc="product.display_name"/>^FS
<t t-if="product.default_code and len(product.default_code) > 15">
^FT100,115^A0N,30,24^FD<t t-esc="product.default_code[:15]"/>^FS
^FT100,150^A0N,30,24^FD<t t-esc="product.default_code[15:30]"/>^FS
</t>
<t t-else="">
^FT100,150^A0N,30,24^FD<t t-esc="product.default_code"/>^FS
</t>
<t t-if="price_included">
^FO600,100,1
^CI28
<t t-if="product.currency_id.position == 'after'">
^A0N,66,48^FH^FD<t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/><t t-esc="product.currency_id.symbol"/>^FS
</t>
<t t-if="product.currency_id.position == 'before'">
^A0N,66,48^FH^FD<t t-esc="product.currency_id.symbol"/><t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/>^FS
</t>
</t>
<t t-if="barcode">
^FO100,160^BY3
^BCN,100,Y,N,N
^FD<t t-esc="barcode"/>^FS
</t>
^XZ
</t>
</t>
</t>
</t>
</t>
De code is hieronder (met behulp van ChatGTP) uitgelegd:
Deze code is bedoeld om labels af te drukken voor producten met bijbehorende barcodes en hoeveelheden. Laten we de coderegels stap voor stap uitleggen:
1. `<t t-name="stock.label_product_product_view">`: Dit is de naam van het sjabloon voor het afdrukken van labels voor producten.
2. `<t t-foreach="quantity.items()" t-as="barcode_and_qty_by_product">`: Dit is een lusconstructie die door elk item in de "quantity" itereren en het toewijzen aan de variabele "barcode_and_qty_by_product". Dit maakt het mogelijk om de barcode en hoeveelheid voor elk product af te drukken.
3. `<t t-set="product" t-value="barcode_and_qty_by_product[0]"/>`: Dit stelt de variabele "product" in en wijst de waarde toe van het eerste element in "barcode_and_qty_by_product", dat het product vertegenwoordigt.
4. `<t t-foreach="barcode_and_qty_by_product[1]" t-as="barcode_and_qty">`: Dit is een lusconstructie die door elk element in de lijst "barcode_and_qty_by_product[1]" itereren en het toewijzen aan de variabele "barcode_and_qty". Dit maakt het mogelijk om meerdere barcodes en hoeveelheden voor hetzelfde product af te drukken.
5. `<t t-set="barcode" t-value="barcode_and_qty[0]"/>`: Dit stelt de variabele "barcode" in en wijst de waarde toe van het eerste element in "barcode_and_qty", dat de barcode vertegenwoordigt.
6. `<t t-foreach="range(barcode_and_qty[1])" t-as="qty">`: Dit is een lusconstructie die door een reeks getallen itereert, waarbij het aantal iteraties wordt bepaald door de waarde van het tweede element in "barcode_and_qty". Dit maakt het mogelijk om dezelfde barcode en hoeveelheid meerdere keren af te drukken.
7. `<t t-translation="off">`: Dit schakelt de vertaling uit voor de inhoud van het label. Dit wordt gebruikt om ervoor te zorgen dat de teksten ongewijzigd blijven, zelfs als er vertalingen zijn gedefinieerd in het systeem.
8. `^XA`: Dit is een opdracht om het afdrukken van ZPL-commando's te starten.
9. `^FT100,80^A0N,40,30^FD<t t-esc="product.display_name"/>^FS`: Dit plaatst de positie en het lettertype van de eerste regel tekst op het label. Hiermee wordt de weergavenaam van het product afgedrukt met behulp van `<t t-esc="product.display_name"/>`.
10. `<t t-if="product.default_code and len(product.default_code) > 15">`: Dit is een voorwaardelijke controle die controleert of het product een standaardcode heeft en of de lengte van de standaardcode groter is dan 15 tekens. Als de voorwaarde waar is, worden de volgende regels uitgevoerd.
11. `^FT100,115^A0N,30,24^FD<t t-esc="product.default_code[:15]"/>^FS`: Dit plaatst de positie en het lettertype van de tweede regel tekst op het label. Hiermee wordt een deel van de standaardcode van het product afgedrukt met behulp van `<t t-esc="product.default_code[:15]"/>`.
12. `^FT100,150^A0N,30,24^FD<t t-esc="product.default_code[15:30]"/>^FS`: Dit plaatst de positie en het lettertype van de derde regel tekst op het label. Hiermee wordt een ander deel van de standaardcode van het product afgedrukt met behulp van `<t t-esc="product.default_code[15:30]"/>`.
13. `<t t-else="">`: Dit is een ander deel van de voorwaardelijke controle. Als de voorwaarde niet waar is, worden de volgende regels uitgevoerd.
14. `^FT100,150^A0N,30,24^FD<t t-esc="product.default_code"/>^FS`: Dit plaatst de positie en het lettertype van de derde regel tekst op het label. Hiermee wordt de volledige standaardcode van het product afgedrukt met behulp van `<t t-esc="product.default_code"/>`.
15. `<t t-if="price_included">`: Dit is een voorwaardelijke controle die controleert of de prijs is inbegrepen. Als dit het geval is, worden de volgende regels uitgevoerd.
16. `^FO600,100,1`: Dit plaatst de positie van de prijs op het label.
17. `^CI28`: Dit stelt de tekenindeling in op UTF-8.
18. `<t t-if="product.currency_id.position == 'after'">`: Dit is een voorwaardelijke controle die controleert of de positie van het valutasymbool na de prijs is. Als dit het geval is, worden de volgende regels uitgevoerd.
19. `^A0N,66,48^FH^FD<t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/><t t-esc="product.currency_id.symbol"/>^FS`: Dit drukt de prijs en het valutasymbool af met behulp van `<t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/>` en `<t t-esc="product.currency_id.symbol"/>`.
20. `<t t-if="product.currency_id.position == 'before'">`: Dit is een andere voorwaardelijke controle die controleert of de positie van het valutasymbool vóór de prijs is. Als dit het geval is, worden de volgende regels uitgevoerd.
21. `^A0N,66,48^FH^FD<t t-esc="product.currency_id.symbol"/><t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/>^FS`: Dit drukt het valutasymbool en de prijs af met behulp van `<t t-esc="product.currency_id.symbol"/>` en `<t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/>`.
22.`<t t-if="barcode">`: Dit is een voorwaardelijke controle die controleert of er een barcode is. Als dit het geval is, worden de volgende regels uitgevoerd.
23. `^FO100,160^BY3`: Dit plaatst de positie en de barcodeparameters op het label.
24. `^BCN,100,Y,N,N`: Dit stelt het type barcode en de grootte van de barcode in.
25. `^FD<t t-esc="barcode"/>^FS`: Dit drukt de barcode af met behulp van `<t t-esc="barcode"/>`.
26. `^XZ`: Dit is een opdracht om het afdrukken van ZPL-commando's te beëindigen.
Deze code genereert labels met de productnaam, standaardcode, prijs en barcode voor elk product met bijbehorende hoeveelheden en barcodes.
Tip ChatGTP:
Gebruik ChatGTP om een onderdeel aan te passen. Op de vraag 'Hoe kunnen we in onderstaande code de lettergrootte verkleinen met 50% en de barcode verkleinen met 50%' komt ChatGTP met het volgende antwoord:
Om de lettergrootte in de code met 50% te verkleinen, moet je de parameters van het lettertype aanpassen. In dit geval worden de lettertypen gedefinieerd met `^A0N`, gevolgd door parameters voor de lettergrootte. Je kunt de waarden van deze parameters halveren om de lettergrootte te verkleinen.
Om de barcode met 50% te verkleinen, moet je de barcodeparameters aanpassen. In de code wordt de grootte van de barcode ingesteld met `^BY3`. Je kunt de waarde van deze parameter aanpassen naar bijvoorbeeld 2.5, 2 of 1.5 om de barcode te verkleinen.
Hier is de aangepaste code waarin de lettergrootte en barcode met 50% zijn verkleind:
<t t-name="stock.label_product_product_view">
<t t-foreach="quantity.items()" t-as="barcode_and_qty_by_product">
<t t-set="product" t-value="barcode_and_qty_by_product[0]"/>
<t t-foreach="barcode_and_qty_by_product[1]" t-as="barcode_and_qty">
<t t-set="barcode" t-value="barcode_and_qty[0]"/>
<t t-foreach="range(barcode_and_qty[1])" t-as="qty">
<t t-translation="off">
^XA
^FT100,80^A0N,20,15^FD<t t-esc="product.display_name"/>^FS
<t t-if="product.default_code and len(product.default_code) > 15">
^FT100,115^A0N,15,12^FD<t t-esc="product.default_code[:15]"/>^FS
^FT100,150^A0N,15,12^FD<t t-esc="product.default_code[15:30]"/>^FS
</t>
<t t-else="">
^FT100,150^A0N,15,12^FD<t t-esc="product.default_code"/>^FS
</t>
<t t-if="price_included">
^FO600,100,1
^CI28
<t t-if="product.currency_id.position == 'after'">
^A0N,33,24^FH^FD<t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/><t t-esc="product.currency_id.symbol"/>^FS
</t>
<t t-if="product.currency_id.position == 'before'">
^A0N,33,24^FH^FD<t t-esc="product.currency_id.symbol"/><t t-esc="product.list_price" t-options="{"widget": "float", "precision": 2}"/>^FS
</t>
</t>
<t t-if="barcode">
^FO100,160^BY2
^BCN,50,Y,N,N
^FD<t t-esc="barcode"/>^FS
</t>
^XZ
</t>
</t>
</t>
</t>
</t>
In deze aangepaste code zijn de lettergrootteparameters gewijzigd naar lagere waarden (bijv. 20, 15, 15, 12), en de barcodeparameters zijn gewijzigd naar een lagere barcodegrootte (bijv. ^BY2, ^BCN,50).