2
.. i18n: XSL:RML reports
3
.. i18n: ===============
8
.. i18n: RML reports don't require programming but require two simple XML files to be written:
10
RML reports don't require programming but require two simple XML files to be written:
12
.. i18n: * a file describing the data to export (\*.xml)
13
.. i18n: * a file containing the presentation rules to apply to that data (\*.xsl)
15
* a file describing the data to export (\*.xml)
16
* a file containing the presentation rules to apply to that data (\*.xsl)
18
.. i18n: .. figure:: images/automatic-reports.png
20
.. i18n: :align: center
22
.. figure:: images/automatic-reports.png
26
.. i18n: The role of the XML template is to describe which fields of the resource have to be exported (by the server). The XSL:RML style sheet deals with the layout of the exported data as well as the "static text" of reports. Static text is referring to the text which is common to all reports of the same type (for example, the title of table columns).
28
The role of the XML template is to describe which fields of the resource have to be exported (by the server). The XSL:RML style sheet deals with the layout of the exported data as well as the "static text" of reports. Static text is referring to the text which is common to all reports of the same type (for example, the title of table columns).
34
.. i18n: Here is, as an example, the different files for the simplest report in the ERP.
36
Here is, as an example, the different files for the simplest report in the ERP.
38
.. i18n: .. figure:: images/ids-report.png
40
.. i18n: :align: center
42
.. figure:: images/ids-report.png
46
.. i18n: **XML Template**
49
.. i18n: <?xml version="1.0"?>
57
.. i18n: <id type="fields" name="id">
60
<id type="fields" name="id">
62
.. i18n: <name type="field" name="name"/>
63
.. i18n: <ref type="field" name="ref"/>
65
<name type="field" name="name"/>
66
<ref type="field" name="ref"/>
74
.. i18n: **XML data file (generated)**
77
.. i18n: <?xml version="1.0"?>
79
**XML data file (generated)**
90
.. i18n: <name>Tiny sprl</name>
91
.. i18n: <ref>pnk00</ref>
93
<name>Tiny sprl</name>
100
.. i18n: <name>ASUS</name>
110
.. i18n: <name>Agrolait</name>
113
<name>Agrolait</name>
120
.. i18n: <name>Banque Plein-Aux-As</name>
123
<name>Banque Plein-Aux-As</name>
130
.. i18n: <name>China Export</name>
133
<name>China Export</name>
140
.. i18n: <name>Ditrib PC</name>
143
<name>Ditrib PC</name>
150
.. i18n: <name>Ecole de Commerce de Liege</name>
153
<name>Ecole de Commerce de Liege</name>
160
.. i18n: <name>Elec Import</name>
163
<name>Elec Import</name>
170
.. i18n: <name>Maxtor</name>
180
.. i18n: <name>Mediapole SPRL</name>
183
<name>Mediapole SPRL</name>
190
.. i18n: <name>Opensides sprl</name>
191
.. i18n: <ref>os</ref>
193
<name>Opensides sprl</name>
200
.. i18n: <name>Tecsas sarl</name>
203
<name>Tecsas sarl</name>
212
.. i18n: **XSL stylesheet**
215
.. i18n: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
220
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
222
.. i18n: <xsl:template match="/">
224
<xsl:template match="/">
226
.. i18n: <xsl:apply-templates select="ids"/>
228
<xsl:apply-templates select="ids"/>
230
.. i18n: </xsl:template>
234
.. i18n: <xsl:template match="ids">
236
<xsl:template match="ids">
242
.. i18n: <template pageSize="21cm,29.7cm">
244
<template pageSize="21cm,29.7cm">
246
.. i18n: <pageTemplate>
250
.. i18n: <frame id="col1" x1="2cm" y1="2.4cm" width="8cm" height="26cm"/>
251
.. i18n: <frame id="col2" x1="11cm" y1="2.4cm" width="8cm" height="26cm"/>
253
<frame id="col1" x1="2cm" y1="2.4cm" width="8cm" height="26cm"/>
254
<frame id="col2" x1="11cm" y1="2.4cm" width="8cm" height="26cm"/>
256
.. i18n: </pageTemplate>
264
.. i18n: <stylesheet>
268
.. i18n: <blockTableStyle id="ids">
270
<blockTableStyle id="ids">
272
.. i18n: <blockFont name="Helvetica-BoldOblique" size="12" start="0,0" stop="-1,0"/>
273
.. i18n: <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,0"/>
275
<blockFont name="Helvetica-BoldOblique" size="12" start="0,0" stop="-1,0"/>
276
<lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,0"/>
278
.. i18n: <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,-1"/>
280
<lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,-1"/>
282
.. i18n: </blockTableStyle>
286
.. i18n: </stylesheet>
294
.. i18n: <blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">
296
<blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">
302
.. i18n: <td t="1">Ref.</td>
303
.. i18n: <td t="1">Name</td>
309
.. i18n: <xsl:apply-templates select="id"/>
312
<xsl:apply-templates select="id"/>
314
.. i18n: </blockTable>
324
.. i18n: </xsl:template>
328
.. i18n: <xsl:template match="id">
330
<xsl:template match="id">
336
.. i18n: <td><xsl:value-of select="ref"/></td>
337
.. i18n: <td><para><xsl:value-of select="name"/></para></td>
339
<td><xsl:value-of select="ref"/></td>
340
<td><para><xsl:value-of select="name"/></para></td>
346
.. i18n: </xsl:template>
347
.. i18n: </xsl:stylesheet>
352
.. i18n: **Resulting RML file (generated)**
355
.. i18n: <?xml version="1.0"?>
357
**Resulting RML file (generated)**
360
<?xml version="1.0"?>
372
.. i18n: <blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">
374
<blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">
380
.. i18n: <td t="1">Ref.</td>
381
.. i18n: <td t="1">Name</td>
392
.. i18n: <td>pnk00</td>
393
.. i18n: <td><para>Tiny sprl</para></td>
396
<td><para>Tiny sprl</para></td>
405
.. i18n: <td><para>ASUS</para></td>
408
<td><para>ASUS</para></td>
417
.. i18n: <td><para>Agrolait</para></td>
420
<td><para>Agrolait</para></td>
429
.. i18n: <td><para>Banque Plein-Aux-As</para></td>
432
<td><para>Banque Plein-Aux-As</para></td>
441
.. i18n: <td><para>China Export</para></td>
444
<td><para>China Export</para></td>
453
.. i18n: <td><para>Ditrib PC</para></td>
456
<td><para>Ditrib PC</para></td>
465
.. i18n: <td><para>Ecole de Commerce de Liege</para></td>
468
<td><para>Ecole de Commerce de Liege</para></td>
477
.. i18n: <td><para>Elec Import</para></td>
480
<td><para>Elec Import</para></td>
489
.. i18n: <td><para>Maxtor</para></td>
492
<td><para>Maxtor</para></td>
501
.. i18n: <td><para>Mediapole SPRL</para></td>
504
<td><para>Mediapole SPRL</para></td>
513
.. i18n: <td><para>Opensides sprl</para></td>
516
<td><para>Opensides sprl</para></td>
526
.. i18n: <td><para>Tecsas sarl</para></td>
528
<td><para>Tecsas sarl</para></td>
534
.. i18n: </blockTable>
546
.. i18n: Fore more information on the formats used:
548
Fore more information on the formats used:
550
.. i18n: * RML : http://reportlab.com/docs/RML_UserGuide_1_0.pdf
551
.. i18n: * XSL - Specification : http://www.w3.org/TR/xslt
552
.. i18n: * XSL - Tutorial : http://www.zvon.org/xxl/XSLTutorial/Books/Output/contents.html
554
* RML : http://reportlab.com/docs/RML_UserGuide_1_0.pdf
555
* XSL - Specification : http://www.w3.org/TR/xslt
556
* XSL - Tutorial : http://www.zvon.org/xxl/XSLTutorial/Books/Output/contents.html
558
.. i18n: All these formats use XML:
560
All these formats use XML:
562
.. i18n: * http://www.w3.org/XML/
564
* http://www.w3.org/XML/
566
.. i18n: XML Template
567
.. i18n: ------------
572
.. i18n: XML templates are simple XML files describing which fields among all available object fields are necessary for the report.
574
XML templates are simple XML files describing which fields among all available object fields are necessary for the report.
582
.. i18n: Tag names can be chosen arbitrarily (it must be valid XML though). In the XSL file, you will have to use those names. Most of the time, the name of a tag will be the same as the name of the object field it refers to.
584
Tag names can be chosen arbitrarily (it must be valid XML though). In the XSL file, you will have to use those names. Most of the time, the name of a tag will be the same as the name of the object field it refers to.
586
.. i18n: Nodes without **type** attribute are transferred identically into the XML destination file (the data file). Nodes with a type attribute will be parsed by the server and their content will be replaced by data coming from objects. In addition to the type attribute, nodes have other possible attributes. These attributes depend on the type of the node (each node type supports or needs different attributes). Most node types have a name attribute, which refers to the **name** of a field of the object on which we work.
588
Nodes without **type** attribute are transferred identically into the XML destination file (the data file). Nodes with a type attribute will be parsed by the server and their content will be replaced by data coming from objects. In addition to the type attribute, nodes have other possible attributes. These attributes depend on the type of the node (each node type supports or needs different attributes). Most node types have a name attribute, which refers to the **name** of a field of the object on which we work.
590
.. i18n: As for the "browse" method on objects, field names in reports can use a notation similar to the notation found in object oriented programming languages. It means that "relation fields" can be used as "bridges" to fetch data from other (related) objects.
592
As for the "browse" method on objects, field names in reports can use a notation similar to the notation found in object oriented programming languages. It means that "relation fields" can be used as "bridges" to fetch data from other (related) objects.
594
.. i18n: Let's use the "account.transfer" object as an example. It contains a partner_id field. This field is a relation field ("many to one") pointing to the "res.partner" object. Let's suppose that we want to create a report for transfers and in this report, we want to use the name of the recipient partner. This name could be accessed using the following expression as the name of the field:
596
Let's use the "account.transfer" object as an example. It contains a partner_id field. This field is a relation field ("many to one") pointing to the "res.partner" object. Let's suppose that we want to create a report for transfers and in this report, we want to use the name of the recipient partner. This name could be accessed using the following expression as the name of the field:
598
.. i18n: partner_id.name
602
.. i18n: Possible types
603
.. i18n: """"""""""""""
608
.. i18n: Here is the list of available field types:
610
Here is the list of available field types:
612
.. i18n: * **field**: It is the simplest type. For nodes of this type, the server replaces the node content by the value of the field whose name is given in the name attribute.
614
.. i18n: * **fields**: when this type of node is used, the server will generate a node in the XML data file for each unique value of the field whose name is given in the name attribute.
616
* **field**: It is the simplest type. For nodes of this type, the server replaces the node content by the value of the field whose name is given in the name attribute.
618
* **fields**: when this type of node is used, the server will generate a node in the XML data file for each unique value of the field whose name is given in the name attribute.
624
.. i18n: ** This node type is often used with "id" as its name attribute. This has the effect of creating one node for each resource selected in the interface by the user.
625
.. i18n: ** The semantics of a node <node type="fields" name="field_name"> is similar to an SQL statement of the form "SELECT FROM object_table WHERE id in identifier_list **GROUP BY** field_name" where identifier_list is the list of ids of the resources selected by the ::user (in the interface).
627
** This node type is often used with "id" as its name attribute. This has the effect of creating one node for each resource selected in the interface by the user.
628
** The semantics of a node <node type="fields" name="field_name"> is similar to an SQL statement of the form "SELECT FROM object_table WHERE id in identifier_list **GROUP BY** field_name" where identifier_list is the list of ids of the resources selected by the ::user (in the interface).
630
.. i18n: * **eval**: This node type evaluate the expression given in the *expr* attribute. This expression may be any Python expression and may contain objects fields names.
632
.. i18n: * **zoom**: This node type allows to "enter" into the resource referenced by the relation field whose name is given in the name attribute. It means that its child nodes will be able to access the fields of that resource without having to prefix them with the field name that makes the link with the other object. In our example above, we could also have accessed the field name of the partner with the following:
634
* **eval**: This node type evaluate the expression given in the *expr* attribute. This expression may be any Python expression and may contain objects fields names.
636
* **zoom**: This node type allows to "enter" into the resource referenced by the relation field whose name is given in the name attribute. It means that its child nodes will be able to access the fields of that resource without having to prefix them with the field name that makes the link with the other object. In our example above, we could also have accessed the field name of the partner with the following:
640
.. i18n: <partner type="zoom" name="partner_id">
644
<partner type="zoom" name="partner_id">
646
.. i18n: <name type="field" name="name"/>
648
<name type="field" name="name"/>
654
.. i18n: In this precise case, there is of course no point in using this notation instead of the standard notation below:
656
In this precise case, there is of course no point in using this notation instead of the standard notation below:
658
.. i18n: <name type="field" name="partner_id.name"/>
660
<name type="field" name="partner_id.name"/>
662
.. i18n: The **zoom** type is only useful when we want to recover several fields in the same object.
664
The **zoom** type is only useful when we want to recover several fields in the same object.
666
.. i18n: * **function**: returns the result of the call to the function whose name is given in the name attribute. This function must be part of the list of predefined functions. For the moment, the only available function is today, which returns the current date.
668
.. i18n: * **call**: calls the object method whose name is given in the name attribute with the arguments given in the args attribute. The result is stored into a dictionary of the form {'name_of_variable': value, ... } and can be accessed through child nodes. These nodes must have a value attribute which correspond to one of the keys of the dictionary returned by the method.
670
* **function**: returns the result of the call to the function whose name is given in the name attribute. This function must be part of the list of predefined functions. For the moment, the only available function is today, which returns the current date.
672
* **call**: calls the object method whose name is given in the name attribute with the arguments given in the args attribute. The result is stored into a dictionary of the form {'name_of_variable': value, ... } and can be accessed through child nodes. These nodes must have a value attribute which correspond to one of the keys of the dictionary returned by the method.
674
.. i18n: **Example**:
677
.. i18n: <cost type="call" name="compute_seller_costs" args="">
682
<cost type="call" name="compute_seller_costs" args="">
684
.. i18n: <name value="name"/>
685
.. i18n: <amount value="amount"/>
688
<amount value="amount"/>
694
.. i18n: **TODO**: documenter format methode appellée def compute_buyer_costs(self, cr, uid, ids, \*args):
696
**TODO**: documenter format methode appellée def compute_buyer_costs(self, cr, uid, ids, \*args):
698
.. i18n: * **attachment**: extract the first attachment of the resource whose id is taken from the field whose name is given in the name attribute, and put it as an image in the report.
700
* **attachment**: extract the first attachment of the resource whose id is taken from the field whose name is given in the name attribute, and put it as an image in the report.
703
.. i18n: <image type="attachment" name="id"/>
706
<image type="attachment" name="id"/>
712
.. i18n: Here is an example of XML file:
715
.. i18n: <?xml version="1.0" encoding="ISO-8859-1"?>
716
.. i18n: <transfer-list>
718
Here is an example of XML file:
721
<?xml version="1.0" encoding="ISO-8859-1"?>
724
.. i18n: <transfer type="fields" name="id">
726
<transfer type="fields" name="id">
728
.. i18n: <name type="field" name="name"/>
729
.. i18n: <partner_id type="field" name="partner_id.name"/>
730
.. i18n: <date type="field" name="date"/>
731
.. i18n: <type type="field" name="type"/>
732
.. i18n: <reference type="field" name="reference"/>
733
.. i18n: <amount type="field" name="amount"/>
734
.. i18n: <change type="field" name="change"/>
736
<name type="field" name="name"/>
737
<partner_id type="field" name="partner_id.name"/>
738
<date type="field" name="date"/>
739
<type type="field" name="type"/>
740
<reference type="field" name="reference"/>
741
<amount type="field" name="amount"/>
742
<change type="field" name="change"/>
748
.. i18n: </transfer-list>
752
.. i18n: Introduction to RML
753
.. i18n: -------------------
758
.. i18n: For more information on the RML format, please refer to the official Reportlab documentation.
760
For more information on the RML format, please refer to the official Reportlab documentation.
762
.. i18n: * http://www.reportlab.com/docs/RML_UserGuide.pdf
764
* http://www.reportlab.com/docs/RML_UserGuide.pdf
766
.. i18n: XSL:RML Stylesheet
767
.. i18n: ------------------
772
.. i18n: There are two possibilities to do a XSL style sheet for a report. Either making everything by yourself, or use our predefined templates
774
There are two possibilities to do a XSL style sheet for a report. Either making everything by yourself, or use our predefined templates
776
.. i18n: Either freestyle or use corporate_defaults + rml_template
778
Either freestyle or use corporate_defaults + rml_template
780
.. i18n: import rml_template.xsl
782
import rml_template.xsl
784
.. i18n: required templates:
789
.. i18n: - stylesheet
796
.. i18n: optional templates:
800
.. i18n: Translations
801
.. i18n: """"""""""""
806
.. i18n: As Open ERP can be used in several langages, reports must be translatable. But in a report, everything doesn't have to be translated : only the actual text has to be translated, not the formatting codes. A field will be processed by the translation system if the XML tag which surrounds it (whatever it is) has a t="1" attribute. The server will translate all the fields with such attributes in the report generation process.
808
As Open ERP can be used in several langages, reports must be translatable. But in a report, everything doesn't have to be translated : only the actual text has to be translated, not the formatting codes. A field will be processed by the translation system if the XML tag which surrounds it (whatever it is) has a t="1" attribute. The server will translate all the fields with such attributes in the report generation process.
810
.. i18n: Useful links:
811
.. i18n: """""""""""""
816
.. i18n: * http://www.reportlab.com/docs/RML_UserGuide.pdf RML UserGuide (pdf) (reportlab.com)
818
.. i18n: * http://www.zvon.org/xxl/XSLTutorial/Output/index.html XSL Tutorial (zvon.org)
819
.. i18n: * http://www.zvon.org/xxl/XSLTreference/Output/index.html XSL Reference (zvon.org)
820
.. i18n: * http://www.w3schools.com/xsl/ XSL tutorial and references (W3Schools)
821
.. i18n: * http://www.w3.org/TR/xslt/ XSL Specification (W3C)
823
* http://www.reportlab.com/docs/RML_UserGuide.pdf RML UserGuide (pdf) (reportlab.com)
825
* http://www.zvon.org/xxl/XSLTutorial/Output/index.html XSL Tutorial (zvon.org)
826
* http://www.zvon.org/xxl/XSLTreference/Output/index.html XSL Reference (zvon.org)
827
* http://www.w3schools.com/xsl/ XSL tutorial and references (W3Schools)
828
* http://www.w3.org/TR/xslt/ XSL Specification (W3C)
830
.. i18n: Example (with corporate defaults):
831
.. i18n: """""""""""""""""""""""""""""""""""
834
.. i18n: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
836
Example (with corporate defaults):
837
"""""""""""""""""""""""""""""""""""
840
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
842
.. i18n: <xsl:import href="../../custom/corporate_defaults.xsl"/>
843
.. i18n: <xsl:import href="../../base/report/rml_template.xsl"/>
844
.. i18n: <xsl:variable name="page_format">a4_normal</xsl:variable>
845
.. i18n: <xsl:template match="/">
847
<xsl:import href="../../custom/corporate_defaults.xsl"/>
848
<xsl:import href="../../base/report/rml_template.xsl"/>
849
<xsl:variable name="page_format">a4_normal</xsl:variable>
850
<xsl:template match="/">
852
.. i18n: <xsl:call-template name="rml"/>
854
<xsl:call-template name="rml"/>
856
.. i18n: </xsl:template>
857
.. i18n: <xsl:template name="stylesheet">
860
<xsl:template name="stylesheet">
862
.. i18n: </xsl:template>
866
.. i18n: <xsl:template name="story">
868
<xsl:template name="story">
870
.. i18n: <xsl:apply-templates select="transfer-list"/>
872
<xsl:apply-templates select="transfer-list"/>
874
.. i18n: </xsl:template>
875
.. i18n: <xsl:template match="transfer-list">
878
<xsl:template match="transfer-list">
880
.. i18n: <xsl:apply-templates select="transfer"/>
882
<xsl:apply-templates select="transfer"/>
884
.. i18n: </xsl:template>
885
.. i18n: <xsl:template match="transfer">
888
<xsl:template match="transfer">
890
.. i18n: <setNextTemplate name="other_pages"/>
893
<setNextTemplate name="other_pages"/>
896
.. i18n: Document: <xsl:value-of select="name"/>
898
Document: <xsl:value-of select="name"/>
900
.. i18n: </para><para>
904
.. i18n: Type: <xsl:value-of select="type"/>
906
Type: <xsl:value-of select="type"/>
908
.. i18n: </para><para>
912
.. i18n: Reference: <xsl:value-of select="reference"/>
914
Reference: <xsl:value-of select="reference"/>
916
.. i18n: </para><para>
920
.. i18n: Partner ID: <xsl:value-of select="partner_id"/>
922
Partner ID: <xsl:value-of select="partner_id"/>
924
.. i18n: </para><para>
928
.. i18n: Date: <xsl:value-of select="date"/>
930
Date: <xsl:value-of select="date"/>
932
.. i18n: </para><para>
936
.. i18n: Amount: <xsl:value-of select="amount"/>
938
Amount: <xsl:value-of select="amount"/>
941
.. i18n: <xsl:if test="number(change)>0">
944
<xsl:if test="number(change)>0">
950
.. i18n: Change: <xsl:value-of select="change"/>
952
Change: <xsl:value-of select="change"/>
959
.. i18n: <setNextTemplate name="first_page"/>
960
.. i18n: <pageBreak/>
963
<setNextTemplate name="first_page"/>
966
.. i18n: </xsl:template>
970
.. i18n: </xsl:stylesheet>
974
.. i18n: Reports without corporate header
975
.. i18n: ================================
977
Reports without corporate header
978
================================
980
.. i18n: **Example (with corporate defaults):**
983
.. i18n: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
984
.. i18n: <xsl:import href="../../base/report/rml_template.xsl"/>
985
.. i18n: <xsl:variable name="page_format">a4_normal</xsl:variable>
987
.. i18n: <xsl:template match="/">
988
.. i18n: <xsl:call-template name="rml"/>
989
.. i18n: </xsl:template>
991
.. i18n: <xsl:template name="stylesheet">
992
.. i18n: </xsl:template>
994
.. i18n: <xsl:template name="story">
995
.. i18n: <xsl:apply-templates select="transfer-list"/>
996
.. i18n: </xsl:template>
998
.. i18n: <xsl:template match="transfer-list">
999
.. i18n: <xsl:apply-templates select="transfer"/>
1000
.. i18n: </xsl:template>
1002
.. i18n: <xsl:template match="transfer">
1003
.. i18n: <setNextTemplate name="other_pages"/>
1006
.. i18n: Document: <xsl:value-of select="name"/>
1007
.. i18n: </para><para>
1008
.. i18n: Type: <xsl:value-of select="type"/>
1009
.. i18n: </para><para>
1010
.. i18n: Reference: <xsl:value-of select="reference"/>
1011
.. i18n: </para><para>
1012
.. i18n: Partner ID: <xsl:value-of select="partner_id"/>
1013
.. i18n: </para><para>
1014
.. i18n: Date: <xsl:value-of select="date"/>
1015
.. i18n: </para><para>
1016
.. i18n: Amount: <xsl:value-of select="amount"/>
1019
.. i18n: <xsl:if test="number(change)>0">
1021
.. i18n: Change: <xsl:value-of select="change"/>
1025
.. i18n: <setNextTemplate name="first_page"/>
1026
.. i18n: <pageBreak/>
1027
.. i18n: </xsl:template>
1028
.. i18n: </xsl:stylesheet>
1030
**Example (with corporate defaults):**
1033
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
1034
<xsl:import href="../../base/report/rml_template.xsl"/>
1035
<xsl:variable name="page_format">a4_normal</xsl:variable>
1037
<xsl:template match="/">
1038
<xsl:call-template name="rml"/>
1041
<xsl:template name="stylesheet">
1044
<xsl:template name="story">
1045
<xsl:apply-templates select="transfer-list"/>
1048
<xsl:template match="transfer-list">
1049
<xsl:apply-templates select="transfer"/>
1052
<xsl:template match="transfer">
1053
<setNextTemplate name="other_pages"/>
1056
Document: <xsl:value-of select="name"/>
1058
Type: <xsl:value-of select="type"/>
1060
Reference: <xsl:value-of select="reference"/>
1062
Partner ID: <xsl:value-of select="partner_id"/>
1064
Date: <xsl:value-of select="date"/>
1066
Amount: <xsl:value-of select="amount"/>
1069
<xsl:if test="number(change)>0">
1071
Change: <xsl:value-of select="change"/>
1075
<setNextTemplate name="first_page"/>
1080
.. i18n: Each report with its own corporate header
1081
.. i18n: =========================================
1083
Each report with its own corporate header
1084
=========================================
1086
.. i18n: **Example (with corporate defaults):**
1089
.. i18n: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
1091
**Example (with corporate defaults):**
1094
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
1096
.. i18n: <xsl:import href="../../custom/corporate_defaults.xsl"/>
1097
.. i18n: <xsl:import href="../../base/report/rml_template.xsl"/>
1098
.. i18n: <xsl:variable name="page_format">a4_normal</xsl:variable>
1099
.. i18n: .....................
1100
.. i18n: </xsl:template>
1102
<xsl:import href="../../custom/corporate_defaults.xsl"/>
1103
<xsl:import href="../../base/report/rml_template.xsl"/>
1104
<xsl:variable name="page_format">a4_normal</xsl:variable>
1105
.....................
1108
.. i18n: </xsl:stylesheet>
1118
.. i18n: Barcodes in RML files
1119
.. i18n: ---------------------
1121
Barcodes in RML files
1122
---------------------
1124
.. i18n: Barcodes can be generated using the <barcode> tag in RML files. The following formats are supported:
1126
Barcodes can be generated using the <barcode> tag in RML files. The following formats are supported:
1130
.. i18n: * code128 (default if no 'code' specified')
1131
.. i18n: * standard39
1132
.. i18n: * standard93
1134
.. i18n: * extended39
1135
.. i18n: * extended93
1142
* code128 (default if no 'code' specified')
1152
.. i18n: You can change the following attributes for rendering your barcode:
1154
You can change the following attributes for rendering your barcode:
1156
.. i18n: * 'code': 'char'
1157
.. i18n: * 'ratio':'float'
1158
.. i18n: * 'xdim':'unit'
1159
.. i18n: * 'height':'unit'
1160
.. i18n: * 'checksum':'bool'
1161
.. i18n: * 'quiet':'bool'
1174
.. i18n: <barcode code="code128" xdim="28cm" ratio="2.2">`SN12345678</barcode>
1176
<barcode code="code128" xdim="28cm" ratio="2.2">`SN12345678</barcode>
1178
.. i18n: How to add a new report
1179
.. i18n: =======================
1181
How to add a new report
1182
=======================
1188
.. i18n: Administration -> Custom -> Low Level -> Base->Actions -> ir.actions.report.xml
1190
Administration -> Custom -> Low Level -> Base->Actions -> ir.actions.report.xml
1198
.. i18n: Code find in [[ ]] tags is python code.
1199
.. i18n: ---------------------------------------
1201
Code find in [[ ]] tags is python code.
1202
---------------------------------------
1204
.. i18n: The context of the code (the variable's values you can use) is the following:
1206
The context of the code (the variable's values you can use) is the following:
1208
.. i18n: python objects/variables, available when the report start:
1210
python objects/variables, available when the report start:
1212
.. i18n: "objects" the list of objects to be printed (invoices for example)
1214
"objects" the list of objects to be printed (invoices for example)
1216
.. i18n: "data" comes from the wizard
1218
"data" comes from the wizard
1220
.. i18n: "time" see python documentation.
1222
"time" see python documentation.
1224
.. i18n: "user" the user object launching the report.
1226
"user" the user object launching the report.
1228
.. i18n: python functions you can use:
1230
python functions you can use:
1232
.. i18n: "setlang('fr')" change the langage used in automated translation (fields...).
1234
"setlang('fr')" change the langage used in automated translation (fields...).
1236
.. i18n: "repeatIn(list,varname)" repeat the template (whole doc. or current paragraph?) for each object in the list. Use varname in the template's tags.
1238
"repeatIn(list,varname)" repeat the template (whole doc. or current paragraph?) for each object in the list. Use varname in the template's tags.
1240
.. i18n: "setTag('para','xpre')" change the enclosing RML tag (usually 'para') by an other (xpre is a preformatted paragraph), in the (converted from sxw)rml document (?)
1242
"setTag('para','xpre')" change the enclosing RML tag (usually 'para') by an other (xpre is a preformatted paragraph), in the (converted from sxw)rml document (?)
1244
.. i18n: "removeParentNode"
1248
.. i18n: Useful tags:
1249
.. i18n: ------------
1250
.. i18n: [ repeatIn(objects,'o') ] objects to be printed
1251
.. i18n: repeatIn(o.invoice_line,'l') print every line
1252
.. i18n: o.quantity * o.price Operations are OK.
1253
.. i18n: '07d' int(o.number) number formating
1254
.. i18n: reduce(lambda x obj: x+obj.qty , list , 0 ) total qty of list (try "objects" as list)
1255
.. i18n: user.name user name.
1256
.. i18n: setLang(o.partner_id.lang) Localized printings
1257
.. i18n: time.strftime('%d/%m/%Y') format=dd MM YYYY, check python doc for more about "%d", ...
1258
.. i18n: [[ time.strftime(time.ctime()[0:10]) ]] [[ time.strftime(time.ctime()[-4:]) ]] prints only date.
1259
.. i18n: time.ctime() it prints the actual date & time.
1260
.. i18n: [[ time.ctime().split()[3] ]] prints only time
1264
[ repeatIn(objects,'o') ] objects to be printed
1265
repeatIn(o.invoice_line,'l') print every line
1266
o.quantity * o.price Operations are OK.
1267
'07d' int(o.number) number formating
1268
reduce(lambda x obj: x+obj.qty , list , 0 ) total qty of list (try "objects" as list)
1269
user.name user name.
1270
setLang(o.partner_id.lang) Localized printings
1271
time.strftime('%d/%m/%Y') format=dd MM YYYY, check python doc for more about "%d", ...
1272
[[ time.strftime(time.ctime()[0:10]) ]] [[ time.strftime(time.ctime()[-4:]) ]] prints only date.
1273
time.ctime() it prints the actual date & time.
1274
[[ time.ctime().split()[3] ]] prints only time
1276
.. i18n: one more interesting tag: if you want to print out the creator of an entry (create_uid) or the last one who wrote on an entry (write_uid) you have to add something like this to the class your report refers to:
1278
one more interesting tag: if you want to print out the creator of an entry (create_uid) or the last one who wrote on an entry (write_uid) you have to add something like this to the class your report refers to:
1280
.. i18n: 'create_uid': fields.many2one('res.users', 'User', readonly=1)
1282
'create_uid': fields.many2one('res.users', 'User', readonly=1)
1284
.. i18n: and then in your report it's like this to print out the corresponding name:
1286
and then in your report it's like this to print out the corresponding name:
1288
.. i18n: o.create_uid.name
1292
.. i18n: Sometimes you might want to print out something only if a certain condition is fullfilled. You can construct it with the pyhton logical operators "not", "and" and "or". Because every object in python has a logical value (TRUE or FALSE) you can construct something like this:
1294
Sometimes you might want to print out something only if a certain condition is fullfilled. You can construct it with the pyhton logical operators "not", "and" and "or". Because every object in python has a logical value (TRUE or FALSE) you can construct something like this:
1296
.. i18n: (o.prop=='draft') and 'YES' or 'NO' print YES or NO
1298
(o.prop=='draft') and 'YES' or 'NO' print YES or NO
1300
.. i18n: it works like this:
1304
.. i18n: and: first value is TRUE then print out the second value. First value is FALSE print out first value.
1306
and: first value is TRUE then print out the second value. First value is FALSE print out first value.
1308
.. i18n: or: first value is TRUE then print out the first value. First value is FALSE print out second value. in this example if o.prop=='draft' -> TRUE then **(o.prop=='draft') and 'YES'** reads **'Yes'**. Next step is 'Yes' or 'No' which leads to a printed 'YES' (because a string's logical value is TRUE). If o.prop=='draft' -> FALSE then it reads FALSE or 'No'. So 'No' is printed. One can use very comlpex structures. To learn more search for some pyhton reference regarding logical opertors.
1310
or: first value is TRUE then print out the first value. First value is FALSE print out second value. in this example if o.prop=='draft' -> TRUE then **(o.prop=='draft') and 'YES'** reads **'Yes'**. Next step is 'Yes' or 'No' which leads to a printed 'YES' (because a string's logical value is TRUE). If o.prop=='draft' -> FALSE then it reads FALSE or 'No'. So 'No' is printed. One can use very comlpex structures. To learn more search for some pyhton reference regarding logical opertors.
1312
.. i18n: python function "filter" can... filter: try something like:
1314
python function "filter" can... filter: try something like:
1316
.. i18n: repeatIn(filter( lambda l: l.product_id.type=='service' ,o.invoice_line), 'line')
1318
repeatIn(filter( lambda l: l.product_id.type=='service' ,o.invoice_line), 'line')
1320
.. i18n: for printing only product with type='service' in a line's section.
1322
for printing only product with type='service' in a line's section.
1324
.. i18n: To display binary field image on report (to be checked)
1326
To display binary field image on report (to be checked)
1328
.. i18n: [[ setTag('para','image',{'width':'100.0','height':'80.0'}) ]] o.image or setTag('image','para')
1331
[[ setTag('para','image',{'width':'100.0','height':'80.0'}) ]] o.image or setTag('image','para')
1334
.. i18n: Unicode reports
1335
.. i18n: ===============
1340
.. i18n: As of OpenERP 5.0-rc3 unicode printing with ReportLab is still not available. The problem is that OpenERP uses the PDF standard fonts (14 fonts, they are not embedded in the document but the reader provides them) that are Type1 and have only Latin1 characters.
1342
As of OpenERP 5.0-rc3 unicode printing with ReportLab is still not available. The problem is that OpenERP uses the PDF standard fonts (14 fonts, they are not embedded in the document but the reader provides them) that are Type1 and have only Latin1 characters.
1344
.. i18n: The solution consists of 3 parts
1345
.. i18n: --------------------------------
1347
The solution consists of 3 parts
1348
--------------------------------
1350
.. i18n: * Provide TrueType fonts and make them accessible for ReportLab.
1351
.. i18n: * Register the TrueType fonts with ReportLab before using them in the reports.
1352
.. i18n: * Replace the old fontNames in xsl and rml templates with the TrueType ones.
1354
* Provide TrueType fonts and make them accessible for ReportLab.
1355
* Register the TrueType fonts with ReportLab before using them in the reports.
1356
* Replace the old fontNames in xsl and rml templates with the TrueType ones.
1358
.. i18n: All these ideas are taken from the forums
1359
.. i18n: -----------------------------------------
1361
All these ideas are taken from the forums
1362
-----------------------------------------
1364
.. i18n: **Free TrueType fonts**
1366
**Free TrueType fonts**
1368
.. i18n: that can be used for this purpose are in the DejaVu family. http://dejavu-fonts.org/wiki/index.php?title=Main_Page They can be installed
1370
that can be used for this purpose are in the DejaVu family. http://dejavu-fonts.org/wiki/index.php?title=Main_Page They can be installed
1372
.. i18n: * in the ReportLab's fonts directory,
1373
.. i18n: * system-wide and include that directory in rl_config.py,
1374
.. i18n: * in a subdirectory of the OpenERP installation and give that path to ReportLab during the font registration.
1376
* in the ReportLab's fonts directory,
1377
* system-wide and include that directory in rl_config.py,
1378
* in a subdirectory of the OpenERP installation and give that path to ReportLab during the font registration.
1380
.. i18n: **In the server/bin/report/render/rml2pdf/__init__.py**
1383
.. i18n: import reportlab.rl_config
1384
.. i18n: reportlab.rl_config.warnOnMissingFontGlyphs = 0
1386
**In the server/bin/report/render/rml2pdf/__init__.py**
1389
import reportlab.rl_config
1390
reportlab.rl_config.warnOnMissingFontGlyphs = 0
1392
.. i18n: from reportlab.pdfbase import pdfmetrics
1393
.. i18n: from reportlab.pdfbase.ttfonts import TTFont
1394
.. i18n: import reportlab
1396
from reportlab.pdfbase import pdfmetrics
1397
from reportlab.pdfbase.ttfonts import TTFont
1400
.. i18n: enc = 'UTF-8'
1404
.. i18n: #repeat these for all the fonts needed
1405
.. i18n: pdfmetrics.registerFont(TTFont('DejaVuSans', 'DejaVuSans.ttf',enc))
1406
.. i18n: pdfmetrics.registerFont(TTFont('DejaVuSans-Bold', 'DejaVuSans-Bold.ttf',enc))
1408
#repeat these for all the fonts needed
1409
pdfmetrics.registerFont(TTFont('DejaVuSans', 'DejaVuSans.ttf',enc))
1410
pdfmetrics.registerFont(TTFont('DejaVuSans-Bold', 'DejaVuSans-Bold.ttf',enc))
1412
.. i18n: from reportlab.lib.fonts import addMapping
1414
from reportlab.lib.fonts import addMapping
1416
.. i18n: #repeat these for all the fonts needed
1417
.. i18n: addMapping('DejaVuSans', 0, 0, 'DejaVuSans') #normal
1418
.. i18n: addMapping('DejaVuSans-Bold', 1, 0, 'DejaVuSans') #normal
1420
#repeat these for all the fonts needed
1421
addMapping('DejaVuSans', 0, 0, 'DejaVuSans') #normal
1422
addMapping('DejaVuSans-Bold', 1, 0, 'DejaVuSans') #normal
1424
.. i18n: trml2pdf.py should be modified to load this if invoked from the command line.
1426
trml2pdf.py should be modified to load this if invoked from the command line.
1428
.. i18n: **All the xsl and rml files have to be modified**
1430
**All the xsl and rml files have to be modified**
1432
.. i18n: A list of possible alternatives:
1435
.. i18n: 'Times-Roman', 'DejaVuSerif.ttf'
1436
.. i18n: 'Times-BoldItalic', 'DejaVuSerif-BoldItalic.ttf'
1437
.. i18n: 'Times-Bold', 'DejaVuSerif-Bold.ttf'
1438
.. i18n: 'Times-Italic', 'DejaVuSerif-Italic.ttf'
1440
A list of possible alternatives:
1443
'Times-Roman', 'DejaVuSerif.ttf'
1444
'Times-BoldItalic', 'DejaVuSerif-BoldItalic.ttf'
1445
'Times-Bold', 'DejaVuSerif-Bold.ttf'
1446
'Times-Italic', 'DejaVuSerif-Italic.ttf'
1448
.. i18n: 'Helvetica', 'DejaVuSans.ttf'
1449
.. i18n: 'Helvetica-BoldItalic', 'DejaVuSans-BoldOblique.ttf'
1450
.. i18n: 'Helvetica-Bold', 'DejaVuSans-Bold.ttf'
1451
.. i18n: 'Helvetica-Italic', 'DejaVuSans-Oblique.ttf'
1453
'Helvetica', 'DejaVuSans.ttf'
1454
'Helvetica-BoldItalic', 'DejaVuSans-BoldOblique.ttf'
1455
'Helvetica-Bold', 'DejaVuSans-Bold.ttf'
1456
'Helvetica-Italic', 'DejaVuSans-Oblique.ttf'
1458
.. i18n: 'Courier', 'DejaVuSansMono.ttf'
1459
.. i18n: 'Courier-Bold', 'DejaVuSansMono-Bold.ttf'
1460
.. i18n: 'Courier-BoldItalic','DejaVuSansMono-BoldOblique.ttf'
1461
.. i18n: 'Courier-Italic', 'DejaVuSansMono-Oblique.ttf'
1463
'Courier', 'DejaVuSansMono.ttf'
1464
'Courier-Bold', 'DejaVuSansMono-Bold.ttf'
1465
'Courier-BoldItalic','DejaVuSansMono-BoldOblique.ttf'
1466
'Courier-Italic', 'DejaVuSansMono-Oblique.ttf'
1468
.. i18n: 'Helvetica-ExtraLight', 'DejaVuSans-ExtraLight.ttf'
1470
'Helvetica-ExtraLight', 'DejaVuSans-ExtraLight.ttf'
1472
.. i18n: 'TimesCondensed-Roman', 'DejaVuSerifCondensed.ttf'
1473
.. i18n: 'TimesCondensed-BoldItalic', 'DejaVuSerifCondensed-BoldItalic.ttf'
1474
.. i18n: 'TimesCondensed-Bold', 'DejaVuSerifCondensed-Bold.ttf'
1475
.. i18n: 'TimesCondensed-Italic', 'DejaVuSerifCondensed-Italic.ttf'
1477
'TimesCondensed-Roman', 'DejaVuSerifCondensed.ttf'
1478
'TimesCondensed-BoldItalic', 'DejaVuSerifCondensed-BoldItalic.ttf'
1479
'TimesCondensed-Bold', 'DejaVuSerifCondensed-Bold.ttf'
1480
'TimesCondensed-Italic', 'DejaVuSerifCondensed-Italic.ttf'
1482
.. i18n: 'HelveticaCondensed', 'DejaVuSansCondensed.ttf'
1483
.. i18n: 'HelveticaCondensed-BoldItalic', 'DejaVuSansCondensed-BoldOblique.ttf'
1484
.. i18n: 'HelveticaCondensed-Bold', 'DejaVuSansCondensed-Bold.ttf'
1485
.. i18n: 'HelveticaCondensed-Italic', 'DejaVuSansCondensed-Oblique.ttf
1487
'HelveticaCondensed', 'DejaVuSansCondensed.ttf'
1488
'HelveticaCondensed-BoldItalic', 'DejaVuSansCondensed-BoldOblique.ttf'
1489
'HelveticaCondensed-Bold', 'DejaVuSansCondensed-Bold.ttf'
1490
'HelveticaCondensed-Italic', 'DejaVuSansCondensed-Oblique.ttf