Adding new reports to OpenERP

Creating new modules for Open ERP is pretty simple. Here is how to package up some new reports into a module.

In this example I’ve created another report to use with sales orders. This is based on the sales order report so in actual fact I use some of the code and xml from that original report to build it up, then tweak them to produce the collection docket I want. I’m not actually going to reproduce the report here, since that’s a trivial thing to customise. The interesting thing is really how the module is packaged together and how to spot mistakes in the packaging.

The files/folders in the zip

module/__openerp__.py                # this contains the module info
module/report/collection_docket.rml  # the report
module/report/sale_order.py          # sets up the report parser
module/report/__init__.py            # just loads the code
module/reports.xml                   # registers the report
module/__init__.py                   # loads the code

__openerp__.py

{
   'name': 'Extra Sales Reports',
   'version': '0.01',
   'category': 'Extra reports for sales',
   'description': """
   The extra sales reports needed for our project,

   * Reports
     - Collection Docket

   """,
   'author': 'OpusVL',
   'website': 'http://www.opusvl.com',
   'depends': ['stock', 'procurement', 'board', 'sale'],
   'init_xml': [],
   'update_xml': [
       'reports.xml',
   ],
   'demo_xml': [],
   'test': [],
   'installable': True,
   'active': False,
}

__init.py__

import report

reports.xml

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <report auto="False" id="collection_docket" model="sale.order" name="sale.collection_docket" rml="module/report/collection_docket.rml" string="Collection Docket" />
    </data>
</openerp>

report/__init__.py

import sale_order

report/sale_order.py

from report import report_sxw
import time


# this bit is basically a copy of the stuff
# in the regular sale order module.
# I can't just import that code because it causes
# the sale.order report to get registered again
# causing it to complain.
# otherwise I’d do this - from addons.sale.report import order 
class order(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context=None):
        super(order, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
        })


report_sxw.report_sxw('report.sale.collection_docket', 'sale.order', 'addons/module/report/collection_docket.rml', parser=order, header="external")

report/collection_docket.rml

<?xml version="1.0"?>
<document filename="Sale Order.pdf">
... this is a copy of the addons/sale/report/sale_order.rml customised as necessary.

The module is then zipped up for distribution in a regular .zip file. This can either be imported directly into OpenERP or it can be unzipped manually into the addons directory.

Installation of the module via the OpenERP client

  1. Go to Administration->Modules,
  2. Select Import module and select the zip [1].
  3. Select the module and mark it for install.
  4. Now restart OpenERP server.
  5. Now go back to the client and schedule the install of the module.

If you install your module this way you will actually find that the module is left in it’s zip file and the OpenERP server simply reads the files from the zip as if they were an extension of the addons directory.

Manual installation

  1. Find the addons directory
  2. Unzip the module into it.
  3. Restart the openerp server
  4. Go to Administration -> Modules
  5. Select ‘Update Module List’.
  6. Find the module and schedule it for install.

Use

The report can now be used programmatically using the standard report method and referencing it as sale.collection_docket. Alternatively you’ll find that a button has appeared on the sales order screen in the OpenERP client that allows you to print the collection docket alongside the button for printing the regular sales order report.

Trouble shooting

ZipImportError: bad local file header in /usr/share/pyshared/openerp-server/addons/myextra_reports.
zip

This normally indicates it is time to restart the server. If you have just imported the zip file of the module and tried to install it straight away you will often get this error.

ERROR:web-services:[01]: Exception: Report /usr/share/pyshared/openerp-server/addons/myextra_report/report/collection_docket.rml doesn’t exist or deleted :

This is generally caused by a typo in the parser python file where the report is registered with the report_sxw.report_sxw call.

ERROR:service:This service does not exist: ‘report.sale.collection_docket’
ERROR:web-services:[07]: KeyError: ‘report.sale.collection_docket’

The report hasn’t been registered. Has your module been installed and loaded against the current database? Remember that installing the module into the OpenERP server and installing it against your current database are two seperate steps.

ERROR:web-services:[01]: Exception: Start tag expected, ‘<' not found, line 1, column 1

This can be caused by a bad filename registered using the xml file. The path to the file should be in relation to the addons path. In other words, if the full path is /usr/share/pyshared/openerp-server/addons/module/report/docket.rml, the relative filename you need is module/report/docket.rml.
http://www.openerp.com/forum/topic26308.html

The alternative cause of this problem is that there is a unicode BOM indicator at the start of the file. One of the support entries appears to indicate that that will cause the parser to dislike the document.

https://bugs.launchpad.net/openobject-server/+bug/694409

[1] If you get a permissions error that’s normally because the addons
directory isn’t writeable by the user that openerp is running as.

Further reading

The OpenERP documentation regarding reports.

