diff --git a/apiserver/bll/project/project_bll.py b/apiserver/bll/project/project_bll.py index a28b756..04ebb4b 100644 --- a/apiserver/bll/project/project_bll.py +++ b/apiserver/bll/project/project_bll.py @@ -1084,6 +1084,7 @@ class ProjectBLL: if not filter_: return conditions + or_conditions = [] for field, field_filter in filter_.items(): if not ( field_filter @@ -1096,12 +1097,28 @@ class ProjectBLL: helper = GetMixin.NewListFieldBucketHelper( field, data=field_filter, legacy=True ) - conditions[field] = {} + field_conditions = {} for action, values in helper.actions.items(): value = list(set(values)) for key in reversed(action.split("__")): value = {f"${key}": value} - conditions[field].update(value) + field_conditions.update(value) + if ( + helper.explicit_operator + and helper.global_operator == Q.OR + and len(field_conditions) > 1 + ): + or_conditions.append( + [{field: {op: cond}} for op, cond in field_conditions.items()] + ) + else: + conditions[field] = field_conditions + + if or_conditions: + if len(or_conditions) == 1: + conditions["$or"] = next(iter(or_conditions)) + else: + conditions["$and"] = [{"$or": c} for c in or_conditions] return conditions diff --git a/apiserver/database/model/base.py b/apiserver/database/model/base.py index 472c8db..3847b63 100644 --- a/apiserver/database/model/base.py +++ b/apiserver/database/model/base.py @@ -163,6 +163,7 @@ class GetMixin(PropsMixin): self.allow_empty = False self.global_operator = None self.actions = defaultdict(list) + self.explicit_operator = False self._support_legacy = legacy current_context = self.default_operator @@ -172,6 +173,7 @@ class GetMixin(PropsMixin): self._support_legacy = False if self.global_operator is None: self.global_operator = d.operator + self.explicit_operator = True continue if self.global_operator is None: diff --git a/apiserver/tests/automated/test_subprojects.py b/apiserver/tests/automated/test_subprojects.py index da26a62..88012eb 100644 --- a/apiserver/tests/automated/test_subprojects.py +++ b/apiserver/tests/automated/test_subprojects.py @@ -90,6 +90,18 @@ class TestSubProjects(TestService): self.assertEqual(p.basename, "project1") self.assertEqual(p.stats.active.total_tasks, 1) + projects = self.api.projects.get_all_ex( + parent=[test_root], + children_type="report", + children_tags=["__$any", "__$not", "test1", "test2"], + shallow_search=True, + include_stats=True, + check_own_contents=True, + ).projects + self.assertEqual(len(projects), 2) + for p in projects: + self.assertEqual(p.stats.active.total_tasks, 1) + def test_query_children(self): test_root_name = "TestQueryChildren" test_root = self._temp_project(name=test_root_name)