diff options
| author | Fabien Pinckaers <fp@openerp.com> | 2015-03-07 20:34:27 -0800 |
|---|---|---|
| committer | Fabien Pinckaers <fp@openerp.com> | 2015-03-07 20:34:27 -0800 |
| commit | 6a7f17a057ca47fd43f85d8089cbd2eb7f22acb6 (patch) | |
| tree | fb1558a7a7c096db3b5c46b4ae85aed5be41be26 | |
| parent | 53fa36df6331885a596c58b56695b8d7f3ea1fba (diff) | |
[IMP] improved usability: revenues & quotes on opportunities, no wizard for opportunity to quotes
| -rw-r--r-- | addons/sale_crm/__init__.py | 1 | ||||
| -rw-r--r-- | addons/sale_crm/__openerp__.py | 2 | ||||
| -rw-r--r-- | addons/sale_crm/crm_lead.py | 31 | ||||
| -rw-r--r-- | addons/sale_crm/sale_crm_view.xml | 26 | ||||
| -rw-r--r-- | addons/sale_crm/test/sale_crm.yml | 19 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/__init__.py | 22 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/crm_make_sale.py | 154 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/crm_make_sale_view.xml | 36 |
8 files changed, 41 insertions, 250 deletions
diff --git a/addons/sale_crm/__init__.py b/addons/sale_crm/__init__.py index 4a269fd4e6c..5ec010a95ea 100644 --- a/addons/sale_crm/__init__.py +++ b/addons/sale_crm/__init__.py @@ -19,6 +19,5 @@ # ############################################################################## -import wizard import sale_crm import crm_lead diff --git a/addons/sale_crm/__openerp__.py b/addons/sale_crm/__openerp__.py index c13509b8a3a..f4c38f3300e 100644 --- a/addons/sale_crm/__openerp__.py +++ b/addons/sale_crm/__openerp__.py @@ -38,13 +38,11 @@ modules. 'website': 'https://www.odoo.com/page/crm', 'depends': ['sale', 'crm', 'web_kanban_gauge'], 'data': [ - 'wizard/crm_make_sale_view.xml', 'sale_crm_view.xml', 'security/sale_crm_security.xml', 'security/ir.model.access.csv', ], 'demo': [], - 'test': ['test/sale_crm.yml'], 'installable': True, 'auto_install': True, } diff --git a/addons/sale_crm/crm_lead.py b/addons/sale_crm/crm_lead.py index 28ea8205eec..4c31f3b9fc3 100644 --- a/addons/sale_crm/crm_lead.py +++ b/addons/sale_crm/crm_lead.py @@ -1,16 +1,23 @@ -from openerp.osv import osv, fields +from openerp import models, fields, api, _ +import openerp.addons.decimal_precision as dp -class crm_lead(osv.Model): - _inherit = 'crm.lead' +class crm_lead(models.Model): + _inherit = ['crm.lead'] - def _get_sale_amount_total(self, cr, uid, ids, fields, args, context=None): - res = dict.fromkeys(ids, False) - sale_rec = self.pool['sale.order'].read_group(cr, uid, [('opportunity_id', 'in', ids), ('state', '!=', 'cancel')], ['opportunity_id', 'amount_total'], ['opportunity_id'], context=context) - for key, value in dict(map(lambda x: (x['opportunity_id'] and x['opportunity_id'][0], x['amount_total']), sale_rec)).items(): - res[key] = value - return res + @api.one + @api.depends('order_ids') + def _get_sale_amount_total(self): + total = 0.0 + nbr = 0 + for order in self.order_ids: + if order.state == 'draft': + nbr += 1 + if order.state not in ('draft', 'cancel'): + total += order.currency_id.compute(order.amount_untaxed, self.company_currency) + self.sale_amount_total = total + self.sale_number = nbr - _columns = { - 'sale_amount_total': fields.function(_get_sale_amount_total, string="Total Amount Of Quotations", type="float") - } + sale_amount_total= fields.Float(compute='_get_sale_amount_total', string="Sum of Orders", readonly=True, digits_compute=dp.get_precision('Account')) + sale_number = fields.Integer(compute='_get_sale_amount_total', string="Number of Quotations", readonly=True) + order_ids = fields.One2many('sale.order', 'opportunity_id', string='Orders') diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index 1b206fbdcea..17dd923784c 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -3,10 +3,18 @@ <data> <act_window name="Sale Orders" + context="{'search_default_opportunity_id': active_id, 'default_opportunity_id': active_id}" + res_model="sale.order" + src_model="crm.lead" + view_mode="form,tree,graph" + domain="[('opportunity_id', '=', active_id)]" + id="sale_action_quotations_new"/> + + <act_window name="Sale Orders" context="{'search_default_opportunity_id': [active_id], 'default_opportunity_id': active_id}" res_model="sale.order" src_model="crm.lead" - domain="[('opportunity_id', 'in', [active_id])]" + domain="[('opportunity_id', '=', active_id)]" id="sale_action_quotations"/> <record model="ir.ui.view" id="crm_case_form_view_oppor"> @@ -16,14 +24,24 @@ <field name="arch" type="xml"> <data> <xpath expr="//field[@name='stage_id']" position="before"> - <button attrs="{'invisible': [('probability', '=', 0)]}" string="Convert to Quotation" name="%(action_crm_make_sale)d" type="action" class="oe_highlight"/> - <button attrs="{'invisible': [('probability', '>', 0)]}" string="Convert to Quotation" name="%(action_crm_make_sale)d" type="action"/> + <button attrs="{'invisible': [('probability', '=', 0)]}" string="New Quotation" name="%(sale_action_quotations_new)d" type="action" class="oe_highlight" + context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}"/> + <button attrs="{'invisible': [('probability', '>', 0)]}" string="New Quotation" name="%(sale_action_quotations_new)d" type="action" + context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}"/> </xpath> <xpath expr="//div[@name='buttons']" position="inside"> <button class="oe_inline oe_stat_button" type="action" name="%(sale_action_quotations)d" icon="stat_button_icon fa fa-usd" context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}"> - <div><strong><field name="sale_amount_total" widget="monetary"/></strong><br/>Sales</div> + <div> + <strong><field name="sale_number" class="oe_inline"/></strong> + <span attrs="{'invisible': [('sale_number', '<', 2)]}"> Quotes</span> + <span attrs="{'invisible': [('sale_number', '>', 1)]}"> Quote</span> + <br/> + <strong attrs="{'invisible': [('sale_amount_total', '=', 0)]}"> + <field name="sale_amount_total" class="oe_inline" widget="monetary" options="{'currency_field': 'company_currency'}"/> + </strong> + </div> </button> </xpath> </data> diff --git a/addons/sale_crm/test/sale_crm.yml b/addons/sale_crm/test/sale_crm.yml deleted file mode 100644 index 21d2cc08195..00000000000 --- a/addons/sale_crm/test/sale_crm.yml +++ /dev/null @@ -1,19 +0,0 @@ -- - I open the wizard "Make sales". -- - !record {model: crm.make.sale, id: crm_make_sale_0}: - partner_id: base.res_partner_4 -- - I convert opportunity into "Quotation". -- - !python {model: crm.make.sale}: | - crm_lead = self.pool.get('crm.lead') - crm = crm_lead.browse(cr, uid, ref("crm.crm_case_13")) - self.makeOrder(cr, uid, [ref("crm_make_sale_0")], {"active_ids": [crm.id], - "active_id": crm.id}) -- - I check that reference number of "Quotation" in opportunity. -- - !python {model: crm.lead}: | - crm = self.browse(cr, uid, ref("crm.crm_case_13")) - assert crm.ref, "Quotation has not been created." diff --git a/addons/sale_crm/wizard/__init__.py b/addons/sale_crm/wizard/__init__.py deleted file mode 100644 index f37964b54a0..00000000000 --- a/addons/sale_crm/wizard/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -import crm_make_sale diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py deleted file mode 100644 index e4166f0c414..00000000000 --- a/addons/sale_crm/wizard/crm_make_sale.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -from openerp.osv import fields, osv -from openerp.tools.translate import _ -from openerp.exceptions import UserError - - -class crm_make_sale(osv.osv_memory): - """ Make sale order for crm """ - - _name = "crm.make.sale" - _description = "Make sales" - - def _selectPartner(self, cr, uid, context=None): - """ - This function gets default value for partner_id field. - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param context: A standard dictionary for contextual values - @return: default value of partner_id field. - """ - if context is None: - context = {} - - lead_obj = self.pool.get('crm.lead') - active_id = context and context.get('active_id', False) or False - if not active_id: - return False - - lead = lead_obj.read(cr, uid, [active_id], ['partner_id'], context=context)[0] - return lead['partner_id'][0] if lead['partner_id'] else False - - def view_init(self, cr, uid, fields_list, context=None): - return super(crm_make_sale, self).view_init(cr, uid, fields_list, context=context) - - def makeOrder(self, cr, uid, ids, context=None): - """ - This function create Quotation on given case. - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of crm make sales' ids - @param context: A standard dictionary for contextual values - @return: Dictionary value of created sales order. - """ - # update context: if come from phonecall, default state values can make the quote crash lp:1017353 - context = dict(context or {}) - context.pop('default_state', False) - - case_obj = self.pool.get('crm.lead') - sale_obj = self.pool.get('sale.order') - partner_obj = self.pool.get('res.partner') - data = context and context.get('active_ids', []) or [] - - for make in self.browse(cr, uid, ids, context=context): - partner = make.partner_id - partner_addr = partner_obj.address_get(cr, uid, [partner.id], - ['default', 'invoice', 'delivery', 'contact']) - pricelist = partner.property_product_pricelist.id - fpos = partner.property_account_position and partner.property_account_position.id or False - payment_term = partner.property_payment_term and partner.property_payment_term.id or False - new_ids = [] - for case in case_obj.browse(cr, uid, data, context=context): - if not partner and case.partner_id: - partner = case.partner_id - fpos = partner.property_account_position and partner.property_account_position.id or False - payment_term = partner.property_payment_term and partner.property_payment_term.id or False - partner_addr = partner_obj.address_get(cr, uid, [partner.id], - ['default', 'invoice', 'delivery', 'contact']) - pricelist = partner.property_product_pricelist.id - if False in partner_addr.values(): - raise UserError(_('No address(es) defined for this customer.')) - - vals = { - 'origin': _('Opportunity: %s') % str(case.id), - 'team_id': case.team_id and case.team_id.id or False, - 'tag_ids': [(6, 0, [categ_id.id for categ_id in case.tag_ids])], - 'partner_id': partner.id, - 'pricelist_id': pricelist, - 'partner_invoice_id': partner_addr['invoice'], - 'partner_shipping_id': partner_addr['delivery'], - 'date_order': fields.datetime.now(), - 'fiscal_position': fpos, - 'payment_term':payment_term, - 'opportunity_id': case.id, - 'campaign_id': case.campaign_id and case.campaign_id.id or False, - 'medium_id': case.medium_id and case.medium_id.id or False, - 'source_id': case.source_id and case.source_id.id or False, - } - if partner.id: - vals['user_id'] = partner.user_id and partner.user_id.id or uid - new_id = sale_obj.create(cr, uid, vals, context=context) - sale_order = sale_obj.browse(cr, uid, new_id, context=context) - case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id}) - new_ids.append(new_id) - message = _("Opportunity has been <b>converted</b> to the quotation <em>%s</em>.") % (sale_order.name) - case.message_post(body=message) - if make.close: - case_obj.case_mark_won(cr, uid, data, context=context) - if not new_ids: - return {'type': 'ir.actions.act_window_close'} - if len(new_ids)<=1: - value = { - 'domain': str([('id', 'in', new_ids)]), - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'sale.order', - 'view_id': False, - 'type': 'ir.actions.act_window', - 'name' : _('Quotation'), - 'res_id': new_ids and new_ids[0] - } - else: - value = { - 'domain': str([('id', 'in', new_ids)]), - 'view_type': 'form', - 'view_mode': 'tree,form', - 'res_model': 'sale.order', - 'view_id': False, - 'type': 'ir.actions.act_window', - 'name' : _('Quotation'), - 'res_id': new_ids - } - return value - - - _columns = { - 'partner_id': fields.many2one('res.partner', 'Customer', required=True, domain=[('customer','=',True)]), - 'close': fields.boolean('Mark Won', help='Check this to close the opportunity after having created the sales order.'), - } - _defaults = { - 'close': False, - 'partner_id': _selectPartner, - } diff --git a/addons/sale_crm/wizard/crm_make_sale_view.xml b/addons/sale_crm/wizard/crm_make_sale_view.xml deleted file mode 100644 index c99f3124b8e..00000000000 --- a/addons/sale_crm/wizard/crm_make_sale_view.xml +++ /dev/null @@ -1,36 +0,0 @@ -<openerp> - <data> - - <!-- crm make sale's view --> - - <record id="view_crm_make_sale" model="ir.ui.view"> - <field name="name">crm.make.sale.form</field> - <field name="model">crm.make.sale</field> - <field name="arch" type="xml"> - <form string="Convert to Quotation" > - <group col="4"> - <field name="partner_id" required="1"/> - <field name="close"/> - </group> - <footer> - <button name="makeOrder" string="_Create" type="object" class="oe_highlight"/> - or - <button string="Cancel" class="oe_link" special="cancel" /> - </footer> - </form> - </field> - </record> - - <!-- crm make sale's action --> - - <record id="action_crm_make_sale" model="ir.actions.act_window"> - <field name="name">Make Quotation</field> - <field name="type">ir.actions.act_window</field> - <field name="res_model">crm.make.sale</field> - <field name="view_type">form</field> - <field name="view_mode">form</field> - <field name="target">new</field> - </record> - - </data> -</openerp> |
