美文网首页OdooodooOdoo
Odoo10开发教程九(报表和WebService)

Odoo10开发教程九(报表和WebService)

作者: luohuayong | 来源:发表于2017-04-08 11:35 被阅读2945次

    报表

    报表打印

    Odoo 8.0 开始使用新的基于QWebTwitter BootstrapWkhtmltopdf的报表引擎。一个报表有两个元素组成:
    其一是ir.actions.report.xml中,针对报表提供的快捷元素<report>,这个元素用于设置报表的各种基本参数(如默认类型,报表生成后是否保存到数据库)

    <report
        id="account_invoices"
        model="account.invoice"
        string="Invoices"
        report_type="qweb-pdf"
        name="account.report_invoice"
        file="account.report_invoice"
        attachment_use="True"
        attachment="(object.state in ('open','paid')) and
            ('INV'+(object.number or '').replace('/','')+'.pdf')"
    />
    

    另一个是标准的QWeb视图,实例如下:

    <t t-call="report.html_container">
        <t t-foreach="docs" t-as="o">
            <t t-call="report.external_layout">
                <div class="page">
                    <h2>Report title</h2>
                </div>
            </t>
        </t>
    </t>
    
    the standard rendering context provides a number of elements, the most
    important being:
    
    ``docs``
        the records for which the report is printed
    ``user``
        the user printing the report
    

    由于报表是标准的web页面,所以都可以通过URL和输出参数来访问,例如HTML版本的发票报表可以通过这个地址访问:http://localhost:8069/report/html/account.report_invoice/1(如果安装了account),而PDF版本可以通过这个地址访问:http://localhost:8069/report/pdf/account.report_invoice/1

    警告
    如果出现了PDF报表没有样式(比如有文本显示但是与html版本的风格/布局不一致),可能是wkhtmltopdf进程不能为下载提供web服务。
    如果你检查服务日志,并且看到生成PDF报表时CSS样式未被下载,那么就可以肯定是这个问题。
    wkhtmltopdf进程使用web.base.url这个系统参数作为根路径来组合所有文件路径,但是这个参数是在管理员帐户登录后自动生成的。如果你的服务器位于某种代理服务器之后,则无法访问该服务器。你可以添加一个系统参数来固化它:

    • report.url,可以访问你的服务器的URL地址,比如http://localhost:8069或者类似的地址。这个参数仅用于这个特殊情况。
    • web.base.url.freeze,当设置这个参数值为True时将停止自动更新web.base.url

    练习创建授课模型的报表
    对于每个授课,报表都将显示它的授课名称,开始和结束时间,以及课程出席人列表。

    openacademy / __ manifest__.py

            'views/openacademy.xml',
            'views/partner.xml',
            'views/session_workflow.xml',
            'reports.xml',
        ],
        # only loaded in demonstration mode
        'demo': [
    

    openacademy/reports.xml

    <odoo>
    <data>
        <report
            id="report_session"
            model="openacademy.session"
            string="Session Report"
            name="openacademy.report_session_view"
            file="openacademy.report_session"
            report_type="qweb-pdf" />
    
        <template id="report_session_view">
            <t t-call="report.html_container">
                <t t-foreach="docs" t-as="doc">
                    <t t-call="report.external_layout">
                        <div class="page">
                            <h2 t-field="doc.name"/>
                            <p>From <span t-field="doc.start_date"/> to <span t-field="doc.end_date"/></p>
                            <h3>Attendees:</h3>
                            <ul>
                                <t t-foreach="doc.attendee_ids" t-as="attendee">
                                    <li><span t-field="attendee.name"/></li>
                                </t>
                            </ul>
                        </div>
                    </t>
                </t>
            </t>
        </template>
    </data>
    </odoo>
    

    仪表盘

    练习定义一个仪表盘
    定义一个仪表盘,这个仪表盘包含了已经建立的图形视图、授课日历视图、课程列表视图(可以选择form视图)。这个仪表盘可以通过菜单中的菜单项使用,并且当选择开放学院主菜单时自动显示在web客户端。

    1. 建立文件openacademy/views/session_board.xml。这个文件包含面板视图,视图的触发action,打开仪表盘的action,以及重新定义主菜单项以添加仪表盘的action。

    注意
    可以使用的仪表盘风格有:11-12-11-1-1

    1. 更新openacademy/__manifest__.py文件,以引用新的数据文件。

    openacademy/__manifest__.py

        'version': '0.1',
    
        # any module necessary for this one to work correctly
        'depends': ['base', 'board'],
    
        # always loaded
        'data': [
    
            'views/openacademy.xml',
            'views/partner.xml',
            'views/session_workflow.xml',
            'views/session_board.xml',
            'reports.xml',
        ],
        # only loaded in demonstration mode
    

    openacademy/views/session_board.xml

    <?xml version="1.0"?>
    <odoo>
        <data>
            <record model="ir.actions.act_window" id="act_session_graph">
                <field name="name">Attendees by course</field>
                <field name="res_model">openacademy.session</field>
                <field name="view_type">form</field>
                <field name="view_mode">graph</field>
                <field name="view_id"
                       ref="openacademy.openacademy_session_graph_view"/>
            </record>
            <record model="ir.actions.act_window" id="act_session_calendar">
                <field name="name">Sessions</field>
                <field name="res_model">openacademy.session</field>
                <field name="view_type">form</field>
                <field name="view_mode">calendar</field>
                <field name="view_id" ref="openacademy.session_calendar_view"/>
            </record>
            <record model="ir.actions.act_window" id="act_course_list">
                <field name="name">Courses</field>
                <field name="res_model">openacademy.course</field>
                <field name="view_type">form</field>
                <field name="view_mode">tree,form</field>
            </record>
            <record model="ir.ui.view" id="board_session_form">
                <field name="name">Session Dashboard Form</field>
                <field name="model">board.board</field>
                <field name="type">form</field>
                <field name="arch" type="xml">
                    <form string="Session Dashboard">
                        <board style="2-1">
                            <column>
                                <action
                                    string="Attendees by course"
                                    name="%(act_session_graph)d"
                                    height="150"
                                    width="510"/>
                                <action
                                    string="Sessions"
                                    name="%(act_session_calendar)d"/>
                            </column>
                            <column>
                                <action
                                    string="Courses"
                                    name="%(act_course_list)d"/>
                            </column>
                        </board>
                    </form>
                </field>
            </record>
            <record model="ir.actions.act_window" id="open_board_session">
              <field name="name">Session Dashboard</field>
              <field name="res_model">board.board</field>
              <field name="view_type">form</field>
              <field name="view_mode">form</field>
              <field name="usage">menu</field>
              <field name="view_id" ref="board_session_form"/>
            </record>
    
            <menuitem
                name="Session Dashboard" parent="base.menu_reporting_dashboard"
                action="open_board_session"
                sequence="1"
                id="menu_board_session" icon="terp-graph"/>
        </data>
    </odoo>
    

    WebServices
    WebService模型为所有web服务提供通用接口:

    • XML-RPC
    • JSON-RPC
      业务对象也可以通过这种分布式机制进行访问,在客户端界面通过上下文编辑这些业务对象。
      Odoo支持通过XML-RPC/JSON-RPC接口访问,这两种协议在许多开发语言中都有库支持。

    XML-RPC库
    下面的例子是Python程序通过xmlrpclib库访问Odoo服务器:

    import xmlrpclib
    
    root = 'http://%s:%d/xmlrpc/' % (HOST, PORT)
    
    uid = xmlrpclib.ServerProxy(root + 'common').login(DB, USER, PASS)
    print "Logged in as %s (uid: %d)" % (USER, uid)
    
    # Create a new note
    sock = xmlrpclib.ServerProxy(root + 'object')
    args = {
        'color' : 8,
        'memo' : 'This is a note',
        'create_uid': uid,
    }
    note_id = sock.execute(DB, uid, PASS, 'note.note', 'create', args)
    

    练习在客户端添加新服务
    编写Python程序,用来发送XML-RPC请求到运行Odoo的PC。这个程序将显示全部授课,以及所对应的座位数。也可以为课程创建新的授课。

    import functools
    import xmlrpclib
    HOST = 'localhost'
    PORT = 8069
    DB = 'openacademy'
    USER = 'admin'
    PASS = 'admin'
    ROOT = 'http://%s:%d/xmlrpc/' % (HOST,PORT)
    
    # 1. Login
    uid = xmlrpclib.ServerProxy(ROOT + 'common').login(DB,USER,PASS)
    print "Logged in as %s (uid:%d)" % (USER,uid)
    
    call = functools.partial(
        xmlrpclib.ServerProxy(ROOT + 'object').execute,
        DB, uid, PASS)
    
    # 2. Read the sessions
    sessions = call('openacademy.session','search_read', [], ['name','seats'])
    for session in sessions:
        print "Session %s (%s seats)" % (session['name'], session['seats'])
    # 3.create a new session
    session_id = call('openacademy.session', 'create', {
        'name' : 'My session',
        'course_id' : 2,
    })
    

    不使用硬编码,通过课程名称查找课程ID:

    # 3.create a new session for the "Functional" course
    course_id = call('openacademy.course', 'search', [('name','ilike','Functional')])[0]
    session_id = call('openacademy.session', 'create', {
        'name' : 'My session',
        'course_id' : course_id,
    })
    

    JSON-RPC库
    下面的例子是一个Python程序,通过Pythong的标准库urllib2json与Odoo服务器交互。

    import json
    import random
    import urllib2
    
    def json_rpc(url, method, params):
        data = {
            "jsonrpc": "2.0",
            "method": method,
            "params": params,
            "id": random.randint(0, 1000000000),
        }
        req = urllib2.Request(url=url, data=json.dumps(data), headers={
            "Content-Type":"application/json",
        })
        reply = json.load(urllib2.urlopen(req))
        if reply.get("error"):
            raise Exception(reply["error"])
        return reply["result"]
    
    def call(url, service, method, *args):
        return json_rpc(url, "call", {"service": service, "method": method, "args": args})
    
    # log in the given database
    url = "http://%s:%s/jsonrpc" % (HOST, PORT)
    uid = call(url, "common", "login", DB, USER, PASS)
    
    # create a new note
    args = {
        'color' : 8,
        'memo' : 'This is another note',
        'create_uid': uid,
    }
    note_id = call(url, "object", "execute", DB, uid, PASS, 'note.note', 'create', args)
    

    下面是使用jsonrpc完成相同功能的程序

    import jsonrpclib
    
    # server proxy object
    url = "http://%s:%s/jsonrpc" % (HOST, PORT)
    server = jsonrpclib.Server(url)
    
    # log in the given database
    uid = server.call(service="common", method="login", args=[DB, USER, PASS])
    
    # helper function for invoking model methods
    def invoke(model, method, *args):
        args = [DB, uid, PASS, model, method] + list(args)
        return server.call(service="object", method="execute", args=args)
    
    # create a new note
    args = {
        'color' : 8,
        'memo' : 'This is another note',
        'create_uid': uid,
    }
    note_id = invoke('note.note', 'create', args)
    

    提醒
    有许多语言可以通过XML-RPC或JSON-RPC访问Odoo系统的高级API,例如:

    相关文章

      网友评论

        本文标题:Odoo10开发教程九(报表和WebService)

        本文链接:https://www.haomeiwen.com/subject/evtpottx.html