zoukankan      html  css  js  c++  java
  • openerp学习笔记 跟踪状态,记录日志,发送消息

    跟踪状态基础数据:

    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()#对象定义结束

  • 相关阅读:
    JAVA中“==”和equals
    C++中各种容器的类型与特点
    程序员面试宝典 笔记 第七章
    程序员面试宝典 笔记(第六章 预处理 const 和sizeof())
    某学长面经
    tomcat 启动日志乱码
    Jenkins关闭和重启实现方式
    linux下svn版本控制的常用命令大全
    Java中的增强 for 循环 foreach
    JS 中 cookie 的使用
  • 原文地址:https://www.cnblogs.com/cnshen/p/3164707.html
Copyright © 2011-2022 走看看