diff --git a/shopinvader/services/address.py b/shopinvader/services/address.py index 3c2892efd9..78cd22fc3b 100644 --- a/shopinvader/services/address.py +++ b/shopinvader/services/address.py @@ -64,7 +64,9 @@ def _to_address_info(self, _id): # Validator def _validator_search(self): - return {"scope": {"type": "dict", "nullable": True}} + validator = self._default_validator_search() + validator.pop("domain", {}) + return validator def _validator_create(self): res = { diff --git a/shopinvader/services/sale.py b/shopinvader/services/sale.py index cf4b8164ca..0db5a90a16 100644 --- a/shopinvader/services/sale.py +++ b/shopinvader/services/sale.py @@ -34,16 +34,12 @@ def ask_email_invoice(self, _id): # Validator def _validator_search(self): - return { - "id": {"coerce": to_int, "type": "integer"}, - "per_page": { - "coerce": to_int, - "nullable": True, - "type": "integer", - }, - "page": {"coerce": to_int, "nullable": True, "type": "integer"}, - "scope": {"type": "dict", "nullable": True}, - } + default_search_validator = self._default_validator_search() + default_search_validator.pop("domain", {}) + default_search_validator.update( + {"id": {"coerce": to_int, "type": "integer"}} + ) + return default_search_validator def _validator_ask_email_invoice(self): return self._validator_ask_email() diff --git a/shopinvader/services/service.py b/shopinvader/services/service.py index 13426e25b4..445e9d7026 100644 --- a/shopinvader/services/service.py +++ b/shopinvader/services/service.py @@ -6,6 +6,7 @@ import logging from odoo import _ +from odoo.addons.base_rest.components.service import to_int from odoo.addons.component.core import AbstractComponent from odoo.exceptions import MissingError, UserError from odoo.osv import expression @@ -72,6 +73,26 @@ def _scope_to_domain(self, scope): except Exception as e: raise UserError(_("Invalid scope %s, error : %s"), scope, e) + # Validator + def _default_validator_search(self): + """ + Get a default validator for search service. + This search include every parameters used for pagination, scope and domain. + This directly used a _validator_search in case of an existing service + doesn't allow all of these parameters (backward compatibility). + :return: dict + """ + return { + "page": {"coerce": to_int, "nullable": True, "type": "integer"}, + "per_page": { + "coerce": to_int, + "nullable": True, + "type": "integer", + }, + "domain": {"type": "list", "nullable": True}, + "scope": {"type": "dict", "nullable": True}, + } + def _paginate_search(self, default_page=1, default_per_page=5, **params): """ Build a domain and search on it. diff --git a/shopinvader/tests/test_address.py b/shopinvader/tests/test_address.py index bb59e32ebe..4afe520f62 100644 --- a/shopinvader/tests/test_address.py +++ b/shopinvader/tests/test_address.py @@ -91,6 +91,17 @@ def test_read_address_all(self): expected_ids = {self.partner.id, self.address.id, self.address_2.id} self.assertEqual(ids, expected_ids) + def test_search_per_page(self): + # Ensure the 'per_page' is working into search. + res = self.service.dispatch("search", params={"per_page": 2})["data"] + self.assertEqual(len(res), 2) + # Ensure the 'page' is working. As there is 3 address for logged user, we + # should have only 1 remaining result on the second page. + res = self.service.dispatch( + "search", params={"per_page": 2, "page": 2} + )["data"] + self.assertEqual(len(res), 1) + def test_delete_address(self): address_id = self.address.id self.address_service.delete(address_id) diff --git a/shopinvader_delivery_carrier/services/delivery.py b/shopinvader_delivery_carrier/services/delivery.py index 32cde2d51f..ba8197235f 100644 --- a/shopinvader_delivery_carrier/services/delivery.py +++ b/shopinvader_delivery_carrier/services/delivery.py @@ -1,7 +1,6 @@ # Copyright 2019 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields -from odoo.addons.base_rest.components.service import to_int from odoo.addons.component.core import Component from odoo.osv import expression @@ -25,15 +24,10 @@ def _validator_search(self): Validator for the search :return: dict """ - schema = { - "per_page": { - "coerce": to_int, - "nullable": True, - "type": "integer", - }, - "page": {"coerce": to_int, "nullable": True, "type": "integer"}, - } - return schema + validator = self._default_validator_search() + validator.pop("domain", {}) + validator.pop("scope", {}) + return validator def _get_picking_schema(self): """ diff --git a/shopinvader_invoice/services/invoice.py b/shopinvader_invoice/services/invoice.py index 8744ea6871..2ceb38be45 100644 --- a/shopinvader_invoice/services/invoice.py +++ b/shopinvader_invoice/services/invoice.py @@ -1,6 +1,5 @@ # Copyright 2019 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo.addons.base_rest.components.service import to_int from odoo.addons.component.core import Component @@ -20,15 +19,10 @@ def _validator_search(self): Validator for the search :return: dict """ - schema = { - "per_page": { - "coerce": to_int, - "nullable": True, - "type": "integer", - }, - "page": {"coerce": to_int, "nullable": True, "type": "integer"}, - } - return schema + default_validator = self._default_validator_search() + default_validator.pop("scope", {}) + default_validator.pop("domain", {}) + return default_validator def _validator_return_search(self): """