X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fcrm%2Fcrm_lead.py;h=ec5bc8bf67a8ec2a8759f1f8614ef265f334af84;hb=3d58511f891bc6f828e90635ea627ddb77617df1;hp=c17948f3646dc2bb14c20cb83e803a8ad3ae92bb;hpb=f9f5b19fc2d08bdf72030ea14eb2779984466572;p=odoo%2Fodoo.git diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index c17948f..ec5bc8b 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -22,6 +22,7 @@ from openerp.addons.base_status.base_stage import base_stage import crm from datetime import datetime +from operator import itemgetter from openerp.osv import fields, osv import time from openerp import tools @@ -259,7 +260,9 @@ class crm_lead(base_stage, format_address, osv.osv): '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 company that will be created while converting the lead into opportunity', select=1), - 'opt_out': fields.boolean('Opt-Out', oldname='optout', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."), + 'opt_out': fields.boolean('Opt-Out', oldname='optout', + help="If opt-out is checked, this contact has refused to receive emails for mass mailing and marketing campaign. " + "Filter 'Available for Mass Mailing' allows users to filter the leads when performing mass mailing."), 'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"), 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True), 'date_closed': fields.datetime('Closed', readonly=True), @@ -567,7 +570,8 @@ class crm_lead(base_stage, format_address, osv.osv): for opportunity in opportunities: subject.append(opportunity.name) title = "%s : %s" % (opportunity.type == 'opportunity' and _('Merged opportunity') or _('Merged lead'), opportunity.name) - details.append(self._mail_body(cr, uid, opportunity, CRM_LEAD_FIELDS_TO_MERGE, title=title, context=context)) + fields = list(CRM_LEAD_FIELDS_TO_MERGE) + details.append(self._mail_body(cr, uid, opportunity, fields, title=title, context=context)) # Chatter message's subject subject = subject[0] + ": " + ", ".join(subject[1:]) @@ -586,27 +590,25 @@ class crm_lead(base_stage, format_address, osv.osv): return True def _merge_opportunity_attachments(self, cr, uid, opportunity_id, opportunities, context=None): - attachment = self.pool.get('ir.attachment') + attach_obj = self.pool.get('ir.attachment') # return attachments of opportunity def _get_attachments(opportunity_id): - attachment_ids = attachment.search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', opportunity_id)], context=context) - return attachment.browse(cr, uid, attachment_ids, context=context) + attachment_ids = attach_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', opportunity_id)], context=context) + return attach_obj.browse(cr, uid, attachment_ids, context=context) - count = 1 first_attachments = _get_attachments(opportunity_id) + #counter of all attachments to move. Used to make sure the name is different for all attachments + count = 1 for opportunity in opportunities: attachments = _get_attachments(opportunity.id) - for first in first_attachments: - for attachment in attachments: - if attachment.name == first.name: - values = dict( - name = "%s (%s)" % (attachment.name, count,), - res_id = opportunity_id, - ) - attachment.write(values) - count+=1 - + for attachment in attachments: + values = {'res_id': opportunity_id,} + for attachment_in_first in first_attachments: + if attachment.name == attachment_in_first.name: + name = "%s (%s)" % (attachment.name, count,), + count+=1 + attachment.write(values) return True def merge_opportunity(self, cr, uid, ids, context=None): @@ -627,19 +629,21 @@ class crm_lead(base_stage, format_address, osv.osv): opportunities = self.browse(cr, uid, ids, context=context) sequenced_opps = [] for opportunity in opportunities: + sequence = -1 if opportunity.stage_id and opportunity.stage_id.state != 'cancel': - sequenced_opps.append((opportunity.stage_id.sequence, opportunity)) - else: - sequenced_opps.append((-1, opportunity)) - sequenced_opps.sort(key=lambda tup: tup[0], reverse=True) - opportunities = [opportunity for sequence, opportunity in sequenced_opps] + sequence = opportunity.stage_id.sequence + sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity)) + + sequenced_opps.sort(reverse=True) + opportunities = map(itemgetter(1), sequenced_opps) ids = [opportunity.id for opportunity in opportunities] highest = opportunities[0] opportunities_rest = opportunities[1:] tail_opportunities = opportunities_rest - merged_data = self._merge_data(cr, uid, ids, highest, CRM_LEAD_FIELDS_TO_MERGE, context=context) + fields = list(CRM_LEAD_FIELDS_TO_MERGE) + merged_data = self._merge_data(cr, uid, ids, highest, fields, context=context) # Merge messages and attachements into the first opportunity self._merge_opportunity_history(cr, uid, highest.id, tail_opportunities, context=context) @@ -650,11 +654,10 @@ class crm_lead(base_stage, format_address, osv.osv): opportunities.extend(opportunities_rest) self._merge_notify(cr, uid, highest, opportunities, context=context) # Check if the stage is in the stages of the sales team. If not, assign the stage with the lowest sequence - if merged_data.get('type') == 'opportunity' and merged_data.get('section_id'): - section_stages = self.pool.get('crm.case.section').read(cr, uid, merged_data['section_id'], ['stage_ids'], context=context) - if merged_data.get('stage_id') not in section_stages['stage_ids']: - stages_sequences = self.pool.get('crm.case.stage').search(cr, uid, [('id','in',section_stages['stage_ids'])], order='sequence', limit=1, context=context) - merged_data['stage_id'] = stages_sequences and stages_sequences[0] or False + if merged_data.get('section_id'): + section_stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('section_ids', 'in', merged_data['section_id']), ('type', '=', merged_data.get('type'))], order='sequence', context=context) + if merged_data.get('stage_id') not in section_stage_ids: + merged_data['stage_id'] = section_stage_ids and section_stage_ids[0] or False # Write merged data into first opportunity self.write(cr, uid, [highest.id], merged_data, context=context) # Delete tail opportunities @@ -711,7 +714,7 @@ class crm_lead(base_stage, format_address, osv.osv): 'parent_id': parent_id, 'phone': lead.phone, 'mobile': lead.mobile, - 'email': lead.email_from and tools.email_split(lead.email_from)[0], + 'email': tools.email_split(lead.email_from) and tools.email_split(lead.email_from)[0] or False, 'fax': lead.fax, 'title': lead.title and lead.title.id or False, 'function': lead.function, @@ -930,7 +933,7 @@ class crm_lead(base_stage, format_address, osv.osv): try: compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1] except ValueError: - compose_form_id = False + compose_form_id = False if context is None: context = {} ctx = context.copy() @@ -961,13 +964,22 @@ class crm_lead(base_stage, format_address, osv.osv): return [lead.section_id.message_get_reply_to()[0] if lead.section_id else False for lead in self.browse(cr, uid, ids, context=context)] + def message_get_suggested_recipients(self, cr, uid, ids, context=None): + recipients = super(crm_lead, self).message_get_suggested_recipients(cr, uid, ids, context=context) + for lead in self.browse(cr, uid, ids, context=context): + if lead.partner_id: + self._message_add_suggested_recipient(cr, uid, recipients, lead, partner=lead.partner_id, reason=_('Customer')) + elif lead.email_from: + self._message_add_suggested_recipient(cr, uid, recipients, lead, email=lead.email_from, reason=_('Customer Email')) + return recipients + def message_new(self, cr, uid, msg, custom_values=None, context=None): """ 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 = {} - + if custom_values is None: + custom_values = {} desc = html2plaintext(msg.get('body')) if msg.get('body') else '' defaults = { 'name': msg.get('subject') or _("No Subject"), @@ -1015,9 +1027,12 @@ class crm_lead(base_stage, format_address, osv.osv): 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 = _("%s a call for the %s.") % (prefix, phonecall.date) + if action == 'log': + prefix = 'Logged' + else: + prefix = 'Scheduled' + suffix = ' %s' % phonecall.description + message = _("%s a call for %s.%s") % (prefix, phonecall.date, suffix) return self.message_post(cr, uid, ids, body=message, context=context) def onchange_state(self, cr, uid, ids, state_id, context=None):