# Copyright 2021 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from functools import wraps from odoo.addons.base.tests.common import BaseCommon LIST_PRICES_MAPPING = { "pricelist_cache.list0": [ {"id": 17, "price": 100.0}, {"id": 18, "price": 15.8}, {"id": 19, "price": 100.0}, {"id": 20, "price": 47.0}, ], "pricelist_cache.list1": [ {"id": 17, "price": 75.0}, {"id": 18, "price": 15.8}, {"id": 19, "price": 100.0}, {"id": 20, "price": 47.0}, ], "pricelist_cache.list2": [ {"id": 17, "price": 50.0}, {"id": 18, "price": 15.8}, {"id": 19, "price": 100.0}, {"id": 20, "price": 47.0}, ], "pricelist_cache.list3": [ {"id": 17, "price": 25.0}, {"id": 18, "price": 15.8}, {"id": 19, "price": 100.0}, {"id": 20, "price": 47.0}, ], "pricelist_cache.list4": [ {"id": 17, "price": 15.0}, {"id": 18, "price": 50.0}, {"id": 19, "price": 100.0}, {"id": 20, "price": 47.0}, ], "pricelist_cache.list5": [ {"id": 17, "price": 45.0}, {"id": 18, "price": 35.8}, {"id": 19, "price": 120.0}, {"id": 20, "price": 67.0}, ], } def check_duplicates(func): @wraps(func) def wrapper(self, *args, **kwargs): func(self, *args, **kwargs) duplicates_query = """ SELECT product_id, pricelist_id, count(*) FROM product_pricelist_cache GROUP BY product_id, pricelist_id HAVING count(*) > 1; """ self.env.cr.execute(duplicates_query) res = self.env.cr.fetchall() self.assertFalse(res) return wrapper class TestPricelistCacheCommon(BaseCommon): @classmethod def setUpClassBaseCache(cls): cls.cache_model.cron_reset_pricelist_cache() cls.env["product.pricelist"].invalidate_model(["is_pricelist_cache_available"]) @classmethod def set_currency(cls): """Sets currency everywhere, as the sale dependency breaks every unit test.""" usd = cls.env.ref("base.USD") cls.env.user.company_id.currency_id = usd cls.products.write({"currency_id": usd.id}) cls.lists.write({"currency_id": usd.id}) cls.pricelist_items.write({"currency_id": usd.id}) @classmethod def setUpClass(cls): super().setUpClass() cls.env = cls.env( context=dict( cls.env.context, queue_job__no_delay=True, ) ) cls.cache_model = cls.env["product.pricelist.cache"] # root pricelists cls.list0 = cls.env.ref("pricelist_cache.list0") # child 1, based on list0 cls.list1 = cls.env.ref("pricelist_cache.list1") # child 2, based on list1 cls.list2 = cls.env.ref("pricelist_cache.list2") # child 3, based on list2 cls.list3 = cls.env.ref("pricelist_cache.list3") # child 4, based on list0 cls.list4 = cls.env.ref("pricelist_cache.list4") # factor list 5, based on list3 cls.list5 = cls.env.ref("pricelist_cache.list5") cls.lists = cls.env["product.pricelist"].browse( [ cls.list0.id, cls.list1.id, cls.list2.id, cls.list3.id, cls.list4.id, cls.list5.id, ] ) # products # TODO: create products instead of using odoo demo data cls.p6 = cls.env.ref("product.product_product_6") cls.p7 = cls.env.ref("product.product_product_7") cls.p8 = cls.env.ref("product.product_product_8") # P9 not in any pricelist cls.p9 = cls.env.ref("product.product_product_9") cls.products = cls.env["product.product"].browse( [cls.p6.id, cls.p7.id, cls.p8.id, cls.p9.id] ) cls.pricelist_items = cls.env["product.pricelist.item"] cls.pricelist_items |= cls.list0.item_ids cls.pricelist_items |= cls.list1.item_ids cls.pricelist_items |= cls.list2.item_ids cls.pricelist_items |= cls.list3.item_ids cls.pricelist_items |= cls.list4.item_ids cls.set_currency() cls.setUpClassBaseCache() cls.partner = cls.env.ref("base.res_partner_12") def _flush_cache(self): self.cache_model.flush_pricelist_cache() self.env["res.partner"].invalidate_model(["is_pricelist_cache_available"]) self.env["product.pricelist"].invalidate_model(["is_pricelist_cache_available"]) def _update_cache(self, pricelist_ids=None, product_ids=None): self.cache_model.update_product_pricelist_cache( product_ids=product_ids, pricelist_ids=pricelist_ids ) self.env["res.partner"].invalidate_model(["is_pricelist_cache_available"]) self.env["product.pricelist"].invalidate_model(["is_pricelist_cache_available"]) def assert_cache_available(self, lists): self.assertTrue(all(lists.mapped("is_pricelist_cache_available"))) def assert_cache_computed(self, lists): self.assertTrue(all(lists.mapped("is_pricelist_cache_computed"))) def assert_cache_not_available(self, lists): self.assertFalse(any(lists.mapped("is_pricelist_cache_available"))) def assert_cache_not_computed(self, lists): self.assertFalse(any(lists.mapped("is_pricelist_cache_computed")))