oca-ocb-core/odoo-bringout-oca-ocb-resource/resource/models/utils.py
Ernad Husremovic 2d3ee4855a 19.0 vanilla
2026-03-09 09:30:27 +01:00

53 lines
2.4 KiB
Python

from odoo.fields import Domain
# Default hour per day value. The one should
# only be used when the one from the calendar
# is not available.
HOURS_PER_DAY = 8
def filter_domain_leaf(domain, field_check, field_name_mapping=None):
"""
filter_domain_lead only keep the leaves of a domain that verify a given check. Logical operators that involves
a leaf that is undetermined (because it does not pass the check) are ignored.
each operator is a logic gate:
- '&' and '|' take two entries and can be ignored if one of them (or the two of them) is undetermined
-'!' takes one entry and can be ignored if this entry is undetermined
params:
- domain: the domain that needs to be filtered
- field_check: the function that the field name used in the leaf needs to verify to keep the leaf
- field_name_mapping: dictionary of the form {'field_name': 'new_field_name', ...}. Occurences of 'field_name'
in the first element of domain leaves will be replaced by 'new_field_name'. This is usefull when adapting a
domain from one model to another when some field names do not match the names of the corresponding fields in
the new model.
returns: The filtered version of the domain
"""
field_name_mapping = field_name_mapping or {}
def adapt_condition(condition, ignored):
field_name = condition.field_expr
if not field_check(field_name):
return ignored
field_name = field_name_mapping.get(field_name)
if field_name is None:
return condition
return Domain(field_name, condition.operator, condition.value)
def adapt_domain(domain: Domain, ignored) -> Domain:
if hasattr(domain, 'OPERATOR'):
if domain.OPERATOR in ('&', '|'):
domain = domain.apply(adapt_domain(d, domain.ZERO) for d in domain.children)
elif domain.OPERATOR == '!':
domain = ~adapt_domain(~domain, ~ignored)
else:
assert False, "domain.OPERATOR = {domain.OPEATOR!r} unhandled"
else:
domain = domain.map_conditions(lambda condition: adapt_condition(condition, ignored))
return ignored if domain.is_true() or domain.is_false() else domain
domain = Domain(domain)
if domain.is_false():
return domain
return adapt_domain(domain, ignored=Domain.TRUE)