odoo V10開發(fā)文檔(第四章:國際化鹊汛、報(bào)表、webservice)

國際化

每個(gè)模塊可以提供一個(gè)國際化翻譯模塊阱冶,存放在模塊的i18n文件夾中的xx.po文件中刁憋,如中文就是zh_CN.po,所有翻譯文件在odoo啟動(dòng)時(shí)會(huì)自動(dòng)加載木蹬。一般默認(rèn)用英語來開發(fā)模塊至耻,然后用odoo內(nèi)置的導(dǎo)出翻譯功能導(dǎo)出生成pot模板,然后就可以根據(jù)這個(gè)模板編輯成其他語言的了镊叁。

報(bào)表

報(bào)表打印

odoo從8.0開始使用qweb引警和bootstrap 尘颓、Wkhtmltopdf來打印報(bào)表
報(bào)表由兩個(gè)元素組成

  • report標(biāo)簽的ir.actions.report.xml,它會(huì)初始化一些報(bào)表的基本參數(shù)如默認(rèn)類型晦譬、生成后是否保存到數(shù)據(jù)庫
<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')"
/>
  • 一個(gè)標(biāo)準(zhǔn)的Qweb視圖用于實(shí)際生成報(bào)表
<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>

報(bào)表是標(biāo)準(zhǔn)的web頁面泥耀,所以是可以通過鏈接直接訪問的。如發(fā)票的html版本報(bào)表可以通過http://localhost:8069/report/html/account.report_invoice/1來訪問蛔添,pdf版本通過http://localhost:8069/report/pdf/account.report_invoice/1查看
如果發(fā)現(xiàn)生成的pdf樣式不對(duì)痰催,那可能是wkhtmltopdf沒辦法訪問web服務(wù)器導(dǎo)致的。wkhtmltopdf進(jìn)程使用web.base.url作為根url來生成對(duì)應(yīng)文件路徑迎瞧,但這個(gè)地址是每次管理員登錄都會(huì)自動(dòng)更新的夸溶,如果使用了代理,可能就出現(xiàn)訪問不了的情況凶硅,可以通過添加一個(gè)系統(tǒng)參數(shù)來解決:report.url指向一個(gè)可訪問的地址如localhost:8069等缝裁、這個(gè)是報(bào)表打印專用參數(shù),或者用web.base.url.freeze足绅,設(shè)置為True時(shí)會(huì)停止自動(dòng)更新捷绑。

實(shí)例:為session模型制作報(bào)表

#__manifest__.py
'data': [
        'security/security.xml',
        'security/ir.model.access.csv',
        'views/views.xml',
        'views/partner.xml',
        'report.xml',
    ],
    
#report.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>
    

儀表板

實(shí)例:制作一個(gè)儀表板,包含已經(jīng)創(chuàng)建的日歷視圖氢妈、圖形視圖粹污、和課程列表,并將它加到菜單項(xiàng)中首量,當(dāng)進(jìn)入academy模塊時(shí)自動(dòng)顯示儀表板內(nèi)容壮吩。

#__manifest__.py
'depends': ['base', 'board'],

# always loaded
'data': [
    'security/security.xml',
    'security/ir.model.access.csv',
    'views/views.xml',
    'views/partner.xml',
    'views/session_board.xml',
    'reports.xml',
    'views/session_workflow.xml',
    #'views/templates.xml',
    #'data/data.xml'
],

#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_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="session_calendar_view"/>
        </record>
        <record model="ir.actions.act_window" id="act_course_list">
            <field name="name">Courses</field>
            <field name="res_model">openacademy.courses</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儀表板" 
            action="open_board_session"
            sequence="1"
            id="menu_board_session" icon="terp-graph"/>
        
    </data>
</odoo>

WebServices

WebServices模塊為所有web服務(wù)提供XML-RPC和JSON-RPC接口进苍,所有業(yè)務(wù)對(duì)象都可通過webservice操作

  • XML-RPC庫

例:使用xmlrpclib訪問odoo服務(wù)的python腳本

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)

例:通過xmlrpc發(fā)送請(qǐng)求到odoo服務(wù)器,顯示全部session及座位數(shù)鸭叙、還可以為課程創(chuàng)建新session

# -*- coding: utf-8 -*-

import functools
import xmlrpclib
HOST = 'localhost'
PORT = 8069
DB = 'odoo'
USER = 'admin'
PASS = '123456'
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,
})
  • JSON-RPC庫

例1:通過python的urllib2和json類庫與odoo服務(wù)器進(jìn)行交互的python腳本

import json
import random
import urllib2

HOST = 'localhost'
PORT = 8069
DB = 'odoo'
USER = 'admin'
PASS = '123456'

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)

print "login successed ,uid : %s" % uid

例2:使用jsonrpclib類庫來實(shí)現(xiàn)一樣的功能

import jsonrpclib

HOST = 'localhost'
PORT = 8069
DB = 'odoo'
USER = 'admin'
PASS = '123456'

# 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])

print "login successed ,uid : %s" % uid

odoo有很多經(jīng)過封裝的api包觉啊,可以省去很多麻煩

rpc里的service和對(duì)應(yīng)的method:
common=》(login,authenticate沈贝,version杠人,about,set_loglevel)
db=》(dbcreate_database宋下,duplicate_database搜吧,drop,dump杨凑,restore滤奈,rename,change_admin_password撩满,migrate_database蜒程,db_exist,list伺帘,list_lang昭躺,list_countries,server_version)
object=》(execute伪嫁,execute_kw领炫,execute_workflow)
report=》(report,report_get张咳,render_report)

內(nèi)容發(fā)布自http://www.reibang.com/u/6fdae8ec06bc帝洪,轉(zhuǎn)載請(qǐng)注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市脚猾,隨后出現(xiàn)的幾起案子葱峡,更是在濱河造成了極大的恐慌,老刑警劉巖龙助,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰奕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡提鸟,警方通過查閱死者的電腦和手機(jī)军援,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來称勋,“玉大人胸哥,你說我怎么就攤上這事∠巢” “怎么了烘嘱?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蝗蛙。 經(jīng)常有香客問我蝇庭,道長(zhǎng),這世上最難降的妖魔是什么捡硅? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任哮内,我火速辦了婚禮,結(jié)果婚禮上壮韭,老公的妹妹穿的比我還像新娘北发。我一直安慰自己,他們只是感情好喷屋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布琳拨。 她就那樣靜靜地躺著,像睡著了一般屯曹。 火紅的嫁衣襯著肌膚如雪狱庇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天恶耽,我揣著相機(jī)與錄音密任,去河邊找鬼。 笑死偷俭,一個(gè)胖子當(dāng)著我的面吹牛浪讳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涌萤,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼淹遵,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了负溪?” 一聲冷哼從身側(cè)響起合呐,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笙以,沒想到半個(gè)月后淌实,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猖腕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拆祈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倘感。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡放坏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出老玛,到底是詐尸還是另有隱情淤年,我是刑警寧澤钧敞,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站麸粮,受9級(jí)特大地震影響溉苛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弄诲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一愚战、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧齐遵,春花似錦寂玲、人聲如沸搞隐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摊册。三九已至志于,卻和暖如春贵少,著一層夾襖步出監(jiān)牢的瞬間镰烧,已是汗流浹背乔询。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國打工谎砾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逢倍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓景图,卻偏偏與公主長(zhǎng)得像较雕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挚币,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容