openerp学习笔记 跟踪状态,记录日志,发送消息

时间:2021-08-07 23:58:22

跟踪状态基础数据:

kl_qingjd/kl_qingjd_data.xml

<?xml version="1.0"?>
<openerp>
    <data
noupdate="1">

<!-- kl_qingjd-related subtypes
for messaging / Chatter -->
       
<record id="mt_qingjd_confirm"
model="mail.message.subtype">
           
<field
name="name">已提交</field>
           
<field
name="res_model">kl.qingjd</field>
           
<field
name="description">请假申请已提交</field>
       
</record>
        <record
id="mt_qingjd_validate"
model="mail.message.subtype">
           
<field
name="name">已批准</field>
           
<field
name="res_model">kl.qingjd</field>
           
<field
name="description">请假申请已批准</field>
       
</record>
        <record
id="mt_qingjd_refuse"
model="mail.message.subtype">
           
<field
name="name">已拒绝</field>
           
<field
name="res_model">kl.qingjd</field>
           
<field name="default" eval="True"/> <!-- 订阅时,默认激活 -->

            <field
name="description">请假申请已拒绝</field>
       
</record>

</data>
</openerp>

跟踪状态,记录日志,发送消息后台代码:

kl_qingjd/kl_qingjd.py

# -*- encoding: utf-8 -*-
import pooler
import logging
import
netsvc
import tools
logger = netsvc.Logger()
import datetime
import
time
import math
from osv import fields,osv
from
openerp.tools.translate import _  #用于翻译代码中的静态字符串

#假期类型对象
class kl_qingjd_type(osv.osv):
    _name =
"kl.qingjd.type"
    _description =
u"假期类型"
    _order = "num asc, id asc"
   

    #对象字段
    _columns =
{
        'num':
fields.integer(u'序号'),
        'name':
fields.char(u'假期类型', size=64, required=True,
translate=True),
        'notes':
fields.char(u'说明', size=200),
    }
   

    #数据库约束
    _sql_constraints =
[
        ('name_check', "unique(name)",
u"假期类型已经存在且不允许重复."),
    ]
   

kl_qingjd_type()#对象定义结束

#请假单对象
class kl_qingjd(osv.osv):
    _name =
'kl.qingjd'
    _description = u'kl 请假单'
   
_order = "date_from asc, type_id asc"
    _inherit =
['mail.thread'] #继承消息模块,用于发消息
    _track =
{
        'state':
{
           
'kl_qingjd.mt_qingjd_validate': lambda self, cr, uid, obj, ctx=None:
obj['state'] ==
'validate',
           
'kl_qingjd.mt_qingjd_refuse': lambda self, cr, uid, obj, ctx=None: obj['state']
==
'refuse',
           
'kl_qingjd.mt_qingjd_confirm': lambda self, cr, uid, obj, ctx=None: obj['state']
== 'confirm',
        },
#自动发送系统消息,可用于记录日志或在邮件中显示,在邮件中显示时需要定义消息的子类型(kl_qingjd_data.xml)和指定消息相关用户(self.message_subscribe_users)
   
}
   
   
#获取当前用户所属的员工
    def _employee_get(self, cr, uid,
context=None):
        ids =
self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)],
context=context)
        if
ids:
           
return ids[0]
        return
False
   
   
#获取当前用户所属部门的id和名称
    def _get_user_department(self, cr, uid,
context={}):
        obj =
self.pool.get('hr.employee')
        ids
= obj.search(cr, uid, [('user_id','=',uid)])

        res = obj.read(cr, uid, ids,
['id','department_id'], context)
       
return res and res[0]['department_id'] or 0
   

    #检测同一时间段内是否存在相同的请假单,False 是存在,不允许创建
   
def _check_date(self, cr, uid,
ids):
        for rec in self.browse(cr,
uid, ids):
           
search_ids = self.search(cr, uid, [('date_from', '<=', rec.date_to),
('date_to', '>=', rec.date_from), ('employee_id', '=', rec.employee_id.id),
('id', '<>',
rec.id)])
           
if
search_ids:
               
