[FIX]Merge Lead/Opp on convert to opportunity
bzr revid: dle@openerp.com-20130204175106-q2r6xmox16co4n35
This commit is contained in:
parent
91954d029f
commit
1b9503923c
|
@ -36,7 +36,6 @@ CRM_LEAD_FIELDS_TO_MERGE = ['name',
|
|||
'company_id',
|
||||
'country_id',
|
||||
'section_id',
|
||||
'stage_id',
|
||||
'state_id',
|
||||
'type_id',
|
||||
'user_id',
|
||||
|
@ -472,6 +471,15 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
return 'lead'
|
||||
|
||||
def _merge_get_result_stage(self, cr, uid, opps, context=None):
|
||||
stage = None
|
||||
for opp in opps:
|
||||
if not stage:
|
||||
stage = opp.stage_id.id
|
||||
if opp.type == 'opportunity':
|
||||
return opp.stage_id.id
|
||||
return stage
|
||||
|
||||
def _merge_data(self, cr, uid, ids, oldest, fields, context=None):
|
||||
"""
|
||||
Prepare lead/opp data into a dictionary for merging. Different types
|
||||
|
@ -520,7 +528,7 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
# Define the resulting type ('lead' or 'opportunity')
|
||||
data['type'] = self._merge_get_result_type(cr, uid, opportunities, context)
|
||||
|
||||
data['stage_id'] = self._merge_get_result_stage(cr, uid, opportunities, context)
|
||||
return data
|
||||
|
||||
def _merge_find_oldest(self, cr, uid, ids, context=None):
|
||||
|
@ -533,9 +541,6 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
|
||||
if context.get('convert'):
|
||||
ids = list(set(ids) - set(context.get('lead_ids', [])))
|
||||
|
||||
# Search opportunities order by create date
|
||||
opportunity_ids = self.search(cr, uid, [('id', 'in', ids)], order='create_date', context=context)
|
||||
oldest_opp_id = opportunity_ids[0]
|
||||
|
@ -643,19 +648,11 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
if len(ids) <= 1:
|
||||
raise osv.except_osv(_('Warning!'),_('Please select more than one element (lead or opportunity) from the list view.'))
|
||||
|
||||
lead_ids = context.get('lead_ids', [])
|
||||
|
||||
ctx_opportunities = self.browse(cr, uid, lead_ids, context=context)
|
||||
opportunities = self.browse(cr, uid, ids, context=context)
|
||||
opportunities_list = list(set(opportunities) - set(ctx_opportunities))
|
||||
ids.sort()
|
||||
oldest = self._merge_find_oldest(cr, uid, ids, context=context)
|
||||
if ctx_opportunities:
|
||||
first_opportunity = ctx_opportunities[0]
|
||||
tail_opportunities = opportunities_list + ctx_opportunities[1:]
|
||||
else:
|
||||
first_opportunity = opportunities_list[0]
|
||||
tail_opportunities = opportunities_list[1:]
|
||||
opportunities_rest = self.browse(cr, uid, list(set(ids) - set([oldest.id])), context=context)
|
||||
first_opportunity = oldest
|
||||
tail_opportunities = opportunities_rest
|
||||
|
||||
merged_data = self._merge_data(cr, uid, ids, oldest, CRM_LEAD_FIELDS_TO_MERGE, context=context)
|
||||
|
||||
|
@ -664,7 +661,7 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
self._merge_opportunity_attachments(cr, uid, first_opportunity.id, tail_opportunities, context=context)
|
||||
|
||||
# Merge notifications about loss of information
|
||||
self._merge_notify(cr, uid, first_opportunity, opportunities, context=context)
|
||||
self._merge_notify(cr, uid, first_opportunity, tail_opportunities, context=context)
|
||||
# Write merged data into first opportunity
|
||||
self.write(cr, uid, [first_opportunity.id], merged_data, context=context)
|
||||
# Delete tail opportunities
|
||||
|
@ -763,7 +760,9 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
res = False
|
||||
res_partner = self.pool.get('res.partner')
|
||||
if partner_id:
|
||||
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
|
||||
if lead.section_id:
|
||||
print '---TESTTRUE---'
|
||||
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id and lead.section_id.id or False})
|
||||
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
|
||||
res = lead.write({'partner_id': partner_id}, context=context)
|
||||
message = _("<b>Partner</b> set to <em>%s</em>." % (lead.partner_id.name))
|
||||
|
@ -870,10 +869,6 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
'res_model': 'crm.lead',
|
||||
'domain': [('type', '=', 'opportunity')],
|
||||
'res_id': int(opportunity_id),
|
||||
'view_id': False,
|
||||
'views': [(form_view or False, 'form'),
|
||||
(tree_view or False, 'tree'),
|
||||
(False, 'calendar'), (False, 'graph')],
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
('convert', 'Convert to opportunity'),
|
||||
('merge', 'Merge with existing opportunities')
|
||||
], 'Conversion Action', required=True),
|
||||
'opportunity_ids': fields.many2many('crm.lead', string='Opportunities', domain=[('type', '=', 'opportunity')]),
|
||||
'opportunity_ids': fields.many2many('crm.lead', string='Opportunities'),
|
||||
'partner_id': fields.many2one('res.partner', 'Customer'),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
|
@ -55,15 +56,14 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
|
||||
#TOFIX: use mail.mail_message.to_mail
|
||||
email = re.findall(r'([^ ,<@]+@[^> ,]+)', lead.email_from or '')
|
||||
email = email[0]
|
||||
|
||||
if partner_id:
|
||||
# Search for opportunities that have the same partner and that arent done or cancelled
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('type', '=', 'opportunity')])
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id)])
|
||||
for id in ids:
|
||||
tomerge.add(id)
|
||||
if email:
|
||||
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email), ('type', '=', 'opportunity')])
|
||||
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0])])
|
||||
for id in ids:
|
||||
tomerge.add(id)
|
||||
|
||||
|
@ -72,7 +72,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
if 'partner_id' in fields:
|
||||
res.update({'partner_id' : partner_id})
|
||||
if 'name' in fields:
|
||||
res.update({'name' : ids and 'merge' or 'convert'})
|
||||
res.update({'name' : len(tomerge) >= 2 and 'merge' or 'convert'})
|
||||
if 'opportunity_ids' in fields and len(tomerge) >= 2:
|
||||
res.update({'opportunity_ids': list(tomerge)})
|
||||
|
||||
|
@ -108,39 +108,44 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
lead.allocate_salesman(cr, uid, lead_ids, user_ids, team_id=team_id, context=context)
|
||||
return res
|
||||
|
||||
def _merge_opportunity(self, cr, uid, ids, opportunity_ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = False
|
||||
# Expected: all newly-converted leads (active_ids) will be merged with the opportunity(ies)
|
||||
# that have been selected in the 'opportunity_ids' m2m, with all these records
|
||||
# merged into the first opportunity (and the rest deleted)
|
||||
opportunity_ids = [o.id for o in opportunity_ids]
|
||||
lead_ids = context.get('active_ids', [])
|
||||
if lead_ids and opportunity_ids:
|
||||
# Add the leads in the to-merge list, next to other opps
|
||||
# (the fact that they're passed in context['lead_ids'] means that
|
||||
# they cannot be selected to contain the result of the merge.
|
||||
opportunity_ids.extend(lead_ids)
|
||||
context.update({'lead_ids': lead_ids, "convert" : True})
|
||||
res = self.pool.get('crm.lead').merge_opportunity(cr, uid, opportunity_ids, context=context)
|
||||
return res
|
||||
|
||||
def action_apply(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Convert lead to opportunity or merge lead and opportunity and open
|
||||
the freshly created opportunity view.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
w = self.browse(cr, uid, ids, context=context)[0]
|
||||
opp_ids = [o.id for o in w.opportunity_ids]
|
||||
if w.name == 'merge':
|
||||
lead_id = self.pool.get('crm.lead').merge_opportunity(cr, uid, opp_ids, context=context)
|
||||
lead_ids = [lead_id]
|
||||
lead = self.pool.get('crm.lead').read(cr, uid, lead_id, ['type'], context=context)
|
||||
if lead['type'] == "lead":
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
|
||||
else:
|
||||
lead_ids = context.get('active_ids', [])
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
|
||||
|
||||
return self.pool.get('crm.lead').redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
|
||||
|
||||
def _create_partner(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Create partner based on action.
|
||||
:return dict: dictionary organized as followed: {lead_id: partner_assigned_id}
|
||||
"""
|
||||
#TODO this method in only called by crm_lead2opportunity_partner
|
||||
#wizard and would probably diserve to be refactored or at least
|
||||
#moved to a better place
|
||||
if context is None:
|
||||
context = {}
|
||||
lead = self.pool.get('crm.lead')
|
||||
lead_ids = context.get('active_ids', [])
|
||||
data = self.browse(cr, uid, ids, context=context)[0]
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
|
||||
if data.name == 'merge':
|
||||
self._merge_opportunity(cr, uid, ids, data.opportunity_ids, context=context)
|
||||
return lead.redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
|
||||
|
||||
print repr(data._table._columns)
|
||||
partner_id = data.partner_id and data.partner_id.id or False
|
||||
return lead.handle_partner_assignation(cr, uid, lead_ids, data.action, partner_id, context=context)
|
||||
|
||||
class crm_lead2opportunity_mass_convert(osv.osv_memory):
|
||||
_name = 'crm.lead2opportunity.partner.mass'
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<group string="Opportunities">
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '!=', 'merge')]}" nolabel="1">
|
||||
<tree>
|
||||
<field name="create_date" groups="base.group_no_one"/>
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="contact_name"/>
|
||||
|
@ -59,10 +59,16 @@
|
|||
<group string="Select Opportunities" attrs="{'invisible': [('name', '!=', 'merge')]}">
|
||||
<field name="opportunity_ids" colspan="4" nolabel="1" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
<field name="type"/>
|
||||
<field name="contact_name"/>
|
||||
<field name="country_id" invisible="context.get('invisible_country', True)"/>
|
||||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="section_id" invisible="context.get('invisible_section', True)"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<separator string="Select Leads/Opportunities"/>
|
||||
<field name="opportunity_ids">
|
||||
<tree>
|
||||
<field name="create_date" groups="base.group_no_one"/>
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="contact_name"/>
|
||||
|
|
|
@ -96,20 +96,4 @@ class crm_partner_binding(osv.osv_memory):
|
|||
|
||||
return res
|
||||
|
||||
def _create_partner(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Create partner based on action.
|
||||
:return dict: dictionary organized as followed: {lead_id: partner_assigned_id}
|
||||
"""
|
||||
#TODO this method in only called by crm_lead2opportunity_partner
|
||||
#wizard and would probably diserve to be refactored or at least
|
||||
#moved to a better place
|
||||
if context is None:
|
||||
context = {}
|
||||
lead = self.pool.get('crm.lead')
|
||||
lead_ids = context.get('active_ids', [])
|
||||
data = self.browse(cr, uid, ids, context=context)[0]
|
||||
partner_id = data.partner_id and data.partner_id.id or False
|
||||
return lead.handle_partner_assignation(cr, uid, lead_ids, data.action, partner_id, context=context)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
Loading…
Reference in New Issue