11 thoughts on “Adding new reports to OpenERP

  1. Hi, i love your tutorial
    but i’m getting keyError, Could you tell me how to fix it in details ?
    i dont understand “The report hasn’t been registered. Has your module been installed and loaded against the current database? Remember that installing the module into the OpenERP server and installing it against your current database are two seperate steps. ”

    Thanks, sorry for my poor english

  2. Log into your system and go to the Administration part of the system. Select the modules and find your new module in the list. If you’re getting the KeyError then it’s likely that that report is in red because it hasn’t been installed. Assuming that’s the case double click the module and schedule it for install, then apply the schedule upgrades.

    If the module definitely is installed then perhaps it’s a goof with the names somewhere? I’d check throughout your module and the code that uses it and ensure that the names are exactly the same in every way.

  3. Did you mean to not include a copy of module/report/sale_order.py? I just copied /usr/share/pyshared/openerp/addons/sale/report/sale_order.py. But Update modules never added this new module. I used your “Manual installation” method.

  4. Dale, the code for sale_order.py was kind of there, but I’d goofed the formatting so I’ve corrected the post now. It was previously embedded in the report/__init__.py part of the post. Your copy of the existing sale_order.py was the right instinct though, that’s essentially all I did too.

    The automatic method of installation doesn’t seem to exist in 6.1 now, and even with 6.0 would only work if you had your permissions set correctly. When I say correctly, I mean setup in a relatively open fashion, so the default debian package has never set them up that way, and I suspect a lot of admins wouldn’t set them that way either. The manual method is the safest and probably sanest option anyway.

  5. Thank you so much Colin; you are very much appreciated! I’ve replaced my copy of sale_order.py and http://localhost:8069/web/webclient/home#page=0&limit=80&view_type=list&title=Modules&model=ir.module.module still does not show any additional modules. Your comments on permissions have me wondering if I should have granted more write access:

    root@QnD:/usr/share/pyshared/openerp/addons/module/report# ll -d ../../module
    drwxr-xr-x 3 root root 4096 Oct 26 12:27 ../../module/
    root@QnD:/usr/share/pyshared/openerp/addons/module/report# ls -lR ../../module
    ../../module:
    total 16
    -rw-r–r– 1 root root 14 Oct 26 12:14 __init__.py
    -rw-r–r– 1 root root 565 Oct 26 12:13 __openerp__.py
    drwxr-xr-x 2 root root 4096 Oct 26 18:49 report
    -rw-r–r– 1 root root 257 Oct 26 12:14 reports.xml

    ../../module/report:
    total 28
    -rw-r–r– 1 root root 19165 Oct 26 12:25 collection_docket.rml
    -rw-r–r– 1 root root 734 Oct 26 12:15 __init__.py
    -rw-r–r– 1 root root 692 Oct 26 18:49 sale_order.py

    Or I wonder if I should add the module folder to some file.xml in the addons folder?

    Sad that I’m still unable to create reports.

  6. That looks like you’ve discovered one of the joys of the way it is packaged on debian with 6.1. It might be the same on other distro’s too, but I’m only familiar with debian. The code is dropped into /usr/share/pyshared/openerp and then it’s actually run from /usr/lib/pymodules/python2.6/openerp. The code is symlinked into the /usr/lib/pymodules directory. This means that in order to install a module now you either drop it straight into the addons directory in the /usr/lib/pymodules path, or create symlinks to where you’ve just installed it. Once the code is visible from that path OpenERP should be able to see it.

  7. I hope you don’t mind me dirtying up your blog with my problems! Thanks to your help; I got it installed!

    I linked the .zip which made it appear in update modules, then; I had some formatting problems in sale_order.py so it errored out. Once I fixed my typographical errors it wouldn’t appear again in update modules so I moved the folder structure into pymodules and it installed without problem.

    Then I go to Sales Orders and run the Collections Docket (I’m so excited right now!) But, sadly encounter this:

    OpenERP Warning
    report.sale.collection_docket
    (, KeyError(u’report.sale.collection_docket’,), )

  8. That error generally relates to the report not being registered. I would suggest restarting openerp, and then doing an upgrade of the module to ensure all the hooks are installed correctly. OpenERP needs to be restarted after every code change, a simple upgrade of a module will not necessarily get the correct code loaded.

    If you are still having the problem after that, take a look at your code that registers the report and check it is okay, that’s the report_sxw.report_sxw line in the sale_order.py.

  9. You are right Colin; I had fooled with the module name leaving partially installed copies. Though my OpenERP module uninstall is beta that along with deleting the database record and “service openerp restart” allowed me to delete my partial installs, correct my file contents and I’ve generated a report; YEA!

    I’ve posted my code and praise here http://cms.mooreworks.net/cms/openerp-collections-docket-report.aspx.

    Thanks Colin; for everything!

Leave a comment