return False
        return
True
   
    # TODO: can be improved using
resource calendar method
   
#计算日期间隔对应的天数
    def _get_number_of_days(self, date_from,
date_to):
        """Returns a float
equals to the timedelta between two dates given as string."""

DATETIME_FORMAT = "%Y-%m-%d
%H:%M:%S"
        from_dt =
datetime.datetime.strptime(date_from,
DATETIME_FORMAT)
        to_dt =
datetime.datetime.strptime(date_to,
DATETIME_FORMAT)
        timedelta = to_dt
- from_dt
        diff_day =
timedelta.days + float(timedelta.seconds) /
86400
        return
diff_day
   
   
#对象字段
    _columns =
{
           
'employee_id': fields.many2one('hr.employee', u"申请人",required=True, select=True,
invisible=False, readonly=True,
states={'draft':[('readonly',False)]}),
           
'department_id':fields.many2one('hr.department', u'申请部门', invisible=False,
readonly=True, states={'draft':[('readonly',False)]}),
#修改职员所属部门后显示原部门
           
#'department_id':fields.related('employee_id', 'department_id', string=u'申请部门',
type='many2one', relation='hr.department', readonly=True, store=True),
#修改职员所属部门后显示新部门
           
'type_id': fields.many2one("kl.qingjd.type", u"假期类型",
required=True,readonly=True,
states={'draft':[('readonly',False)]}),
           
'date_from': fields.datetime(u'起始日期',required=True, readonly=True,
states={'draft':[('readonly',False)]},
select=True),
           
'date_to': fields.datetime(u'结束日期', readonly=True,
states={'draft':[('readonly',False)]}),
           
'days': fields.float(u'天数', digits=(8, 2), readonly=True,
states={'draft':[('readonly',False)]}),
           
'notes': fields.text(u'请假原因',readonly=True,
states={'draft':[('readonly',False)]}),
           
'manager_id': fields.many2one('hr.employee', u'审批人', invisible=False,
readonly=True,
help=u'审批和拒绝时自动记录审批人'),
           
'refuse_notes': fields.char(u'拒绝原因', size=200, invisible=False, readonly=True,
states={'confirm':[('readonly',False)],
'validate':[('readonly',False)]}),
           
'state': fields.selection([('draft', u'草稿'), ('cancel', u'已作废'),('confirm',
u'待审批'), ('refuse', u'已拒绝'), ('validate', u'已审批')], u'状态', readonly=True,
track_visibility='onchange'),
           
'create_uid': fields.many2one('res.users', u"创建用户", invisible=False,
readonly=True),
#需要在记录中读取该字段或者在视图、打印中显示该字段时,对象中必须包含
           
'create_date': fields.datetime(u"创建日期", invisible=True, readonly=True),
#需要在记录中读取该字段或者在视图、打印中显示该字段时,对象中必须包含
         
}
   
   
#字段默认值     
    _defaults = {

                
'state':
'draft',
                
'employee_id':
_employee_get,
                
'department_id': lambda self,cr,uid,context:
self._get_user_department(cr,uid,context),

                
}
  
    #对象约束
   
_constraints =
[
                   
(_check_date, u'您在相同的时间段内不允许创建多张请假单!',
[u'起始日期',u'结束日期']),
                   
]
   
    #数据库约束
   
_sql_constraints = [
       
('date_check', "CHECK (date_from <= date_to)",
u"开始日期必须小于结束日期."),
        ('days_check',
"CHECK (days > 0 )", u"请假天数必须大于 0 ."),
   
]
   
   
#创建,此处取消自动记录创建
    def create(self, cr, uid, values,
context=None):
        """ Override to
avoid automatic logging of creation
"""
        if context is
None:
           
context = {}
        context =
dict(context,
mail_create_nolog=True)
       
return super(kl_qingjd, self).create(cr, uid, values, context=context)

#复制(未知用途)
    def copy(self, cr, uid,
id, default=None, context=None):
       
#if default is None:
       
#    default = {}
       
#if context is None:
       
#    context = {}
       
#default = default.copy()
       
