diff --git a/addons/sale_margin/__init__.py b/addons/sale_margin/__init__.py index c61d2d59a98..a5f67aebd79 100644 --- a/addons/sale_margin/__init__.py +++ b/addons/sale_margin/__init__.py @@ -1,4 +1,5 @@ +# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -import sale_margin +import models import report diff --git a/addons/sale_margin/__openerp__.py b/addons/sale_margin/__openerp__.py index f4a693a31e3..f8289c67545 100644 --- a/addons/sale_margin/__openerp__.py +++ b/addons/sale_margin/__openerp__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. { @@ -11,11 +12,7 @@ This module adds the 'Margin' on sales order. This gives the profitability by calculating the difference between the Unit Price and Cost Price. """, - 'author':'OpenERP SA', 'depends':['sale'], - 'demo':['sale_margin_demo.xml'], - 'test': ['test/sale_margin.yml'], - 'data':['security/ir.model.access.csv','sale_margin_view.xml'], - 'auto_install': False, - 'installable': True, + 'demo':['data/sale_margin_demo.xml'], + 'data':['security/ir.model.access.csv','views/sale_margin_view.xml'], } diff --git a/addons/sale_margin/sale_margin_demo.xml b/addons/sale_margin/data/sale_margin_demo.xml similarity index 98% rename from addons/sale_margin/sale_margin_demo.xml rename to addons/sale_margin/data/sale_margin_demo.xml index a41f05304a4..8c1a96535a4 100644 --- a/addons/sale_margin/sale_margin_demo.xml +++ b/addons/sale_margin/data/sale_margin_demo.xml @@ -1,5 +1,5 @@ - + @@ -43,4 +43,4 @@ - + diff --git a/addons/sale_margin/models/__init__.py b/addons/sale_margin/models/__init__.py new file mode 100644 index 00000000000..76bcb3512a1 --- /dev/null +++ b/addons/sale_margin/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import sale_order diff --git a/addons/sale_margin/models/sale_order.py b/addons/sale_margin/models/sale_order.py new file mode 100644 index 00000000000..f836d24935e --- /dev/null +++ b/addons/sale_margin/models/sale_order.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models +import odoo.addons.decimal_precision as dp + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + margin = fields.Float(compute='_product_margin', digits=dp.get_precision('Product Price'), store=True) + purchase_price = fields.Float(string='Cost', digits=dp.get_precision('Product Price')) + + @api.multi + @api.onchange('product_id', 'product_uom_qty') + def product_id_change_margin(self): + for line in self: + if line.order_id.pricelist_id: + frm_cur = self.env.user.company_id.currency_id + to_cur = line.order_id.pricelist_id.currency_id + purchase_price = line.product_id.standard_price + if line.product_uom != line.product_id.uom_id: + purchase_price = self.env['product.uom']._compute_price(line.product_id.uom_id.id, purchase_price, to_uom_id=line.product_uom.id) + ctx = self.env.context.copy() + ctx['date'] = line.order_id.date_order + price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False) + line.purchase_price = price + + @api.depends('product_id', 'purchase_price', 'product_uom_qty', 'price_unit') + def _product_margin(self): + for line in self: + currency = line.order_id.pricelist_id.currency_id + line.margin = currency.round(line.price_subtotal - ((line.purchase_price or line.product_id.standard_price) * line.product_uom_qty)) + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + margin = fields.Monetary(compute='_product_margin', help="It gives profitability by calculating the difference between the Unit Price and the cost.", currency_field='currency_id', digits=dp.get_precision('Product Price'), store=True) + + @api.depends('order_line.margin') + def _product_margin(self): + for order in self: + order.margin = sum(order.order_line.filtered(lambda r: r.state != 'cancel').mapped('margin')) diff --git a/addons/sale_margin/report/__init__.py b/addons/sale_margin/report/__init__.py index aa0c78c6ade..894dd3f737b 100644 --- a/addons/sale_margin/report/__init__.py +++ b/addons/sale_margin/report/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. import sale_report diff --git a/addons/sale_margin/report/sale_report.py b/addons/sale_margin/report/sale_report.py index 9388ce3d5b5..5bfcaaacf34 100644 --- a/addons/sale_margin/report/sale_report.py +++ b/addons/sale_margin/report/sale_report.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. -from openerp import models, fields +from odoo import fields, models -class sale_report(models.Model): +class SaleReport(models.Model): _inherit = 'sale.report' margin = fields.Float('Margin') def _select(self): - return super(sale_report, self)._select() + ", SUM(l.margin) AS margin" + return super(SaleReport, self)._select() + ", SUM(l.margin) AS margin" diff --git a/addons/sale_margin/sale_margin.py b/addons/sale_margin/sale_margin.py deleted file mode 100644 index 62659b5c046..00000000000 --- a/addons/sale_margin/sale_margin.py +++ /dev/null @@ -1,67 +0,0 @@ -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from openerp import api -from openerp.osv import fields, osv -import openerp.addons.decimal_precision as dp - -class sale_order_line(osv.osv): - _inherit = "sale.order.line" - - @api.multi - @api.onchange('product_id', 'product_uom_qty') - def product_id_change_margin(self): - for line in self: - if line.order_id.pricelist_id: - frm_cur = self.env.user.company_id.currency_id - to_cur = line.order_id.pricelist_id.currency_id - purchase_price = line.product_id.standard_price - if line.product_uom != line.product_id.uom_id: - purchase_price = self.env['product.uom']._compute_price(line.product_id.uom_id.id, purchase_price, to_uom_id=line.product_uom.id) - ctx = self.env.context.copy() - ctx['date'] = line.order_id.date_order - price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False) - line.purchase_price = price - - def _product_margin(self, cr, uid, ids, field_name, arg, context=None): - cur_obj = self.pool.get('res.currency') - res = {} - for line in self.browse(cr, uid, ids, context=context): - cur = line.order_id.pricelist_id.currency_id - res[line.id] = 0 - if line.product_id: - tmp_margin = line.price_subtotal - ((line.purchase_price or line.product_id.standard_price) * line.product_uom_qty) - res[line.id] = cur_obj.round(cr, uid, cur, tmp_margin) - return res - - _columns = { - 'margin': fields.function(_product_margin, string='Margin', digits_compute= dp.get_precision('Product Price'), - store = True), - 'purchase_price': fields.float('Cost', digits_compute= dp.get_precision('Product Price')) - } - - -class sale_order(osv.osv): - _inherit = "sale.order" - - def _product_margin(self, cr, uid, ids, field_name, arg, context=None): - result = {} - for sale in self.browse(cr, uid, ids, context=context): - result[sale.id] = 0.0 - for line in sale.order_line: - if line.state == 'cancel': - continue - result[sale.id] += line.margin or 0.0 - return result - - def _get_order(self, cr, uid, ids, context=None): - result = {} - for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context): - result[line.order_id.id] = True - return result.keys() - - _columns = { - 'margin': fields.function(_product_margin, string='Margin', help="It gives profitability by calculating the difference between the Unit Price and the cost.", store={ - 'sale.order.line': (_get_order, ['margin', 'purchase_price'], 20), - 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 20), - }, digits_compute= dp.get_precision('Product Price')), - } diff --git a/addons/sale_margin/test/sale_margin.yml b/addons/sale_margin/test/sale_margin.yml deleted file mode 100644 index 38b987d30f5..00000000000 --- a/addons/sale_margin/test/sale_margin.yml +++ /dev/null @@ -1,31 +0,0 @@ -- - In order to test the sale_margin module in OpenERP, - I create a sale order and verify its margin -- - I place a sale order for product keyboard, quantity 50 -- - !record {model: sale.order, id: sale_order_so11}: - date_order: !eval time.strftime('%Y-%m-%d') - name: Test_SO011 - order_line: - - name: '[CARD] Graphics Card' - price_unit: 7.0 - product_uom: product.product_uom_unit - product_uom_qty: 100.0 - state: draft - product_id: product.product_product_24 - partner_id: base.res_partner_4 - partner_invoice_id: base.res_partner_address_7 - partner_shipping_id: base.res_partner_address_7 - pricelist_id: product.list0 -- - I confirm the sale order -- - !python {model: sale.order}: | - self.action_confirm(cr, uid, [ref("sale_order_so11")], context=context) -- - I verify that margin field gets bind with the value -- - !python {model: sale.order}: | - so = self.browse(cr, uid, ref("sale_order_so11")) - assert so.margin, "No margin !" diff --git a/addons/sale_margin/tests/__init__.py b/addons/sale_margin/tests/__init__.py new file mode 100644 index 00000000000..4a3d8eb45c4 --- /dev/null +++ b/addons/sale_margin/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_sale_margin diff --git a/addons/sale_margin/tests/test_sale_margin.py b/addons/sale_margin/tests/test_sale_margin.py new file mode 100644 index 00000000000..c2481690a2d --- /dev/null +++ b/addons/sale_margin/tests/test_sale_margin.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import common +from datetime import datetime + + +class TestSaleMargin(common.TransactionCase): + + def setUp(self): + super(TestSaleMargin, self).setUp() + self.SaleOrder = self.env['sale.order'] + + self.product_uom_id = self.ref('product.product_uom_unit') + self.product_id = self.ref('product.product_product_24') + self.partner_id = self.ref('base.res_partner_4') + self.partner_invoice_address_id = self.ref('base.res_partner_address_7') + self.pricelist_id = self.ref('product.list0') + + def test_sale_margin(self): + """ Test the sale_margin module in Odoo. """ + # Create a sale order for product Graphics Card. + sale_order_so11 = self.SaleOrder.create({ + 'date_order': datetime.today(), + 'name': 'Test_SO011', + 'order_line': [(0, 0, { + 'name': '[CARD] Graphics Card', + 'purchase_price': 700.0, + 'price_unit': 1000.0, + 'product_uom': self.product_uom_id, + 'product_uom_qty': 10.0, + 'state': 'draft', + 'product_id': self.product_id})], + 'partner_id': self.partner_id, + 'partner_invoice_id': self.partner_invoice_address_id, + 'partner_shipping_id': self.partner_invoice_address_id, + 'pricelist_id': self.pricelist_id}) + # Confirm the sale order. + sale_order_so11.action_confirm() + # Verify that margin field gets bind with the value. + self.assertEqual(sale_order_so11.margin, 3000.00, "Sale order margin should be 3000.00") diff --git a/addons/sale_margin/sale_margin_view.xml b/addons/sale_margin/views/sale_margin_view.xml similarity index 90% rename from addons/sale_margin/sale_margin_view.xml rename to addons/sale_margin/views/sale_margin_view.xml index d0cffa1e035..fa9c56fe28a 100644 --- a/addons/sale_margin/sale_margin_view.xml +++ b/addons/sale_margin/views/sale_margin_view.xml @@ -1,6 +1,5 @@ - - + sale.order.margin.view.form @@ -9,7 +8,7 @@ - + @@ -37,5 +36,4 @@ - - +