98 lines
No EOL
4.6 KiB
Python
98 lines
No EOL
4.6 KiB
Python
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from urllib.parse import urlencode
|
|
|
|
from odoo import http
|
|
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
|
from odoo.http import request
|
|
|
|
SIGNUP_FLAG = "membership_signup=1"
|
|
|
|
|
|
class WebsiteSaleMembershipSignup(WebsiteSale):
|
|
|
|
def _membership_signup_is_required(self, product_id):
|
|
"""Return True iff an anonymous visitor adding `product_id` to the
|
|
cart must be redirected to /web/signup first.
|
|
"""
|
|
website = request.website
|
|
return website._membership_signup_required_for(
|
|
product_id, request.env.user._is_public()
|
|
)
|
|
|
|
def _membership_signup_redirect_url(self, product_id):
|
|
"""Build the `/web/signup?membership_signup=1&redirect=<product_url>`
|
|
URL preserving the current language.
|
|
"""
|
|
product = request.env["product.product"].browse(int(product_id))
|
|
tmpl = product.product_tmpl_id
|
|
product_url = "/shop/%s" % request.env["ir.http"]._slug(tmpl)
|
|
query = urlencode({"membership_signup": "1", "redirect": product_url})
|
|
return "/web/signup?%s" % query
|
|
|
|
def _membership_signup_mark_session(self, product_id):
|
|
request.session["membership_signup_active"] = True
|
|
request.session["membership_signup_product_id"] = int(product_id)
|
|
|
|
@http.route()
|
|
def cart_update(
|
|
self, product_id, add_qty=1, set_qty=0,
|
|
product_custom_attribute_values=None,
|
|
no_variant_attribute_value_ids=None, **kwargs
|
|
):
|
|
if self._membership_signup_is_required(product_id):
|
|
self._membership_signup_mark_session(product_id)
|
|
return request.redirect(self._membership_signup_redirect_url(product_id))
|
|
return super().cart_update(
|
|
product_id=product_id, add_qty=add_qty, set_qty=set_qty,
|
|
product_custom_attribute_values=product_custom_attribute_values,
|
|
no_variant_attribute_value_ids=no_variant_attribute_value_ids,
|
|
**kwargs
|
|
)
|
|
|
|
@http.route()
|
|
def cart_update_json(
|
|
self, product_id, line_id=None, add_qty=None, set_qty=None, display=True,
|
|
product_custom_attribute_values=None, no_variant_attribute_value_ids=None, **kwargs
|
|
):
|
|
if self._membership_signup_is_required(product_id):
|
|
self._membership_signup_mark_session(product_id)
|
|
# The JSON route cannot perform an HTTP redirect on its own; signal
|
|
# the frontend so it can navigate to the signup URL. The standard
|
|
# "Add to Cart" on a product page uses /shop/cart/update (http),
|
|
# which is the primary path for this flow (RF-01). The JSON route
|
|
# covers add-to-cart from snippets/wishlist on the same page
|
|
# (`stayOnPageOption` / `o_we_buy_now` express).
|
|
#
|
|
# The JS handler in
|
|
# `static/src/js/website_membership_signup_required.js` reads
|
|
# `data.force_redirect` and navigates to it. The other keys are
|
|
# NOT consumed by our handler: they exist to keep the core's
|
|
# `cartHandlerMixin._addToCartInPage` (in
|
|
# `website_sale/static/src/js/website_sale_utils.js`) from crashing.
|
|
# That method does, in order:
|
|
# if (data.cart_quantity && ...) updateCartNavBar(data);
|
|
# showCartNotification(call, data.notification_info);
|
|
# `showCartNotification` accesses `props.lines` and `props.warning`
|
|
# on `data.notification_info`; if it is `undefined` (as it was in
|
|
# the first iteration, which only returned `{force_redirect: ...}`)
|
|
# the access raises `TypeError: can't access property "lines",
|
|
# props is undefined` and the redirect never fires.
|
|
#
|
|
# Shape (mirrors the empty-cart branch in
|
|
# `WebsiteSaleController.cart_update_json`):
|
|
# cart_quantity = 0 -> falsy, so `updateCartNavBar` is skipped.
|
|
# notification_info = {lines: [], warning: ""}
|
|
# -> `showCartNotification` no-ops on both empty fields.
|
|
return {
|
|
"force_redirect": self._membership_signup_redirect_url(product_id),
|
|
"cart_quantity": 0,
|
|
"notification_info": {"lines": [], "warning": ""},
|
|
}
|
|
return super().cart_update_json(
|
|
product_id=product_id, line_id=line_id, add_qty=add_qty,
|
|
set_qty=set_qty, display=display,
|
|
product_custom_attribute_values=product_custom_attribute_values,
|
|
no_variant_attribute_value_ids=no_variant_attribute_value_ids,
|
|
**kwargs
|
|
) |