From a7aba1162163c9162dd477ddb1d440d44520abc4 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 25 Mar 2024 10:58:43 +0100 Subject: [PATCH] Add shopinvader_api_cart_step --- .../odoo/addons/shopinvader_api_cart_step | 1 + setup/shopinvader_api_cart_step/setup.py | 6 +++ shopinvader_api_cart_step/README.rst | 1 + shopinvader_api_cart_step/__init__.py | 2 + shopinvader_api_cart_step/__manifest__.py | 14 ++++++ shopinvader_api_cart_step/helpers/__init__.py | 1 + .../helpers/cart_helper.py | 20 ++++++++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 1 + shopinvader_api_cart_step/schemas/__init__.py | 1 + shopinvader_api_cart_step/schemas/cart.py | 18 +++++++ shopinvader_api_cart_step/tests/__init__.py | 1 + .../tests/test_api_cart_step.py | 48 +++++++++++++++++++ 13 files changed, 115 insertions(+) create mode 120000 setup/shopinvader_api_cart_step/odoo/addons/shopinvader_api_cart_step create mode 100644 setup/shopinvader_api_cart_step/setup.py create mode 100644 shopinvader_api_cart_step/README.rst create mode 100644 shopinvader_api_cart_step/__init__.py create mode 100644 shopinvader_api_cart_step/__manifest__.py create mode 100644 shopinvader_api_cart_step/helpers/__init__.py create mode 100644 shopinvader_api_cart_step/helpers/cart_helper.py create mode 100644 shopinvader_api_cart_step/readme/CONTRIBUTORS.rst create mode 100644 shopinvader_api_cart_step/readme/DESCRIPTION.rst create mode 100644 shopinvader_api_cart_step/schemas/__init__.py create mode 100644 shopinvader_api_cart_step/schemas/cart.py create mode 100644 shopinvader_api_cart_step/tests/__init__.py create mode 100644 shopinvader_api_cart_step/tests/test_api_cart_step.py diff --git a/setup/shopinvader_api_cart_step/odoo/addons/shopinvader_api_cart_step b/setup/shopinvader_api_cart_step/odoo/addons/shopinvader_api_cart_step new file mode 120000 index 0000000000..1163c3b528 --- /dev/null +++ b/setup/shopinvader_api_cart_step/odoo/addons/shopinvader_api_cart_step @@ -0,0 +1 @@ +../../../../shopinvader_api_cart_step \ No newline at end of file diff --git a/setup/shopinvader_api_cart_step/setup.py b/setup/shopinvader_api_cart_step/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/shopinvader_api_cart_step/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopinvader_api_cart_step/README.rst b/shopinvader_api_cart_step/README.rst new file mode 100644 index 0000000000..ddfd4d0241 --- /dev/null +++ b/shopinvader_api_cart_step/README.rst @@ -0,0 +1 @@ +bot pls :) diff --git a/shopinvader_api_cart_step/__init__.py b/shopinvader_api_cart_step/__init__.py new file mode 100644 index 0000000000..c52572d832 --- /dev/null +++ b/shopinvader_api_cart_step/__init__.py @@ -0,0 +1,2 @@ +from . import schemas +from . import helpers diff --git a/shopinvader_api_cart_step/__manifest__.py b/shopinvader_api_cart_step/__manifest__.py new file mode 100644 index 0000000000..8b58e5f4e2 --- /dev/null +++ b/shopinvader_api_cart_step/__manifest__.py @@ -0,0 +1,14 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Cart steps cart API integration", + "summary": """ + Track checkout steps on sale cart. + """, + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Camptocamp", + "website": "https://github.com/shopinvader/odoo-shopinvader", + "depends": ["sale_cart_step", "shopinvader_api_cart"], +} diff --git a/shopinvader_api_cart_step/helpers/__init__.py b/shopinvader_api_cart_step/helpers/__init__.py new file mode 100644 index 0000000000..7479542842 --- /dev/null +++ b/shopinvader_api_cart_step/helpers/__init__.py @@ -0,0 +1 @@ +from . import cart_helper diff --git a/shopinvader_api_cart_step/helpers/cart_helper.py b/shopinvader_api_cart_step/helpers/cart_helper.py new file mode 100644 index 0000000000..ed4dc4d1c3 --- /dev/null +++ b/shopinvader_api_cart_step/helpers/cart_helper.py @@ -0,0 +1,20 @@ +# Copyright 2024 Camptocamp SA +# @author: Simone Orsi +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ShopinvaderApiCartRouterHelper(models.AbstractModel): + _inherit = "shopinvader_api_cart.cart_router.helper" + + def _update_prepare_data(self, data): + vals = super()._update_prepare_data(data) + if data.current_step or data.next_step: + vals.update(self._update_prepare_data_step(data)) + return vals + + def _update_prepare_data_step(self, data): + return self.env["sale.order"]._cart_step_update_vals( + current_step=data.current_step, next_step=data.next_step + ) diff --git a/shopinvader_api_cart_step/readme/CONTRIBUTORS.rst b/shopinvader_api_cart_step/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..f1c71bce18 --- /dev/null +++ b/shopinvader_api_cart_step/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Simone Orsi diff --git a/shopinvader_api_cart_step/readme/DESCRIPTION.rst b/shopinvader_api_cart_step/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..7fadb0d8f4 --- /dev/null +++ b/shopinvader_api_cart_step/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Plugs ``sale_cart_step`` within cart api. \ No newline at end of file diff --git a/shopinvader_api_cart_step/schemas/__init__.py b/shopinvader_api_cart_step/schemas/__init__.py new file mode 100644 index 0000000000..d98a08bc7f --- /dev/null +++ b/shopinvader_api_cart_step/schemas/__init__.py @@ -0,0 +1 @@ +from . import cart diff --git a/shopinvader_api_cart_step/schemas/cart.py b/shopinvader_api_cart_step/schemas/cart.py new file mode 100644 index 0000000000..ce7cf09cbc --- /dev/null +++ b/shopinvader_api_cart_step/schemas/cart.py @@ -0,0 +1,18 @@ +# Copyright 2024 Camptocamp SA +# @author: Simone Orsi +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.addons.shopinvader_api_cart.schemas import ( + CartUpdateInput as BaseCartUpdateInput, +) + + +class CartUpdateInput(BaseCartUpdateInput, extends=True): + + current_step: str | None = None + next_step: str | None = None + + def convert_to_sale_write(self): + vals = super().convert_to_sale_write() + # NOTE: is not possible to use `env` to retrive data here + return vals diff --git a/shopinvader_api_cart_step/tests/__init__.py b/shopinvader_api_cart_step/tests/__init__.py new file mode 100644 index 0000000000..175030b51e --- /dev/null +++ b/shopinvader_api_cart_step/tests/__init__.py @@ -0,0 +1 @@ +from . import test_api_cart_step diff --git a/shopinvader_api_cart_step/tests/test_api_cart_step.py b/shopinvader_api_cart_step/tests/test_api_cart_step.py new file mode 100644 index 0000000000..f728a5e357 --- /dev/null +++ b/shopinvader_api_cart_step/tests/test_api_cart_step.py @@ -0,0 +1,48 @@ +# Copyright 2024 Camptocamp SA +# @author: Simone Orsi +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import json + +from fastapi import status +from requests import Response + +from odoo.addons.shopinvader_api_cart.routers.cart import cart_router +from odoo.addons.shopinvader_api_cart.tests.common import CommonSaleCart + + +class TestSaleCart(CommonSaleCart): + @classmethod + def setUpClass(cls): + super(TestSaleCart, cls).setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.address_step = cls.env.ref("sale_cart_step.cart_step_address") + cls.checkout_step = cls.env.ref("sale_cart_step.cart_step_checkout") + cls.last_step = cls.env.ref("sale_cart_step.cart_step_last") + + def test_update(self): + so = self.env["sale.order"]._create_empty_cart( + self.default_fastapi_authenticated_partner.id + ) + data = { + "current_step": self.address_step.code, + "next_step": self.checkout_step.code, + } + with self._create_test_client(router=cart_router) as test_client: + response: Response = test_client.post( + f"/{so.uuid}/update", content=json.dumps(data) + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn(self.address_step, so.cart_step_done_ids) + self.assertEqual(so.cart_step_id, self.checkout_step) + data = { + "current_step": self.checkout_step.code, + "next_step": self.last_step.code, + } + with self._create_test_client(router=cart_router) as test_client: + response: Response = test_client.post( + f"/{so.uuid}/update", content=json.dumps(data) + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn(self.checkout_step, so.cart_step_done_ids) + self.assertEqual(so.cart_step_id, self.last_step)