diff --git a/account_invoice_margin/__manifest__.py b/account_invoice_margin/__manifest__.py index de6a2931..70bc5892 100755 --- a/account_invoice_margin/__manifest__.py +++ b/account_invoice_margin/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Invoice Margin', 'author': 'Hibou Corp. ', - 'version': '16.0.1.0.0', + 'version': '16.0.1.1.0', 'license': 'AGPL-3', 'category': 'Accounting', 'sequence': 95, diff --git a/account_invoice_margin/models/account_invoice.py b/account_invoice_margin/models/account_invoice.py index ff7cd3b8..a8940c11 100644 --- a/account_invoice_margin/models/account_invoice.py +++ b/account_invoice_margin/models/account_invoice.py @@ -4,9 +4,14 @@ from odoo import api, fields, models class AccountMoveLine(models.Model): _inherit = "account.move.line" - margin = fields.Float(compute='_product_margin', digits='Product Price', store=True) - purchase_price = fields.Float(string='Cost', digits='Product Price') + margin = fields.Monetary(compute='_compute_product_margin', digits='Product Price', store=True, + groups='base.group_user') + margin_percent = fields.Float(compute='_product_margin', store=True, string='Margin (%)', + groups='base.group_user') + purchase_price = fields.Monetary(string='Cost', digits='Product Price', + groups='base.group_user') + # Note we are keeping this API because it is easy to customize and extend the purchase price/margin calculation def _compute_margin(self, move, product, product_uom, sale_lines): # if sale_line_ids and don't re-browse for line in sale_lines: @@ -25,7 +30,7 @@ class AccountMoveLine(models.Model): def product_id_change_margin(self): for line in self: if not line.product_id: - line.purchase_price = 0 + line.purchase_price = 0.0 else: line.purchase_price = line._compute_margin(line.move_id, line.product_id, line.product_uom_id, line.sale_line_ids) @@ -37,7 +42,7 @@ class AccountMoveLine(models.Model): return lines @api.depends('product_id', 'purchase_price', 'quantity', 'price_unit', 'price_subtotal') - def _product_margin(self): + def _compute_product_margin(self): for line in self: currency = line.move_id.currency_id price = line.purchase_price @@ -49,18 +54,21 @@ class AccountMoveLine(models.Model): margin = line.price_subtotal - (price * line.quantity) line.margin = currency.round(margin) if currency else margin + line.margin_percent = 1.0 if not line.price_subtotal else line.margin / line.price_subtotal class AccountMove(models.Model): _inherit = "account.move" - 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='Product Price', - store=True) + margin = fields.Monetary(compute='_compute_product_margin', store=True, digits='Product Price', + help="Profitability by calculating the difference between the Unit Price and the cost.", + groups='base.group_user') + margin_percent = fields.Float(compute='_compute_product_margin', store=True, string='Margin (%)', + groups='base.group_user') - @api.depends('invoice_line_ids.margin') - def _product_margin(self): + @api.depends('invoice_line_ids.margin', 'invoice_line_ids.price_subtotal') + def _compute_product_margin(self): for invoice in self: invoice.margin = sum(invoice.invoice_line_ids.mapped('margin')) + total_price_subtotal = sum(invoice.invoice_line_ids.mapped('price_subtotal')) + invoice.margin_percent = 1.0 if not total_price_subtotal else invoice.margin / total_price_subtotal diff --git a/account_invoice_margin/tests/test_invoice_margin.py b/account_invoice_margin/tests/test_invoice_margin.py index 156c14c2..0ae28f72 100644 --- a/account_invoice_margin/tests/test_invoice_margin.py +++ b/account_invoice_margin/tests/test_invoice_margin.py @@ -1,3 +1,4 @@ +from odoo.fields import Command from odoo.addons.sale_margin.tests.test_sale_margin import TestSaleMargin from datetime import datetime @@ -7,56 +8,45 @@ class TestInvoiceMargin(TestSaleMargin): def setUp(self): super(TestInvoiceMargin, self).setUp() self.AccountMove = self.env['account.move'] + self.SaleOrder = self.env['sale.order'] def test_invoice_margin(self): - """ Test the sale_margin module in Odoo. """ - # Create a sales order for product Graphics Card. - sale_order_so11 = self.SaleOrder.create({ - 'date_order': datetime.today(), - 'name': 'Test_SO011', - 'order_line': [ - (0, 0, { - 'name': '[CARD] Individual Workplace', - '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}), - (0, 0, { - 'name': 'Line without product_uom', - 'price_unit': 1000.0, - 'purchase_price': 700.0, - '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 sales order. - sale_order_so11.action_confirm() - # Verify that margin field gets bind with the value. - self.assertEqual(sale_order_so11.margin, 6000.00, "Sales order margin should be 6000.00") + self.product.standard_price = 700.0 + order = self.empty_order - sale_order_so11.order_line.write({'qty_delivered': 10.0}) + order.order_line = [ + Command.create({ + 'price_unit': 1000.0, + 'product_uom_qty': 10.0, + 'product_id': self.product.id, + }), + ] + # Confirm the sales order. + order.action_confirm() + # Verify that margin field gets bind with the value. + self.assertEqual(order.margin, 3000.00, "Sales order profit should be 6000.00") + self.assertEqual(order.margin_percent, 0.3, "Sales order margin should be 30%") + + order.order_line.write({'qty_delivered': 10.0}) # Invoice the sales order. - inv = sale_order_so11._create_invoices() - self.assertEqual(inv.margin, sale_order_so11.margin) + inv = order._create_invoices() + self.assertEqual(inv.margin, order.margin) + self.assertEqual(inv.margin_percent, order.margin_percent) - account = self.env['account.account'].search([('internal_type', '=', 'other')], limit=1) + account = self.env['account.account'].search([('account_type', '=', 'expense')], limit=1) + self.assertTrue(account) inv = self.AccountMove.create({ 'move_type': 'in_invoice', - 'partner_id': self.partner_id, + 'partner_id': order.partner_id.id, 'invoice_line_ids': [ (0, 0, { 'account_id': account.id, 'name': '[CARD] Graphics Card', - 'purchase_price': 600.0, 'price_unit': 1000.0, + 'purchase_price': 600.0, 'quantity': 10.0, - 'product_id': self.product_id}), + 'product_id': self.product.id}), (0, 0, { 'account_id': account.id, 'name': 'Line without product_uom', @@ -67,3 +57,4 @@ class TestInvoiceMargin(TestSaleMargin): }) self.assertEqual(len(inv.invoice_line_ids), 2) self.assertEqual(inv.margin, 6000.0) + self.assertEqual(inv.margin_percent, 0.3) diff --git a/account_invoice_margin/views/account_invoice_views.xml b/account_invoice_margin/views/account_invoice_views.xml index e1495b0b..89729da0 100644 --- a/account_invoice_margin/views/account_invoice_views.xml +++ b/account_invoice_margin/views/account_invoice_views.xml @@ -8,6 +8,9 @@ + + () +