Skip to content
Permalink
Browse files

[MERGE][IMP] sale_crm : create partner from lead to new quotation

When creating a quotation from a opportunity that does not have any
customer set, we ended up on a quotation without any customer or any of
the contact information entered on the crm.lead.

With this commit, if no customer is set on the opportunity, when hitting New
Quotation button,  a modal is displayed to ask the user what to do to fill in the
customer field.

- Create a new customer : Use the information from the opportunity to create
automatically a res.partner. Set the res.partner on the quotation
and on the opportunity.
- Use an existing customer : Set this customer on the quotation
and on the opportunity.

Extra
For consistency, in the 'convert to opportunity' modal,
move the 'create a new customer' at the top of the selection values
+ change the group title to 'Customer' instead of 'Customers'

Task-1917332

closes #30475

Signed-off-by: Jérome Maes (jem) <jem@openerp.com>
  • Loading branch information...
robodoo committed Mar 26, 2019
2 parents 9ea4fef + c092d8f commit e64ed7cece84104231674d95598e9230f58c07ec
@@ -29,7 +29,7 @@
</tree>
</field>
</group>
<group name="action" attrs="{'invisible': [('name', '!=', 'convert')]}" string="Customers" col="1">
<group name="action" attrs="{'invisible': [('name', '!=', 'convert')]}" string="Customer" col="1">
<field name="action" nolabel="1" widget="radio"/>
<group col="2">
<field name="partner_id" widget="res_partner_many2one" domain="[('customer', '=', True)]" context="{'search_default_customer': 1, 'show_vat': True}" attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"/>
@@ -29,8 +29,8 @@ def default_get(self, fields):
return res

action = fields.Selection([
('exist', 'Link to an existing customer'),
('create', 'Create a new customer'),
('exist', 'Link to an existing customer'),
('nothing', 'Do not link to a customer')
], 'Related Customer', required=True)
partner_id = fields.Many2one('res.partner', 'Customer')
@@ -64,4 +64,8 @@ def _find_matching_partner(self):
partner = Partner.search([('name', 'ilike', '%' + lead.contact_name+'%')], limit=1)
return partner.id

if lead.name: # to be aligned with _create_lead_partner, search on lead's name as last possibility
partner = Partner.search([('name', 'ilike', '%' + lead.name + '%')], limit=1)
return partner.id

return False
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import models
from . import wizard

from odoo import api, SUPERUSER_ID

@@ -22,7 +22,8 @@
'views/partner_views.xml',
'views/sale_order_views.xml',
'views/crm_lead_views.xml',
'views/crm_team_views.xml'
'views/crm_team_views.xml',
'wizard/crm_opportunity_to_quotation_views.xml'
],
'auto_install': True,
'uninstall_hook': 'uninstall_hook'
@@ -60,3 +60,25 @@ def retrieve_sales_dashboard(self):

res['invoiced']['target'] = self.env.user.target_sales_invoiced
return res

def action_sale_quotations_new(self):
if not self.partner_id:
return self.env.ref("sale_crm.crm_quotation_partner_action").read()[0]
else:
return self.action_new_quotation()

def action_new_quotation(self):
action = self.env.ref("sale_crm.sale_action_quotations_new").read()[0]
action['context'] = {
'search_default_opportunity_id': self.id,
'default_opportunity_id': self.id,
'search_default_partner_id': self.partner_id.id,
'default_partner_id': self.partner_id.id,
'default_team_id': self.team_id.id,
'default_campaign_id': self.campaign_id.id,
'default_medium_id': self.medium_id.id,
'default_origin': self.name,
'default_name': self.name,
'default_source_id': self.source_id.id
}
return action
@@ -7,15 +7,8 @@
<field name="inherit_id" ref="crm.crm_case_form_view_oppor"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_set_won_rainbowman']" position="before">
<button string="New Quotation" name="%(sale_action_quotations_new)d" type="action" class="oe_highlight"
attrs="{'invisible': ['&amp;', ('probability', '=', 0), ('active', '=', False)]}"
context="{'search_default_partner_id': partner_id,
'default_partner_id': partner_id,
'default_team_id': team_id,
'default_campaign_id': campaign_id,
'default_medium_id': medium_id,
'default_origin': name,
'default_source_id': source_id}"/>
<button string="New Quotation" name="action_sale_quotations_new" type="object" class="oe_highlight"
attrs="{'invisible': ['&amp;', ('probability', '=', 0), ('active', '=', False)]}"/>
</xpath>
<button name="action_schedule_meeting" position="after">
<button class="oe_stat_button" type="action"
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import crm_opportunity_to_quotation
@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
from odoo.exceptions import UserError


class Opportunity2Quotation(models.TransientModel):

_name = 'crm.quotation.partner'
_description = 'Create new or use existing Customer on new Quotation'
_inherit = 'crm.partner.binding'

@api.model
def default_get(self, fields):
result = super(Opportunity2Quotation, self).default_get(fields)

active_model = self._context.get('active_model')
if active_model != 'crm.lead':
raise UserError(_('You can only apply this action from a lead.'))

active_id = self._context.get('active_id')
if 'lead_id' in fields and active_id:
result['lead_id'] = active_id
return result

action = fields.Selection([
('create', 'Create a new customer'),
('exist', 'Use an existing customer')
], 'Quotation Customer', required=True)
lead_id = fields.Many2one('crm.lead', "Associated Lead", required=True)

@api.multi
def action_apply(self):
""" Convert lead to opportunity or merge lead and opportunity and open
the freshly created opportunity view.
"""
self.ensure_one()
self.lead_id.write({
'partner_id': self.partner_id.id if self.action == 'exist' else self._create_partner()
})
self.lead_id._onchange_partner_id()
return self.lead_id.action_new_quotation()

def _create_partner(self):
""" Create partner based on action.
:return int: created res.partner id
"""
self.ensure_one()
result = self.lead_id.handle_partner_assignation(action='create')
return result.get(self.lead_id.id)

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="crm_quotation_partner_view_form" model="ir.ui.view">
<field name="name">crm.quotation.partner.view.form</field>
<field name="model">crm.quotation.partner</field>
<field name="arch" type="xml">
<form string="New Quotation">
<group>
<group>
<field name="action" widget="radio"/>
<field name="lead_id" invisible="1"/>
</group>
</group>
<group>
<group>
<field name="partner_id" attrs="{'invisible': [('action','!=','exist')], 'required':[('action', '=','exist')]}"/>
</group>
</group>
<footer>
<button name="action_apply" string="Confirm" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>

<record id="crm_quotation_partner_action" model="ir.actions.act_window">
<field name="name">New Quotation</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.quotation.partner</field>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_quotation_partner_view_form"/>
<field name="target">new</field>
</record>
</odoo>

0 comments on commit e64ed7c

Please sign in to comment.
You can’t perform that action at this time.