【Odoo 模块开发】(一)Wokflow 教程

工作流概念:“ 工作流,指的是一系列相互衔接、自动进行的业务活动或任务。” -百度百科
我的个人理解,工作流就是执行一个任务的一系列过程(步骤),每个步骤可能需要设计不同“模块”,而且步骤之间又有着各种各样的联系。以企业的采购为例:采购过程包括 采购申请采购批准采购订单审核采购订单→…… ;其中采购申请可能是A部门申请,批准可能是B部门批准……这就是一个简单的工作流。

  • 本文将使用Odoo框架,开发一个简单的workflow模块,代码解释将嵌套在源码中

文件结构

文件结构

Model创建(models.py)

  • 注意在init.py 文件中导入你的“ models.py ”模块
  • Odoo 框架中的代码跟平时开发时代码规范有些许出入
  • 关于@api.one 链接
# -*- coding: utf-8 -*-

from openerp import models, fields, api


class workflow_demo(models.Model):
    """
    Author  : SXY
    Date    : 2016/3/24 9:28
    Version : 1.0
    """
    _name = 'workflow_demo.workflow_demo'

    WORKFLOW_STATE_SELECTION = [
        ('init', '初始'),
        ('start', '开始'),
        ('confirm', '确认'),
        ('complete', '完成'),
    ]

    name = fields.Char(string="姓名")
    state = fields.Selection(WORKFLOW_STATE_SELECTION, default='init', string="状态", readonly=True)

    # 注意使用新版本定义方法是,需要添加装饰器@api.one/@api.multi
    # 将state 置于开始状态
    @api.one
    def do_start(self):
        print "------------self.state = 'start'"
        self.state = 'start'
        return True

    # 将state 置于确认状态
    @api.one
    def do_confirm(self):
        print "------------self.state = 'confirm'"
        self.state = 'confirm'
        return True

    # 将state 置于完成状态
    @api.one
    def do_complete(self):
        print "------------self.state = 'complete'"
        self.state = 'complete'
        return True

View 创建 (workflow_view.xml)

  • 注意,关于field,官网(链接)(参见lists中的field)有如下要求:要求同一个name只能使用一次。如 <field name="state" /> 中这个“state”只能使用一次,如果多次使用,那么只显示最后使用这个"state"的标签
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
    <data>
        <!-- form 视图-->
        <record id="workflow_demo_form_view" model="ir.ui.view">
            <field name="name">Workflow</field>
            <field name="type">form</field>
            <field name="model">workflow_demo.workflow_demo</field>
            <field name="arch" type="xml">
                <form string="Workflow单">
                    <!-- workflow 声明-->
                    <!-- 添加header标签用来显示workflow中的按钮-->
                    <header>
                        <!-- 首先指明button的type为workflow类型 -->
                        <!-- name 对应于workflow.transition中的signal-->
                        <!-- states 属性用来控制button显示隐藏,例如states="init",当state属性为init时,这个button显示,否则不显示 -->
                        <button name="workflow_start" states="init" string="开始" type="workflow" class="oe_highlight"/>
                        <button name="workflow_confirm" states="start" string="确认" type="workflow" class="oe_highlight"/>
                        <button name="workflow_end" states="confirm" string="完成" type="workflow" class="oe_highlight"/>
                        <!-- 右上角 进度显示。注意在此处已经使用的state属性,所以在接下来的tree标签里面就不能再次声明<field name="state"/>了如果再次声明此处的进度显示便会失去作用 -->
                        <field name="state" widget="statusbar" statusbar_visible="start,confirm,complete"/>
                    </header>
                    <sheet>
                        <group col="4">
                            <field name="name"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>
        <!-- tree(list)视图 -->
        <record id="workflow_demo_tree_view" model="ir.ui.view">
            <field name="name">workflow_demo</field>
            <field name="type">tree</field>
            <field name="model">workflow_demo.workflow_demo</field>
            <field name="arch" type="xml">
                <tree string="Workflow">
                    <field name="name"/>
                </tree>
            </field>
        </record>

        <record id="workflow_demo_action" model="ir.actions.act_window">
            <field name="name">Workflow</field>
            <field name="type">ir.actions.act_window</field>
            <field name="res_model">workflow_demo.workflow_demo</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="help" type="html">
                <p class="oe_view_nocontent_create">创建Workflow单</p>
            </field>
        </record>

        <!-- 菜单 -->
        <menuitem id="workflow_demo_main_menu" name="Workflow演示"/>
        <menuitem id="workflow_demo_sub_menu" name="Workflow演示" parent="workflow_demo_main_menu"/>
        <menuitem id="workflow_demo_item_menu" name="Workflow" parent="workflow_demo_sub_menu"
                  action="workflow_demo_action" sequence="1"/>
    </data>
