From d0b7144c0fc46c0d50b9b80aee1208ff1fefb776 Mon Sep 17 00:00:00 2001 From: "uco (OpenERP)" Date: Tue, 2 Feb 2010 14:17:57 +0530 Subject: [PATCH 01/12] [IMP] crm_hr, crm_project: Removed repeating method and unused import statements. bzr revid: uco@tinyerp.co.in-20100202084757-0qvctmbcfknuqiw2 --- addons/crm_hr/crm_hr.py | 20 -------------------- addons/crm_project/crm_project_bug.py | 21 +-------------------- addons/crm_project/crm_project_feature.py | 22 ++-------------------- 3 files changed, 3 insertions(+), 60 deletions(-) diff --git a/addons/crm_hr/crm_hr.py b/addons/crm_hr/crm_hr.py index 7fe2f2c4878..b122cc6b9e9 100644 --- a/addons/crm_hr/crm_hr.py +++ b/addons/crm_hr/crm_hr.py @@ -19,22 +19,9 @@ # ############################################################################## -import time -import re -import os - -import mx.DateTime -import base64 - -from tools.translate import _ - -import tools from osv import fields,osv,orm -from osv.orm import except_orm - from crm import crm - class crm_job(osv.osv): _name = "crm.job" _description = "Job Cases" @@ -63,13 +50,6 @@ class crm_job(osv.osv): "the partner mentality in relation to our services.The scale has" \ "to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."), 'phonecall_id':fields.many2one ('crm.phonecall', 'Phonecall'), - - } - def onchange_categ_id(self, cr, uid, ids, categ, context={}): - if not categ: - return {'value':{}} - cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability - return {'value':{'probability':cat}} crm_job() diff --git a/addons/crm_project/crm_project_bug.py b/addons/crm_project/crm_project_bug.py index 6e56e0e3746..3a7939b6484 100644 --- a/addons/crm_project/crm_project_bug.py +++ b/addons/crm_project/crm_project_bug.py @@ -19,22 +19,9 @@ # ############################################################################## -import time -import re -import os - -import mx.DateTime -import base64 - -from tools.translate import _ - -import tools from osv import fields,osv,orm -from osv.orm import except_orm - from crm import crm - class crm_project_bug(osv.osv): _name = "crm.project.bug" _description = "Project Bug Cases" @@ -72,13 +59,7 @@ class crm_project_bug(osv.osv): _defaults = { 'project_id':_get_project - } - def onchange_categ_id(self, cr, uid, ids, categ, context={}): - if not categ: - return {'value':{}} - cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability - return {'value':{'probability':cat}} - + } crm_project_bug() diff --git a/addons/crm_project/crm_project_feature.py b/addons/crm_project/crm_project_feature.py index 77314ec32de..e80be383987 100644 --- a/addons/crm_project/crm_project_feature.py +++ b/addons/crm_project/crm_project_feature.py @@ -19,19 +19,7 @@ # ############################################################################## -import time -import re -import os - -import mx.DateTime -import base64 - -from tools.translate import _ - -import tools from osv import fields,osv,orm -from osv.orm import except_orm - from crm import crm class crm_project_future_request(osv.osv): @@ -70,13 +58,7 @@ class crm_project_future_request(osv.osv): _defaults = { 'project_id':_get_project - } - def onchange_categ_id(self, cr, uid, ids, categ, context={}): - if not categ: - return {'value':{}} - cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability - return {'value':{'probability':cat}} - - + } + crm_project_future_request() From 644fb6d0fac428a5396593817ab595075261b3ed Mon Sep 17 00:00:00 2001 From: "uco (OpenERP)" Date: Tue, 2 Feb 2010 19:17:02 +0530 Subject: [PATCH 02/12] [ADD] base_action_rule: Added new module which can be used to set action rules for any object. bzr revid: uco@tinyerp.co.in-20100202134702-33lb9937qdr257y7 --- addons/base_action_rule/__init__.py | 24 +++ addons/base_action_rule/__terp__.py | 39 ++++ addons/base_action_rule/base_action_rule.py | 187 ++++++++++++++++++ .../base_action_rule_data.xml | 15 ++ .../base_action_rule_view.xml | 179 +++++++++++++++++ .../security/ir.model.access.csv | 4 + 6 files changed, 448 insertions(+) create mode 100644 addons/base_action_rule/__init__.py create mode 100644 addons/base_action_rule/__terp__.py create mode 100644 addons/base_action_rule/base_action_rule.py create mode 100644 addons/base_action_rule/base_action_rule_data.xml create mode 100644 addons/base_action_rule/base_action_rule_view.xml create mode 100644 addons/base_action_rule/security/ir.model.access.csv diff --git a/addons/base_action_rule/__init__.py b/addons/base_action_rule/__init__.py new file mode 100644 index 00000000000..c14f1081f46 --- /dev/null +++ b/addons/base_action_rule/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import base_action_rule + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/base_action_rule/__terp__.py b/addons/base_action_rule/__terp__.py new file mode 100644 index 00000000000..13040a8d5f1 --- /dev/null +++ b/addons/base_action_rule/__terp__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'Action Rule', + 'version': '1.0', + 'category': 'Generic Modules/Others', + 'description': "This module allows to implement action rules for any object.", + 'author': 'Tiny', + 'website': 'http://www.openerp.com', + 'depends': ['base'], + 'init_xml': ['base_action_rule_data.xml'], + 'update_xml': [ + 'base_action_rule_view.xml', + 'security/ir.model.access.csv', + ], + 'demo_xml': [], + 'installable': True, + 'active': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py new file mode 100644 index 00000000000..65012ac501b --- /dev/null +++ b/addons/base_action_rule/base_action_rule.py @@ -0,0 +1,187 @@ +import time +import mx.DateTime + +from osv import fields, osv, orm +from osv.orm import except_orm + +AVAILABLE_STATES = [ + ('draft','Draft'), + ('open','Open'), + ('cancel', 'Cancelled'), + ('done', 'Closed'), + ('pending','Pending') +] + +AVAILABLE_PRIORITIES = [ + ('5','Lowest'), + ('4','Low'), + ('3','Normal'), + ('2','High'), + ('1','Highest') +] + +class base_action_rule(osv.osv): + _name = 'base.action.rule' + _description = 'Action Rules' + _columns = { + 'name': fields.many2one('ir.model', 'Model', required=True), + 'max_level': fields.integer('Max Level'), + 'rule_lines': fields.one2many('base.action.rule.line','rule_id','Rule Lines'), + 'create_date': fields.datetime('Create Date', readonly=1) + } + + def _check(self, cr, uid, ids=False, context={}): + ''' + Function called by the scheduler to process models + ''' + ruleobj = self.pool.get('base.action.rule') + ids = ruleobj.search(cr, uid, []) + rules = ruleobj.browse(cr, uid, ids, context) + return ruleobj._action(cr, uid, rules, False, context=context) + + def _action(self, cr, uid, rules, state_to, scrit=None, context={}): + if not scrit: + scrit = [] + history = [] + history_obj = self.pool.get('base.action.rule.history') + if rules: + cr.execute('select * from base_action_rule_history where rule_id in (%s)' %(','.join(map(lambda x: "'"+str(x.id)+"'",rules)))) + history = cr.fetchall() + checkids = map(lambda x: x[0], history or []) + + if not len(history) or len(history) < len(rules): + for rule in rules: + if rule.id not in checkids: + lastDate = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') + history_obj.create(cr, uid, {'rule_id': rule.id, 'res_id': rule.name.id, 'date_action_last': lastDate}) + + for rule in rules: + for action in rule.rule_lines: + if action.trg_date_type=='create': + base = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') + elif action.trg_date_type=='action_last': + for hist in history: + if hist[6]: + base = mx.DateTime.strptime(hist[6][:19], '%Y-%m-%d %H:%M:%S') + else: + base = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') + history_obj.write(cr, uid, [hist[0]], {'date_action_last': base}) + elif action.trg_date_type=='deadline' and rule.name.date_deadline: + base = mx.DateTime.strptime(rule.name.date_deadline, '%Y-%m-%d %H:%M:%S') + elif action.trg_date_type=='date' and rule.name.date: + base = mx.DateTime.strptime(rule.name.date, '%Y-%m-%d %H:%M:%S') + + if base: + fnct = { + 'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval), + 'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval), + 'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval), + 'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval), + } + d = base + fnct[action.trg_date_range_type](action.trg_date_range) + dt = d.strftime('%Y-%m-%d %H:%M:%S') + for hist in history: + if not hist[8] or dt < hist[8]: + history_obj.write(cr, uid, [hist[0]], {'date_action_next': dt}, context) + return True + +base_action_rule() + +class base_action_rule_line(osv.osv): + _name = 'base.action.rule.line' + _description = 'Action Rule Lines' + _columns = { + 'name': fields.char('Rule Name',size=64, required=True), + 'rule_id': fields.many2one('base.action.rule','Rule'), + 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case rule without removing it."), + 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case rules."), + + 'trg_state_from': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'State', size=16), + 'trg_state_to': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'Button Pressed', size=16), + + 'trg_date_type': fields.selection([ + ('none','None'), + ('create','Creation Date'), + ('action_last','Last Action Date'), + ('deadline','Deadline'), + ('date','Date'), + ], 'Trigger Date', size=16), + 'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date, specifies you can put a negative number " \ + "if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting."), + 'trg_date_range_type': fields.selection([('minutes', 'Minutes'),('hour','Hours'),('day','Days'),('month','Months')], 'Delay type'), + + + 'trg_user_id': fields.many2one('res.users', 'Responsible'), + + 'trg_partner_id': fields.many2one('res.partner', 'Partner'), + 'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'), + + 'trg_priority_from': fields.selection([('','')] + AVAILABLE_PRIORITIES, 'Minimum Priority'), + 'trg_priority_to': fields.selection([('','')] + AVAILABLE_PRIORITIES, 'Maximim Priority'), + + + 'act_method': fields.char('Call Object Method', size=64), + 'act_state': fields.selection([('','')]+AVAILABLE_STATES, 'Set state to', size=16), + 'act_user_id': fields.many2one('res.users', 'Set responsible to'), + 'act_priority': fields.selection([('','')] + AVAILABLE_PRIORITIES, 'Set priority to'), + 'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="These people will receive a copy of the future communication between partner and users by email"), + + 'act_remind_partner': fields.boolean('Remind Partner', help="Check this if you want the rule to send a reminder by email to the partner."), + 'act_remind_user': fields.boolean('Remind responsible', help="Check this if you want the rule to send a reminder by email to the user."), + 'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if you want that all documents attached to the case be attached to the reminder email sent."), + + 'act_mail_to_user': fields.boolean('Mail to responsible',help="Check this if you want the rule to send an email to the responsible person."), + 'act_mail_to_partner': fields.boolean('Mail to partner',help="Check this if you want the rule to send an email to the partner."), + 'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this if you want the rule to mark CC(mail to any other person defined in actions)."), + 'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id of the persons whom mail is to be sent"), + 'act_mail_body': fields.text('Mail body',help="Content of mail"), + 'regex_name': fields.char('Regular Expression on Case Name', size=128), + 'regex_history': fields.char('Regular Expression on Case History', size=128), + 'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the action name." \ + "eg:on which object which ation to be taken on basis of which condition"), + } + + _defaults = { + 'active': lambda *a: 1, + 'trg_date_type': lambda *a: 'none', + 'trg_date_range_type': lambda *a: 'day', + 'act_mail_to_user': lambda *a: 0, + 'act_remind_partner': lambda *a: 0, + 'act_remind_user': lambda *a: 0, + 'act_mail_to_partner': lambda *a: 0, + 'act_mail_to_watchers': lambda *a: 0, + } + + _order = 'sequence' + + def _check_mail(self, cr, uid, ids, context=None): + emptycase = orm.browse_null() + for rule in self.browse(cr, uid, ids): + if rule.act_mail_body: + try: + obj = self.pool.get(rule.rule_id.name.model) + obj.format_mail(emptycase, rule.act_mail_body) + except (ValueError, KeyError, TypeError): + return False + return True + + _constraints = [ + (_check_mail, 'Error: The mail is not well formated', ['act_mail_body']), + ] + +base_action_rule_line() + +class base_action_rule_history(osv.osv): + _name = 'base.action.rule.history' + _description = 'Action Rule History' + _rec_name = 'rule_id' + _columns = { + 'rule_id': fields.many2one('base.action.rule','Rule', required=True, readonly=1), + 'res_id': fields.integer('Resource ID', readonly=1), + 'date_action_last': fields.datetime('Last Action', readonly=1), + 'date_action_next': fields.datetime('Next Action', readonly=1), + } + +base_action_rule_history() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_action_rule/base_action_rule_data.xml b/addons/base_action_rule/base_action_rule_data.xml new file mode 100644 index 00000000000..026553e2aae --- /dev/null +++ b/addons/base_action_rule/base_action_rule_data.xml @@ -0,0 +1,15 @@ + + + + + Check Rules + 4 + hours + -1 + + + + + + + \ No newline at end of file diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml new file mode 100644 index 00000000000..b8c762cbd63 --- /dev/null +++ b/addons/base_action_rule/base_action_rule_view.xml @@ -0,0 +1,179 @@ + + + + + + + + base.action.rule.form + base.action.rule + form + +
+ + + + + +
+ + + base.action.rule.tree + base.action.rule + tree + + + + + + + + + + + Action Rules + base.action.rule + form + tree,form + + + + + + + base.action.rule.line.form + base.action.rule.line + form + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + base.action.rule.line.tree + base.action.rule.line + tree + + + + + + + + + Action Rule Lines + base.action.rule.line + form + tree,form + + + + + + + base.action.rule.history.form + base.action.rule.history + form + +
+ + + + + + +
+ + + base.action.rule.history.tree + base.action.rule.history + tree + + + + + + + + + + + + Action Rule History + base.action.rule.history + form + tree,form + + + + +
+
\ No newline at end of file diff --git a/addons/base_action_rule/security/ir.model.access.csv b/addons/base_action_rule/security/ir.model.access.csv new file mode 100644 index 00000000000..2f09e8fd656 --- /dev/null +++ b/addons/base_action_rule/security/ir.model.access.csv @@ -0,0 +1,4 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_base_action_rule","base.action.rule","model_base_action_rule",,1,1,1,1 +"access_base_action_rule_line","base.action.rule.line","model_base_action_rule_line",,1,1,1,1 +"access_base_action_rule_history","base.action.rule.history","model_base_action_rule_history",,1,1,1,1 \ No newline at end of file From 904c896e0c0f80512639103dffa5aca939206722 Mon Sep 17 00:00:00 2001 From: "uco (OpenERP)" Date: Wed, 3 Feb 2010 15:58:09 +0530 Subject: [PATCH 03/12] [IMP] base_action_rule, crm: Improved base_action_rule. Removed crm.case.rule from crm and added objects of base.actio.rule. bzr revid: uco@tinyerp.co.in-20100203102809-h622irvspyflvw0e --- addons/base_action_rule/base_action_rule.py | 132 +++-- .../base_action_rule_view.xml | 10 +- addons/crm/__terp__.py | 2 +- addons/crm/crm.py | 455 ++++++++---------- addons/crm/crm_data.xml | 13 +- addons/crm/crm_view.xml | 134 ++---- addons/crm/security/ir.model.access.csv | 2 - 7 files changed, 333 insertions(+), 415 deletions(-) diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 65012ac501b..753a7c0365b 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -1,6 +1,7 @@ import time import mx.DateTime +import tools from osv import fields, osv, orm from osv.orm import except_orm @@ -44,45 +45,91 @@ class base_action_rule(osv.osv): scrit = [] history = [] history_obj = self.pool.get('base.action.rule.history') + cr.execute("select nextcall from ir_cron where model='base.action.rule'") + action_next = cr.fetchone()[0] if rules: cr.execute('select * from base_action_rule_history where rule_id in (%s)' %(','.join(map(lambda x: "'"+str(x.id)+"'",rules)))) history = cr.fetchall() checkids = map(lambda x: x[0], history or []) - if not len(history) or len(history) < len(rules): for rule in rules: if rule.id not in checkids: lastDate = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') - history_obj.create(cr, uid, {'rule_id': rule.id, 'res_id': rule.name.id, 'date_action_last': lastDate}) + history_obj.create(cr, uid, {'rule_id': rule.id, 'res_id': rule.name.id, 'date_action_last': lastDate, 'date_action_next': action_next}) for rule in rules: + obj = self.pool.get(rule.name.model) + rec_ids = obj.search(cr, uid, []) for action in rule.rule_lines: - if action.trg_date_type=='create': - base = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') - elif action.trg_date_type=='action_last': - for hist in history: - if hist[6]: - base = mx.DateTime.strptime(hist[6][:19], '%Y-%m-%d %H:%M:%S') - else: - base = mx.DateTime.strptime(rule.create_date[:19], '%Y-%m-%d %H:%M:%S') - history_obj.write(cr, uid, [hist[0]], {'date_action_last': base}) - elif action.trg_date_type=='deadline' and rule.name.date_deadline: - base = mx.DateTime.strptime(rule.name.date_deadline, '%Y-%m-%d %H:%M:%S') - elif action.trg_date_type=='date' and rule.name.date: - base = mx.DateTime.strptime(rule.name.date, '%Y-%m-%d %H:%M:%S') - - if base: - fnct = { - 'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval), - 'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval), - 'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval), - 'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval), - } - d = base + fnct[action.trg_date_range_type](action.trg_date_range) - dt = d.strftime('%Y-%m-%d %H:%M:%S') - for hist in history: - if not hist[8] or dt < hist[8]: - history_obj.write(cr, uid, [hist[0]], {'date_action_next': dt}, context) + for data in obj.browse(cr, uid, rec_ids): + ok = True + ok = ok and (not action.trg_state_from or action.trg_state_from==data.state) + ok = ok and (not action.trg_state_to or action.trg_state_to==state_to) + ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==data.user_id.id) + ok = ok and (not action.trg_partner_id.id or action.trg_partner_id.id==data.partner_id.id) + ok = ok and ( + not action.trg_partner_categ_id.id or + ( + data.partner_id.id and + (action.trg_partner_categ_id.id in map(lambda x: x.id, data.partner_id.category_id or [])) + ) + ) + ok = ok and (not action.trg_priority_from or action.trg_priority_from>=data.priority) + ok = ok and (not action.trg_priority_to or action.trg_priority_to<=data.priority) + + reg_name = action.regex_name + result_name = True + if reg_name: + ptrn = re.compile(str(reg_name)) + _result = ptrn.search(str(data.name)) + if not _result: + result_name = False + regex_n = not reg_name or result_name + ok = ok and regex_n + + if not ok: + continue + + base = False + if action.trg_date_type=='create': + base = mx.DateTime.strptime(data.create_date[:19], '%Y-%m-%d %H:%M:%S') + elif action.trg_date_type=='action_last': + for hist in history: + if hist[6]: + base = hist[8] + else: + base = mx.DateTime.strptime(data.create_date[:19], '%Y-%m-%d %H:%M:%S') + elif action.trg_date_type=='date' and data.date: + base = mx.DateTime.strptime(data.date, '%Y-%m-%d %H:%M:%S') + if base: + fnct = { + 'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval), + 'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval), + 'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval), + 'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval), + } + d = base + fnct[action.trg_date_range_type](action.trg_date_range) + dt = d.strftime('%Y-%m-%d %H:%M:%S') + for hist in history: + ok = (dt <= time.strftime('%Y-%m-%d %H:%M:%S')) and \ + ((not hist[8]) or \ + (dt >= hist[8] and \ + hist[6] < hist[8])) + if not ok: + if not hist[8] or dt < hist[8]: + history_obj.write(cr, uid, [hist[0]], {'date_action_next': dt}, context) + + else: + ok = action.trg_date_type=='none' + + if ok: + if action.server_action_id: + context.update({'active_id':case.id,'active_ids':[case.id]}) + self.pool.get('ir.actions.server').run(cr, uid, [action.server_action_id.id], context) + for hist in history: + if hist[6]: + base = hist[8] + history_obj.write(cr, uid, [hist[0]], {'date_action_last': base, 'date_action_next': action_next}) return True base_action_rule() @@ -103,7 +150,6 @@ class base_action_rule_line(osv.osv): ('none','None'), ('create','Creation Date'), ('action_last','Last Action Date'), - ('deadline','Deadline'), ('date','Date'), ], 'Trigger Date', size=16), 'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date, specifies you can put a negative number " \ @@ -135,10 +181,9 @@ class base_action_rule_line(osv.osv): 'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this if you want the rule to mark CC(mail to any other person defined in actions)."), 'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id of the persons whom mail is to be sent"), 'act_mail_body': fields.text('Mail body',help="Content of mail"), - 'regex_name': fields.char('Regular Expression on Case Name', size=128), - 'regex_history': fields.char('Regular Expression on Case History', size=128), + 'regex_name': fields.char('Regular Expression on Model Name', size=128), 'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the action name." \ - "eg:on which object which ation to be taken on basis of which condition"), + "eg:on which object which action to be taken on basis of which condition"), } _defaults = { @@ -154,13 +199,32 @@ class base_action_rule_line(osv.osv): _order = 'sequence' + def format_body(self, body): + return body and tools.ustr(body.encode('ascii', 'replace')) or '' + + def format_mail(self, case, body): + data = { + 'case_id': case.id, + 'case_subject': case.name, + 'case_date': case.date, + 'case_description': case.description, + + 'case_user': (case.user_id and case.user_id.name) or '/', + 'case_user_email': (case.user_id and case.user_id.address_id and case.user_id.address_id.email) or '/', + 'case_user_phone': (case.user_id and case.user_id.address_id and case.user_id.address_id.phone) or '/', + + 'email_from': case.email_from, + 'partner': (case.partner_id and case.partner_id.name) or '/', + 'partner_email': (case.partner_address_id and case.partner_address_id.email) or '/', + } + return self.format_body(body % data) + def _check_mail(self, cr, uid, ids, context=None): emptycase = orm.browse_null() for rule in self.browse(cr, uid, ids): if rule.act_mail_body: try: - obj = self.pool.get(rule.rule_id.name.model) - obj.format_mail(emptycase, rule.act_mail_body) + self.format_mail(emptycase, rule.act_mail_body) except (ValueError, KeyError, TypeError): return False return True diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml index b8c762cbd63..441d2956151 100644 --- a/addons/base_action_rule/base_action_rule_view.xml +++ b/addons/base_action_rule/base_action_rule_view.xml @@ -57,10 +57,10 @@ - - + + - + @@ -73,10 +73,8 @@ - - -