odoo V10開發(fā)文檔(第三章:工作流、安全機制效斑、向?qū)В?/h1>

工作流

工作流是與業(yè)務(wù)流程相關(guān)聯(lián)的模型,工作流同時可用于跟蹤工序的演變過程

例:為session模型添加一個state字段用于定義一個工作流
state有三種取值:Draft (默認), Confirmed and Done.
在session表單添加state的顯示柱徙,并添加一個改變其狀態(tài)的按鈕

#models.py
state = fields.Selection([
        ('draft', "Draft"),
        ('confirmed', "Confirmed"),
        ('done', "Done"),
    ], default='draft')
@api.multi
    def action_draft(self):
        self.state = 'draft'

@api.multi
def action_confirm(self):
    self.state = 'confirmed'

@api.multi
def action_done(self):
    self.state = 'done'
    
#views.xml
<form string="Session Form">
    <header>
        <button name="action_draft" type="object"
                string="Reset to draft"
                states="confirmed,done"/>
        <button name="action_confirm" type="object"
                string="Confirm" states="draft"
                class="oe_highlight"/>
        <button name="action_done" type="object"
                string="Mark as done" states="confirmed"
                class="oe_highlight"/>
        <field name="state" widget="statusbar"/>
    </header>
    <sheet>
        <group>
            <group string="General">

工作流可與odoo的任意對象相關(guān)聯(lián)缓屠,可以自定義。工作流用于構(gòu)造护侮、管理業(yè)務(wù)對象和文檔的整個生命周期敌完,并可用圖形化工具來定義轉(zhuǎn)換、觸發(fā)器等羊初。工作流滨溉、活動(節(jié)點或操作)、轉(zhuǎn)換通常在xml里以record定義长赞。在工作流中處理的單個流程稱為工作項晦攒。

與模型關(guān)聯(lián)的工作流是在創(chuàng)建模型記錄時生成的,工作流定義之前創(chuàng)建的模型記錄是沒有相應(yīng)的工作流的得哆。

例:將之前定義的偽工作流修改為真正的工作流脯颜,修改視圖讓按鈕觸發(fā)真正的工作流

#__manifest__.py
'data':[
    'templates.xml',
    'views/openacademy.xml',
    'views/partner.xml',
    'views/session_workflow.xml',
],

#models.py
state = fields.Selection([
        ('draft', "Draft"),
        ('confirmed', "Confirmed"),
        ('done', "Done"),
    ])

#views.xml
<form string="Session Form">
    <header>
        <button name="draft" type="workflow"
                string="Reset to draft"
                states="confirmed,done"/>
        <button name="confirm" type="workflow"
                string="Confirm" states="draft"
                class="oe_highlight"/>
        <button name="done" type="workflow"
                string="Mark as done" states="confirmed"
                class="oe_highlight"/>
        <field name="state" widget="statusbar"/>
    </header>
    
#views/session_workflow.xml
<odoo>
    <data>
        <record model="workflow" id="wkf_session">
            <field name="name">OpenAcademy sessions workflow</field>
            <field name="osv">openacademy.session</field>
            <field name="on_create">True</field>
        </record>

        <record model="workflow.activity" id="draft">
            <field name="name">Draft</field>
            <field name="wkf_id" ref="wkf_session"/>
            <field name="flow_start" eval="True"/>
            <field name="kind">function</field>
            <field name="action">action_draft()</field>
        </record>
        <record model="workflow.activity" id="confirmed">
            <field name="name">Confirmed</field>
            <field name="wkf_id" ref="wkf_session"/>
            <field name="kind">function</field>
            <field name="action">action_confirm()</field>
        </record>
        <record model="workflow.activity" id="done">
            <field name="name">Done</field>
            <field name="wkf_id" ref="wkf_session"/>
            <field name="kind">function</field>
            <field name="action">action_done()</field>
        </record>

        <record model="workflow.transition" id="session_draft_to_confirmed">
            <field name="act_from" ref="draft"/>
            <field name="act_to" ref="confirmed"/>
            <field name="signal">confirm</field>
        </record>
        <record model="workflow.transition" id="session_confirmed_to_draft">
            <field name="act_from" ref="confirmed"/>
            <field name="act_to" ref="draft"/>
            <field name="signal">draft</field>
        </record>
        <record model="workflow.transition" id="session_done_to_draft">
            <field name="act_from" ref="done"/>
            <field name="act_to" ref="draft"/>
            <field name="signal">draft</field>
        </record>
        <record model="workflow.transition" id="session_confirmed_to_done">
            <field name="act_from" ref="confirmed"/>
            <field name="act_to" ref="done"/>
            <field name="signal">done</field>
        </record>
    </data>
