_description = "Lead/Opportunity"
_order = "priority,date_action,id desc"
_inherit = ['ir.needaction_mixin', 'mail.thread']
+ _mail_compose_message = True
def _get_default_section_id(self, cr, uid, context=None):
""" Gives default section by checking if present in the context """
'fax': fields.char('Fax', size=64),
'mobile': fields.char('Mobile', size=64),
'function': fields.char('Function', size=128),
- 'title': fields.many2one('res.partner.title','Title'),
+ 'title': fields.many2one('res.partner.title', 'Title'),
'company_id': fields.many2one('res.company', 'Company', select=1),
}
'color': 0,
}
- def get_needaction_user_ids(self, cr, uid, ids, context=None):
- result = dict.fromkeys(ids, [])
- for obj in self.browse(cr, uid, ids, context=context):
- # salesman must perform an action when in draft mode
- if obj.state == 'draft' and obj.user_id:
- result[obj.id] = [obj.user_id.id]
- return result
-
def create(self, cr, uid, vals, context=None):
obj_id = super(crm_lead, self).create(cr, uid, vals, context)
self.create_send_note(cr, uid, [obj_id], context=context)
if not stage_id:
return {'value':{}}
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
+ if stage.state == "draft":
+ return {'value':{'probability': 0.0}}
+ if stage.state == "open":
+ cases = self.browse(cr, uid, ids, context=context)
+ data = {'active': True}
+ for case in cases:
+ if case.stage_id and case.stage_id.state == 'draft':
+ data['date_open'] = fields.datetime.now()
+ if not case.user_id:
+ data['user_id'] = uid
+ return {'value':data}
if not stage.on_change:
return {'value':{}}
- return {'value':{'probability': stage.probability}}
+ else:
+ return {'value':{'probability': stage.probability}}
def _check(self, cr, uid, ids=False, context=None):
""" Override of the base.stage method.
'type': 'ir.actions.act_window',
}
+ def action_makeMeeting(self, cr, uid, ids, context=None):
+ """ This opens Meeting's calendar view to schedule meeting on current Opportunity
+ @return : Dictionary value for created Meeting view
+ """
+ opportunity = self.browse(cr, uid, ids[0], context)
+ res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid, 'base_calendar', 'action_crm_meeting', context)
+ res['context'] = {
+ 'default_opportunity_id': opportunity.id,
+ 'default_partner_id': opportunity.partner_id and opportunity.partner_id.id or False,
+ 'default_user_id': uid,
+ 'default_section_id': opportunity.section_id and opportunity.section_id.id or False,
+ 'default_email_from': opportunity.email_from,
+ 'default_state': 'open',
+ 'default_name': opportunity.name,
+ }
+ return res
+
+ def unlink(self, cr, uid, ids, context=None):
+ for lead in self.browse(cr, uid, ids, context):
+ if (not lead.section_id.allow_unlink) and (lead.state != 'draft'):
+ raise osv.except_osv(_('Error'),
+ _("You cannot delete lead '%s'; it must be in state 'Draft' to be deleted. " \
+ "You should better cancel it, instead of deleting it.") % lead.name)
+ return super(crm_lead, self).unlink(cr, uid, ids, context)
+
+ def write(self, cr, uid, ids, vals, context=None):
+ if vals.get('stage_id') and not vals.get('probability'):
+ # change probability of lead(s) if required by stage
+ stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
+ if stage.on_change:
+ vals['probability'] = stage.probability
+ return super(crm_lead,self).write(cr, uid, ids, vals, context)
+
+ # ----------------------------------------
+ # Mail Gateway
+ # ----------------------------------------
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)
- subject = msg.get('subject') or _("No Subject")
- body = msg.get('body_text')
-
- msg_from = msg.get('from')
- priority = msg.get('priority')
- vals = {
- 'name': subject,
- 'email_from': msg_from,
+ """ Overrides mail_thread message_new that is called by the mailgateway
+ through message_process.
+ This override updates the document according to the email.
+ """
+ if custom_values is None: custom_values = {}
+ custom_values.update({
+ 'name': msg.get('subject') or _("No Subject"),
+ 'description': msg.get('body_text'),
+ 'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
- 'description': body,
'user_id': False,
- }
- if priority:
- vals['priority'] = priority
- vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
- self.write(cr, uid, [res_id], vals, context)
- return res_id
-
- def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
+ })
+ if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
+ custom_values['priority'] = msg.get('priority')
+ custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
+ return super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
+
+ def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+ """ Overrides mail_thread message_update that is called by the mailgateway
+ through message_process.
+ This method updates the document according to the email.
+ """
if isinstance(ids, (str, int, long)):
ids = [ids]
- if vals == None:
- vals = {}
- super(crm_lead, self).message_update(cr, uid, ids, msg, context=context)
+ if update_vals is None: update_vals = {}
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
vals['priority'] = msg.get('priority')
maps = {
'cost':'planned_cost',
'revenue': 'planned_revenue',
- 'probability':'probability'
+ 'probability':'probability',
}
- vls = {}
- for line in msg['body_text'].split('\n'):
+ for line in msg.get('body_text', '').split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
key = maps.get(res.group(1).lower())
- vls[key] = res.group(2).lower()
- vals.update(vls)
-
- # Unfortunately the API is based on lists
- # but we want to update the state based on the
- # previous state, so we have to loop:
- for case in self.browse(cr, uid, ids, context=context):
- values = dict(vals)
- if case.state in CRM_LEAD_PENDING_STATES:
- #re-open
- values.update(state=crm.AVAILABLE_STATES[1][0])
- if not case.date_open:
- values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
- res = self.write(cr, uid, [case.id], values, context=context)
- return res
+ vals[key] = res.group(2).lower()
- def action_makeMeeting(self, cr, uid, ids, context=None):
- """
- This opens Meeting's calendar view to schedule meeting on current Opportunity
- @return : Dictionary value for created Meeting view
- """
- if context is None:
- context = {}
- value = {}
- data_obj = self.pool.get('ir.model.data')
- for opp in self.browse(cr, uid, ids, context=context):
- # Get meeting views
- tree_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_tree_view_meet')
- form_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_form_view_meet')
- calander_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_calendar_view_meet')
- search_view = data_obj.get_object_reference(cr, uid, 'crm', 'view_crm_case_meetings_filter')
- context.update({
- 'default_opportunity_id': opp.id,
- 'default_partner_id': opp.partner_id and opp.partner_id.id or False,
- 'default_user_id': uid,
- 'default_section_id': opp.section_id and opp.section_id.id or False,
- 'default_email_from': opp.email_from,
- 'default_state': 'open',
- 'default_name': opp.name
- })
- value = {
- 'name': _('Meetings'),
- 'context': context,
- 'view_type': 'form',
- 'view_mode': 'calendar,form,tree',
- 'res_model': 'crm.meeting',
- 'view_id': False,
- 'views': [(calander_view and calander_view[1] or False, 'calendar'), (form_view and form_view[1] or False, 'form'), (tree_view and tree_view[1] or False, 'tree')],
- 'type': 'ir.actions.act_window',
- 'search_view_id': search_view and search_view[1] or False,
- 'nodestroy': True
- }
- return value
-
-
- def unlink(self, cr, uid, ids, context=None):
- for lead in self.browse(cr, uid, ids, context):
- if (not lead.section_id.allow_unlink) and (lead.state != 'draft'):
- raise osv.except_osv(_('Error'),
- _("You cannot delete lead '%s'; it must be in state 'Draft' to be deleted. " \
- "You should better cancel it, instead of deleting it.") % lead.name)
- return super(crm_lead, self).unlink(cr, uid, ids, context)
+ return super(crm_lead, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
- def write(self, cr, uid, ids, vals, context=None):
- if vals.get('stage_id') and not vals.get('probability'):
- # change probability of lead(s) if required by stage
- stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
- if stage.on_change:
- vals['probability'] = stage.probability
- return super(crm_lead,self).write(cr, uid, ids, vals, context)
-
# ----------------------------------------
# OpenChatter methods and notifications
# ----------------------------------------
def message_get_subscribers(self, cr, uid, ids, context=None):
- sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context)
- # add salesman to the subscribers
+ """ Override to add the salesman. """
+ user_ids = super(crm_lead, self).message_get_subscribers(cr, uid, ids, context=context)
for obj in self.browse(cr, uid, ids, context=context):
- if obj.user_id:
- sub_ids.append(obj.user_id.id)
- return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
-
+ if obj.user_id and not obj.user_id.id in user_ids:
+ user_ids.append(obj.user_id.id)
+ return user_ids
+
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1]