[FIX] sale: fix rounded discount

Steps to reproduce:
- Install and launch sales
- In settings: activate price lists and discount; price list based on advanced rules
- Create a new price list; based on percentage (54%)*; applicable on all products; show discount
- Make sure the Public Price List has show discount activated
- Create a new quotation
- Select the Test pricelist
- Select a product (price 0.03 eur/$/other)*
- Change the price list to Public price list
- update the prices
- change the price list to Test price list
- update the prices
-> The Discount shown is not the one defined in the price list (66.67%)*
*(values for my example)

Solution:
Use the real price and not the a posteriori-rounded price for the computation of the discount  in the `update_prices` method.

opw-2677884

closes odoo/odoo#81395

X-original-commit: 986dbc20952caae9d5a1b4b7ee34cfb994dea077
Signed-off-by: yosa-odoo <yosa@odoo.com>
This commit is contained in:
Yolann Sabaux
2021-12-16 09:51:50 +00:00
parent 2e10595925
commit fcd6610bcc
2 changed files with 63 additions and 1 deletions
+2 -1
View File
@@ -534,7 +534,8 @@ class SaleOrder(models.Model):
price_unit = self.env['account.tax']._fix_tax_included_price_company(
line._get_display_price(product), line.product_id.taxes_id, line.tax_id, line.company_id)
if self.pricelist_id.discount_policy == 'without_discount' and price_unit:
discount = max(0, (price_unit - product.price) * 100 / price_unit)
price_discount_unrounded = self.pricelist_id.get_product_price(product, line.product_uom_qty, self.partner_id, self.date_order, line.product_uom.id)
discount = max(0, (price_unit - price_discount_unrounded) * 100 / price_unit)
else:
discount = 0
lines_to_update.append((1, line.id, {'price_unit': price_unit, 'discount': discount}))
+61
View File
@@ -350,3 +350,64 @@ class TestSaleOrder(TestSaleCommon):
self.assertEqual(order_line.price_unit, 180, "First pricelist rule not applied")
order_line.product_uom = new_uom
self.assertEqual(order_line.price_unit, 1800, "First pricelist rule not applied")
def test_sale_change_of_pricelists_excluded_value_discount(self):
""" Test SO with the pricelist 'discount displayed' and check displayed percentage value after multiple changes of pricelist """
# Create a pricelist without discount policy: percentage on all products
pricelist_discount_excl_global = self.env['product.pricelist'].create({
'name': 'Pricelist C',
'discount_policy': 'without_discount',
'company_id': self.env.company.id,
'item_ids': [(0, 0, {
'applied_on': '3_global',
'compute_price': 'percentage',
'percent_price': 54,
})],
})
# Create a product with a very low price
amazing_product = self.env['product.product'].create({
'name': 'Amazing Product',
'lst_price': 0.03,
})
# create a simple Sale Order with a unique line
sale_order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'order_line': [(0, 0, {
'name': amazing_product.name,
'product_id': amazing_product.id,
'product_uom_qty': 1,
'product_uom': amazing_product.uom_id.id,
'price_unit': 0.03,
'tax_id': False,
})],
})
# Change the pricelist
sale_order.write({'pricelist_id': pricelist_discount_excl_global.id})
# Update Prices
sale_order.update_prices()
# Check that the discount displayed is the correct one
self.assertEqual(
sale_order.order_line.discount, 54,
"Wrong discount computed for specified product & pricelist"
)
# Additional to check for overall consistency
self.assertEqual(
sale_order.order_line.price_unit, 0.03,
"Wrong unit price computed for specified product & pricelist"
)
self.assertEqual(
sale_order.order_line.price_subtotal, 0.01,
"Wrong subtotal price computed for specified product & pricelist"
)
self.assertFalse(
sale_order.order_line.tax_id,
"Wrong tax applied for specified product & pricelist"
)