_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "priority,date_action,id desc"
- _inherit = ['mail.thread','res.partner.address']
+ _inherit = ['ir.needaction_mixin', 'mail.thread','res.partner']
def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
access_rights_uid = access_rights_uid or uid
'stage_id': _read_group_stage_ids
}
- # overridden because res.partner.address has an inconvenient name_get,
- # especially if base_contact is installed.
- def name_get(self, cr, user, ids, context=None):
- if isinstance(ids, (int, long)):
- ids = [ids]
- return [(r['id'], tools.ustr(r[self._rec_name]))
- for r in self.read(cr, user, ids, [self._rec_name], context)]
-
def _compute_day(self, cr, uid, ids, fields, args, context=None):
"""
@param cr: the current row, from the database cursor,
return res
_columns = {
- # Overridden from res.partner.address:
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null',
select=True, help="Optional linked partner, usually after conversion of the lead"),
domain="['|',('section_id','=',section_id),('section_id','=',False)]", help="From which campaign (seminar, marketing campaign, mass mailing, ...) did this contact come from?"),
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel (mail, direct, phone, ...)"),
'contact_name': fields.char('Contact Name', size=64),
- 'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner that will be created while converting the lead into opportunity', select=1),
+ 'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner company that will be created while converting the lead into opportunity', select=1),
'optin': fields.boolean('Opt-In', help="If opt-in is checked, this contact has accepted to receive emails."),
'optout': fields.boolean('Opt-Out', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."),
'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"),
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
# Only used for type opportunity
- 'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"),
'probability': fields.float('Probability (%)',group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'title_action': fields.char('Next Action', size=64),
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
'color': fields.integer('Color Index'),
- 'partner_address_name': fields.related('partner_address_id', 'name', type='char', string='Partner Contact Name', readonly=True),
- 'partner_address_email': fields.related('partner_address_id', 'email', type='char', string='Partner Contact Email', readonly=True),
+ 'partner_address_name': fields.related('partner_id', 'name', type='char', string='Partner Contact Name', readonly=True),
+ 'partner_address_email': fields.related('partner_id', 'email', type='char', string='Partner Contact Email', readonly=True),
'company_currency': fields.related('company_id', 'currency_id', 'symbol', type='char', string='Company Currency', readonly=True),
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True),
'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._case_create_notification(cr, uid, [obj_id], context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
-
-
- def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
- """This function returns value of partner email based on Partner Address
- """
- if not add:
- return {'value': {'email_from': False, 'country_id': False}}
- address = self.pool.get('res.partner.address').browse(cr, uid, add)
- return {'value': {'email_from': address.email, 'phone': address.phone, 'country_id': address.country_id.id}}
-
+
def on_change_optin(self, cr, uid, ids, optin):
return {'value':{'optin':optin,'optout':False}}
def stage_find_won(self, cr, uid, section_id):
return self.stage_find_percent(cr, uid, 100.0, section_id)
- def _case_create_notification(self, cr, uid, ids, context=None):
- for obj in self.browse(cr, uid, ids, context=context):
- self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context)
- if obj.type=="opportunity" and obj.state=="draft":
- message = _("Opportunity is <b>created</b>.")
- elif obj.type=="lead" :
- message = _("Lead is <b>created</b>.")
- else:
- message = _("The case has been <b>created</b>.")
- self.message_append_note(cr, uid, ids, _('System notification'),
- message, type='notification', need_action_user_id=obj.user_id.id, context=context)
- return True
-
- def _case_open_notification(self, lead, context=None):
- if lead.state != 'draft' and lead.state != 'pending':
- return False
- if lead.type == 'lead':
- message = _("The lead has been <b>opened</b>.")
- elif lead.type == 'opportunity':
- message = _("The opportunity has been <b>opened</b>.")
- else:
- message = _("The case has been <b>opened</b>.")
- lead.message_append_note('' ,message, need_action_user_id=lead.user_id.id)
-
- def _case_close_notification(self, lead, context=None):
- lead[0].message_mark_done(context)
- if lead[0].type == 'lead':
- message = _("The lead has been <b>closed</b>.")
- elif lead[0].type == 'opportunity':
- message = _("The opportunity has been <b>closed</b>.")
- else:
- message = _("The case has been <b>closed</b>.")
- lead[0].message_append_note('' ,message)
-
- def _case_mark_lost_notification(self, lead, context=None):
- lead.message_mark_done(context)
- message = _("The opportunity has been <b>marked as lost</b>.")
- lead.message_append_note('' ,message)
-
- def _case_mark_won_notification(self, lead, context=None):
- lead.message_mark_done(context)
- message = _("The opportunity has been <b>won</b>.")
- lead.message_append_note('' ,message)
-
- def _case_cancel_notification(self, lead, context=None):
- lead[0].message_mark_done(context)
- if lead[0].type == 'lead':
- message = _("The lead has been <b>cancelled</b>.")
- elif lead[0].type == 'opportunity':
- message = _("The opportunity has been <b>cancelled</b>.")
- lead[0].message_append_note('' ,message)
-
- def _case_pending_notification(self, case, context=None):
- if case[0].type == 'lead':
- message = _("The lead is <b>pending</b>.")
- elif case[0].type == 'opportunity':
- message = _("The opportunity is <b>pending</b>.")
- case[0].message_append_note('' ,message)
-
- def _case_escalate_notification(self, case, context=None):
- message = _("The lead is <b>escalated</b>.")
- case.message_append_note('' ,message)
-
- def _case_phonecall_notification(self, cr, uid, ids, case, phonecall, action, context=None):
- for obj in phonecall.browse(cr, uid, ids, context=context):
- if action == "schedule" :
- message = _("<b>%s a call</b> for the %s.") % (action, obj.date)
- else :
- message = _("<b>%s a call</b>.") % (action)
- case.message_append_note('', message)
- if action == "schedule" :
- phonecall.message_append_note(cr, uid, ids, '', message, need_action_user_id=obj.user_id.id)
-
def case_open(self, cr, uid, ids, context=None):
- res = super(crm_lead, self).case_open(cr, uid, ids, context)
for lead in self.browse(cr, uid, ids, context=context):
- value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
- self.write(cr, uid, [lead.id], value)
- if lead.type == 'opportunity' and not lead.stage_id:
- stage_id = self.stage_find(cr, uid, lead.section_id.id or False, [('sequence','>',0)])
- if stage_id:
- self.stage_set(cr, uid, [lead.id], stage_id)
+ if lead.state == 'draft':
+ value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
+ self.write(cr, uid, [lead.id], value)
+ if lead.type == 'opportunity' and not lead.stage_id:
+ stage_id = self.stage_find(cr, uid, lead.section_id.id or False, [('sequence','>',0)])
+ if stage_id:
+ self.stage_set(cr, uid, [lead.id], stage_id)
+ res = super(crm_lead, self).case_open(cr, uid, ids, context)
return res
def case_close(self, cr, uid, ids, context=None):
stage_id = self.stage_find_won(cr, uid, lead.section_id.id or False)
if stage_id:
self.stage_set(cr, uid, [lead.id], stage_id)
- self._case_mark_won_notification(lead, context=context)
+ self.case_mark_won_send_note(cr, uid, [lead.id], context=context)
return res
def set_priority(self, cr, uid, ids, priority):
subject = subject[0] + ", ".join(subject[1:])
details = "\n\n".join(details)
- return opportunity.message_append_note(subject, body=details, need_action_user_id=opportunity.user_id.id)
+ return self.message_append_note(cr, uid, [opportunity_id], subject=subject, body=details)
def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
message = self.pool.get('mail.message')
first_opportunity = opportunities_list[0]
tail_opportunities = opportunities_list[1:]
- fields = ['partner_id', 'title', 'name', 'categ_id', 'channel_id', 'city', 'company_id', 'contact_name', 'country_id',
- 'partner_address_id', 'type_id', 'user_id', 'section_id', 'state_id', 'description', 'email', 'fax', 'mobile',
+ fields = ['partner_id', 'title', 'name', 'categ_id', 'channel_id', 'city', 'company_id', 'contact_name', 'country_id', 'type_id', 'user_id', 'section_id', 'state_id', 'description', 'email', 'fax', 'mobile',
'partner_name', 'phone', 'probability', 'planned_revenue', 'street', 'street2', 'zip', 'create_date', 'date_action_last',
'date_action_next', 'email_from', 'email_cc', 'partner_name']
'stage_id': stage_id or False,
'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),
- 'partner_address_id': contact_id,
}
- def _convert_opportunity_notification(self, cr, uid, lead, context=None):
- success_message = _("Lead is <b>converted to an opportunity</b>.")
- lead.message_append_note(success_message ,success_message, need_action_user_id=lead.user_id.id)
- return True
-
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
partner = self.pool.get('res.partner')
mail_message = self.pool.get('mail.message')
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
- self._convert_opportunity_notification(cr, uid, lead, context=context)
+ self.convert_opportunity_send_note(cr, uid, lead, context=context)
#TOCHECK: why need to change partner details in all messages of lead ?
if lead.partner_id:
msg_ids = [ x.id for x in lead.message_ids]
}, context=context)
return True
- def _lead_create_partner(self, cr, uid, lead, context=None):
+ def _lead_create_contact(self, cr, uid, lead, name, is_company, parent_id=False, context=None):
partner = self.pool.get('res.partner')
- partner_id = partner.create(cr, uid, {
- 'name': lead.partner_name or lead.contact_name or lead.name,
- 'user_id': lead.user_id.id,
- 'comment': lead.description,
- 'section_id': lead.section_id.id or False,
- 'address': []
- })
+ vals = { 'name': name,
+ 'user_id': lead.user_id.id,
+ 'comment': lead.description,
+ 'section_id': lead.section_id.id or False,
+ 'parent_id': parent_id,
+ 'phone': lead.phone,
+ 'mobile': lead.mobile,
+ 'email': lead.email_from and to_email(lead.email_from)[0],
+ 'fax': lead.fax,
+ 'title': lead.title and lead.title.id or False,
+ 'function': lead.function,
+ 'street': lead.street,
+ 'street2': lead.street2,
+ 'zip': lead.zip,
+ 'city': lead.city,
+ 'country_id': lead.country_id and lead.country_id.id or False,
+ 'state_id': lead.state_id and lead.state_id.id or False,
+ 'is_company': is_company,
+ 'type': 'contact'
+ }
+ partner = partner.create(cr, uid,vals, context)
+ return partner
+
+ def _create_lead_partner(self, cr, uid, lead, context=None):
+ partner_id = False
+ if lead.partner_name and lead.contact_name:
+ partner_id = self._lead_create_contact(cr, uid, lead, lead.partner_name, True, context=context)
+ self._lead_create_contact(cr, uid, lead, lead.contact_name, False, partner_id, context=context)
+ elif lead.partner_name and not lead.contact_name:
+ partner_id = self._lead_create_contact(cr, uid, lead, lead.partner_name, True, context=context)
+ elif not lead.partner_name and lead.contact_name:
+ partner_id = self._lead_create_contact(cr, uid, lead, lead.contact_name, False, context=context)
+ else:
+ partner_id = self._lead_create_contact(cr, uid, lead, lead.name, False, context=context)
return partner_id
def _lead_set_partner(self, cr, uid, lead, partner_id, context=None):
if partner_id:
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
- res = lead.write({'partner_id' : partner_id, 'partner_address_id': contact_id}, context=context)
-
+ res = lead.write({'partner_id' : partner_id, }, context=context)
+ self._lead_set_partner_send_note(cr, uid, [lead.id], context)
return res
- def _lead_create_partner_address(self, cr, uid, lead, partner_id, context=None):
- address = self.pool.get('res.partner.address')
- return address.create(cr, uid, {
- 'partner_id': partner_id,
- 'name': lead.contact_name,
- 'phone': lead.phone,
- 'mobile': lead.mobile,
- 'email': lead.email_from and to_email(lead.email_from)[0],
- 'fax': lead.fax,
- 'title': lead.title and lead.title.id or False,
- 'function': lead.function,
- 'street': lead.street,
- 'street2': lead.street2,
- 'zip': lead.zip,
- 'city': lead.city,
- 'country_id': lead.country_id and lead.country_id.id or False,
- 'state_id': lead.state_id and lead.state_id.id or False,
- })
-
def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
"""
This function convert partner based on action.
for lead in self.browse(cr, uid, ids, context=context):
if action == 'create':
if not partner_id:
- partner_id = self._lead_create_partner(cr, uid, lead, context=context)
- self._lead_create_partner_address(cr, uid, lead, partner_id, context=context)
+ partner_id = self._create_lead_partner(cr, uid, lead, context)
self._lead_set_partner(cr, uid, lead, partner_id, context=context)
partner_ids[lead.id] = partner_id
return partner_ids
'date' : schedule_time,
'section_id' : section_id or False,
'partner_id': lead.partner_id and lead.partner_id.id or False,
- 'partner_address_id': lead.partner_address_id and lead.partner_address_id.id or False,
- 'partner_phone' : phone or lead.phone or (lead.partner_address_id and lead.partner_address_id.phone or False),
- 'partner_mobile' : lead.partner_address_id and lead.partner_address_id.mobile or False,
+ 'partner_phone' : phone or lead.phone or (lead.partner_id and lead.partner_id.phone or False),
+ 'partner_mobile' : lead.partner_id and lead.partner_id.mobile or False,
'priority': lead.priority,
}
-
new_id = phonecall.create(cr, uid, vals, context=context)
- phonecall.case_open(cr, uid, [new_id])
+ phonecall.case_open(cr, uid, [new_id], context=context)
if action == 'log':
- phonecall.case_close(cr, uid, [new_id])
+ phonecall.case_close(cr, uid, [new_id], context=context)
phonecall_dict[lead.id] = new_id
- self._case_phonecall_notification(cr, uid, [new_id], lead, phonecall, action, context=context)
+ self.schedule_phonecall_send_note(cr, uid, [lead.id], new_id, action, context=context)
return phonecall_dict
# change probability of lead(s) if required by stage
if not vals.get('probability') and stage.on_change:
vals['probability'] = stage.probability
- text = _("Changed Stage to: %s") % stage.name
-
for case in self.browse(cr, uid, ids, context=context):
- if case.type == 'lead' or context.get('stage_type') == 'lead':
- message = _("The stage of lead has been changed to <b>%s</b>.") % (stage.name)
- case.message_append_note(text, message)
- elif case.type == 'opportunity':
- message = _("The stage of opportunity has been changed to <b>%s</b>.") % (stage.name)
- case.message_append_note(text, message)
-
+ message = _("Stage changed to <b>%s</b>.") % (stage.name)
+ case.message_append_note(body=message)
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
+ 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)
+
+ def case_get_note_msg_prefix(self, cr, uid, lead, context=None):
+ if isinstance(lead, (int, long)):
+ lead = self.browse(cr, uid, [lead], context=context)[0]
+ return ('Opportunity' if lead.type == 'opportunity' else 'Lead')
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ for id in ids:
+ message = _("%s has been <b>created</b>.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
+ self.message_append_note(cr, uid, [id], body=message, context=context)
+ return True
+
+ def case_mark_lost_send_note(self, cr, uid, ids, context=None):
+ message = _("Opportunity has been <b>lost</b>.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def case_mark_won_send_note(self, cr, uid, ids, context=None):
+ message = _("Opportunity has been <b>won</b>.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
+ phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
+ if action == 'log': prefix = 'Logged'
+ else: prefix = 'Scheduled'
+ message = _("<b>%s a call</b> for the <em>%s</em>.") % (prefix, phonecall.date)
+ return self. message_append_note(cr, uid, ids, body=message, context=context)
+
+ def _lead_set_partner_send_note(self, cr, uid, ids, context=None):
+ for lead in self.browse(cr, uid, ids, context=context):
+ message = _("%s <b>partner</b> is now set to <em>%s</em>." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name))
+ lead.message_append_note(body=message)
+ return True
+
+ def convert_opportunity_send_note(self, cr, uid, lead, context=None):
+ message = _("Lead has been <b>converted to an opportunity</b>.")
+ lead.message_append_note(body=message)
+ return True
crm_lead()