#default['date_from'] = False
       
#default['date_to'] = False
        raise
osv.except_osv(_(u'警告!'),_(u'请假单暂不支持复制功能.'))
       
return super(kl_qingjd, self).copy(cr, uid, id, default,
context=context)
   
   
#写入,可用于校验写入和更改数据的合法性
    def write(self, cr, uid, ids, vals,
context=None):
        return
super(kl_qingjd, self).write(cr, uid, ids, vals,
context=context)
   
   
#删除当前请假单,需要验证请假单的状态
    def unlink(self, cr, uid, ids,
context=None):
        for rec in
self.browse(cr, uid, ids,
context=context):
           
if rec.state not in ['draft', 'cancel', 'confirm',
'refuse']:
               
raise osv.except_osv(_(u'警告!'),_(u'您不能删除以下状态的请假单 %s
.')%(rec.state))
           
#当请假单不是自己创建的时,不能删除
           
if  (rec.create_uid.id != uid):
#此处需要读取创建者ID时,必须在对象中包含create_uid列
               
raise
osv.except_osv(_(u'警告!'),_(u'您只能删除自己创建的单据.'))
       
return super(kl_qingjd, self).unlink(cr, uid, ids,
context)
   
   
#更换员工时自动修改员工所属的部门
    def onchange_employee(self, cr, uid,
ids, employee_id):
        result =
{'value': {'department_id':
False}}
        if
employee_id:
           
employee = self.pool.get('hr.employee').browse(cr, uid,
employee_id)
           
result['value'] = {'department_id':
employee.department_id.id}
        return
result
   
   
#更改起始日期,自动计算请假天数
    def onchange_date_from(self, cr, uid,
ids, date_to, date_from):
       
"""
        If there are no date set for
date_to, automatically set one 8 hours later
than
        the
date_from.
        Also update the
number_of_days.
       
"""
        # date_to has to be greater
than date_from
        if (date_from and
date_to) and (date_from >
date_to):
           
raise osv.except_osv(_(u'警告!'),_(u'开始日期必须小于结束日期.'))

result = {'value': {}}

# No date_to set so far:
automatically compute one 8 hours
later
        if date_from and not
date_to:
           
date_to_with_delta = datetime.datetime.strptime(date_from,
tools.DEFAULT_SERVER_DATETIME_FORMAT) +
datetime.timedelta(hours=8)
           
result['value']['date_to'] = str(date_to_with_delta)

# Compute and update the number of
days
        if (date_to and date_from)
and (date_from <=
date_to):
           
diff_day = self._get_number_of_days(date_from,
date_to)
           
result['value']['days'] =
round(math.floor(diff_day))+1
       
else:
           
result['value']['days'] = 0

return
result
   
   
#更改结束日期,自动计算请假天数
    def onchange_date_to(self, cr, uid, ids,
date_to, date_from):
       
"""
        Update the
number_of_days.
       
"""
        # date_to has to be greater
than date_from
        if (date_from and
date_to) and (date_from >
date_to):
           
raise osv.except_osv(_(u'警告!'),_(u'开始日期必须小于结束日期.'))

result = {'value': {}}

# Compute and update the number of
days
        if (date_to and date_from)
and (date_from <=
date_to):
           
diff_day = self._get_number_of_days(date_from,
date_to)
           
result['value']['days'] =
round(math.floor(diff_day))+1
       
else:
           
result['value']['days'] = 0

return
result
   
   
#设置为草稿状态,需要重新初始化工作流
    def set_to_draft(self, cr, uid, ids,
context=None):
        for rec in
self.browse(cr, uid, ids,
context=context):
           
#当请假单不是自己创建的时,不能设置为草稿
           
if  rec.create_uid.id !=
uid:
               
raise
osv.except_osv(_(u'警告!'),_(u'您不能设置他人创建的单据为草稿状态.'))
           

        self.write(cr, uid, ids,
{
            'state':
'draft',
           
'manager_id':
False,
           
'refuse_notes':False
       
})
       
#重新初始化工作流
        wf_service =
netsvc.LocalService("workflow")
       
for id in
ids:
           
wf_service.trg_delete(uid, 'kl.qingjd', id, cr)
#传入对象名称
           
wf_service.trg_create(uid, 'kl.qingjd', id,
cr)
        return
True
   
   
#审批请假单,自动记录审批人
    def set_to_validate(self, cr, uid, ids,
context=None):
       
#审批时,此处可以增加审批权限的校验
        for rec in
self.browse(cr, uid, ids,
context=context):
           
#当请假单的主管不是自己时,不能审批
           
if  rec.employee_id and rec.employee_id.parent_id and
rec.employee_id.parent_id.user_id:
               
if rec.employee_id.parent_id.user_id.id !=
uid:
                   
raise
osv.except_osv(_(u'警告!'),_(u'您不能审批当前单据,应由申请人的主管审批.'))
           
else:
               
raise
osv.except_osv(_(u'警告!'),_(u'您不能审批当前单据,应由申请人的主管审批.'))
       

        obj_emp =
self.pool.get('hr.employee')
        ids2
= obj_emp.search(cr, uid, [('user_id', '=',
uid)])
        manager = ids2 and ids2[0]
or False
       
#self.send_validate_notificate(cr, uid, ids, context=context)
#批准时发送消息给自己,跟系统自动发送的消息重复
       
return self.write(cr, uid, ids, {'state':'validate', 'manager_id':
manager})
   
   
#发送消息给自己,已批准
    #def send_validate_notificate(self, cr, uid,
ids, context=None):
    #    for obj in
self.browse(cr, uid, ids, context=context):
   
#        self.message_post(cr, uid, [obj.id],
body=_(u'您的请假申请已批准!'), context=context)
   

    #提交请假单,发送消息给主管
    def
