diff --git a/website_sale_disable_shop/__init__.py b/website_sale_disable_shop/__init__.py new file mode 100644 index 000000000..12c48aeb2 --- /dev/null +++ b/website_sale_disable_shop/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2024 Onestein +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). + +from . import models diff --git a/website_sale_disable_shop/__manifest__.py b/website_sale_disable_shop/__manifest__.py new file mode 100644 index 000000000..644203d99 --- /dev/null +++ b/website_sale_disable_shop/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2024 Onestein +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). + +{ + "name": "Website Sale Enable/Disable Shop", + "category": "Website", + "version": "16.0.1.0.0", + "author": "Onestein, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/website", + "license": "LGPL-3", + "depends": [ + "website_sale", + ], + "data": [ + "views/res_config_settings_view.xml", + ], + "installable": True, +} diff --git a/website_sale_disable_shop/models/__init__.py b/website_sale_disable_shop/models/__init__.py new file mode 100644 index 000000000..d64aca60f --- /dev/null +++ b/website_sale_disable_shop/models/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2024 Onestein +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). + +from . import ir_http +from . import res_config_settings +from . import website diff --git a/website_sale_disable_shop/models/ir_http.py b/website_sale_disable_shop/models/ir_http.py new file mode 100644 index 000000000..dd63e3667 --- /dev/null +++ b/website_sale_disable_shop/models/ir_http.py @@ -0,0 +1,39 @@ +# Copyright 2024 Onestein +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0). +from pathlib import Path + +import werkzeug + +from odoo import models +from odoo.http import request + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + @classmethod + def _dispatch(cls, endpoint): + res = cls._check_shop_enabled_disabled() + if res: + return res + return super()._dispatch(endpoint) + + @classmethod + def _serve_fallback(cls): + res = cls._check_shop_enabled_disabled() + if res: + return res + return super()._serve_fallback() + + @classmethod + def _check_shop_enabled_disabled(cls): + # if not website request - skip + website = request.env["website"].sudo().get_current_website() + if not website: + return None + if not website.shop_enabled: + path = request.httprequest.path + if path == "/shop" or Path("/shop") in Path(path).parents: + if path == "/shop/cart/quantity": + return 0.0 + raise werkzeug.exceptions.NotFound() diff --git a/website_sale_disable_shop/models/res_config_settings.py b/website_sale_disable_shop/models/res_config_settings.py new file mode 100644 index 000000000..4e9735083 --- /dev/null +++ b/website_sale_disable_shop/models/res_config_settings.py @@ -0,0 +1,10 @@ +# Copyright 2024 Onestein +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + shop_enabled = fields.Boolean(related="website_id.shop_enabled", readonly=False) diff --git a/website_sale_disable_shop/models/website.py b/website_sale_disable_shop/models/website.py new file mode 100644 index 000000000..c4ed302e6 --- /dev/null +++ b/website_sale_disable_shop/models/website.py @@ -0,0 +1,10 @@ +# Copyright 2024 Onestein +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class Website(models.Model): + _inherit = "website" + + shop_enabled = fields.Boolean(default=True) diff --git a/website_sale_disable_shop/readme/CONTRIBUTORS.rst b/website_sale_disable_shop/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..be93ff7a5 --- /dev/null +++ b/website_sale_disable_shop/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Onestein diff --git a/website_sale_disable_shop/readme/DESCRIPTION.rst b/website_sale_disable_shop/readme/DESCRIPTION.rst new file mode 100644 index 000000000..1f760e2c1 --- /dev/null +++ b/website_sale_disable_shop/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows to enable/disable shops per website. diff --git a/website_sale_disable_shop/readme/USAGE.rst b/website_sale_disable_shop/readme/USAGE.rst new file mode 100644 index 000000000..7aabd8438 --- /dev/null +++ b/website_sale_disable_shop/readme/USAGE.rst @@ -0,0 +1,5 @@ +To configure this module, you need to: + +#. Go to **Website > Configuration > Settings** +#. Search 'Shop Enabled' option. +#. When shop is disabled when user tries to access mywebsite.com/shop or any of its child pages, they will be redirected to homepage. diff --git a/website_sale_disable_shop/static/description/icon.png b/website_sale_disable_shop/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/website_sale_disable_shop/static/description/icon.png differ diff --git a/website_sale_disable_shop/tests/__init__.py b/website_sale_disable_shop/tests/__init__.py new file mode 100644 index 000000000..e2983aa2a --- /dev/null +++ b/website_sale_disable_shop/tests/__init__.py @@ -0,0 +1 @@ +from . import test_ir_http diff --git a/website_sale_disable_shop/tests/test_ir_http.py b/website_sale_disable_shop/tests/test_ir_http.py new file mode 100644 index 000000000..c591887e3 --- /dev/null +++ b/website_sale_disable_shop/tests/test_ir_http.py @@ -0,0 +1,27 @@ +from odoo.tests import HttpCase + + +class TestIrHttp(HttpCase): + def setUp(self): + super().setUp() + self.website = self.env["website"].sudo().get_current_website() + self.path = "/shop" + + def test_dispatch_shop_enabled(self): + # Test that a user can access "/shop + response = self.url_open(self.path) + self.assertEqual( + response.status_code, + 200, + "Expected the response status code to be 200 which means no redirection", + ) + + def test_dispatch__shop_disabled(self): + # Test that a user cannot access "/shop + self.website.shop_enabled = False + response = self.url_open(self.path, allow_redirects=False) + self.assertEqual( + response.status_code, + 303, + "Expected the response status code to be 303 indicating a redirect", + ) diff --git a/website_sale_disable_shop/views/res_config_settings_view.xml b/website_sale_disable_shop/views/res_config_settings_view.xml new file mode 100644 index 000000000..7e0bfaef8 --- /dev/null +++ b/website_sale_disable_shop/views/res_config_settings_view.xml @@ -0,0 +1,28 @@ + + + + + Website Shop Enable/Disable + res.config.settings + + +
+

Website Shop

+
+
+
+ +
+
+
+
+
+
+
+
+