diff --git a/mpt_api_client/rql/query_builder.py b/mpt_api_client/rql/query_builder.py index c1b05212..589c8f53 100644 --- a/mpt_api_client/rql/query_builder.py +++ b/mpt_api_client/rql/query_builder.py @@ -257,28 +257,39 @@ def __getattr__(self, name: str) -> Self: def __str__(self) -> str: return self._to_string(self) - def any(self) -> Self: + def any(self, collection_name: str) -> Self: """Any nested objects have to match the filter condition. + Args: + collection_name: The name of the collection to which apply the `any` operator. + Returns: RQLQuery: RQLQuery with new condition Examples: - RQLQuery(saleDetails__orderQty__gt=11).any() - will result: any(saleDetails,orderQty=11) + RQLQuery(orderQty__gt=11).any("saleDetails") + will result (single): any(saleDetails,orderQty=11) + (RQLQuery(orderQty__gt=11) & RQLQuery(price__lt=100)).any("saleDetails") + will result (multiple): any(and(saleDetails,gt(orderQty,11),lt(price,100))) """ - return self.new(op=self.OP_ANY, children=[self]) + return self._nest(self.OP_ANY, collection_name) - def all(self) -> Self: + def all(self, collection_name: str) -> Self: """All nested objects have to match the filter condition. + Args: + collection_name: The name of the collection to which apply the `all` operator. + Returns: RQLQuery: RQLQuery with new condition - Example: - RQLQuery(saleDetails__orderQty__gt=1).all() + Examples: + RQLQuery(orderQty__gt=1).all("saleDetails") + will result (single): all(saleDetails,gt(orderQty,1)) + (RQLQuery(orderQty__gt=11) & RQLQuery(price__lt=100)).all("saleDetails") + will result (multiple): all(and(saleDetails,gt(orderQty,11),lt(price,100))) """ - return self.new(op=self.OP_ALL, children=[self]) + return self._nest(self.OP_ALL, collection_name) def n(self, name: str) -> Self: # noqa: WPS111 """Set the current field for this `RQLQuery` object. @@ -522,3 +533,9 @@ def _append(self, query: "RQLQuery") -> "RQLQuery" | Self: self.children.append(query) return self + + def _nest(self, op: str, collection_name: str) -> Self: + name = collection_name.replace("__", ".") + collection = self._to_string(self) if self.children else self.expr or "" + expr = f"{op}({name},{collection})" + return self.new(expr=expr) diff --git a/tests/unit/rql/query_builder/test_rql_all_any.py b/tests/unit/rql/query_builder/test_rql_all_any.py index ae0ea6a6..caf13071 100644 --- a/tests/unit/rql/query_builder/test_rql_all_any.py +++ b/tests/unit/rql/query_builder/test_rql_all_any.py @@ -2,16 +2,36 @@ def test_all(): - query = RQLQuery(saleDetails__orderQty__gt=1).all() + query = RQLQuery(orderQty__gt=1).all("saleDetails") result = str(query) - assert result == "all(gt(saleDetails.orderQty,1))" + assert result == "all(saleDetails,gt(orderQty,1))" def test_any(): - query = RQLQuery(saleDetails__orderQty__gt=1).any() + query = RQLQuery(orderQty__gt=1).any("saleDetails") result = str(query) - assert result == "any(gt(saleDetails.orderQty,1))" + assert result == "any(saleDetails,gt(orderQty,1))" + + +def test_all_multiple_conditions(): + order_qty_query = RQLQuery(orderQty__gt=1) + price_query = RQLQuery(price__lt=100) + query = (order_qty_query & price_query).all("saleDetails") + + result = str(query) + + assert result == "all(saleDetails,and(gt(orderQty,1),lt(price,100)))" + + +def test_any_multiple_conditions(): + order_qty_query = RQLQuery(orderQty__gt=1) + price_query = RQLQuery(price__lt=100) + query = (order_qty_query & price_query).any("saleDetails") + + result = str(query) + + assert result == "any(saleDetails,and(gt(orderQty,1),lt(price,100)))"