set_to_confirm(self, cr, uid, ids,
context=None):
       
#发送消息给主管
        for rec in
self.browse(cr, uid, ids,
context=context):
           
#当请假单不是自己创建的时,不能提交
           
if  rec.create_uid.id !=
uid:
               
raise
osv.except_osv(_(u'警告!'),_(u'您不能提交他人创建的单据.'))
           
#提交请假单时发送系统消息,指定消息相关的用户(发送消息给主管和自己),消息的起始点,如果接收人只有自己则消息不在邮件中显示
           
if rec.employee_id and rec.employee_id.parent_id and
rec.employee_id.parent_id.user_id:
               
self.message_subscribe_users(cr, uid, [rec.id],
user_ids=[rec.employee_id.parent_id.user_id.id],
context=context)
        return
self.write(cr, uid, ids, {'state': 'confirm'})
   

    #拒绝请假单,自动记录审批人
    def
set_to_refuse(self, cr, uid, ids,
context=None):
       

        for rec in self.browse(cr, uid,
ids,
context=context):
           
#当请假单的主管不是自己时,不能拒绝
           
if  rec.employee_id and rec.employee_id.parent_id and
rec.employee_id.parent_id.user_id:
               
if rec.employee_id.parent_id.user_id.id !=
uid:
                   
raise
osv.except_osv(_(u'警告!'),_(u'您不能拒绝当前单据,应由申请人的主管拒绝.'))
           
else:
               
raise
osv.except_osv(_(u'警告!'),_(u'您不能拒绝当前单据,应由申请人的主管拒绝.'))
           
#拒绝时验证决绝原因不能为空
           
if (rec.refuse_notes == False) or (rec.refuse_notes.strip() ==
''):
               
raise
osv.except_osv(_(u'警告!'),_(u'拒绝原因不能为空,请编辑并填写.'))
           

        obj_emp =
self.pool.get('hr.employee')
        ids2
= obj_emp.search(cr, uid, [('user_id', '=',
uid)])
        manager = ids2 and ids2[0]
or False
       
#self.send_refuse_notificate(cr, uid, ids, context=context)
#拒绝时发送消息给自己,跟系统自动发送的消息重复
       
return self.write(cr, uid, ids, {'state':'refuse', 'manager_id':
manager})
   
   
#发送消息给自己,已拒绝
    #def send_refuse_notificate(self, cr, uid,
