美文网首页OdooOdoo程序员
Odoo10开发教程七(工作流和安全)

Odoo10开发教程七(工作流和安全)

作者: luohuayong | 来源:发表于2017-03-30 10:51 被阅读1256次

    工作流

    工作流是与动态业务对象相关联的模型。工作流也用于跟踪动态演进的进程。

    练习伪工作流
    在授课模型上添加一个字段state,用于定义一个工作流程。授课存在三个可能的状态:Draft(草稿,默认值)、Confirmed(已确认)、Done(已完成)。在授课的form视图中,添加一个只读字段用于显示课程状态,并可以通过按钮来改变状态。有效的状态值迁移包括:

    • Draft->Confirmed
    • Confirmed->Draft
    • Confirmed->Done
    • Done->Draft
    1. 添加一个新的字段state
    2. 添加状态迁移方法,这个方法可以被form表单的按钮所调用,用以更改授课的状态
    3. 将相关按钮添加到授课的form视图
      openacademy/models.py
        attendees_count = fields.Integer(
            string="Attendees count", compute='_get_attendees_count', store=True)
    
        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'
    
        @api.depends('seats', 'attendee_ids')
        def _taken_seats(self):
            for r in self:
    

    openacademy/views/openacademy.xml

                <field name="model">openacademy.session</field>
                <field name="arch" type="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中的任何对象关联,并且可完全定制化。工作流用于构造和管理业务对象和文档的生命周期,并且通过图形化工具定义转换器、触发器等。工作流、动作(节点或操作)和迁移(条件)通常以XML记录行的形式定义。在工作流进行导航的标签称为工作项。

    警告
    与模型相关的工作流仅在创建模型记录时被创建。因此,在工作流定义之前创建的授课实例是没有与之对应的工作流实例的。

    练习工作流
    使用真正的授课工作流替换之前的伪工作流。修改授课的form视图,按钮将调用工作流而不是调用模型的方法。

    openacademy/__manifest__.py

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

    openacademy/models.py

            ('draft', "Draft"),
            ('confirmed', "Confirmed"),
            ('done', "Done"),
        ])
    
        @api.multi
        def action_draft(self):
    

    openacademy/views/openacademy.xml

                <field name="arch" type="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"/>
    

    openacademy/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>
    

    提示
    要检查授课实例对应的工作流实例是否被正确创建,可以:设置->技术->工作流->实例

    练习自动状态迁移
    当超过一半座席被保留时,自动将授课的状态从Draft迁移到Confirmed

    openacademy/views/session_workflow.xml

                <field name="act_to" ref="done"/>
                <field name="signal">done</field>
            </record>
    
            <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>
        </data>
    </odoo>
    

    练习服务器动作
    用服务器动作替换用于同步授课状态的Python方法。工作流和服务器动作都可以从UI创建。

    openacademy/views/session_workflow.xml

                <field name="on_create">True</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>
    
            <record model="workflow.transition" id="session_draft_to_confirmed">
    
    安全

    安全是为了实现统一的安全策略而进行配置的访问控制机制。
    基于组的访问控制机制
    组是通过在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_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
    

    练习
    通过Odoo界面添加访问控制权限
    建立一个新用户John Smith,然后建立OpenAcademy/Session Read组,并赋予这个组对授课模型的读权限。

    1. 建立一个新用户John Smit通过 设置->用户->用户
    2. 建立一个新组session_read通过 设置->用户->组,这个组拥有对授课模型的读权限
    3. 编辑John Smith用户,把他加入到session_read
    4. John Smith身份登录系统,检查权限是否正确。

    练习
    通过数据文件添加访问控制权限:

    • 建立一个组OpenAcademy / Manager,这个组对开放学院的所有模型都有完全权限。
    • SessionCourse对所有用户可读
    1. 建立新的文件openacademy/security/security.xml用来定义OpenAcademy Manager
    2. 编辑文件openacademy/security/ir.model.access.csv来添加对模型的访问权限
    3. 最后更新openacademy/__manifest__.py来添加新的数据文件

    openacademy/__manifest__.py

        # always loaded
        'data': [
            'security/security.xml',
            'security/ir.model.access.csv',
            'templates.xml',
            'views/openacademy.xml',
            'views/partner.xml',
    

    openacademy/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_course,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_course,,1,0,0,0
    session_read_all,session all,model_openacademy_session,,1,0,0,0
    

    openacademy/security/security.xml

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

    记录规则
    记录规则限制对给定模型的记录子集的访问权限。一个规则就是ir.rule模型的一行记录,并且将其关联到模型、数组(many2many字段)、或domain。domain指定了对那些记录有访问权限。
    这是一个记录规则的例子,这个规则防止非cancel状态的负责人被删除。请注意,groups字段的值必须遵守与ORM的write()方法一样的规则。

    <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>
    

    练习记录规则
    授课模型和OpenAcademy / Manager组添加记录规则,这个记录规则限制只有课程负责人可以对课程进行writeunlink操作,如果课程还没有负责人,这个组的所有用户都可以编辑它。在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">
                <field name="name">Only Responsible can modify Course</field>
                <field name="model_id" ref="model_openacademy_course"/>
                <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>
        </data>
    </odoo>
    

    相关文章

      网友评论

      • 路边的吃瓜群众:按照上面流程做的,但是还是报错
        不知道哪里有问题
        raise Exception(_('Module loading %s failed: file %s could not be processed:\n %s') % (module, fname, warning_msg))
        Exception: 模块加载 openacademy 失败: 文件 openacademy/security/ir.model.access.csv 无法处理:
        在字段'Group'中没找到匹配的记录外部id 'group_manager'
        在字段'Group'中没找到匹配的记录外部id 'group_manager'
        在字段'Object'中没找到匹配的记录外部id 'model_scheduler_demo'
        在字段'Group'中没找到匹配的记录外部id 'group_manager'
        找不到字段 'Object' (model_id)所需的值
      • 307258c2857e:非常不错,希望能和你多学习

      本文标题:Odoo10开发教程七(工作流和安全)

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