diff --git a/sale_triple_discount/models/sale_order_line.py b/sale_triple_discount/models/sale_order_line.py index 493292f78a4..fa5c5ed9e8a 100644 --- a/sale_triple_discount/models/sale_order_line.py +++ b/sale_triple_discount/models/sale_order_line.py @@ -4,42 +4,12 @@ # Copyright 2018 ~ 2021 Simone Rubino - Agile Business Group # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models -import odoo.addons.decimal_precision as dp +from odoo import api, models class SaleOrderLine(models.Model): - _inherit = "sale.order.line" - - def _get_final_discount(self): - self.ensure_one() - if self.discounting_type == "additive": - return self._additive_discount() - elif self.discounting_type == "multiplicative": - return self._multiplicative_discount() - - def _additive_discount(self): - self.ensure_one() - discount = sum( - [getattr(self, x) or 0.0 for x in self._discount_fields()] - ) - if discount <= 0: - return 0 - elif discount >= 100: - return 100 - return discount - - def _multiplicative_discount(self): - self.ensure_one() - discounts = [1 - (self[x] or 0.0) / 100 - for x in self._discount_fields()] - final_discount = 1 - for discount in discounts: - final_discount *= discount - return 100 - final_discount * 100 - - def _discount_fields(self): - return ['discount', 'discount2', 'discount3'] + _name = "sale.order.line" + _inherit = ["line.triple_discount.mixin", "sale.order.line"] @api.depends('discount2', 'discount3', 'discounting_type') def _compute_amount(self): @@ -48,45 +18,6 @@ def _compute_amount(self): super(SaleOrderLine, line)._compute_amount() line.triple_discount_postprocess(prev_values) - discount2 = fields.Float( - 'Disc. 2 (%)', - digits=dp.get_precision('Discount'), - default=0.0, - ) - discount3 = fields.Float( - 'Disc. 3 (%)', - digits=dp.get_precision('Discount'), - default=0.0, - ) - discounting_type = fields.Selection( - string="Discounting type", - selection=[ - ('additive', 'Additive'), - ('multiplicative', 'Multiplicative'), - ], - default="multiplicative", - required=True, - help="Specifies whether discounts should be additive " - "or multiplicative.\nAdditive discounts are summed first and " - "then applied.\nMultiplicative discounts are applied sequentially.\n" - "Multiplicative discounts are default", - ) - - _sql_constraints = [ - ('discount2_limit', 'CHECK (discount2 <= 100.0)', - 'Discount 2 must be lower than 100%.'), - ('discount3_limit', 'CHECK (discount3 <= 100.0)', - 'Discount 3 must be lower than 100%.'), - ] - - def _get_triple_discount(self): - """Get the discount that is equivalent to the subsequent application - of discount, discount2 and discount3""" - discount_factor = 1.0 - for discount in [self.discount, self.discount2, self.discount3]: - discount_factor *= (100.0 - discount) / 100.0 - return 100.0 - (discount_factor * 100.0) - def _prepare_invoice_line(self, qty): res = super(SaleOrderLine, self)._prepare_invoice_line(qty) res.update({ @@ -100,30 +31,3 @@ def _get_price_reduce(self): prev_values = self.triple_discount_preprocess() super(SaleOrderLine, self)._get_price_reduce() self.triple_discount_postprocess(prev_values) - - @api.multi - def triple_discount_preprocess(self): - """Save the values of the discounts in a dictionary, - to be restored in postprocess. - Resetting discount2 and discount3 to 0.0 avoids issues if - this method is called multiple times.""" - prev_values = dict() - - for line in self: - prev_values[line] = dict( - discount=line.discount, - discount2=line.discount2, - discount3=line.discount3, - ) - line.update({ - 'discount': line._get_final_discount(), - 'discount2': 0.0, - 'discount3': 0.0 - }) - return prev_values - - @api.model - def triple_discount_postprocess(self, prev_values): - """Restore the discounts of the lines in the dictionary prev_values.""" - for line, prev_vals_dict in list(prev_values.items()): - line.update(prev_vals_dict) diff --git a/sale_triple_discount/tests/test_sale_triple_discount.py b/sale_triple_discount/tests/test_sale_triple_discount.py index 1577c1d566b..3ded85a4111 100644 --- a/sale_triple_discount/tests/test_sale_triple_discount.py +++ b/sale_triple_discount/tests/test_sale_triple_discount.py @@ -150,3 +150,19 @@ def test_05_round_globally(self): self.assertEqual(self.so_line2.price_subtotal, 300.0) self.assertEqual(self.order.amount_untaxed, 375.0) self.assertEqual(self.order.amount_tax, 56.25) + + def test_06_discounts(self): + """ Tests discounts in edge case """ + order = self.env['sale.order'].create({ + 'partner_id': self.partner.id, + 'order_line': [(0, 0, { + 'name': 'Line 1', + 'product_id': self.product2.id, + 'price_unit': 25.0, + 'product_uom_qty': 65, + 'discount': 50, + 'discount2': 13, + 'discount3': 0, + })], + }) + self.assertEqual(order.order_line.price_subtotal, 706.88)