ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
现在用户已经可以在系统添加请假单了。但是还没有审批流程。先来设置一个简单的审批流程,员工填写请假单(草稿状态)->提交请假单给领导(待审批状态)->领导审批(完成状态)。 编辑类文件 `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">function</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用户登录系统,创建一个请假单,并保存。 ![](http://upload-images.jianshu.io/upload_images/3551405-f45608469720a3da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 带工作流的请假单 我们看到在头部出现的`提交`按钮,状态条,并显示默认的`草稿`状态。 提交后,出现了`审批`按钮,显示`待审批`状态。 批准后,无按钮,显示`已完成`状态。 工作流都按预期执行了,但是这里有点问题,就是自己有权限审批自己的请假单,这是因为权限配置的问题,我们把`审批`按钮的权限给到了`base.group_user`组,而我们知道这是一个默认全部账号都有的基本组。下次我们来解决这个问题。