ids, context=None):
    #    for obj in
self.browse(cr, uid, ids, context=context):
   
#        self.message_post(cr, uid, [obj.id],
body=_(u'您的请假申请已拒绝!'), context=context)

kl_qingjd()#对象定义结束

openerp学习笔记 跟踪状态,记录日志,发送消息的更多相关文章

  1. RocketMQ 源码学习笔记————Producer 是怎么将消息发送至 Broker 的?

    目录 RocketMQ 源码学习笔记----Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest ...

  2. RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?

    目录 RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest Roc ...

  3. 【Visual C&plus;&plus;】游戏编程学习笔记之八:鼠标输入消息(小demo)

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  4. APUE学习笔记——10&period;9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  5. webservice系统学习笔记5-手动构建&sol;发送&sol;解析SOAP消息

    手动拼接SOAP消息调用webservice SOAP消息的组成: 1.创建需要发送的SOAP消息的XML(add方法为例子) /** * 创建访问add方法的SOAP消息的xml */ @Test ...

  6. rabbitMQ学习笔记&lpar;二&rpar; 简单的发送与接收消息 HelloWorld

    首先要下载rabbitmq的javaClient库,然后加入到项目中,下载地址为:http://www.rabbitmq.com/releases/rabbitmq-java-client/v3.1. ...

  7. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

  8. 【Visual C&plus;&plus;】游戏编程学习笔记之七:键盘输入消息

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  9. RabbitMQ学习系列二-C&num;代码发送消息

    RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...

随机推荐

  1. 关于更改MYECLIPSE JS 代码背景颜色

    白色的背景,看花了眼,你想改一下编辑器的背景颜色,移步这里就可以了. 这时你高兴的打开编辑器,发现颜色确实变了,但是当你打开有JS的JSP时,你碉堡了,发现JS的背景颜色还是默认的, 看着让人纠结,好 ...

  2. Oracle -&gt&semi;&gt&semi; 连续聚合

    select id, grp_factor, sum (id) over( partition by grp_factor order by id rows between unbounded pre ...

  3. backbone-1&period;3&period;3源码解析-----------Event

    第一次写,写的不对的请指正 backbone.js中的Event实现了自定义事件.自定义事件就是一个对象的键值对,key为事件名,value为一个function数组.在backbone这个对象中有一 ...

  4. &sol;Home&sol;Tpl&sol;Equipment&sol;rangeIndex&period;html 里调用魔板

    <pre name="code" class="html">demo:/var/www/DEVOPS# vim ./Home/Tpl/Equipme ...

  5. JSP导出Excel后身份证后三位为0

    JSP导出Excel身份证号码超出Excel最大限制,用科学计数法表示,但后三位为0,修改方式: <style type="text/css">.txt    {    ...

  6. CMDB资产管理系统开发【day25】&colon;表结构设计1

    资产表 # _*_coding:utf-8_*_ __author__ = 'jieli' from assets.myauth import UserProfile from django.db i ...

  7. sql 查询语句的练习2

    --14.列出所有雇员的雇员名称.部门名称和薪金. select e.ename,d.dname,e.sal from emp e,dept d where e.deptno = d.deptno;- ...

  8. 前端自动化构建工具webpack (二)之css和插件加载总结

    1.  webpack只识别js文件,其他文件都需要转换成js文件.所有文件都是模块; 2. css解析      css需要css-loader  --->style-loader ----- ...

  9. JVM探秘2--详解内存溢出OutOfMemoryError异常

    JVM运行时内存被划分成多个区域,而除了程序计数器之外,其他几个区都会出现OutOfMemoryError异常,主要原因就是对应内存区域的内存不足以再分配内存,一般要么是内存泄漏了要么就是内存参数设置 ...

  10. &lbrack;转帖&rsqb;新的Linux后门开始肆虐 主要攻击中国服务器

    新的Linux后门开始肆虐 主要攻击中国服务器 https://www.cnbeta.com/articles/tech/815639.htm 一种新的 Linux 系统后门已经开始肆虐,并主要运行在 ...