# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.fields import Command from odoo.tests import tagged from odoo.addons.product.tests.common import ProductCommon @tagged('post_install', '-at_install') class TestPricelist(ProductCommon): @classmethod def setUpClass(cls): super().setUpClass() cls.datacard = cls.env['product.product'].create({'name': 'Office Lamp'}) cls.usb_adapter = cls.env['product.product'].create({'name': 'Office Chair'}) cls.sale_pricelist_id = cls.env['product.pricelist'].create({ 'name': 'Sale pricelist', 'item_ids': [ Command.create({ 'compute_price': 'formula', 'base': 'list_price', # based on public price 'price_discount': 10, 'product_id': cls.usb_adapter.id, 'applied_on': '0_product_variant', }), Command.create({ 'compute_price': 'formula', 'base': 'list_price', # based on public price 'price_surcharge': -0.5, 'product_id': cls.datacard.id, 'applied_on': '0_product_variant', }), ], }) def test_10_discount(self): # Make sure the price using a pricelist is the same than without after # applying the computation manually self.assertEqual( self.pricelist._get_product_price(self.usb_adapter, 1.0)*0.9, self.sale_pricelist_id._get_product_price(self.usb_adapter, 1.0)) self.assertEqual( self.pricelist._get_product_price(self.datacard, 1.0)-0.5, self.sale_pricelist_id._get_product_price(self.datacard, 1.0)) self.assertAlmostEqual( self.sale_pricelist_id._get_product_price(self.usb_adapter, 1.0, uom=self.uom_unit)*12, self.sale_pricelist_id._get_product_price(self.usb_adapter, 1.0, uom=self.uom_dozen)) # price_surcharge applies to product default UoM, here "Units", so surcharge will be multiplied self.assertAlmostEqual( self.sale_pricelist_id._get_product_price(self.datacard, 1.0, uom=self.uom_unit)*12, self.sale_pricelist_id._get_product_price(self.datacard, 1.0, uom=self.uom_dozen)) def test_20_pricelist_uom(self): # Verify that the pricelist rules are correctly using the product's default UoM # as reference, and return a result according to the target UoM (as specific in the context) tonne_price = 100 # make sure 'tonne' resolves down to 1 'kg'. self.uom_ton.write({'rounding': 0.001}) # setup product stored in 'tonnes', with a discounted pricelist for qty > 3 tonnes spam = self.env['product.product'].create({ 'name': '1 tonne of spam', 'uom_id': self.uom_ton.id, 'uom_po_id': self.uom_ton.id, 'list_price': tonne_price, 'type': 'consu' }) self.env['product.pricelist.item'].create({ 'pricelist_id': self.pricelist.id, 'applied_on': '0_product_variant', 'compute_price': 'formula', 'base': 'list_price', # based on public price 'min_quantity': 3, # min = 3 tonnes 'price_surcharge': -10, # -10 EUR / tonne 'product_id': spam.id }) def test_unit_price(qty, uom_id, expected_unit_price): uom = self.env['uom.uom'].browse(uom_id) unit_price = self.pricelist._get_product_price(spam, qty, uom=uom) self.assertAlmostEqual(unit_price, expected_unit_price, msg='Computed unit price is wrong') # Test prices - they are *per unit*, the quantity is only here to match the pricelist rules! test_unit_price(2, self.uom_kgm.id, tonne_price / 1000.0) test_unit_price(2000, self.uom_kgm.id, tonne_price / 1000.0) test_unit_price(3500, self.uom_kgm.id, (tonne_price - 10) / 1000.0) test_unit_price(2, self.uom_ton.id, tonne_price) test_unit_price(3, self.uom_ton.id, tonne_price - 10) def test_30_pricelists_order(self): # Verify the order of pricelists after creation ProductPricelist = self.env['product.pricelist'] res_partner = self.env['res.partner'].create({'name': 'Ready Corner'}) ProductPricelist.search([]).active = False pl_first = ProductPricelist.create({'name': 'First Pricelist'}) res_partner.invalidate_recordset(['property_product_pricelist']) self.assertEqual(res_partner.property_product_pricelist, pl_first) ProductPricelist.create({'name': 'Second Pricelist'}) res_partner.invalidate_recordset(['property_product_pricelist']) self.assertEqual(res_partner.property_product_pricelist, pl_first)