</odoo>

自動轉(zhuǎn)換:當(dāng)上座率達到50%時自動將session的狀態(tài)由draft變?yōu)閏onfirmed

#session_workflow.xml
<!-- 工作流自動轉(zhuǎn)換 -->
<record model="workflow.transition" id="session_auto_confirm_half_filled">
    <field name="act_from" ref="draft"/>
    <field name="act_to" ref="confirmed"/>
    <field name="condition">taken_seats > 50</field>
</record>

<record model="ir.actions.server" id="set_session_to_draft">
    <field name="name">Set session to Draft</field>
    <field name="model_id" ref="model_openacademy_session"/>
    <field name="code">
model.search([('id', 'in', context['active_ids'])]).action_draft()
    </field>
</record>

<record model="workflow.activity" id="draft">
    <field name="name">Draft</field>
    <field name="wkf_id" ref="wkf_session"/>
    <field name="flow_start" eval="True"/>
    <field name="kind">dummy</field>
    <field name="action"></field>
    <field name="action_id" ref="set_session_to_draft"/>
</record>

<record model="ir.actions.server" id="set_session_to_confirmed">
    <field name="name">Set session to Confirmed</field>
    <field name="model_id" ref="model_openacademy_session"/>
    <field name="code">
model.search([('id', 'in', context['active_ids'])]).action_confirm()
    </field>
</record>
<record model="workflow.activity" id="confirmed">
    <field name="name">Confirmed</field>
    <field name="wkf_id" ref="wkf_session"/>
    <field name="kind">dummy</field>
    <field name="action"></field>
    <field name="action_id" ref="set_session_to_confirmed"/>
</record>
<record model="ir.actions.server" id="set_session_to_done">
    <field name="name">Set session to Done</field>
    <field name="model_id" ref="model_openacademy_session"/>
    <field name="code">
model.search([('id', 'in', context['active_ids'])]).action_done()
    </field>
</record>
<record model="workflow.activity" id="done">
    <field name="name">Done</field>
    <field name="wkf_id" ref="wkf_session"/>
    <field name="kind">dummy</field>
    <field name="action"></field>
    <field name="action_id" ref="set_session_to_done"/>
</record>

安全機制

1.基于組的權(quán)限控制機制

組是以單條記錄的形式記錄在res.group模型中的,通過菜單定義來控制訪問權(quán)限贩据。但在不通過菜單訪問情況下仍然是可以訪問到對象的栋操,所以需要為組定義對象級別的權(quán)限(read,write,create,unlink),一般是通過csv文件來定義,也可通過group屬性來限制對象或視圖中的字段權(quán)限

2.訪問權(quán)限

訪問權(quán)限通過ir.model.access的csv文件來定義乐设,每一條記錄定義了 模型讼庇、組、和讀取近尚、寫入蠕啄、創(chuàng)建、取消關(guān)聯(lián)權(quán)限

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_idea_idea,idea.idea,model_idea_idea,base.group_user,1,1,1,0
access_idea_vote,idea.vote,model_idea_vote,base.group_user,1,1,1,0

例:
通過用戶界面來添加權(quán)限控制

通過設(shè)置-用戶-用戶 添加一個新用戶
通過設(shè)置-用戶-組 建立一個新組
編輯創(chuàng)建的新用戶將他加入到新建的組中
用新增的用戶帳號登錄,看權(quán)限是否正確

通過文件來設(shè)置權(quán)限

