Skip to content
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.

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'


closes #30475

Signed-off-by: Jérome Maes (jem) <>
  • Loading branch information...
robodoo committed Mar 26, 2019
2 parents 9ea4fef + c092d8f commit e64ed7cece84104231674d95598e9230f58c07ec
@@ -29,7 +29,7 @@
<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 =[('name', 'ilike', '%' + lead.contact_name+'%')], limit=1)

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

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 @@
'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]
return self.action_new_quotation()

def action_new_quotation(self):
action = self.env.ref("sale_crm.sale_action_quotations_new").read()[0]
action['context'] = {
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)]}"/>
<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'

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)

def action_apply(self):
""" Convert lead to opportunity or merge lead and opportunity and open
the freshly created opportunity view.
'partner_id': if self.action == 'exist' else self._create_partner()
return self.lead_id.action_new_quotation()

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

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<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">
<field name="action" widget="radio"/>
<field name="lead_id" invisible="1"/>
<field name="partner_id" attrs="{'invisible': [('action','!=','exist')], 'required':[('action', '=','exist')]}"/>
<button name="action_apply" string="Confirm" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>

<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>

0 comments on commit e64ed7c

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