diff options
| author | David Beguin <dbe@odoo.com> | 2018-12-11 14:28:05 +0000 |
|---|---|---|
| committer | David Beguin <dbe@odoo.com> | 2019-03-25 14:50:55 +0000 |
| commit | 4c9c249cc398d42e93939646e1237a1d0ff61166 (patch) | |
| tree | c0947faf665051856faf3d4dfac3ef7cc7b18db4 | |
| parent | 9ea4fefed2f94c6d211951e573b9a9a456f00ce6 (diff) | |
[IMP] sale_crm : create partner on new quotation if no customer set on opportunity
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.
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.
Task ID : 1917332
Closes PR #30475
| -rw-r--r-- | addons/crm/wizard/crm_partner_binding.py | 4 | ||||
| -rw-r--r-- | addons/sale_crm/__init__.py | 1 | ||||
| -rw-r--r-- | addons/sale_crm/__manifest__.py | 3 | ||||
| -rw-r--r-- | addons/sale_crm/models/crm_lead.py | 22 | ||||
| -rw-r--r-- | addons/sale_crm/views/crm_lead_views.xml | 11 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/__init__.py | 4 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/crm_opportunity_to_quotation.py | 52 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml | 35 |
8 files changed, 122 insertions, 10 deletions
diff --git a/addons/crm/wizard/crm_partner_binding.py b/addons/crm/wizard/crm_partner_binding.py index 85acbc62396..136f2b41a93 100644 --- a/addons/crm/wizard/crm_partner_binding.py +++ b/addons/crm/wizard/crm_partner_binding.py @@ -64,4 +64,8 @@ class PartnerBinding(models.TransientModel): 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 diff --git a/addons/sale_crm/__init__.py b/addons/sale_crm/__init__.py index e3e519761b8..ab491732dfe 100644 --- a/addons/sale_crm/__init__.py +++ b/addons/sale_crm/__init__.py @@ -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 diff --git a/addons/sale_crm/__manifest__.py b/addons/sale_crm/__manifest__.py index 9620ea428e7..fd554044d9d 100644 --- a/addons/sale_crm/__manifest__.py +++ b/addons/sale_crm/__manifest__.py @@ -22,7 +22,8 @@ modules. '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' diff --git a/addons/sale_crm/models/crm_lead.py b/addons/sale_crm/models/crm_lead.py index 6d080f1b1f9..e5fe4e07203 100644 --- a/addons/sale_crm/models/crm_lead.py +++ b/addons/sale_crm/models/crm_lead.py @@ -60,3 +60,25 @@ class CrmLead(models.Model): 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 diff --git a/addons/sale_crm/views/crm_lead_views.xml b/addons/sale_crm/views/crm_lead_views.xml index 1634b340bda..d0c79228246 100644 --- a/addons/sale_crm/views/crm_lead_views.xml +++ b/addons/sale_crm/views/crm_lead_views.xml @@ -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': ['&', ('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': ['&', ('probability', '=', 0), ('active', '=', False)]}"/> </xpath> <button name="action_schedule_meeting" position="after"> <button class="oe_stat_button" type="action" diff --git a/addons/sale_crm/wizard/__init__.py b/addons/sale_crm/wizard/__init__.py new file mode 100644 index 00000000000..cf3b469f815 --- /dev/null +++ b/addons/sale_crm/wizard/__init__.py @@ -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 diff --git a/addons/sale_crm/wizard/crm_opportunity_to_quotation.py b/addons/sale_crm/wizard/crm_opportunity_to_quotation.py new file mode 100644 index 00000000000..d88d3706971 --- /dev/null +++ b/addons/sale_crm/wizard/crm_opportunity_to_quotation.py @@ -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) + diff --git a/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml b/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml new file mode 100644 index 00000000000..f435040ff51 --- /dev/null +++ b/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml @@ -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> |
