From 6a7f17a057ca47fd43f85d8089cbd2eb7f22acb6 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sat, 7 Mar 2015 20:34:27 -0800 Subject: [PATCH] [IMP] improved usability: revenues & quotes on opportunities, no wizard for opportunity to quotes --- addons/sale_crm/__init__.py | 1 - addons/sale_crm/__openerp__.py | 2 - addons/sale_crm/crm_lead.py | 31 ++-- addons/sale_crm/sale_crm_view.xml | 26 ++- addons/sale_crm/test/sale_crm.yml | 19 --- addons/sale_crm/wizard/__init__.py | 22 --- addons/sale_crm/wizard/crm_make_sale.py | 154 ------------------ addons/sale_crm/wizard/crm_make_sale_view.xml | 36 ---- 8 files changed, 41 insertions(+), 250 deletions(-) delete mode 100644 addons/sale_crm/test/sale_crm.yml delete mode 100644 addons/sale_crm/wizard/__init__.py delete mode 100644 addons/sale_crm/wizard/crm_make_sale.py delete mode 100644 addons/sale_crm/wizard/crm_make_sale_view.xml 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 @@ -2,11 +2,19 @@ + + @@ -16,14 +24,24 @@ - 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 (). -# -# 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 . -# -############################################################################## - -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 (). -# -# 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 . -# -############################################################################## - -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 converted to the quotation %s.") % (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 @@ - - - - - - - crm.make.sale.form - crm.make.sale - -
- - - - -
-
-
-
-
- - - - - Make Quotation - ir.actions.act_window - crm.make.sale - form - form - new - - -
-