Skip to content

Commit

Permalink
Fix taxes calculation and override in a proper way
Browse files Browse the repository at this point in the history
  • Loading branch information
chienandalu committed Jul 19, 2017
1 parent 22ccb6d commit 374908b
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 39 deletions.
1 change: 1 addition & 0 deletions account_invoice_triple_discount/models/__init__.py
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-

from . import account_invoice
from . import account_invoice_line
25 changes: 25 additions & 0 deletions account_invoice_triple_discount/models/account_invoice.py
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Tecnativa - David Vidal
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class AccountInvoice(models.Model):
_inherit = "account.invoice"

def get_taxes_values(self):
prices = {}
discount = {}
for line in self.invoice_line_ids:
prices[line.id] = line.price_unit
discount[line.id] = line.discount
line.price_unit *= (1 - (line.discount or 0.0) / 100.0)
line.price_unit *= (1 - (line.discount2 or 0.0) / 100.0)
line.price_unit *= (1 - (line.discount3 or 0.0) / 100.0)
line['discount'] = 0.0
tax_grouped = super(AccountInvoice, self).get_taxes_values()
for line in self.invoice_line_ids:
line['price_unit'] = prices[line.id]
line['discount'] = discount[line.id]
return tax_grouped
32 changes: 9 additions & 23 deletions account_invoice_triple_discount/models/account_invoice_line.py
Expand Up @@ -27,26 +27,12 @@ class AccountInvoiceLine(models.Model):
'invoice_id.company_id', 'invoice_id.date_invoice')
def _compute_price(self):
for line in self:
currency = line.invoice_id and line.invoice_id.currency_id or None
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
price *= (1 - (line.discount2 or 0.0) / 100.0)
price *= (1 - (line.discount3 or 0.0) / 100.0)
taxes = False
if line.invoice_line_tax_ids:
taxes = line.invoice_line_tax_ids.compute_all(
price, currency, line.quantity, product=line.product_id,
partner=line.invoice_id.partner_id)
line.price_subtotal = price_subtotal_signed = taxes[
'total_excluded'] if taxes else line.quantity * price
if (line.invoice_id.currency_id and
line.invoice_id.company_id and
line.invoice_id.currency_id !=
line.invoice_id.company_id.currency_id):
price_subtotal_signed = \
line.invoice_id.currency_id.with_context(
date=line.invoice_id.date_invoice).compute(
price_subtotal_signed,
line.invoice_id.company_id.currency_id)
sign = line.invoice_id.type in ['in_refund',
'out_refund'] and -1 or 1
line.price_subtotal_signed = price_subtotal_signed * sign
price = line.price_unit
discount = line.discount
line.price_unit *= (1 - (line.discount or 0.0) / 100.0)
line.price_unit *= (1 - (line.discount2 or 0.0) / 100.0)
line.price_unit *= (1 - (line.discount3 or 0.0) / 100.0)
line['discount'] = 0.0
super(AccountInvoiceLine, line)._compute_price()
line['price_unit'] = price
line['discount'] = discount
Expand Up @@ -11,6 +11,12 @@ class TestInvoiceTripleDiscount(SavepointCase):
def setUpClass(cls):
super(TestInvoiceTripleDiscount, cls).setUpClass()
cls.partner = cls.env['res.partner'].create({'name': 'Test'})
cls.tax = cls.env['account.tax'].create({
'name': 'TAX 15%',
'amount_type': 'percent',
'type_tax_use': 'purchase',
'amount': 15.0,
})
cls.account_type = cls.env['account.account.type'].create({
'name': 'Test',
'type': 'receivable',
Expand All @@ -34,40 +40,44 @@ def setUpClass(cls):
'name': 'Line 1',
'price_unit': 200.0,
'account_id': cls.account.id,
'invoice_line_tax_ids': [(6, 0, [cls.tax.id])],
})
cls.invoice._onchange_invoice_line_ids()

def test_discounts(self):
def test_01_discounts(self):
""" Tests multiple discounts in line with taxes """
# Adds a first discount
self.invoice_line1.discount = 50.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 100.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 115.0)
# Adds a second discount over the price calculated before
self.invoice_line1.discount2 = 40.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 60.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 69.0)
# Adds a third discount over the price calculated before
self.invoice_line1.discount3 = 50.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 30.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 34.5)
# Deletes first discount
self.invoice_line1.discount = 0.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 60.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 69.0)
# Charge 5% over price:
self.invoice_line1.discount = -5.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 63.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 72.45)

def test_discounts_multiple_lines(self):
def test_02_discounts_multiple_lines(self):
""" Tests multiple lines with mixed taxes """
self.invoice_line2 = self.invoice_line.create({
'invoice_id': self.invoice.id,
'name': 'Line 1',
'price_unit': 500.0,
'account_id': self.account.id,
})
self.invoice_line2.discount3 = 50.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 450.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 480.0)
self.invoice_line1.discount = 50.0
self.invoice._compute_amount()
self.assertEqual(self.invoice.amount_total, 350.0)
self.invoice._onchange_invoice_line_ids()
self.assertEqual(self.invoice.amount_total, 365.0)

0 comments on commit 374908b

Please sign in to comment.