</openerp>

Workflow 创建(workflow_demo.xml)

  • workflow 介绍
  • Workflow transitions 中的group 属性可以进行操作权限控制
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
    <data>
        <!-- Workflow 工作流 -->
        <!-- https://www.odoo.com/documentation/8.0/reference/workflows.html -->
        <!-- 设置record的model为系统自带的 “workflow” -->
        <record model="workflow" id="workflow_demo">
            <field name="name">workflow_demo</field>
            <!-- 关联的model -->
            <field name="osv">workflow_demo.workflow_demo</field>
            <!-- 是否主动被实例化 -->
            <field name="on_create">True</field>
        </record>

        <!-- workflow.activity 用来指定要调用的model里的方法,一般用来更改state状态-->
        <record model="workflow.activity" id="activity_one">
            <!-- wkf_id 这个activity对应于哪个workflow,这里对应于上面声明的workflow-->
            <field name="wkf_id" ref="workflow_demo"/>
            <field name="name">workflow.demo.activity.one</field>
            <!-- dummy 类型用来指定这个activity 是workflow的开始还是结束-->
            <field name="kind">dummy</field>
            <!-- 开始是flow_start  结束是flow_end-->
            <field name="flow_start">True</field>
        </record>

        <record model="workflow.activity" id="activity_two">
            <field name="wkf_id" ref="workflow_demo"/>
            <field name="name">workflow.demo.activity.two</field>
            <!-- function 表示要执行model中的方法-->
            <field name="kind">function</field>
            <!-- 对应model中的方法-->
            <field name="action">do_start()</field>
        </record>

        <record model="workflow.activity" id="activity_three">
            <field name="wkf_id" ref="workflow_demo"/>
            <field name="name">workflow.demo.activity.three</field>
            <field name="kind">function</field>
            <field name="action">do_confirm()</field>
        </record>

        <record model="workflow.activity" id="activity_four">
            <field name="wkf_id" ref="workflow_demo"/>
            <field name="name">workflow.demo.activity.four</field>
            <field name="kind">function</field>
            <field name="action">do_complete()</field>
        </record>

        <record model="workflow.activity" id="activity_five">
            <field name="wkf_id" ref="workflow_demo"/>
            <field name="name">workflow.temp.activity.five</field>
            <field name="kind">dummy</field>
            <field name="flow_end">True</field>
        </record>

        <!-- 相当于一个转换器,用来接受button传来的信号,调用相关的activity-->
        <record model="workflow.transition" id="transition_one">
            <!-- 表示上一个执行的activity,与上面声明的activity对应-->
            <field name="act_from" ref="activity_one"/>
            <!-- 表示上一个将要执行的activity-->
            <field name="act_to" ref="activity_two"/>
            <!-- 用来做一个严重,当满足条件是才能执行,可省略-->
            <field name="condition">state == 'init'</field>
            <!-- 接收的信号 -->
            <field name="signal">workflow_start</field>
        </record>

        <record model="workflow.transition" id="transition_two">
            <field name="act_from" ref="activity_two"/>
            <field name="act_to" ref="activity_three"/>
            <field name="condition">state == 'start'</field>
            <field name="signal">workflow_confirm</field>
        </record>

        <record model="workflow.transition" id="transition_three">
            <field name="act_from" ref="activity_three"/>
            <field name="act_to" ref="activity_four"/>
            <field name="condition">state == 'confirm'</field>
            <field name="signal">workflow_end</field>
        </record>

    </data>
</openerp>

xml声明(openerp.py)

部分代码:

'data': [
        # 声明workflow的相关xml
        'views/workflow_view.xml',
        'views/workflow_demo.xml',
    ],

切记添加完workflow之后,一定要在此做一下声明,好让模块加载过程中能够对workflow进行实例化。
到此,workflow 已经基本实现

测试

  • 安装模块
  • 测试
test_one.png
test_two.png

小结

workflow 该功能的开发要注意,workflow、workflow_activity、workflow_transition三者的关系
Odoo 相比较于现在的workflow声明方式,还有另外一种简单的方式,这种方式要在下一章节给大家介绍。
源码地址 http://git.oschina.net/tobe/OdooDemo (workflow_demo)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容