#__manifest__.py
'data': [
        'security/security.xml',
    
#security/ir.model.access.csv
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
course_manager,course manager,model_openacademy_courses,group_manager,1,1,1,1
session_manager,session manager,model_openacademy_session,group_manager,1,1,1,1
course_read_all,course all,model_openacademy_courses,,1,0,0,0
session_read_all,session all,model_openacademy_session,,1,0,0,0

#security/security.xml
<odoo>
    <data>
        <record id="group_manager" model="res.groups">
            <field name="name">OpenAcademy / Manager</field>
        </record>
    </data>
</odoo>

3.基于記錄的權(quán)限控制

基于記錄的權(quán)限可以控制指定模型的所有數(shù)據(jù)集歼跟,使用模型的ir.rule屬性來聲明和媳,可以控制其關(guān)聯(lián)模型、many2many字段哈街、domain表達式所過濾出的字段

例:狀態(tài)為cancel的負責(zé)人才可以刪除留瞳,group的值必須與ORM的write()方法規(guī)定的一致

<record id="delete_cancelled_only" model="ir.rule">
    <field name="name">Only cancelled leads may be deleted</field>
    <field name="model_id" ref="crm.model_crm_lead"/>
    <field name="groups" eval="[(4, ref('sales_team.group_sale_manager'))]"/>
    <field name="perm_read" eval="0"/>
    <field name="perm_write" eval="0"/>
    <field name="perm_create" eval="0"/>
    <field name="perm_unlink" eval="1" />
    <field name="domain_force">[('state','=','cancel')]</field>
</record>

例:為課程模型添加記錄行權(quán)限,限制write和unlink權(quán)限骚秦,當(dāng)課程沒有負責(zé)人時所有組內(nèi)成員就都可以修改她倘,有負責(zé)人時只有負責(zé)人有權(quán)修改

#security.xml
<record id="only_responsible_can_modify" model="ir.rule">
    <field name="name">Only Responsible can modify Course</field>
    <field name="model_id" ref="model_openacademy_courses"/>
    <field name="groups" eval="[(4, ref('openacademy.group_manager'))]"/>
    <field name="perm_read" eval="0"/>
    <field name="perm_write" eval="1"/>
    <field name="perm_create" eval="0"/>
    <field name="perm_unlink" eval="1"/>
    <field name="domain_force">
        ['|', ('responsible_id','=',False),
              ('responsible_id','=',user.id)]
    </field>
</record>

向?qū)?/h2>

向?qū)б詣討B(tài)的形式描述與用戶或?qū)υ捒虻慕换ィ粋€向?qū)鋵嵕褪且粋€繼承自TransientModel的模型作箍,TransientModel又繼承自model硬梁,在繼承原有屬性的基礎(chǔ)上新增了新特性

  • 記錄是臨時的,會在一定時間內(nèi)自動從數(shù)據(jù)庫刪除
  • 向?qū)P筒恍枰L問權(quán)限胞得,所有用戶均可訪問
  • 向?qū)в涗浛梢酝ㄟ^many2one關(guān)聯(lián)普通記錄或其他向?qū)в涗浻梗胀ㄓ涗洘o法通過many2one關(guān)系向?qū)в涗?/li>

實例:創(chuàng)建一個與session模型有多對一關(guān)系、與partner模型有多對多關(guān)系的向?qū)?/p>

#__init__.py
from . import wizard

#wizard.py
# -*- coding: utf-8 -*-

from odoo import models, fields, api

class Wizard(models.TransientModel):
    _name = 'openacademy.wizard'

    session_id = fields.Many2one('openacademy.session',
        string="Session", required=True)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

啟動向?qū)?/h3>

向?qū)Э梢酝ㄟ^ir.actions.act_window記錄來啟動阶剑,將target字段值設(shè)置為new即可跃巡。target屬性會給出一個向?qū)У膹棾隹颉_€可以通過一個額外的src_model字段來指定某個模型的向?qū)Р僮骺捎媚脸睿趚ml中用act_window標(biāo)簽定義素邪。

<act_window id="launch_the_wizard"
            name="Launch the Wizard"
            src_model="context.model.name"
            res_model="wizard.model.name"
            view_mode="form"
            target="new"
            key2="client_action_multi"/>

向?qū)褂玫氖浅R?guī)視圖,我們可以給它的按鈕添加special="cancel"屬性來實現(xiàn)不保存任何數(shù)據(jù)的情況下關(guān)閉向?qū)?/p>

例1:為向?qū)Фx一個表單递宅,在session模型中添加一個按鈕來啟動向?qū)锵悖褂胹elf._context拿到當(dāng)前session,給向?qū)У膕ession字段添加一個默認值
下面的例子可以為session創(chuàng)建一個添加出席者的向?qū)?/p>

