[ADD] website_sale_aplicoop: serve Eskaera per website
A co-op can run the plain shop on one website and the group orders on another, but routes are registered process-wide: every /eskaera page answered on every website of the database, and Odoo had already copied the Eskaera menu to all of them. `website.eskaera_enabled` decides which websites serve it, on by default so installing changes nothing. It reaches the settings screen through `website_id`, so it follows the website selector there. Where it is off the routes raise NotFound and the menu is hidden. The menu is hidden rather than deleted, by extending `_compute_visible`. That keeps the record and any manual rename or reordering, so switching the feature back on restores it as it was. Note that a JSON route reports the 404 inside the JSON-RPC payload and still answers HTTP 200; that is the transport, not a hole in the guard, and a test pins it so the next reader does not take it for one. The three remaining settings (lazy loading, products per page, low stock threshold) are still `config_parameter`, so they stay global to the database. Two websites share their values. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
817ff31d39
commit
5a2f5d120f
9 changed files with 313 additions and 0 deletions
|
|
@ -1,10 +1,13 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
import functools
|
||||
import json
|
||||
import logging
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
from odoo import fields
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
|
@ -25,6 +28,22 @@ from .exceptions import GroupOrderUnavailable
|
|||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def eskaera_route(route_method):
|
||||
"""Serve an Eskaera page only on websites that run Eskaera.
|
||||
|
||||
A co-op can keep the plain shop on one website and the group orders on
|
||||
another. Routes are registered process-wide, so without this guard the
|
||||
/eskaera pages would answer on every website of the database.
|
||||
"""
|
||||
|
||||
@functools.wraps(route_method)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if not request.website.eskaera_enabled:
|
||||
raise NotFound()
|
||||
return route_method(self, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class AplicoopWebsiteSale(WebsiteSale):
|
||||
"""Controlador personalizado para website_sale de Aplicoop.
|
||||
|
|
@ -435,6 +454,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
|
||||
@http.route(["/eskaera"], type="http", auth="user", website=True)
|
||||
@eskaera_route
|
||||
def eskaera_list(self, **post):
|
||||
"""Página de pedidos de grupo abiertos esta semana.
|
||||
|
||||
|
|
@ -711,6 +731,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
return request.redirect(url)
|
||||
|
||||
@http.route(["/eskaera/<int:order_id>"], type="http", auth="user", website=True)
|
||||
@eskaera_route
|
||||
def eskaera_shop_legacy(self, order_id, **post):
|
||||
"""Keep the old numeric shop URL working, pointing at the slug one."""
|
||||
return self._redirect_to_slug_url(order_id, post)
|
||||
|
|
@ -721,6 +742,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_shop(self, group_order_slug, **post):
|
||||
"""Página de tienda para un pedido específico (eskaera).
|
||||
|
||||
|
|
@ -913,6 +935,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
website=True,
|
||||
methods=["GET"],
|
||||
)
|
||||
@eskaera_route
|
||||
def load_eskaera_page(self, order_id, **post):
|
||||
"""Load next page of products for lazy loading.
|
||||
|
||||
|
|
@ -1030,6 +1053,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def load_products_ajax(self, order_id, **post):
|
||||
"""Load products via AJAX for infinite scroll.
|
||||
|
||||
|
|
@ -1166,6 +1190,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
@http.route(
|
||||
["/eskaera/<int:order_id>/checkout"], type="http", auth="user", website=True
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_checkout_legacy(self, order_id, **post):
|
||||
"""Keep the old numeric checkout URL working, pointing at the slug one."""
|
||||
return self._redirect_to_slug_url(order_id, post, suffix="/checkout")
|
||||
|
|
@ -1176,6 +1201,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_checkout(self, group_order_slug, **post):
|
||||
"""Checkout page to close the cart for the order (eskaera)."""
|
||||
group_order = self._get_group_order_by_slug(group_order_slug)
|
||||
|
|
@ -1381,6 +1407,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_payment(self, group_order_slug, **post):
|
||||
"""Payment step: pick a method and pay the order placed at checkout."""
|
||||
group_order = self._get_group_order_by_slug(group_order_slug)
|
||||
|
|
@ -1451,6 +1478,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_payment_confirmation(self, group_order_slug, order_id, **post):
|
||||
"""Landing page after paying: show the outcome and free the cart.
|
||||
|
||||
|
|
@ -1488,6 +1516,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def check_group_order_status(self, **post):
|
||||
"""Return status information for a group.order.
|
||||
|
||||
|
|
@ -1568,6 +1597,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def load_draft_cart(self, **post):
|
||||
"""Load items from the most recent draft sale.order for current period."""
|
||||
import json
|
||||
|
|
@ -1727,6 +1757,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def eskaera_clear_cart(self, **post):
|
||||
"""Clear the user's cart and cancel any existing draft sale.order.
|
||||
|
||||
|
|
@ -1828,6 +1859,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def save_eskaera_draft(self, **post):
|
||||
"""Save order as draft (without confirming).
|
||||
|
||||
|
|
@ -1968,6 +2000,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def confirm_eskaera(self, **post):
|
||||
"""Confirm order and create sale.order from cart (localStorage).
|
||||
|
||||
|
|
@ -2130,6 +2163,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
@eskaera_route
|
||||
def load_order_from_history(self, group_order_id=None, sale_order_id=None, **post):
|
||||
"""Load a historical order (draft/confirmed) back into the cart.
|
||||
|
||||
|
|
@ -2276,6 +2310,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
website=True,
|
||||
methods=["POST"],
|
||||
)
|
||||
@eskaera_route
|
||||
def confirm_order_from_portal(
|
||||
self, group_order_id=None, sale_order_id=None, **post
|
||||
):
|
||||
|
|
@ -2367,6 +2402,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
website=True,
|
||||
csrf=False,
|
||||
)
|
||||
@eskaera_route
|
||||
def get_checkout_labels(self, **post):
|
||||
"""Return ALL translated UI labels and messages unified.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue