From d42b06aea1237b4a579c303b365f22d65a0491a1 Mon Sep 17 00:00:00 2001 From: Mathieu Walravens Date: Thu, 14 Mar 2024 13:43:55 +0000 Subject: [PATCH] [PERF] uom: Improve reference check for large UoM categories This commit improves the performance of the reference check for large categories of Units of Measure (UoM). After this commit, the number of UoMs in the category is counted using the read_group method instead, resulting in faster performance. Benchmark: | Nbr of UoM | Before | After | | ---------: | -----: | ----: | | 0 | 0ms | 0ms | | 1 | 1ms | 1ms | | 30 | 6ms | 3ms | | 200 | 7ms | 2ms | | 18000 | 900ms | 15ms | opw-3775689 closes odoo/odoo#162540 X-original-commit: 9f47341de352d08a8e325d14f25af8221bb392cb Signed-off-by: Quentin Wolfs (quwo) Signed-off-by: Walravens Mathieu (wama) --- addons/uom/models/uom_uom.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/addons/uom/models/uom_uom.py b/addons/uom/models/uom_uom.py index 865c94bb24c..c4762e81d57 100644 --- a/addons/uom/models/uom_uom.py +++ b/addons/uom/models/uom_uom.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from collections import defaultdict from datetime import timedelta from odoo import api, fields, tools, models, _ @@ -82,14 +83,24 @@ class UoM(models.Model): ] def _check_category_reference_uniqueness(self): + categ_res = self.read_group( + [("category_id", "in", self.category_id.ids)], + ["category_id", "uom_type"], + ["category_id", "uom_type"], + lazy=False, + ) + uom_by_category = defaultdict(int) + ref_by_category = {} + for res in categ_res: + uom_by_category[res["category_id"][0]] += res["__count"] + if res["uom_type"] == "reference": + ref_by_category[res["category_id"][0]] = res["__count"] + for category in self.category_id: - if not category.uom_ids: - continue - reference_count = sum( - uom.uom_type == 'reference' for uom in category.uom_ids) + reference_count = ref_by_category.get(category.id, 0) if reference_count > 1: raise ValidationError(_("UoM category %s should only have one reference unit of measure.", category.name)) - elif reference_count == 0: + elif reference_count == 0 and uom_by_category.get(category.id, 0) > 0: raise ValidationError(_("UoM category %s should have a reference unit of measure.", category.name)) @api.depends('factor')