#wizard.py
def _default_session(self):
        return self.env['openacademy.session'].browse(self._context.get('active_id'))
session_id = fields.Many2one('openacademy.session',
        string="Session", required=True, default=_default_session)
        
#views.xml
<record model="ir.ui.view" id="wizard_form_view">
    <field name="name">wizard.form</field>
    <field name="model">openacademy.wizard</field>
    <field name="arch" type="xml">
        <form string="Add Attendees">
            <group>
                <field name="session_id"/>
                <field name="attendee_ids"/>
            </group>
        </form>
    </field>
</record>

<act_window id="launch_session_wizard"
            name="Add Attendees"
            src_model="openacademy.session"
            res_model="openacademy.wizard"
            view_mode="form"
            target="new"
            key2="client_action_multi"/>
        

例2:注冊出席人
給向?qū)砑右粋€按鈕办龄,并將出席人添加到指定session中

#views.xml
</group>
<footer>
      <button name="subscribe" type="object"
              string="Subscribe" class="oe_highlight"/>
      or
      <button special="cancel" string="Cancel"/>
  </footer>
</form>

#wizard.py
 @api.multi
    def subscribe(self):
        self.session_id.attendee_ids |= self.attendee_ids
        return {}

例3:將出席人注冊到多個session

#views.xml
<form string="Add Attendees">
    <group>
        <field name="session_ids"/>
        <field name="attendee_ids"/>
    </group>
   
#wizard.py
def _default_sessions(self):
        return self.env['openacademy.session'].browse(self._context.get('active_ids'))

    session_ids = fields.Many2many('openacademy.session',
        string="Sessions", required=True, default=_default_sessions)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

    @api.multi
    def subscribe(self):
        for session in self.session_ids:
            session.attendee_ids |= self.attendee_ids
        return {}

內(nèi)容發(fā)布自http://www.dingyii.cn烘绽,轉(zhuǎn)載請注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俐填,隨后出現(xiàn)的幾起案子安接,更是在濱河造成了極大的恐慌,老刑警劉巖英融,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盏檐,死亡現(xiàn)場離奇詭異,居然都是意外死亡驶悟,警方通過查閱死者的電腦和手機胡野,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痕鳍,“玉大人硫豆,你說我怎么就攤上這事龙巨。” “怎么了熊响?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵旨别,是天一觀的道長。 經(jīng)常有香客問我汗茄,道長秸弛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任洪碳,我火速辦了婚禮递览,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞳腌。我一直安慰自己非迹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布纯趋。 她就那樣靜靜地躺著,像睡著了一般冷离。 火紅的嫁衣襯著肌膚如雪吵冒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天西剥,我揣著相機與錄音痹栖,去河邊找鬼。 笑死瞭空,一個胖子當(dāng)著我的面吹牛揪阿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咆畏,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼南捂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旧找?” 一聲冷哼從身側(cè)響起溺健,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钮蛛,沒想到半個月后鞭缭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡魏颓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年岭辣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甸饱。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡沦童,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搞动,我是刑警寧澤躏精,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站鹦肿,受9級特大地震影響矗烛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箩溃,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一瞭吃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涣旨,春花似錦歪架、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至烹棉,卻和暖如春攒霹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浆洗。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工催束, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伏社。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓抠刺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摘昌。 傳聞我的和親對象是個殘疾皇子速妖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

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

  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,708評論 0 15
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)聪黎,斷路器买优,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司挺举,掛了不少杀赢,但最終還是拿到小米、百度湘纵、阿里脂崔、京東、新浪梧喷、CVTE砌左、樂視家的研發(fā)崗...
    時芥藍閱讀 42,218評論 11 349
  • 圖文/耳風(fēng) 你的腳步與我的心跳同步在時間星海閃爍后墜落進大地暮色沉寂借此把樓的影子摁入想你的汇歹,不眠夜和愛你的屁擅,每秒鐘
    耳風(fēng)丶閱讀 405評論 14 48
  • 在寬恕中我們得到赦免痰哨,在死亡之時即可進入永生胶果。 如果我是受害者,我會不會選擇原諒那個傷害我的人呢斤斧?尤其是當(dāng)他奪...
    乂禾央閱讀 325評論 0 0