[IMP] website_sale_aplicoop: readable slug in the group order URL
Group order pages were published under their database id (`/eskaera/1`), which says nothing to the member opening the link. `group.order` gains a `slug` field and the public pages move to `/eskaera/<slug>` (e.g. `/eskaera/escola-fructuos`). The slug is generated from the order name on creation, is unique, and can be edited under the name on the form; emptying it regenerates it from the current name. Values that would make the order unreachable are rejected: a plain number (the legacy numeric URLs win that match) and the static routes served under `/eskaera/` (`labels`, `save-order`, `i18n`, ...). `/eskaera/<id>` and `/eskaera/<id>/checkout` are kept as redirects to their slug URL, so the links already shared with members keep working. The AJAX endpoints (`load-page`, `save-order`, `confirm`, ...) stay numeric: they never show up in the address bar. Consequently the frontend now reads the order id from the `data-order-id` attribute only, as the URL no longer carries it. The post-migration script fills the slug of the orders that already existed. Renaming the `/eskaera` prefix itself (`/escolas` for a schools deployment) needs no code: a *308 Redirect / Rewrite* rule per public route in Website > Configuration > Redirects serves the pages on the new prefix, rewrites the links in the templates and redirects the old URLs, per website. Documented in `readme/CONFIGURE.rst`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2b1cabbb43
commit
23edee6154
14 changed files with 463 additions and 28 deletions
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import json
|
||||
import logging
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from odoo import fields
|
||||
from odoo import http
|
||||
|
|
@ -703,18 +704,52 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
request,
|
||||
)
|
||||
|
||||
def _get_group_order_by_slug(self, group_order_slug):
|
||||
"""Return the consumer group order published under `group_order_slug`."""
|
||||
return (
|
||||
request.env["group.order"]
|
||||
.sudo()
|
||||
.search([("slug", "=", group_order_slug)], limit=1)
|
||||
)
|
||||
|
||||
def _eskaera_url(self, group_order, suffix=""):
|
||||
"""Return the public URL of `group_order`, falling back to the list."""
|
||||
if not group_order or not group_order.slug:
|
||||
return "/eskaera"
|
||||
return f"/eskaera/{group_order.slug}{suffix}"
|
||||
|
||||
def _redirect_to_slug_url(self, order_id, suffix="", **post):
|
||||
"""Send a legacy /eskaera/<id> URL to its /eskaera/<slug> equivalent."""
|
||||
group_order = request.env["group.order"].sudo().browse(order_id).exists()
|
||||
url = self._eskaera_url(group_order, suffix=suffix)
|
||||
if post and url != "/eskaera":
|
||||
url = f"{url}?{urlencode(post)}"
|
||||
return request.redirect(url)
|
||||
|
||||
@http.route(["/eskaera/<int:order_id>"], type="http", auth="user", website=True)
|
||||
def eskaera_shop(self, order_id, **post):
|
||||
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)
|
||||
|
||||
@http.route(
|
||||
["/eskaera/<string:group_order_slug>"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
def eskaera_shop(self, group_order_slug, **post):
|
||||
"""Página de tienda para un pedido específico (eskaera).
|
||||
|
||||
Muestra productos del pedido y gestiona el carrito separado.
|
||||
Soporta búsqueda y filtrado por categoría.
|
||||
"""
|
||||
group_order = request.env["group.order"].sudo().browse(order_id)
|
||||
group_order = self._get_group_order_by_slug(group_order_slug)
|
||||
|
||||
if not group_order.exists():
|
||||
if not group_order:
|
||||
return request.redirect("/eskaera")
|
||||
|
||||
order_id = group_order.id
|
||||
|
||||
# Verificar que el pedido está activo
|
||||
if group_order.state != "open":
|
||||
return request.redirect("/eskaera")
|
||||
|
|
@ -1259,11 +1294,21 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
@http.route(
|
||||
["/eskaera/<int:order_id>/checkout"], type="http", auth="user", website=True
|
||||
)
|
||||
def eskaera_checkout(self, order_id, **post):
|
||||
"""Checkout page to close the cart for the order (eskaera)."""
|
||||
group_order = request.env["group.order"].sudo().browse(order_id)
|
||||
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, suffix="/checkout", **post)
|
||||
|
||||
if not group_order.exists():
|
||||
@http.route(
|
||||
["/eskaera/<string:group_order_slug>/checkout"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
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)
|
||||
|
||||
if not group_order:
|
||||
return request.redirect("/eskaera")
|
||||
|
||||
# Verificar que el pedido está activo
|
||||
|
|
@ -2125,7 +2170,9 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Verify the order belongs to the requested group_order
|
||||
if sale_order.group_order_id.id != group_order_id:
|
||||
return request.redirect("/eskaera/%d" % sale_order.group_order_id.id)
|
||||
return request.redirect(
|
||||
self._eskaera_url(sale_order.group_order_id.sudo())
|
||||
)
|
||||
|
||||
# Get the current group_order (the one being viewed, not necessarily the one from the history)
|
||||
group_order = request.env["group.order"].sudo().browse(group_order_id)
|
||||
|
|
@ -2198,6 +2245,9 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
"website_sale_aplicoop.eskaera_load_from_history",
|
||||
{
|
||||
"group_order_id": group_order_id,
|
||||
# sessionStorage keys stay keyed by id; the redirect at
|
||||
# the end of the template needs the public URL instead.
|
||||
"group_order_url": self._eskaera_url(group_order),
|
||||
"items_json": json.dumps(
|
||||
available_items
|
||||
), # Pass ONLY available items
|
||||
|
|
@ -2224,7 +2274,11 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
import traceback
|
||||
|
||||
_logger.error(traceback.format_exc())
|
||||
return request.redirect("/eskaera/%d" % group_order_id)
|
||||
return request.redirect(
|
||||
self._eskaera_url(
|
||||
request.env["group.order"].sudo().browse(group_order_id).exists()
|
||||
)
|
||||
)
|
||||
|
||||
@http.route(
|
||||
["/eskaera/<int:group_order_id>/confirm/<int:sale_order_id>"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue