[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
This commit is contained in:
parent
b527df9a9c
commit
904c896e0c
|
@ -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
|
||||
|
|
|
@ -57,10 +57,10 @@
|
|||
<separator colspan="4" string="Conditions on States"/>
|
||||
<field name="trg_state_from" select="2"/>
|
||||
<field name="trg_state_to" select="2"/>
|
||||
<separator colspan="4" string="Conditions on Case Fields"/>
|
||||
<field name="regex_name" string="Regex on Case Name" colspan="2"/>
|
||||
<separator colspan="4" string="Conditions on Model Fields"/>
|
||||
<field name="regex_name" string="Regex on Model Name" colspan="2"/>
|
||||
<field name="trg_user_id" select="2"/>
|
||||
<separator colspan="4" string="Conditions on Case Partner"/>
|
||||
<separator colspan="4" string="Conditions on Model Partner"/>
|
||||
<field name="trg_partner_id"/>
|
||||
<field name="trg_partner_categ_id"/>
|
||||
<separator colspan="4" string="Conditions on Priority Range"/>
|
||||
|
@ -73,10 +73,8 @@
|
|||
<field name="trg_date_range" nolabel="1"/>
|
||||
<field name="trg_date_range_type" nolabel="1"/>
|
||||
</group>
|
||||
<separator colspan="4" string="Condition on Communication History"/>
|
||||
<field name="regex_history" string="Regex on Communication History"/>
|
||||
<separator colspan="4" string="Note"/>
|
||||
<label align="0.0" string="The rule use a AND operator. The case must match all non empty fields so that the rule execute the action described in the 'Actions' tab." colspan="4"/>
|
||||
<label align="0.0" string="The rule use a AND operator. The model must match all non empty fields so that the rule execute the action described in the 'Actions' tab." colspan="4"/>
|
||||
</page>
|
||||
<page string="Actions">
|
||||
<separator colspan="4" string="Fields to Change"/>
|
||||
|
|
|
@ -44,7 +44,7 @@ The CRM module has a email gateway for the synchronisation interface
|
|||
between mails and Open ERP.""",
|
||||
'author': 'Tiny',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base',
|
||||
'depends': ['base', 'base_action_rule',
|
||||
'caldav',
|
||||
'process',
|
||||
'mail_gateway',
|
||||
|
|
|
@ -163,18 +163,185 @@ class crm_case_stage(osv.osv):
|
|||
|
||||
crm_case_stage()
|
||||
|
||||
class base_action_rule(osv.osv):
|
||||
_inherit = 'base.action.rule'
|
||||
_description = 'Action Rules'
|
||||
|
||||
def _check(self, cr, uid, ids=False, context={}):
|
||||
'''
|
||||
Function called by the scheduler to process cases for date actions
|
||||
Only works on not done and cancelled cases
|
||||
'''
|
||||
obj = self.pool.get('base.action.rule')
|
||||
ids2 = obj.search(cr, uid, [('name.model','=','crm.case')])
|
||||
cases = obj.browse(cr, uid, ids2, context)
|
||||
return obj._action(cr, uid, cases, False, context=context)
|
||||
|
||||
class crm_case_rule(osv.osv):
|
||||
_name = "crm.case.rule"
|
||||
_description = "Case Rule"
|
||||
def _action(self, cr, uid, cases, state_to, scrit=None, context={}):
|
||||
if not scrit:
|
||||
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]
|
||||
action_ids = self.pool.get('base.action.rule').search(cr, uid, scrit)
|
||||
level = MAX_LEVEL
|
||||
if cases and action_ids:
|
||||
cr.execute('select * from base_action_rule_history where rule_id in (%s)' %(','.join(map(lambda x: "'"+str(x.id)+"'",cases))))
|
||||
history = cr.fetchall()
|
||||
checkids = map(lambda x: x[0], history or [])
|
||||
|
||||
if not len(history) or len(history) < len(cases):
|
||||
for case in cases:
|
||||
if case.id not in checkids:
|
||||
lastDate = mx.DateTime.strptime(case.create_date[:19], '%Y-%m-%d %H:%M:%S')
|
||||
history_obj.create(cr, uid, {'rule_id': case.id, 'res_id': case.name.id, 'date_action_last': lastDate, 'date_action_next': action_next})
|
||||
caseobj = self.pool.get('crm.case')
|
||||
case_ids = caseobj.search(cr, uid, [('state', 'not in', ('cancel','done'))])
|
||||
|
||||
while len(action_ids) and level:
|
||||
newactions = []
|
||||
actions = self.pool.get('base.action.rule').browse(cr, uid, action_ids, context)
|
||||
for case in cases:
|
||||
for line in actions:
|
||||
for action in line.rule_lines:
|
||||
for cs in caseobj.browse(cr, uid, case_ids):
|
||||
ok = True
|
||||
ok = ok and (not action.trg_state_from or action.trg_state_from==cs.state)
|
||||
ok = ok and (not action.trg_state_to or action.trg_state_to==state_to)
|
||||
ok = ok and (not action.trg_section_id or action.trg_section_id.id==cs.section_id.id)
|
||||
ok = ok and (not action.trg_categ_id or action.trg_categ_id.id==cs.categ_id.id)
|
||||
ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==cs.user_id.id)
|
||||
ok = ok and (not action.trg_partner_id.id or action.trg_partner_id.id==cs.partner_id.id)
|
||||
ok = ok and (not action.trg_max_history or action.trg_max_history<=(len(cs.history_line)+1))
|
||||
ok = ok and (
|
||||
not action.trg_partner_categ_id.id or
|
||||
(
|
||||
cs.partner_id.id and
|
||||
(action.trg_partner_categ_id.id in map(lambda x: x.id, cs.partner_id.category_id or []))
|
||||
)
|
||||
)
|
||||
ok = ok and (not action.trg_priority_from or action.trg_priority_from>=case.priority)
|
||||
ok = ok and (not action.trg_priority_to or action.trg_priority_to<=case.priority)
|
||||
|
||||
reg_name = action.regex_name
|
||||
result_name = True
|
||||
if reg_name:
|
||||
ptrn = re.compile(str(reg_name))
|
||||
_result = ptrn.search(str(cs.name))
|
||||
if not _result:
|
||||
result_name = False
|
||||
regex_n = not reg_name or result_name
|
||||
ok = ok and regex_n
|
||||
|
||||
reg_history = action.regex_history
|
||||
result_history = True
|
||||
if reg_history:
|
||||
ptrn = re.compile(str(reg_history))
|
||||
if cs.history_line:
|
||||
_result = ptrn.search(str(cs.history_line[0].description))
|
||||
if not _result:
|
||||
result_history = False
|
||||
regex_h = not reg_history or result_history
|
||||
ok = ok and regex_h
|
||||
|
||||
if not ok:
|
||||
continue
|
||||
|
||||
base = False
|
||||
if action.trg_date_type=='create':
|
||||
base = mx.DateTime.strptime(case.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], '%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
base = mx.DateTime.strptime(cs.create_date[:19], '%Y-%m-%d %H:%M:%S')
|
||||
elif action.trg_date_type=='deadline' and cs.date_deadline:
|
||||
base = mx.DateTime.strptime(cs.date_deadline, '%Y-%m-%d %H:%M:%S')
|
||||
elif action.trg_date_type=='date' and cs.date:
|
||||
base = mx.DateTime.strptime(cs.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':cs.id,'active_ids':[cs.id]})
|
||||
self.pool.get('ir.actions.server').run(cr, uid, [action.server_action_id.id], context)
|
||||
write = {}
|
||||
if action.act_state:
|
||||
cs.state = action.act_state
|
||||
write['state'] = action.act_state
|
||||
if action.act_section_id:
|
||||
cs.section_id = action.act_section_id
|
||||
write['section_id'] = action.act_section_id.id
|
||||
if action.act_user_id:
|
||||
cs.user_id = action.act_user_id
|
||||
write['user_id'] = action.act_user_id.id
|
||||
if action.act_priority:
|
||||
cs.priority = action.act_priority
|
||||
write['priority'] = action.act_priority
|
||||
if action.act_email_cc:
|
||||
if '@' in (cs.email_cc or ''):
|
||||
emails = cs.email_cc.split(",")
|
||||
if action.act_email_cc not in emails:# and '<'+str(action.act_email_cc)+">" not in emails:
|
||||
write['email_cc'] = cs.email_cc+','+action.act_email_cc
|
||||
else:
|
||||
write['email_cc'] = action.act_email_cc
|
||||
caseobj.write(cr, uid, [cs.id], write, context)
|
||||
if action.act_remind_user:
|
||||
caseobj.remind_user(cr, uid, [cs.id], context, attach=action.act_remind_attach)
|
||||
if action.act_remind_partner:
|
||||
caseobj.remind_partner(cr, uid, [cs.id], context, attach=action.act_remind_attach)
|
||||
if action.act_method:
|
||||
getattr(caseobj, 'act_method')(cr, uid, [cs.id], action, context)
|
||||
emails = []
|
||||
if action.act_mail_to_user:
|
||||
if cs.user_id and cs.user_id.address_id:
|
||||
emails.append(cs.user_id.address_id.email)
|
||||
if action.act_mail_to_partner:
|
||||
emails.append(cs.email_from)
|
||||
if action.act_mail_to_watchers:
|
||||
emails += (action.act_email_cc or '').split(',')
|
||||
if action.act_mail_to_email:
|
||||
emails += (action.act_mail_to_email or '').split(',')
|
||||
emails = filter(None, emails)
|
||||
if len(emails) and action.act_mail_body:
|
||||
emails = list(set(emails))
|
||||
caseobj.email_send(cr, uid, cs, emails, action.act_mail_body)
|
||||
break
|
||||
action_ids = newactions
|
||||
level -= 1
|
||||
return True
|
||||
|
||||
base_action_rule()
|
||||
|
||||
class base_action_rule_line(osv.osv):
|
||||
_inherit = 'base.action.rule.line'
|
||||
_columns = {
|
||||
'name': fields.char('Rule Name',size=64, required=True),
|
||||
'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, 'Case State', size=16),
|
||||
'trg_state_to': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'Button Pressed', size=16),
|
||||
|
||||
'trg_section_id': fields.many2one('crm.case.section', 'Section'),
|
||||
'trg_max_history': fields.integer('Maximum Communication History'),
|
||||
'trg_categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',trg_section_id)]"),
|
||||
'regex_history' : fields.char('Regular Expression on Case History', size=128),
|
||||
'act_section_id': fields.many2one('crm.case.section', 'Set section to'),
|
||||
'trg_date_type': fields.selection([
|
||||
('none','None'),
|
||||
('create','Creation Date'),
|
||||
|
@ -182,88 +349,9 @@ class crm_case_rule(osv.osv):
|
|||
('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_section_id': fields.many2one('crm.case.section', 'Section'),
|
||||
}
|
||||
|
||||
#'trg_categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',trg_section_id)]"),
|
||||
'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'),
|
||||
'trg_max_history': fields.integer('Maximum Communication History'),
|
||||
|
||||
'act_method': fields.char('Call Object Method', size=64),
|
||||
'act_state': fields.selection([('','')]+AVAILABLE_STATES, 'Set state to', size=16),
|
||||
'act_section_id': fields.many2one('crm.case.section', 'Set section to'),
|
||||
'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(self, cr, uid, ids=False, context={}):
|
||||
'''
|
||||
Function called by the scheduler to process cases for date actions
|
||||
Only works on not done and cancelled cases
|
||||
'''
|
||||
cr.execute('select * from crm_case \
|
||||
where (date_action_last<%s or date_action_last is null) \
|
||||
and (date_action_next<=%s or date_action_next is null) \
|
||||
and state not in (\'cancel\',\'done\')',
|
||||
(time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
time.strftime('%Y-%m-%d %H:%M:%S')))
|
||||
ids2 = map(lambda x: x[0], cr.fetchall() or [])
|
||||
case_obj = self.pool.get('crm.case')
|
||||
cases = case_obj.browse(cr, uid, ids2, context)
|
||||
return case_obj._action(cr, uid, cases, False, context=context)
|
||||
|
||||
|
||||
def _check_mail(self, cr, uid, ids, context=None):
|
||||
caseobj = self.pool.get('crm.case')
|
||||
emptycase = orm.browse_null()
|
||||
for rule in self.browse(cr, uid, ids):
|
||||
if rule.act_mail_body:
|
||||
try:
|
||||
caseobj.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']),
|
||||
]
|
||||
|
||||
crm_case_rule()
|
||||
base_action_rule_line()
|
||||
|
||||
def _links_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.request.link')
|
||||
|
@ -335,9 +423,6 @@ class crm_case(osv.osv):
|
|||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'company_id': fields.many2one('res.company','Company'),
|
||||
}
|
||||
def _get_default_partner_address(self, cr, uid, context):
|
||||
|
@ -427,164 +512,6 @@ class crm_case(osv.osv):
|
|||
value['email_from'] = case.email_from
|
||||
return {'value': value}
|
||||
|
||||
def _action(self, cr, uid, cases, state_to, scrit=None, context={}):
|
||||
if not scrit:
|
||||
scrit = []
|
||||
action_ids = self.pool.get('crm.case.rule').search(cr, uid, scrit)
|
||||
level = MAX_LEVEL
|
||||
while len(action_ids) and level:
|
||||
newactions = []
|
||||
actions = self.pool.get('crm.case.rule').browse(cr, uid, action_ids, context)
|
||||
for case in cases:
|
||||
for action in actions:
|
||||
ok = True
|
||||
ok = ok and (not action.trg_state_from or action.trg_state_from==case.state)
|
||||
ok = ok and (not action.trg_state_to or action.trg_state_to==state_to)
|
||||
ok = ok and (not action.trg_section_id or action.trg_section_id.id==case.section_id.id)
|
||||
ok = ok and (not action.trg_categ_id or action.trg_categ_id.id==case.categ_id.id)
|
||||
ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==case.user_id.id)
|
||||
ok = ok and (not action.trg_partner_id.id or action.trg_partner_id.id==case.partner_id.id)
|
||||
ok = ok and (not action.trg_max_history or action.trg_max_history<=(len(case.history_line)+1))
|
||||
ok = ok and (
|
||||
not action.trg_partner_categ_id.id or
|
||||
(
|
||||
case.partner_id.id and
|
||||
(action.trg_partner_categ_id.id in map(lambda x: x.id, case.partner_id.category_id or []))
|
||||
)
|
||||
)
|
||||
ok = ok and (not action.trg_priority_from or action.trg_priority_from>=case.priority)
|
||||
ok = ok and (not action.trg_priority_to or action.trg_priority_to<=case.priority)
|
||||
|
||||
reg_name = action.regex_name
|
||||
result_name = True
|
||||
if reg_name:
|
||||
ptrn = re.compile(str(reg_name))
|
||||
_result = ptrn.search(str(case.name))
|
||||
if not _result:
|
||||
result_name = False
|
||||
regex_n = not reg_name or result_name
|
||||
ok = ok and regex_n
|
||||
|
||||
reg_history = action.regex_history
|
||||
result_history = True
|
||||
if reg_history:
|
||||
ptrn = re.compile(str(reg_history))
|
||||
if case.history_line:
|
||||
_result = ptrn.search(str(case.history_line[0].description))
|
||||
if not _result:
|
||||
result_history = False
|
||||
regex_h = not reg_history or result_history
|
||||
ok = ok and regex_h
|
||||
|
||||
if not ok:
|
||||
continue
|
||||
|
||||
base = False
|
||||
if action.trg_date_type=='create':
|
||||
base = mx.DateTime.strptime(case.create_date[:19], '%Y-%m-%d %H:%M:%S')
|
||||
elif action.trg_date_type=='action_last':
|
||||
if case.date_action_last:
|
||||
base = mx.DateTime.strptime(case.date_action_last, '%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
base = mx.DateTime.strptime(case.create_date[:19], '%Y-%m-%d %H:%M:%S')
|
||||
elif action.trg_date_type=='deadline' and case.date_deadline:
|
||||
base = mx.DateTime.strptime(case.date_deadline, '%Y-%m-%d %H:%M:%S')
|
||||
elif action.trg_date_type=='date' and case.date:
|
||||
base = mx.DateTime.strptime(case.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')
|
||||
ok = (dt <= time.strftime('%Y-%m-%d %H:%M:%S')) and \
|
||||
((not case.date_action_next) or \
|
||||
(dt >= case.date_action_next and \
|
||||
case.date_action_last < case.date_action_next))
|
||||
if not ok:
|
||||
if not case.date_action_next or dt < case.date_action_next:
|
||||
case.date_action_next = dt
|
||||
self.write(cr, uid, [case.id], {'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)
|
||||
write = {}
|
||||
if action.act_state:
|
||||
case.state = action.act_state
|
||||
write['state'] = action.act_state
|
||||
if action.act_section_id:
|
||||
case.section_id = action.act_section_id
|
||||
write['section_id'] = action.act_section_id.id
|
||||
if action.act_user_id:
|
||||
case.user_id = action.act_user_id
|
||||
write['user_id'] = action.act_user_id.id
|
||||
if action.act_priority:
|
||||
case.priority = action.act_priority
|
||||
write['priority'] = action.act_priority
|
||||
if action.act_email_cc:
|
||||
if '@' in (case.email_cc or ''):
|
||||
emails = case.email_cc.split(",")
|
||||
if action.act_email_cc not in emails:# and '<'+str(action.act_email_cc)+">" not in emails:
|
||||
write['email_cc'] = case.email_cc+','+action.act_email_cc
|
||||
else:
|
||||
write['email_cc'] = action.act_email_cc
|
||||
write['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
self.write(cr, uid, [case.id], write, context)
|
||||
caseobj = self.pool.get('crm.case')
|
||||
if action.act_remind_user:
|
||||
caseobj.remind_user(cr, uid, [case.id], context, attach=action.act_remind_attach)
|
||||
if action.act_remind_partner:
|
||||
caseobj.remind_partner(cr, uid, [case.id], context, attach=action.act_remind_attach)
|
||||
if action.act_method:
|
||||
getattr(caseobj, 'act_method')(cr, uid, [case.id], action, context)
|
||||
emails = []
|
||||
if action.act_mail_to_user:
|
||||
if case.user_id and case.user_id.address_id:
|
||||
emails.append(case.user_id.address_id.email)
|
||||
if action.act_mail_to_partner:
|
||||
emails.append(case.email_from)
|
||||
if action.act_mail_to_watchers:
|
||||
emails += (action.act_email_cc or '').split(',')
|
||||
if action.act_mail_to_email:
|
||||
emails += (action.act_mail_to_email or '').split(',')
|
||||
emails = filter(None, emails)
|
||||
if len(emails) and action.act_mail_body:
|
||||
emails = list(set(emails))
|
||||
self.email_send(cr, uid, case, emails, action.act_mail_body)
|
||||
break
|
||||
action_ids = newactions
|
||||
level -= 1
|
||||
return True
|
||||
|
||||
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 __history(self, cr, uid, cases, keyword, history=False, email=False, details=None, context={}):
|
||||
model_obj = self.pool.get('ir.model')
|
||||
for case in cases:
|
||||
|
@ -612,7 +539,8 @@ class crm_case(osv.osv):
|
|||
res = super(crm_case, self).create(cr, uid, *args, **argv)
|
||||
cases = self.browse(cr, uid, [res])
|
||||
cases[0].state # to fill the browse record cache
|
||||
self._action(cr,uid, cases, 'draft')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr,uid, cases, 'draft')
|
||||
return res
|
||||
|
||||
def remind_partner(self, cr, uid, ids, context={}, attach=False):
|
||||
|
@ -745,7 +673,8 @@ class crm_case(osv.osv):
|
|||
#
|
||||
# We use the cache of cases to keep the old case state
|
||||
#
|
||||
self._action(cr,uid, cases, 'done')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr,uid, cases, 'done')
|
||||
return True
|
||||
|
||||
def case_escalate(self, cr, uid, ids, *args):
|
||||
|
@ -761,7 +690,8 @@ class crm_case(osv.osv):
|
|||
self.write(cr, uid, ids, data)
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self.__history(cr, uid, cases, _('Escalate'))
|
||||
self._action(cr, uid, cases, 'escalate')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr, uid, cases, 'escalate')
|
||||
return True
|
||||
|
||||
|
||||
|
@ -773,7 +703,8 @@ class crm_case(osv.osv):
|
|||
if not case.user_id:
|
||||
data['user_id'] = uid
|
||||
self.write(cr, uid, ids, data)
|
||||
self._action(cr,uid, cases, 'open')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr,uid, cases, 'open')
|
||||
return True
|
||||
|
||||
|
||||
|
@ -782,7 +713,8 @@ class crm_case(osv.osv):
|
|||
cases[0].state # to fill the browse record cache
|
||||
self.__history(cr, uid, cases, _('Cancel'))
|
||||
self.write(cr, uid, ids, {'state':'cancel', 'active':True})
|
||||
self._action(cr,uid, cases, 'cancel')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr,uid, cases, 'cancel')
|
||||
return True
|
||||
|
||||
def case_pending(self, cr, uid, ids, *args):
|
||||
|
@ -790,7 +722,8 @@ class crm_case(osv.osv):
|
|||
cases[0].state # to fill the browse record cache
|
||||
self.__history(cr, uid, cases, _('Pending'))
|
||||
self.write(cr, uid, ids, {'state':'pending', 'active':True})
|
||||
self._action(cr,uid, cases, 'pending')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr,uid, cases, 'pending')
|
||||
return True
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
|
@ -798,7 +731,8 @@ class crm_case(osv.osv):
|
|||
cases[0].state # to fill the browse record cache
|
||||
self.__history(cr, uid, cases, _('Draft'))
|
||||
self.write(cr, uid, ids, {'state':'draft', 'active':True})
|
||||
self._action(cr, uid, cases, 'draft')
|
||||
obj = self.pool.get('base.action.rule')
|
||||
obj._action(cr, uid, cases, 'draft')
|
||||
return True
|
||||
crm_case()
|
||||
|
||||
|
@ -909,6 +843,3 @@ class users(osv.osv):
|
|||
'context_section_id': fields.selection(_section_get, 'Sales Section'),
|
||||
}
|
||||
users()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -59,17 +59,6 @@
|
|||
<record id="event_type_case_cancel" model="res.partner.event.type">
|
||||
<field eval="False" name="active"/>
|
||||
</record>
|
||||
|
||||
<record id="ir_cron_crm_action" model="ir.cron">
|
||||
<field name="name">Check cases rules</field>
|
||||
<field name="interval_number">4</field>
|
||||
<field name="interval_type">hours</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
<field eval="'crm.case.rule'" name="model"/>
|
||||
<field eval="'_check'" name="function"/>
|
||||
<field eval="'()'" name="args"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -133,105 +133,45 @@
|
|||
|
||||
|
||||
<!-- Case rules -->
|
||||
<record id="crm_case_rule-view" model="ir.ui.view">
|
||||
<field name="name">crm.case.rule.form</field>
|
||||
<field name="model">crm.case.rule</field>
|
||||
<record id="view_base_action_rule_line_form1" model="ir.ui.view">
|
||||
<field name="name">base.action.rule.line.form.inherit</field>
|
||||
<field name="model">base.action.rule.line</field>
|
||||
<field name="inherit_id" ref="base_action_rule.view_base_action_rule_line_form"/>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Case Rule">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="2"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Conditions">
|
||||
<separator colspan="4" string="Conditions on States"/>
|
||||
<field name="trg_state_from" select="2"/>
|
||||
<field name="trg_state_to" select="2"/>
|
||||
|
||||
<separator colspan="4" string="Conditions on Case Fields"/>
|
||||
<field name="regex_name" string="Regex on Case Name" colspan="2"/>
|
||||
<field name="trg_section_id" select="1" widget="selection"/>
|
||||
<!--<field name="trg_categ_id"/>-->
|
||||
<field name="trg_user_id" select="2"/>
|
||||
<separator colspan="4" string="Conditions on Case Partner"/>
|
||||
<field name="trg_partner_id"/>
|
||||
<field name="trg_partner_categ_id"/>
|
||||
<separator colspan="4" string="Conditions on Priority Range"/>
|
||||
<field name="trg_priority_from"/>
|
||||
<field name="trg_priority_to"/>
|
||||
<separator colspan="4" string="Conditions on Timing"/>
|
||||
<field name="trg_date_type"/>
|
||||
<label align="1.0" string="Delay After Trigger Date:"/>
|
||||
<group col="2" colspan="1">
|
||||
<field name="trg_date_range" nolabel="1"/>
|
||||
<field name="trg_date_range_type" nolabel="1"/>
|
||||
</group>
|
||||
<separator colspan="4" string="Condition on Communication History"/>
|
||||
<field name="regex_history" string="Regex on Communication History"/>
|
||||
<field name="trg_max_history"/>
|
||||
<separator colspan="4" string="Note"/>
|
||||
<label align="0.0" string="The rule use a AND operator. The case must match all non empty fields so that the rule execute the action described in the 'Actions' tab." colspan="4"/>
|
||||
</page>
|
||||
<page string="Actions">
|
||||
<separator colspan="4" string="Fields to Change"/>
|
||||
<field name="act_state"/>
|
||||
<field name="act_section_id"/>
|
||||
<field name="act_user_id"/>
|
||||
<field name="act_priority"/>
|
||||
<separator colspan="4" string="E-Mail Reminders (includes the content of the case)"/>
|
||||
<field name="act_remind_user"/>
|
||||
<field name="act_remind_partner"/>
|
||||
<field name="act_remind_attach"/>
|
||||
<field colspan="4" name="act_email_cc"/>
|
||||
<separator colspan="4" string="Server Action to be Triggered"/>
|
||||
<field name="server_action_id"/>
|
||||
<!--
|
||||
<field name="act_method" colspan="4" readonly="1"/>
|
||||
-->
|
||||
</page>
|
||||
<page string="E-Mail Actions">
|
||||
<separator colspan="4" string="Template of Email to Send"/>
|
||||
<field name="act_mail_to_user"/>
|
||||
<field name="act_mail_to_partner"/>
|
||||
<field name="act_mail_to_watchers"/>
|
||||
<field colspan="4" name="act_mail_to_email"/>
|
||||
<field colspan="4" name="act_mail_body"/>
|
||||
|
||||
<separator colspan="4" string="Special Keywords to Be Used in The Body"/>
|
||||
<label align="0.0" string="%%(case_id)s = Case ID" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_subject)s = Case subject" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_description)s = Case description" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_date)s = Creation date" colspan="2"/>
|
||||
<label align="0.0" string="%%(email_from)s = Partner email" colspan="2"/>
|
||||
<label align="0.0" string="%%(partner)s = Partner name" colspan="2"/>
|
||||
<label align="0.0" string="%%(partner_email)s = Partner email" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_user)s = Responsible name" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_user_email)s = Responsible email" colspan="2"/>
|
||||
<label align="0.0" string="%%(case_user_phone)s = Responsible phone" colspan="2"/>
|
||||
<label align="0.0" string="%% = The '%%' Character" colspan="2"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_rule_tree-view" model="ir.ui.view">
|
||||
<field name="name">crm.case.rule.tree</field>
|
||||
<field name="model">crm.case.rule</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="trg_priority_to" position="after">
|
||||
<separator colspan="4" string="Condition on Communication History"/>
|
||||
<field name="regex_history"/>
|
||||
<field name="trg_max_history"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_base_action_rule_line_form2" model="ir.ui.view">
|
||||
<field name="name">base.action.rule.line.form2.inherit</field>
|
||||
<field name="model">base.action.rule.line</field>
|
||||
<field name="inherit_id" ref="base_action_rule.view_base_action_rule_line_form"/>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Case Rule">
|
||||
<field name="name"/>
|
||||
<field name="active"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_rule-act" model="ir.actions.act_window">
|
||||
<field name="name">Rules</field>
|
||||
<field name="res_model">crm.case.rule</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_rule_tree-view"/>
|
||||
</record>
|
||||
<menuitem action="crm_case_rule-act" id="menu_crm_case_rule-act" parent="crm.menu_crm_configuration"/>
|
||||
|
||||
<field name="regex_name" position="after">
|
||||
<field name="trg_section_id" select="1" widget="selection"/>
|
||||
<field name="trg_categ_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_base_action_rule_line_form3" model="ir.ui.view">
|
||||
<field name="name">base.action.rule.line.form3.inherit</field>
|
||||
<field name="model">base.action.rule.line</field>
|
||||
<field name="inherit_id" ref="base_action_rule.view_base_action_rule_line_form"/>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="act_state" position="after">
|
||||
<field name="act_section_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_crm_email_add_cc_wizard" model="ir.ui.view">
|
||||
<field name="name">Add CC</field>
|
||||
<field name="model">crm.email.add.cc</field>
|
||||
|
@ -377,8 +317,6 @@
|
|||
<field name="active" select="2"/>
|
||||
<separator colspan="4" string="Dates"/>
|
||||
<field name="create_date"/>
|
||||
<field name="date_action_last"/>
|
||||
<field name="date_action_next"/>
|
||||
<field colspan="4" name="log_ids" nolabel="1">
|
||||
<form string="Actions">
|
||||
<separator colspan="4" string="Action Information"/>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"access_crm_segmentation_line","crm.segmentation.line","model_crm_segmentation_line","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_case_section","crm.case.section","model_crm_case_section","crm.group_crm_user",1,0,0,0
|
||||
"access_crm_case_categ","crm.case.categ","model_crm_case_categ","crm.group_crm_user",1,0,0,0
|
||||
"access_crm_case_rule","crm.case.rule","model_crm_case_rule","crm.group_crm_user",1,0,0,0
|
||||
"access_crm_case_manger","crm.case manager","model_crm_case","crm.group_crm_user",1,1,1,1
|
||||
"access_crm_case","crm.case","model_crm_case","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_claim","crm.claim","model_crm_claim","crm.group_crm_manager",1,1,1,1
|
||||
|
@ -17,7 +16,6 @@
|
|||
"access_crm_case_history","crm.case.history","model_crm_case_history","crm.group_crm_user",1,1,1,1
|
||||
"access_crm_case_section_manager","crm.case.section.manager","model_crm_case_section","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_case_categ_manager","crm.case.categ.manager","model_crm_case_categ","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_case_rule_manager","crm.case.rule.manager","model_crm_case_rule","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_case_log_manager","crm.case.log manager","model_crm_case_log","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_case_history_manager","crm.case.history manager","model_crm_case_history","crm.group_crm_manager",1,1,1,1
|
||||
"access_crm_email_add_cc_manager","crm.email.add.cc","model_crm_email_add_cc","crm.group_crm_manager",1,1,1,1
|
||||
|
|
|
Loading…
Reference in New Issue