Odoo10開發教程7—工作流和安全
工作流
工作流是與動態業務對象相關聯的模型。工作流也用於跟蹤動態演進的進程。
練習偽工作流
在授課模型上添加一個欄位state,用於定義一個工作流程。授課存在三個可能的狀態:Draft(草稿,默認值)、Confirmed(已確認)、Done(已完成)。在授課的form視圖中,添加一個只讀欄位用於顯示課程狀態,並可以通過按鈕來改變狀態。有效的狀態值遷移包括:
- Draft->Confirmed
- Confirmed->Draft
- Confirmed->Done
- Done->Draft
- 添加一個新的欄位state
- 添加狀態遷移方法,這個方法可以被form表單的按鈕所調用,用以更改授課的狀態
- 將相關按鈕添加到授課的form視圖
openacademy/models.py
attendees_count = fields.Integer(n string="Attendees count", compute=_get_attendees_count, store=True)nn state = fields.Selection([n (draft, "Draft"),n (confirmed, "Confirmed"),n (done, "Done"),n ], default=draft)nn @api.multin def action_draft(self):n self.state = draftnn @api.multin def action_confirm(self):n self.state = confirmednn @api.multin def action_done(self):n self.state = donenn @api.depends(seats, attendee_ids)n def _taken_seats(self):n for r in self:n
openacademy/views/openacademy.xml
<field name="model">openacademy.session</field>n <field name="arch" type="xml">n <form string="Session Form">n <header>n <button name="action_draft" type="object"n string="Reset to draft"n states="confirmed,done"/>n <button name="action_confirm" type="object"n string="Confirm" states="draft"n class="oe_highlight"/>n <button name="action_done" type="object"n string="Mark as done" states="confirmed"n class="oe_highlight"/>n <field name="state" widget="statusbar"/>n </header>nn <sheet>n <group>n <group string="General">n
工作流可以與Odoo中的任何對象關聯,並且可完全定製化。工作流用於構造和管理業務對象和文檔的生命周期,並且通過圖形化工具定義轉換器、觸發器等。工作流、動作(節點或操作)和遷移(條件)通常以XML記錄行的形式定義。在工作流進行導航的標籤稱為工作項。
警告
與模型相關的工作流僅在創建模型記錄時被創建。因此,在工作流定義之前創建的授課實例是沒有與之對應的工作流實例的。練習工作流
使用真正的授課工作流替換之前的偽工作流。修改授課的form視圖,按鈕將調用工作流而不是調用模型的方法。
openacademy/__manifest__.py
templates.xml,n views/openacademy.xml,n views/partner.xml,n views/session_workflow.xml,n ],n # only loaded in demonstration moden demo: [n
openacademy/models.py
(draft, "Draft"),n (confirmed, "Confirmed"),n (done, "Done"),n ])nn @api.multin def action_draft(self):n
openacademy/views/openacademy.xml
<field name="arch" type="xml">n <form string="Session Form">n <header>n <button name="draft" type="workflow"n string="Reset to draft"n states="confirmed,done"/>n <button name="confirm" type="workflow"n string="Confirm" states="draft"n class="oe_highlight"/>n <button name="done" type="workflow"n string="Mark as done" states="confirmed"n class="oe_highlight"/>n <field name="state" widget="statusbar"/>n
openacademy/views/session_workflow.xml
<odoo>n <data>n <record model="workflow" id="wkf_session">n <field name="name">OpenAcademy sessions workflow</field>n <field name="osv">openacademy.session</field>n <field name="on_create">True</field>n </record>nn <record model="workflow.activity" id="draft">n <field name="name">Draft</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="flow_start" eval="True"/>n <field name="kind">function</field>n <field name="action">action_draft()</field>n </record>n <record model="workflow.activity" id="confirmed">n <field name="name">Confirmed</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="kind">function</field>n <field name="action">action_confirm()</field>n </record>n <record model="workflow.activity" id="done">n <field name="name">Done</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="kind">function</field>n <field name="action">action_done()</field>n </record>nn <record model="workflow.transition" id="session_draft_to_confirmed">n <field name="act_from" ref="draft"/>n <field name="act_to" ref="confirmed"/>n <field name="signal">confirm</field>n </record>n <record model="workflow.transition" id="session_confirmed_to_draft">n <field name="act_from" ref="confirmed"/>n <field name="act_to" ref="draft"/>n <field name="signal">draft</field>n </record>n <record model="workflow.transition" id="session_done_to_draft">n <field name="act_from" ref="done"/>n <field name="act_to" ref="draft"/>n <field name="signal">draft</field>n </record>n <record model="workflow.transition" id="session_confirmed_to_done">n <field name="act_from" ref="confirmed"/>n <field name="act_to" ref="done"/>n <field name="signal">done</field>n </record>n </data>n</odoo>n
提示
要檢查授課實例對應的工作流實例是否被正確創建,可以:設置->技術->工作流->實例練習自動狀態遷移當超過一半座席被保留時,自動將授課的狀態從Draft遷移到Confirmed。
openacademy/views/session_workflow.xml
<field name="act_to" ref="done"/>n <field name="signal">done</field>n </record>nn <record model="workflow.transition" id="session_auto_confirm_half_filled">n <field name="act_from" ref="draft"/>n <field name="act_to" ref="confirmed"/>n <field name="condition">taken_seats > 50</field>n </record>n </data>n</odoo>n
練習伺服器動作
用伺服器動作替換用於同步授課狀態的Python方法。工作流和伺服器動作都可以從UI創建。
openacademy/views/session_workflow.xml
<field name="on_create">True</field>n </record>nn <record model="ir.actions.server" id="set_session_to_draft">n <field name="name">Set session to Draft</field>n <field name="model_id" ref="model_openacademy_session"/>n <field name="code">nmodel.search([(id, in, context[active_ids])]).action_draft()n </field>n </record>n <record model="workflow.activity" id="draft">n <field name="name">Draft</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="flow_start" eval="True"/>n <field name="kind">dummy</field>n <field name="action"></field>n <field name="action_id" ref="set_session_to_draft"/>n </record>nn <record model="ir.actions.server" id="set_session_to_confirmed">n <field name="name">Set session to Confirmed</field>n <field name="model_id" ref="model_openacademy_session"/>n <field name="code">nmodel.search([(id, in, context[active_ids])]).action_confirm()n </field>n </record>n <record model="workflow.activity" id="confirmed">n <field name="name">Confirmed</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="kind">dummy</field>n <field name="action"></field>n <field name="action_id" ref="set_session_to_confirmed"/>n </record>nn <record model="ir.actions.server" id="set_session_to_done">n <field name="name">Set session to Done</field>n <field name="model_id" ref="model_openacademy_session"/>n <field name="code">nmodel.search([(id, in, context[active_ids])]).action_done()n </field>n </record>n <record model="workflow.activity" id="done">n <field name="name">Done</field>n <field name="wkf_id" ref="wkf_session"/>n <field name="kind">dummy</field>n <field name="action"></field>n <field name="action_id" ref="set_session_to_done"/>n </record>nn <record model="workflow.transition" id="session_draft_to_confirmed">n
安全
安全是為了實現統一的安全策略而進行配置的訪問控制機制。
基於組的訪問控制機制
組是通過在res.groups模型的記錄行來創建的,並通過菜單訪問許可權來限制許可權。但是,即使沒有菜單,對象仍然可以間接被訪問,因此必須為組定義實際的對象級許可權(讀取、寫入、創建、取消關聯)。一般通過模塊中的CSV文件插入。也可以通過欄位的groups屬性來限制對視圖或對象上特定欄位的訪問。
訪問許可權
訪問許可權通過ir.model.access的記錄行來定義。每個訪問許可權與模型、組(或者非全局訪問的組)相關聯,並且是一組許可權:讀取、寫入、創建、取消關聯。這些訪問許可權一般通過ir.model.access.csv這個CSV文件創建。
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlinknaccess_idea_idea,idea.idea,model_idea_idea,base.group_user,1,1,1,0naccess_idea_vote,idea.vote,model_idea_vote,base.group_user,1,1,1,0n
練習
通過Odoo界面添加訪問控制許可權建立一個新用戶John Smith,然後建立OpenAcademy/Session Read組,並賦予這個組對授課模型的讀許可權。
- 建立一個新用戶John Smit通過 設置->用戶->用戶
- 建立一個新組session_read通過 設置->用戶->組,這個組擁有對授課模型的讀許可權
- 編輯John Smith用戶,把他加入到session_read組
- 以John Smith身份登錄系統,檢查許可權是否正確。
練習
通過數據文件添加訪問控制許可權:
- 建立一個組OpenAcademy / Manager,這個組對開放學院的所有模型都有完全許可權。
- 讓Session和Course對所有用戶可讀
- 建立新的文件openacademy/security/security.xml用來定義OpenAcademy Manager組
- 編輯文件openacademy/security/ir.model.access.csv來添加對模型的訪問許可權
- 最後更新openacademy/__manifest__.py來添加新的數據文件
openacademy/__manifest__.py
# always loadedn data: [n security/security.xml,n security/ir.model.access.csv,n templates.xml,n views/openacademy.xml,n views/partner.xml,n
openacademy/security/ir.model.access.csv
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlinkncourse_manager,course manager,model_openacademy_course,group_manager,1,1,1,1nsession_manager,session manager,model_openacademy_session,group_manager,1,1,1,1ncourse_read_all,course all,model_openacademy_course,,1,0,0,0nsession_read_all,session all,model_openacademy_session,,1,0,0,0n
openacademy/security/security.xml
<odoo>n <data>n <record id="group_manager" model="res.groups">n <field name="name">OpenAcademy / Manager</field>n </record>n </data>n</odoo>n
記錄規則
記錄規則限制對給定模型的記錄子集的訪問許可權。一個規則就是ir.rule模型的一行記錄,並且將其關聯到模型、數組(many2many欄位)、或domain。domain指定了對那些記錄有訪問許可權。
這是一個記錄規則的例子,這個規則防止非cancel狀態的負責人被刪除。請注意,groups欄位的值必須遵守與ORM的write()方法一樣的規則。
<record id="delete_cancelled_only" model="ir.rule">n <field name="name">Only cancelled leads may be deleted</field>n <field name="model_id" ref="crm.model_crm_lead"/>n <field name="groups" eval="[(4, ref(sales_team.group_sale_manager))]"/>n <field name="perm_read" eval="0"/>n <field name="perm_write" eval="0"/>n <field name="perm_create" eval="0"/>n <field name="perm_unlink" eval="1" />n <field name="domain_force">[(state,=,cancel)]</field>n</record>n
練習記錄規則
為授課模型和OpenAcademy / Manager組添加記錄規則,這個記錄規則限制只有課程負責人可以對課程進行write和unlink操作,如果課程還沒有負責人,這個組的所有用戶都可以編輯它。在openacademy/security/security.xml文件中創建新的規則:openacademy/security/security.xml``` <record id="group_manager" model="res.groups"> <field name="name">OpenAcademy / Manager</field> </record>
<record id="only_responsible_can_modify" model="ir.rule">n <field name="name">Only Responsible can modify Course</field>n <field name="model_id" ref="model_openacademy_course"/>n <field name="groups" eval="[(4, ref(openacademy.group_manager))]"/>n <field name="perm_read" eval="0"/>n <field name="perm_write" eval="1"/>n <field name="perm_create" eval="0"/>n <field name="perm_unlink" eval="1"/>n <field name="domain_force">n [|, (responsible_id,=,False),n (responsible_id,=,user.id)]n </field>n </record>n</data>n
</odoo>
```
推薦閱讀:
※ERP實施顧問轉型較容易的方向大概有哪幾個?
※ERP是什麼?
※易訂貨,訂貨寶,懶螞蟻,都是基於saas~我很想知道下,除了服務行業不同,其他上面還有沒啥區別了?
※哪位同學能用最簡單的語言解釋一下什麼是ERP?
※IT諮詢顧問發展路線是怎麼樣?
TAG:Odoo原OpenERP | ERP | 软件开发 |