[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) <quwo@odoo.com>
Signed-off-by: Walravens Mathieu (wama) <wama@odoo.com>
This commit is contained in:
Mathieu Walravens
2024-04-19 23:49:51 +00:00
parent 09295d229d
commit d42b06aea1
+16 -5
View File
@@ -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')