]
class crm_case(object):
- """A simple python class to be used for common functions """
+ """A python class to be used as common abstract class for CRM business objects"""
def _find_lost_stage(self, cr, uid, type, section_id):
return self._find_percent_stage(cr, uid, 0.0, type, section_id)
return self._find_percent_stage(cr, uid, 100.0, type, section_id)
def _find_percent_stage(self, cr, uid, percent, type, section_id):
- """
- Return the first stage with a probability == percent
- """
+ """Return the first stage with a probability == percent"""
stage_pool = self.pool.get('crm.case.stage')
if section_id :
ids = stage_pool.search(cr, uid, [("probability", '=', percent), ("type", 'like', type), ("section_ids", 'in', [section_id])])
def _find_first_stage(self, cr, uid, type, section_id):
- """
- return the first stage that has a sequence number equal or higher than sequence
- """
+ """Returns the first stage that has a sequence number equal or higher than sequence"""
stage_pool = self.pool.get('crm.case.stage')
if section_id :
ids = stage_pool.search(cr, uid, [("sequence", '>', 0), ("type", 'like', type), ("section_ids", 'in', [section_id])])
return False
def onchange_stage_id(self, cr, uid, ids, stage_id, context={}):
-
- """ @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of stage’s IDs
- @stage_id: change state id on run time """
-
if not stage_id:
return {'value':{}}
return {'value':{'probability': stage.probability}}
def _get_default_partner_address(self, cr, uid, context=None):
-
- """Gives id of default address for current user
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Gives id of default address for current user"""
if context is None:
context = {}
if not context.get('portal', False):
return self.pool.get('res.users').browse(cr, uid, uid, context).address_id.id
def _get_default_partner(self, cr, uid, context=None):
- """Gives id of partner for current user
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Gives id of partner for current user"""
if context is None:
context = {}
if not context.get('portal', False):
return user.address_id.partner_id.id
def copy(self, cr, uid, id, default=None, context=None):
- """
- Overrides orm copy method.
- @param self: the object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param id: Id of mailgate thread
- @param default: Dictionary of default values for copy.
- @param context: A standard dictionary for contextual values
- """
- if context is None:
- context = {}
+ """Overrides orm copy method to avoid copying messages,
+ as well as date_closed and date_open columns if they
+ exist."""
if default is None:
default = {}
return super(osv.osv, self).copy(cr, uid, id, default, context=context)
def _get_default_email(self, cr, uid, context=None):
- """Gives default email address for current user
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
- if not context.get('portal', False):
+ """Gives default email address for current user"""
+ if context and not context.get('portal'):
return False
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
if not user.address_id:
return user.address_id.email
def _get_default_user(self, cr, uid, context=None):
- """Gives current user id
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
- if context and context.get('portal', False):
+ if context and context.get('portal'):
return False
return uid
def _get_section(self, cr, uid, context=None):
- """Gives section id for current User
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Gives section id for current User"""
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.context_section_id.id or False
return self._find_next_stage(cr, uid, stage_list, index + 1, current_seq, stage_pool)
def stage_change(self, cr, uid, ids, context=None, order='sequence'):
- if context is None:
- context = {}
-
stage_pool = self.pool.get('crm.case.stage')
stage_type = context and context.get('stage_type','')
current_seq = False
def stage_next(self, cr, uid, ids, context=None):
"""This function computes next stage for case from its current stage
- using available stage for that case type
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param context: A standard dictionary for contextual values"""
+ using available stage for that case type
+ """
return self.stage_change(cr, uid, ids, context=context, order='sequence')
def stage_previous(self, cr, uid, ids, context=None):
"""This function computes previous stage for case from its current stage
- using available stage for that case type
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param context: A standard dictionary for contextual values"""
+ using available stage for that case type
+ """
return self.stage_change(cr, uid, ids, context=context, order='sequence desc')
def onchange_partner_id(self, cr, uid, ids, part, email=False):
"""This function returns value of partner address based on partner
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param part: Partner's id
- @email: Partner's email ID
+
+ :param part: Partner id
+ :param email: unused
"""
data={}
if part:
return {'value': data}
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
- """This function returns value of partner email based on Partner Address
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param add: Id of Partner's address
- @email: Partner's email ID
+ """Set partner email and phone based on selected address
+
+ :param add: selected address id
+ :param email: unused
"""
if not add:
return {'value': {'email_from': False}}
return {'value': {'phone': address.phone}}
def case_open(self, cr, uid, ids, *args):
- """Opens Case
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
-
+ """Opens Case"""
cases = self.browse(cr, uid, ids)
self.history(cr, uid, cases, _('Open'))
for case in cases:
if not case.user_id:
data['user_id'] = uid
self.write(cr, uid, case.id, data)
-
-
self._action(cr, uid, cases, 'open')
return True
def case_close(self, cr, uid, ids, *args):
- """Closes Case
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
+ """Closes Case"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.history(cr, uid, cases, _('Close'))
return True
def case_escalate(self, cr, uid, ids, *args):
- """Escalates case to top level
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
+ """Escalates case to parent level"""
cases = self.browse(cr, uid, ids)
for case in cases:
data = {'active': True}
-
if case.section_id.parent_id:
data['section_id'] = case.section_id.parent_id.id
if case.section_id.parent_id.change_responsible:
return True
def case_cancel(self, cr, uid, ids, *args):
- """Cancels Case
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
+ """Cancels Case"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.history(cr, uid, cases, _('Cancel'))
return True
def case_pending(self, cr, uid, ids, *args):
- """Marks case as pending
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
+ """Marks case as pending"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.history(cr, uid, cases, _('Pending'))
return True
def case_reset(self, cr, uid, ids, *args):
- """Resets case as draft
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
- """
+ """Resets case as draft"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.history(cr, uid, cases, _('Draft'))
return True
def remind_partner(self, cr, uid, ids, context=None, attach=False):
-
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Remind Partner's IDs
- @param context: A standard dictionary for contextual values
-
- """
-
return self.remind_user(cr, uid, ids, context, attach,
destination=False)
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case's IDs to remind
- @param context: A standard dictionary for contextual values
- """
- email_message_obj = self.pool.get('email.message')
+ mail_message = self.pool.get('mail.message')
for case in self.browse(cr, uid, ids, context=context):
if not destination and not case.email_from:
raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Case"))
# Send an email
subject = "Reminder: [%s] %s" % (str(case.id), case.name, )
- email_message_obj.schedule_with_attach(cr, uid,
+ mail_message.schedule_with_attach(cr, uid,
src,
[dest],
subject,
body,
model='crm.case',
reply_to=case.section_id.reply_to,
- openobject_id=str(case.id),
- attach=attach_to_send
+ res_id=str(case.id),
+ attachments=attach_to_send
)
return True
def _check(self, cr, uid, ids=False, context=None):
- """
- Function called by the scheduler to process cases for date actions
- Only works on not done and cancelled cases
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
+ """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) \
return self.pool.get('base.action.rule').format_mail(obj, body)
def thread_followers(self, cr, uid, ids, context=None):
- """ Get a list of emails of the people following this thread
- """
res = {}
for case in self.browse(cr, uid, ids, context=context):
l=[]
class crm_case_stage(osv.osv):
- """ Stage of case """
+ """Stage of case"""
_name = "crm.case.stage"
_description = "Stage of case"
_rec_name = 'name'
_order = "sequence"
-
-
def _get_type_value(self, cr, user, context):
return [('lead','Lead'),('opportunity','Opportunity')]
-
_columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
'type': fields.selection(_get_type_value, 'Type', required=True),
}
-
def _find_stage_type(self, cr, uid, context=None):
- """Finds type of stage according to object.
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Finds type of stage according to record"""
type = context and context.get('type', '') or ''
return type
'type': _find_stage_type,
}
-crm_case_stage()
-
class crm_case_section(osv.osv):
"""Sales Team"""
('code_uniq', 'unique (code)', 'The code of the sales team must be unique !')
]
- def _check_recursion(self, cr, uid, ids, context=None):
-
- """
- Checks for recursion level for sales team
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Sales team ids
- """
- level = 100
-
- while len(ids):
- cr.execute('select distinct parent_id from crm_case_section where id IN %s', (tuple(ids),))
- ids = filter(None, map(lambda x: x[0], cr.fetchall()))
- if not level:
- return False
- level -= 1
-
- return True
-
_constraints = [
- (_check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
+ (osv.osv._check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
]
def name_get(self, cr, uid, ids, context=None):
- """Overrides orm name_get method
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of sales team ids
- """
- if context is None:
- context = {}
+ """Overrides orm name_get method"""
if not isinstance(ids, list) :
ids = [ids]
res = []
res.append((record['id'], name))
return res
-crm_case_section()
-
class crm_case_categ(osv.osv):
- """ Category of Case """
+ """Category of Case"""
_name = "crm.case.categ"
_description = "Category of Case"
_columns = {
}
def _find_object_id(self, cr, uid, context=None):
- """Finds id for case object
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
-
+ """Finds id for case object"""
object_id = context and context.get('object_id', False) or False
ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
return ids and ids[0]
_defaults = {
'object_id' : _find_object_id
-
}
-crm_case_categ()
-
class crm_case_stage(osv.osv):
_inherit = "crm.case.stage"
'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', 'Sections'),
}
-crm_case_stage()
-
-
class crm_case_resource_type(osv.osv):
- """ Resource Type of case """
+ """Resource Type of case"""
_name = "crm.case.resource.type"
_description = "Campaign"
_rec_name = "name"
'name': fields.char('Campaign Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
-crm_case_resource_type()
-
def _links_get(self, cr, uid, context=None):
- """Gets links value for reference field
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Gets links value for reference field"""
obj = self.pool.get('res.request.link')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['object', 'name'], context)
def create(self, cr, uid, vals, context=None):
res = super(users, self).create(cr, uid, vals, context=context)
section_obj=self.pool.get('crm.case.section')
-
- if vals.get('context_section_id', False):
+ if vals.get('context_section_id'):
section_obj.write(cr, uid, [vals['context_section_id']], {'member_ids':[(4, res)]}, context)
return res
-users()
class res_partner(osv.osv):
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
-res_partner()
-
'regex_history' : fields.char('Regular Expression on Case History', size=128),
'act_section_id': fields.many2one('crm.case.section', 'Set Team to'),
'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'),
- '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_partner': fields.boolean('Mail to Partner',
+ help="Check this if you want the rule to send an email to the partner."),
}
-
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context=None):
- email_message_obj = self.pool.get('email.message')
+ mail_message = self.pool.get('mail.message')
body = self.format_mail(obj, body)
if not emailfrom:
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email:
else:
reply_to = emailfrom
if not emailfrom:
- raise osv.except_osv(_('Error!'),
- _("No E-Mail ID Found for your Company address!"))
- return email_message_obj.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, openobject_id=str(obj.id))
+ raise osv.except_osv(_('Error!'), _("No E-Mail Found for your Company address!"))
+ return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, res_id=str(obj.id))
def do_check(self, cr, uid, action, obj, context=None):
- """ @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values"""
ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context)
if hasattr(obj, 'section_id'):
#Cheking for history
regex = action.regex_history
- result_history = True
if regex:
res = False
ptrn = re.compile(str(regex))
if _result:
res = True
break
- result_history = res
- ok = ok and (not regex or result_history)
+ ok = ok and res
- res_count = True
if action.trg_max_history:
res_count = False
- history_ids = filter(lambda x: x.history, obj.message_ids)
+ history_ids = filter(lambda x: x.email_from, obj.message_ids)
if len(history_ids) <= action.trg_max_history:
res_count = True
- ok = ok and res_count
+ ok = ok and res_count
return ok
def do_action(self, cr, uid, action, model_obj, obj, context=None):
- """ @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context)
write = {}
def state_get(self, cr, uid, context=None):
- """Gets available states for crm
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
+ """Gets available states for crm"""
res = super(base_action_rule, self).state_get(cr, uid, context=context)
return res + crm.AVAILABLE_STATES
def priority_get(self, cr, uid, context=None):
- """@param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
res = super(base_action_rule, self).priority_get(cr, uid, context=context)
return res + crm.AVAILABLE_PRIORITIES
-base_action_rule()
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "date_action, priority, id desc"
- _inherit = ['email.thread','res.partner.address']
+ _inherit = ['mail.thread','res.partner.address']
def _compute_day(self, cr, uid, ids, fields, args, context=None):
"""
@param cr: the current row, from the database cursor,
def _history_search(self, cr, uid, obj, name, args, context=None):
res = []
- msg_obj = self.pool.get('email.message')
- message_ids = msg_obj.search(cr, uid, [('history','=',True), ('subject', args[0][1], args[0][2])], context=context)
+ msg_obj = self.pool.get('mail.message')
+ message_ids = msg_obj.search(cr, uid, [('email_from','!=',False), ('subject', args[0][1], args[0][2])], context=context)
lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context)
if lead_ids:
for obj in self.browse(cr, uid, ids, context=context):
res[obj.id] = ''
for msg in obj.message_ids:
- if msg.history:
+ if msg.email_from:
res[obj.id] = msg.subject
break
return res
\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\'.'),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', method=True, type='char', size=64),
}
if 'stage_id' in vals and vals['stage_id']:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
- self.history(cr, uid, ids, _("Changed Stage to: %s") % stage_obj.name, details=_("Changed Stage to: %s") % stage_obj.name)
+ text = _("Changed Stage to: %s") % stage_obj.name
+ self.history(cr, uid, ids, text, body_text=text)
message=''
for case in self.browse(cr, uid, ids, context=context):
if case.type == 'lead' or context.get('stage_type',False)=='lead':
_('You can not delete this lead. You should better cancel it.'))
return super(crm_lead, self).unlink(cr, uid, ids, context)
- def message_new(self, cr, uid, msg, context=None):
- """
- Automatically calls when new email message arrives
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks
- @param msg: dictionary object to contain email message data
- """
- thread_pool = self.pool.get('email.thread')
-
+ def message_new(self, cr, uid, msg, custom_values=None, context=None):
+ """Automatically calls when new email message arrives"""
+ res_id = super(crm_lead, self).message_new(cr, uid, msg,
+ custom_values=custom_values,
+ context=context)
+ mail_thread = self.pool.get('mail.thread')
subject = msg.get('subject')
- body = msg.get('body')
+ body = msg.get('body_text')
msg_from = msg.get('from')
priority = msg.get('priority')
-
vals = {
'name': subject,
'email_from': msg_from,
}
if msg.get('priority', False):
vals['priority'] = priority
-
- res = thread_pool.get_partner(cr, uid, msg.get('from', False))
+ res = mail_thread.get_partner(cr, uid, msg.get('from', False))
if res:
vals.update(res)
-
- res_id = self.create(cr, uid, vals, context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, [res_id], _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
-
+ res_id = self.write(cr, uid, [res_id], vals, context)
return res_id
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of update mail’s IDs
- """
if isinstance(ids, (str, int, long)):
ids = [ids]
+ super(crm_lead, self).message_update(cr, uid, msg,
+ custom_values=custom_values,
+ context=context)
+
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
vals['priority'] = msg.get('priority')
-
maps = {
'cost':'planned_cost',
'revenue': 'planned_revenue',
'probability':'probability'
}
vls = {}
- for line in msg['body'].split('\n'):
+ for line in msg['body_text'].split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
if case.state in CRM_LEAD_PENDING_STATES:
values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
res = self.write(cr, uid, [case.id], values, context=context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, ids, _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
return res
def on_change_optin(self, cr, uid, ids, optin):
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="History">
<field name="display_text" string="History Information"/>
- <field name="history" invisible="1"/>
<button
- string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
+ string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action" />
</tree>
-
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
<field name="email_to" size="512"/>
<field name="email_cc" size="512"/>
- <field name="subject" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
- <field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
- <field name="history" invisible="1"/>
+ <field name="subject" colspan="4" widget="char" attrs="{'invisible': [('email_from', '=', False)]}" size="512"/>
+ <field name="display_text" colspan="4" attrs="{'invisible': [('email_from', '!=', False)]}"/>
</group>
<notebook colspan="4">
<page string="Details">
- <field name="body" colspan="4" nolabel="1"/>
- <group attrs="{'invisible': [('history', '!=', True)]}">
+ <field name="body_text" colspan="4" nolabel="1"/>
+ <group attrs="{'invisible': [('email_from', '=', False)]}">
<button colspan="4" string="Reply"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply'}"
_name = 'crm.meeting'
_description = "Meeting"
_order = "id desc"
- _inherit = ['email.thread',"calendar.event"]
+ _inherit = ['mail.thread',"calendar.event"]
_columns = {
# From crm.case
'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
'event_id', 'attendee_id', 'Attendees', states={'done': [('readonly', True)]}),
'date_closed': fields.datetime('Closed', readonly=True),
'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
'state': fields.selection([('open', 'Confirmed'),
('draft', 'Unconfirmed'),
('cancel', 'Cancelled'),
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="History">
<field name="display_text" string="History Information"/>
- <field name="history" invisible="1"/>
- <button string="Reply"
+ <button string="Reply" attrs="{'invisible': [('email_from', '=', False)]}
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action"/>
<field name="date"/>
<field name="email_to" size="512"/>
<field name="email_cc" size="512"/>
-
- <field name="subject" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
- <field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
- <field name="history" invisible="1"/>
+ <field name="subject" colspan="4" widget="char" attrs="{'invisible': [('email_from', '=', False)]}" size="512"/>
+ <field name="display_text" colspan="4" attrs="{'invisible': [('email_from', '!=', False)]}"/>
</group>
<notebook colspan="4">
<page string="Details">
- <field name="body" colspan="4" nolabel="1"/>
- <group attrs="{'invisible': [('history', '!=', True)]}">
+ <field name="body_text" colspan="4" nolabel="1"/>
+ <group attrs="{'invisible': [('email_from', '=', False)]}">
<button colspan="4"
string="Reply"
name="%(mail.action_email_compose_message_wizard)d"
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
- _inherit = ['email.thread']
+ _inherit = ['mail.thread']
_columns = {
# From crm.case
'id': fields.integer('ID'),
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Opportunity'),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
}
_defaults = {
<notebook colspan="4">
<page string="Sales Team">
<group col="2" colspan="1">
- <separator string="Mailgateway" colspan="2"/>
+ <separator string="Mail Gateway" colspan="2"/>
<field name="reply_to" select="2"/>
</group>
<group col="2" colspan="1">
c.planned_revenue,
c.planned_revenue*(c.probability/100) as probable_revenue,
1 as nbr,
- (SELECT count(id) FROM email_message WHERE model='crm.lead' AND res_id=c.id AND history=True) AS email,
+ (SELECT count(id) FROM mail_message WHERE model='crm.lead' AND res_id=c.id AND email_from is not null) AS email,
date_trunc('day',c.create_date) as create_date,
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
abs(extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24)) as delay_expected,
"access_res_partner_manager","res.partner.crm.manager","base.model_res_partner","base.group_sale_manager",1,0,0,0
"access_res_partner_address_manager","res.partner.address.crm.user.manager","base.model_res_partner_address","base.group_sale_manager",1,0,0,0
"access_res_partner_category_manager","res.partner.category.crm.manager","base.model_res_partner_category","base.group_sale_manager",1,0,0,0
-"email_email_message_manager","mail.email.message.manager","mail.model_email_message","base.group_sale_manager",1,0,0,0
-"email_thread_manager","mail.thread.manager","mail.model_email_thread","base.group_sale_manager",1,1,1,1
+"mail_mail_message_manager","mail.message.manager","mail.model_mail_message","base.group_sale_manager",1,0,0,0
+"mail_thread_manager","mail.thread.manager","mail.model_mail_thread","base.group_sale_manager",1,1,1,1
"access_calendar_attendee_crm_user","calendar.attendee.crm.user","model_calendar_attendee","base.group_sale_salesman",1,1,1,0
"access_calendar_attendee_crm_manager","calendar.attendee.crm.manager","model_calendar_attendee","base.group_sale_manager",1,1,1,1
"access_res_partner","res.partner.crm.user","base.model_res_partner","base.group_sale_salesman",1,1,1,0
"access_res_partner_address","res.partner.address.crm.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0
"access_res_partner_category","res.partner.category.crm.user","base.model_res_partner_category","base.group_sale_salesman",1,1,1,0
-"email_mailgate_thread","email.thread","mail.model_email_thread","base.group_sale_salesman",1,1,1,1
-"email_gateway_email_message_user","mail.email.message.user","mail.model_email_message","base.group_sale_salesman",1,1,1,1
+"mail_mailgate_thread","mail.thread","mail.model_mail_thread","base.group_sale_salesman",1,1,1,1
+"mail_gateway_mail_message_user","mail.message.user","mail.model_mail_message","base.group_sale_salesman",1,1,1,1
"access_crm_case_categ_manager","crm.case.categ manager","model_crm_case_categ","base.group_sale_manager",1,1,1,1
"access_base_action_rule_manager","base.action.rule manager","model_base_action_rule","base.group_sale_manager",1,1,1,1
"access_crm_lead_report_user","crm.lead.report user","model_crm_lead_report","base.group_sale_salesman",1,1,1,1
from osv import fields, osv
from tools.translate import _
import base64
+from mail.mail_message import truncate_text
AVAILABLE_STATES = crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')]
context=context)
case = case_list[0]
user_obj = self.pool.get('res.users')
- user_name = user_obj.browse(cr, uid, [uid], context=context)[0].name
attach = dict(
(x.name, base64.decodestring(x.binary)) for x in obj.attachment_ids
)
- case_pool.history(cr, uid, [case], self.pool.get('email.message').truncate_data(cr, uid, obj.body, context=context), history=False,
- details=obj.body, email_from=user_name, attach=attach)
+ case_pool.history(cr, uid, [case], truncate_text(obj.body),
+ body_text=obj.body, attachments=attach)
if obj.state == 'unchanged':
pass
vals['partner_address_id'] = False
lead.write(vals, context=context)
- leads.history(cr, uid, [lead], _('Converted to opportunity'), details='Converted to Opportunity', context=context)
+ text = _('Converted to opportunity')
+ leads.history(cr, uid, [lead], text, body_text=text, context=context)
if lead.partner_id:
msg_ids = [ x.id for x in lead.message_ids]
- self.pool.get('email.message').write(cr, uid, msg_ids, {
+ self.pool.get('mail.message').write(cr, uid, msg_ids, {
'partner_id': lead.partner_id.id
}, context=context)
leads.log(cr, uid, lead.id, _("Lead '%s' has been converted to an opportunity.") % lead.name)
email_to = lead.user_id and lead.user_id.user_email
if not email_to:
return False
- message_pool = self.pool.get('email.message')
+ message_pool = self.pool.get('mail.message')
email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
partner = lead.partner_id and lead.partner_id.name or lead.partner_name
subject = "lead %s converted into opportunity" % lead.name
@param opp_ids : list of opportunities ids to merge
"""
opp_obj = self.pool.get('crm.lead')
- message_obj = self.pool.get('email.message')
+ message_obj = self.pool.get('mail.message')
lead_ids = context and context.get('lead_ids', []) or []
for opp in tail_opportunities + [first_opportunity]:
attach_ids = self.get_attachments(cr, uid, opp, context=context)
self.set_attachements_res_id(cr, uid, first_opportunity.id, attach_ids)
- for history in opp.message_ids:
- new_history = message_obj.write(cr, uid, history.id, {'res_id': first_opportunity.id, 'name' : _("From %s : %s") % (opp.name, history.subject) }, context=context)
+ for mail_msg in opp.message_ids:
+ message_obj.write(cr, uid, mail_msg.id, {'res_id': first_opportunity.id, 'name' : _("From %s : %s") % (opp.name, mail_msg.subject) }, context=context)
#Notification about loss of information
details = []
subject = subject[0] + ", ".join(subject[1:])
details = "\n\n".join(details)
- opp_obj.history(cr, uid, [first_opportunity], subject, details=details)
+ opp_obj.history(cr, uid, [first_opportunity], subject, body_text=details)
#data.update({'message_ids' : [(6, 0 ,self._concat_o2m('message_ids', op_ids))]})
opp_obj.write(cr, uid, [first_opportunity.id], data)
unlink_ids = map(lambda x: x.id, tail_opportunities)
models_data = self.pool.get('ir.model.data')
-
-
# Get Opportunity views
result = models_data._get_id(
cr, uid, 'crm', 'view_crm_case_opportunities_filter')
from osv import fields
import tools
-email_model = [
- 'crm.lead',
- ]
+SUPPORTED_MODELS = ['crm.lead',]
-class email_compose_message(osv.osv_memory):
- _inherit = 'email.compose.message'
+class mail_compose_message(osv.osv_memory):
+ _inherit = 'mail.compose.message'
- def get_value(self, cr, uid, model, resource_id, context=None):
- '''
- To get values of the resource_id for the model
- @param model: Object
- @param resource_id: id of a record for which values to be read
+ def get_value(self, cr, uid, model, res_id, context=None):
+ """Returns a defaults-like dict with initial values for the composition
+ wizard when sending an email related to the document record identified
+ by ``model`` and ``res_id``.
- @return: Returns a dictionary
- '''
- if context is None:
- context = {}
- result = super(email_compose_message, self).get_value(cr, uid, model, resource_id, context=context)
- if model in email_model and resource_id:
+ The default implementation returns an empty dictionary, and is meant
+ to be overridden by subclasses.
+
+ :param str model: model name of the document record this mail is related to.
+ :param int res_id: id of the document record this mail is related to.
+ :param dict context: several context values will modify the behavior
+ of the wizard, cfr. the class description.
+ """
+ result = super(mail_compose_message, self).get_value(cr, uid, model, res_id, context=context)
+ if model in SUPPORTED_MODELS and res_id:
model_obj = self.pool.get(model)
- data = model_obj.browse(cr, uid , resource_id, context)
+ data = model_obj.browse(cr, uid , res_id, context)
result.update({
'subject' : data.name or False,
'email_to' : data.email_from or False,
'email_from' : data.user_id and data.user_id.address_id and data.user_id.address_id.email or tools.config.get('email_from', False),
- 'body' : '\n' + (tools.ustr(data.user_id.signature or '')),
+ 'body_text' : '\n' + (tools.ustr(data.user_id.signature or '')),
'email_cc' : tools.ustr(data.email_cc or ''),
'model': model,
- 'res_id': resource_id,
+ 'res_id': res_id,
})
if hasattr(data, 'section_id'):
result.update({'reply_to' : data.section_id and data.section_id.reply_to or False})
return result
-email_compose_message()
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
res = ''
- if data.get('model',False) and data.get('ids',False):
+ if data.get('model') and data.get('ids'):
model_obj = pooler.get_pool(cr.dbname).get(data['model'])
res = model_obj.browse(cr, uid, data['ids'], context=context)
if len(res):
_name = "crm.claim"
_description = "Claim"
_order = "priority,date desc"
- _inherit = ['email.thread']
+ _inherit = ['mail.thread']
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Claim Subject', size=128, required=True),
\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\'.'),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
}
def stage_next(self, cr, uid, ids, context=None):
return stage
def _get_stage_id(self, cr, uid, context=None):
- """Finds type of stage according to object.
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- """
+ """Finds type of stage according to object."""
if context is None:
context = {}
type = context and context.get('stage_type', '')
def onchange_partner_id(self, cr, uid, ids, part, email=False):
"""This function returns value of partner address based on partner
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param part: Partner's id
- @email: Partner's email ID
+
+ :param part: Partner's id
+ :param email: ignored
"""
if not part:
return {'value': {'partner_address_id': False,
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
"""This function returns value of partner email based on Partner Address
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case IDs
- @param add: Id of Partner's address
- @email: Partner's email ID
+
+ :param part: Partner's id
+ :param email: ignored
"""
if not add:
return {'value': {'email_from': False}}
return {'value': {'email_from': address.email, 'partner_phone': address.phone, 'partner_mobile': address.mobile}}
def case_open(self, cr, uid, ids, *args):
- """
- Opens Claim
- """
+ """Opens Claim"""
res = super(crm_claim, self).case_open(cr, uid, ids, *args)
claims = self.browse(cr, uid, ids)
return res
- def message_new(self, cr, uid, msg, context=None):
- """
- Automatically calls when new email message arrives
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks
- @param msg: dictionary object to contain email message data
- """
- thread_pool = self.pool.get('email.thread')
-
+ def message_new(self, cr, uid, msg, custom_values=None, context=None):
+ """Automatically called when new email message arrives"""
+ res_id = super(crm_claim,self).message_new(cr, uid, msg,
+ custom_values=custom_values,
+ context=context)
+ mail_thread = self.pool.get('mail.thread')
subject = msg.get('subject')
- body = msg.get('body')
+ body = msg.get('body_text')
msg_from = msg.get('from')
priority = msg.get('priority')
-
vals = {
'name': subject,
'email_from': msg_from,
'description': body,
'user_id': False,
}
- if msg.get('priority', False):
+ if priority:
vals['priority'] = priority
-
- res = thread_pool.get_partner(cr, uid, msg.get('from', False))
+ res = mail_thread.get_partner(cr, uid, msg.get('from', False))
if res:
vals.update(res)
-
- res_id = self.create(cr, uid, vals, context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, [res_id], _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
-
+ self.write(cr, uid, [res_id], vals, context=context)
return res_id
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of update mail’s IDs
- """
if isinstance(ids, (str, int, long)):
ids = [ids]
+ res_id = super(crm_claim,self).message_update(cr, uid, msg, context=context)
+
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
vals['priority'] = msg.get('priority')
'probability':'probability'
}
vls = {}
- for line in msg['body'].split('\n'):
+ for line in msg['body_text'].split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
if case.state in CRM_CLAIM_PENDING_STATES:
values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
res = self.write(cr, uid, [case.id], values, context=context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, ids, _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
return res
-crm_claim()
-
-
class crm_stage_claim(osv.osv):
def _get_type_value(self, cr, user, context):
'type': fields.selection(_get_type_value, 'Type'),
}
-
-crm_stage_claim()
-
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
<tree string="History">
<field name="display_text" string="History Information"/>
- <field name="history" invisible="1"/>
<button
- string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
+ string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply'}"
icon="terp-mail-replied" type="action" />
<field name="email_to" widget="char" size="512"/>
<field name="email_cc" widget="char" size="512"/>
<field name="subject" colspan="4" widget="char" size="512"/>
- <field name="history" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Details">
- <group attrs="{'invisible': [('history', '!=', True)]}">
- <field name="body" colspan="4" nolabel="1" height="250"/>
+ <group attrs="{'invisible': [('email_from', '=', False)]}">
+ <field name="body_text" colspan="4" nolabel="1" height="250"/>
<button colspan="4" string="Reply"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action"/>
</group>
- <group attrs="{'invisible': [('history', '=', True)]}">
+ <group attrs="{'invisible': [('email_from', '!=', False)]}">
<field name="display_text" colspan="4" nolabel="1" height="250"/>
</group>
</page>
c.type_action as type_action,
date_trunc('day',c.create_date) as create_date,
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close,
- (SELECT count(id) FROM email_message WHERE model='crm.claim' AND res_id=c.id AND history=True) AS email,
+ (SELECT count(id) FROM email_message WHERE model='crm.claim' AND res_id=c.id AND email_from IS NOT NULL) AS email,
(SELECT avg(probability) FROM crm_case_stage WHERE type='claim' AND id=c.stage_id) AS probability,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected
from
_name = "crm.fundraising"
_description = "Fund Raising"
_order = "id desc"
- _inherit = ['email.thread']
+ _inherit = ['mail.thread']
_columns = {
'id': fields.integer('ID'),
'name': fields.char('Name', size=128, required=True),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', \
- help="The channels represent the different communication \
- modes available with the customer."),
+ help="The channels represent the different communication modes available with the customer."),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\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\'.'),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
}
_defaults = {
'planned_revenue': lambda *a:0.0,
}
-crm_fundraising()
-
class crm_stage_fundraising(osv.osv):
'type': fields.selection(_get_type_value, 'Type'),
}
-
-crm_stage_fundraising()
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="History">
<field name="display_text" string="History Information"/>
- <field name="history" invisible="1"/>
<button
- string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
+ string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action" />
<field name="email_to" widget="char" size="512"/>
<field name="email_cc" widget="char" size="512"/>
<field name="subject" colspan="4" widget="char" size="512"/>
- <field name="history" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Details">
- <group attrs="{'invisible': [('history', '!=', True)]}">
- <field name="body" colspan="4" nolabel="1" height="250"/>
+ <group attrs="{'invisible': [('email_from', '=', False)]}">
+ <field name="body_text" colspan="4" nolabel="1" height="250"/>
<button colspan="4" string="Reply"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action"/>
</group>
- <group attrs="{'invisible': [('history', '=', True)]}">
+ <group attrs="{'invisible': [('email_from', '!=', False)]}">
<field name="display_text" colspan="4" nolabel="1" height="250"/>
</group>
</page>
_name = "crm.helpdesk"
_description = "Helpdesk"
_order = "id desc"
- _inherit = ['email.thread']
+ _inherit = ['mail.thread']
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', \
- help="The channels represent the different communication \
- modes available with the customer."),
+ help="The channels represent the different communication modes available with the customer."),
'planned_revenue': fields.float('Planned Revenue'),
'planned_cost': fields.float('Planned Costs'),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
\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\'.'),
- 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+ 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
}
_defaults = {
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
}
- def message_new(self, cr, uid, msg, context=None):
- """
- Automatically calls when new email message arrives
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks
- @param msg: dictionary object to contain email message data
- """
- thread_pool = self.pool.get('email.thread')
-
+ def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
+ """Automatically called when new email message arrives"""
+ res_id = super(crm_helpdesk,self).message_new(cr, uid, msg_dict, custom_values=custom_values, context=context)
+ thread_pool = self.pool.get('mail.thread')
subject = msg.get('subject')
- body = msg.get('body')
+ body = msg.get('body_text')
msg_from = msg.get('from')
priority = msg.get('priority')
if res:
vals.update(res)
- res_id = self.create(cr, uid, vals, context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, [res_id], _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
-
+ self.write(cr, uid, [res_id], vals, context)
return res_id
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of update mail’s IDs
- """
if isinstance(ids, (str, int, long)):
ids = [ids]
+ super(crm_helpdesk,self).message_update(cr, uid, msg, context=context)
+
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
vals['priority'] = msg.get('priority')
'probability':'probability'
}
vls = {}
- for line in msg['body'].split('\n'):
+ for line in msg['body_text'].split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
if case.state in CRM_HELPDESK_STATES:
values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
res = self.write(cr, uid, [case.id], values, context=context)
-
- attachments = msg.get('attachments', {})
- self.history(cr, uid, ids, _('receive'), history=True,
- subject = msg.get('subject'),
- email = msg.get('to'),
- details = msg.get('body'),
- email_from = msg.get('from'),
- email_cc = msg.get('cc'),
- message_id = msg.get('message-id'),
- references = msg.get('references', False) or msg.get('in-reply-to', False),
- attach = attachments,
- email_date = msg.get('date'),
- body_html= msg.get('body_html'),
- sub_type = msg.get('sub_type'),
- headers = msg.get('headers'),
- priority = msg.get('priority'),
- context = context)
return res
-crm_helpdesk()
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
<tree string="History">
<field name="display_text" string="History Information"/>
- <field name="history" invisible="1"/>
<button
- string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
+ string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action" />
<field name="email_to" widget="char" size="512"/>
<field name="email_cc" widget="char" size="512"/>
<field name="subject" colspan="4" widget="char" size="512"/>
- <field name="history" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Details">
- <group attrs="{'invisible': [('history', '!=', True)]}">
- <field name="body" colspan="4" nolabel="1" height="250"/>
+ <group attrs="{'invisible': [('email_from', '=', False)]}">
+ <field name="body_text" colspan="4" nolabel="1" height="250"/>
<button colspan="4" string="Reply"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action"/>
</group>
- <group attrs="{'invisible': [('history', '=', True)]}">
+ <group attrs="{'invisible': [('email_from', '!=', False)]}">
<field name="display_text" colspan="4" nolabel="1" height="250"/>
</group>
</page>
c.planned_cost,
count(*) as nbr,
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
- (SELECT count(id) FROM email_message WHERE model='crm.helpdesk' AND res_id=c.id AND history=True) AS email,
+ (SELECT count(id) FROM email_message WHERE model='crm.helpdesk' AND res_id=c.id AND email_from IS NOT NULL) AS email,
abs(avg(extract('epoch' from (c.date_deadline - c.date_closed)))/(3600*24)) as delay_expected
from
crm_helpdesk c
'subject' : data.name or False,
'email_to' : data.email_from or False,
'email_from' : data.user_id and data.user_id.address_id and data.user_id.address_id.email or False,
- 'body' : '\n' + (tools.ustr(data.user_id.signature or '')),
+ 'body_text' : '\n' + (tools.ustr(data.user_id.signature or '')),
'email_cc' : tools.ustr(data.email_cc or ''),
'model': model,
'res_id': resource_id,
class crm_lead_forward_to_partner(osv.osv_memory):
"""Forwards lead history"""
_name = 'crm.lead.forward.to.partner'
- _inherit = "email.compose.message"
+ _inherit = "mail.compose.message"
_columns = {
'send_to': fields.selection([('user', 'User'), ('partner', 'Partner'), \
@param hist_id: Id of latest history
@param context: A standard dictionary for contextual values
"""
- log_pool = self.pool.get('email.message')
+ log_pool = self.pool.get('mail.message')
hist = log_pool.browse(cr, uid, hist_id, context=context)
header = '-------- Original Message --------'
sender = 'From: %s' %(hist.email_from or '')
to = 'To: %s' % (hist.email_to or '')
sentdate = 'Date: %s' % (hist.date or '')
- desc = '\n%s'%(hist.body)
+ desc = '\n%s'%(hist.body_text)
original = [header, sender, to, sentdate, desc]
original = '\n'.join(original)
return original
res_id = context.get('active_id')
msg_val = self._get_case_history(cr, uid, history_type, res_id, context=context)
if msg_val:
- res = {'value': {'description' : '\n\n' + msg_val}}
+ res = {'value': {'body_text' : '\n\n' + msg_val}}
return res
def _get_case_history(self, cr, uid, history_type, res_id, context=None):
elif history_type == 'whole':
log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
- log_ids = map(lambda x: x.id, filter(lambda x: x.history, log_ids))
+ log_ids = map(lambda x: x.id, filter(lambda x: x.email_from, log_ids))
msg_val = case_info + '\n\n' + self.get_whole_history(cr, uid, log_ids, context=context)
elif history_type == 'latest':
log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
- log_ids = filter(lambda x: x.history and x.id, log_ids)
+ log_ids = filter(lambda x: x.email_from and x.id, log_ids)
if not log_ids:
msg_val = case_info
else:
body = self._get_case_history(cr, uid, defaults.get('history', 'latest'), lead.id, context=context)
defaults.update({
'subject' : '%s: %s - %s' % (_('Fwd'), 'Openerp lead forward', lead.name),
- 'body' : body,
+ 'body_text' : body,
'email_cc' : email_cc,
'email_to' : email or 'dummy@dummy.ly'
})
return defaults
-crm_lead_forward_to_partner()
-
class crm_lead_mass_forward_to_partner(osv.osv_memory):
_name = 'crm.lead.mass.forward.to.partner'
_inherit = 'crm.lead.forward.to.partner'
continue
context.update({'active_id' : case.id})
- value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history'], context=context)
+ value = self.default_get(cr, uid, ['body_text', 'email_to', 'email_cc', 'subject', 'history'], context=context)
self.write(cr, uid, ids, value, context=context)
self.action_forward(cr,uid, ids, context=context)
return {'type': 'ir.actions.act_window_close'}
-crm_lead_mass_forward_to_partner()
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: