美文网首页odoo
odoo10 学习笔记4(工作流)

odoo10 学习笔记4(工作流)

作者: luohuayong | 来源:发表于2017-01-13 17:57 被阅读2460次

    现在用户已经可以在系统添加请假单了。但是还没有审批流程。先来设置一个简单的审批流程,员工填写请假单(草稿状态)->提交请假单给领导(待审批状态)->领导审批(完成状态)。
    编辑类文件 models/models.py

    # -*- coding: utf-8 -*-
    
    from odoo import models, fields, api
    
    
    class qingjiadan(models.Model):
        WORKFLOW_STATE_SELECTION = [
            ('draft', '草稿'),
            ('confirm', '待审批'),
            ('complete', '已完成')
        ]
    
        _name = 'qingjia.qingjiadan'
        name = fields.Char(string="申请人")
        days = fields.Integer(string="天数")
        startdate = fields.Date(string="开始日期")
        reason = fields.Text(string="请假事由")
        state = fields.Selection(WORKFLOW_STATE_SELECTION,
                                 default='draft',
                                 string='状态',
                                 readonly=True)
    
        @api.multi
        def do_confirm(self):
            self.state = 'confirm'
            return True
    
        @api.multi
        def do_complete(self):
            self.state = 'complete'
            return True
    

    添加了一个字段state,请假单状态,字段类型为fields.Selection,包含三个状态draft(草稿),confirm(待审批),complete(已完成),默认值为draft(草稿),readonly=True属性表示在form视图下是不能修改的。
    添加了两个方法do_confirm(),do_complete(),用于改变请假单状态。@api.multi修饰符还不明白用途。按钮事件方法必须有返回值,这里没有什么需要返回的值就返回return True
    然后编辑视图资源文件 views/views.xml中的form视图部分

        <!-- form视图 -->
        <record id="view_form_qingjia_qingjiadan" model="ir.ui.view">
          <field name="name">请假单</field>
          <field name="model">qingjia.qingjiadan</field>
          <field name="arch" type="xml">
            <form>
              <header>
                <button name="button_confirm" states="draft"
                        string="提交" type="workflow" class="oe_highlight"/>
                <button name="button_complete" states="confirm"
                        string="批准" type="workflow" class="oe_highlight"
                        groups="base.group_user"/>
                <!-- 右上角 进度显示。-->
                <field name="state" widget="statusbar"/>
              </header>
              <sheet>
                <group name="group_top" string="请假单">
                  <field name="name"/>
                  <field name="days"/>
                  <field name="startdate"/>
                  <field name="reason"/>
                </group>            
              </sheet>
            </form>
          </field>
        </record>
    

    添加了<header>...</header>节,名称可知这是表单布局的头部。其中添加了三个元素,两个按钮,一个状态条。
    按钮的属性:
    name:
    指定按钮点击后的事件名,对应工作流的activity,后面会看到
    states:
    表示按钮在什么状态下显示,对应state字段的值
    type:
    工作流的按钮固定值workflow
    class:
    按钮的class样式,oe_highlight样式为高亮显示
    groups:
    这里就是上一节提到的第三级权限,字段级权限

    状态条属性:
    name:
    状态条绑定字段名
    widget:
    类型,状态条固定值statusbar


    在tree视图中加入state字段显示

    <!-- tree视图 -->
    <record id="view_tree_qingjia_qingjiadan" model="ir.ui.view">
      <field name="name">请假单列表</field>
      <field name="model">qingjia.qingjiadan</field>
      <field name="arch" type="xml">
        <tree>
          <field name="name"/>
          <field name="days"/>
          <field name="startdate"/>
          <field name="state"/>
        </tree>
      </field>
    </record> 
    

    新建工作流资源文件views/workflow.xml
    添加工作流:

    <!-- 工作流 -->
    <record id="workflow_qingjia_qingjiadan" model="workflow">
        <field name="name">请假单工作流</field>
        <field name="osv">qingjia.qingjiadan</field>
        <field name="on_create">True</field>
    </record>
    

    这个文件中定义了一个工作流,id为workflow_qingjia_qingjiadan。三个工作流活动,id分别为activity_draft,activity_confirm,activity_complete,两个工作流流转,id分别为transition_draft2confirm,transition_confirm2complete。工作流属性:
    model:
    工作流模型,固定为workflow
    name:
    工作流名称,任意填写
    osv:
    工作流绑定的对象模型
    on_create:
    创建一个绑定的对象模型的对象时,是否自动生成一个工作流对象。说起来有点绕口,其实就是创建一个请假单时,自动创建一个请假单工作流对象。


    添加工作流活动:

    <!-- 工作流活动 -->
    <record id="activity_draft" model="workflow.activity">
        <field name="name">草稿</field>
        <field name="wkf_id">workflow_qingjia_qingjiadan</field>
        <field name="kind">dummy</field>
        <field name="flow_start">True</field>
    </record>
    <record id="activity_confirm" model="workflow.activity">
        <field name="name">待审核</field>
        <field name="wkf_id">workflow_qingjia_qingjiadan</field>
        <field name="kind">function</field>
        <field name="action">do_confirm()</field>
    </record>
    <record id="activity_complete" model="workflow.activity">
        <field name="name">已完成</field>
        <field name="wkf_id">workflow_qingjia_qingjiadan</field>
        <field name="kind">function</field>
        <field name="action">do_complete()</field>
    </record>
    

    model:
    工作流活动模型,固定为workflow.activity
    name:
    工作流活动名称,任意填写
    wkf_id:
    工作流活动所属的工作流id
    kind:
    工作流活动类型,有三个可选项,'dummy'不执行任何动作,'function'执行action中定义的python代码,并且执行action_id中定义的server action,'subflow'触发subflow_id中指定的工作流。
    flow_start:
    表示流程的开始节点


    添加工作流流转:

    <!-- 工作流流转 -->
    <record id="transition_draft2confirm" model="workflow.transition">
        <field name="act_from">activity_draft</field>
        <field name="act_to">activity_confirm</field>
        <field name="signal">button_confirm</field>
    </record>
    <record id="transition_confirm2complete" model="workflow.transition">
        <field name="act_from">activity_confirm</field>
        <field name="act_to">activity_complete</field>
        <field name="signal">button_complete</field>
    </record>
    

    model:
    工作流流转模型,固定为workflow.transition
    act_from:
    流转起始的工作流活动id
    act_to:
    流转结束的工作流活动id
    signal:
    触发流转的信号,还记得前面在form视图中添加的工作流按钮

    <button name="button_confirm" states="draft"
        string="提交" type="workflow" class="oe_highlight"/>
    <button name="button_complete" states="confirm"
        string="批准" type="workflow" class="oe_highlight"
        groups="base.group_user"/>
    

    按钮name值就是发出的信号,触发对应的流转。


    最后工作流资源文件views/workflow.xml是这样的:

    <?xml version="1.0" encoding="UTF-8"?>
    <openerp>
      <data>
          <!-- 工作流 -->
          <record id="workflow_qingjia_qingjiadan" model="workflow">
              <field name="name">请假单工作流</field>
              <field name="osv">qingjia.qingjiadan</field>
              <field name="on_create">True</field>
          </record>
    
          <!-- 工作流活动 -->
          <record id="activity_draft" model="workflow.activity">
              <field name="name">草稿</field>
              <field name="wkf_id" ref="workflow_qingjia_qingjiadan"/>
              <field name="kind">dummy</field>
              <field name="flow_start">True</field>
          </record>
          <record id="activity_confirm" model="workflow.activity">
              <field name="name">待审核</field>
              <field name="wkf_id" ref="workflow_qingjia_qingjiadan"/>
              <field name="kind">function</field>
              <field name="action">do_confirm()</field>
          </record>
          <record id="activity_complete" model="workflow.activity">
              <field name="name">已完成</field>
              <field name="wkf_id" ref="workflow_qingjia_qingjiadan"/>
              <field name="kind">function</field>
              <field name="action">do_complete()</field>
          </record>
    
          <!-- 工作流流转 -->
          <record id="transition_draft2confirm" model="workflow.transition">
              <field name="act_from">activity_draft</field>
              <field name="act_to">activity_confirm</field>
              <field name="signal">button_confirm</field>
          </record>
          <record id="transition_confirm2complete" model="workflow.transition">
              <field name="act_from">activity_confirm</field>
              <field name="act_to">activity_complete</field>
              <field name="signal">button_complete</field>
          </record>
    
      </data>
    </openerp>
    

    编辑配置文件__manifest__.py,添加对工作流资源文件views/workflow.xml载入:

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

    好了,代码编辑完了,可以测试下效果。因为修改了python代码文件,所以需要重启服务,然后升级请假模块。也可以把之前的模块卸载后再次安装,不过卸载模块会将之前的数据也清空,这里因为在表中新建了字段,所以我是直接卸载后重新安装的。
    用user1用户登录系统,创建一个请假单,并保存。

    带工作流的请假单
    我们看到在头部出现的提交按钮,状态条,并显示默认的草稿状态。
    提交后,出现了审批按钮,显示待审批状态。
    批准后,无按钮,显示已完成状态。
    工作流都按预期执行了,但是这里有点问题,就是自己有权限审批自己的请假单,这是因为权限配置的问题,我们把审批按钮的权限给到了base.group_user组,而我们知道这是一个默认全部账号都有的基本组。下次我们来解决这个问题。

    相关文章

      网友评论

      • 2148339a41dd:博主,想请教一下,只有上级才能有审批权限,自己不能有要怎么实现呢
      • DreamsZero:楼主,那个只有管理员可以批准是怎么实现的啊
      • squirrel_0601:新入职。刚开始接触odoo。跟着你的文章学习。很有帮助。
        期待你的更新。
        感谢。
      • zhangzw:我也遇到了2楼同样的问题,ParseError: "invalid input syntax for integer: "activity_draft",对比博文中运行错误的代码和github上运行正确的代码,出错原因有以下:
        1.博文<!-- 工作流流转 -->的代码写错了,github上运行正确的代码是:
        <record id="transition_draft2confirm" model="workflow.transition">
        <field name="act_from" ref="activity_draft"/>
        <field name="act_to" ref="activity_confirm"/>
        <field name="signal">button_confirm</field>
        </record>
        <record id="transition_confirm2complete" model="workflow.transition">
        <field name="act_from" ref="activity_confirm"/>
        <field name="act_to" ref="activity_complete"/>
        <field name="signal">button_complete</field>
        <field name="group_id" ref="group_qingjia_manager"/>
        </record>

        2.博文中<!-- 工作流活动 -->有一段错误代码:
        <record id="activity_draft" model="workflow.activity">
        <field name="name">草稿</field>
        <field name="wkf_id" ref="workflow_qingjia_qingjiadan"/>
        <field name="kind">function</field>
        <field name="flow_start">True</field>
        </record>
        github上运行正确的代码是:
        <record id="activity_draft" model="workflow.activity">
        <field name="name">草稿</field>
        <field name="wkf_id" ref="workflow_qingjia_qingjiadan"/>
        <field name="kind">dummy</field>
        <field name="flow_start">True</field>
        </record>
        —————这里的差异是 <field name="kind">dummy</field>原本是写对了的,但博文后来说“最后工作流资源文件views/workflow.xml是这样的:”时将代码写错了,写成<field name="kind">function</field>。

        根据1,2的提示对比看看你的代码是不是有这样的问题?用了github上的代码就可以正确运行了。
        luohuayong:谢谢 zhangzw 的指正,我已经更新了文章。
        zhangzw:博主在2楼回复过本次项目的github地址,我再贴一次:
        https://github.com/luohuayong/myaddons/tree/master/qingjia
      • bc56f9ac39f7:老大我又来了,我测试运行的时候,views/workflow.xml提示这个错误:ParseError: "\u9519\u8bef: \u65e0\u6548\u7684\u6574\u6570\u7c7b\u578b\u8f93\u5165\u8bed\u6cd5: "workflow_qingjia_qingjiadan"
        LINE 1: ...wkf_activity_id_seq'), 'function', '\u8349\u7a3f', 'XOR', 'workflow_...
        ^
        " while parsing file:///C:/Users/kong/Documents/odoo/odoo10/jfhaddons/jfhsale/views/workflow.xml:12, near
        <record id="activity_draft" model="workflow.activity">
        <field name="name">草稿</field>
        <field name="wkf_id">workflow_qingjia_qingjiadan</field>
        <field name="kind">function</field>
        <field name="flow_start">True</field>
        </record>
        object_li:请问有审批流的文章吗
        luohuayong:我把代码上传到github,地址:https://github.com/luohuayong/myaddons/tree/master/qingjia
        希望能帮到你。
        bc56f9ac39f7:ParseError: "\u9519\u8bef: \u65e0\u6548\u7684\u6574\u6570\u7c7b\u578b\u8f93\u5165\u8bed\u6cd5,
        错误:无效的整数类型输入语法

      本文标题:odoo10 学习笔记4(工作流)

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