add website_membership_signup_required: force to create user before add to cart a membership product
This commit is contained in:
parent
80f24bcc46
commit
c4d32c6add
22 changed files with 1202 additions and 0 deletions
BIN
website_membership_signup_required/static/description/icon.png
Normal file
BIN
website_membership_signup_required/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
|
|
@ -0,0 +1,41 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
// Force-redirect handler for the membership signup flow.
|
||||
//
|
||||
// The `cart_update_json` controller override returns
|
||||
// `{ force_redirect: <signup_url> }` when an anonymous visitor tries to add a
|
||||
// membership product to the cart in "stay on page" mode
|
||||
// (`website.add_to_cart_action == 'stay'`), which is the JSON path used by
|
||||
// `_addToCartInPage` in the core `WebsiteSale` widget. The core handler only
|
||||
// reads `cart_quantity` / `notification_info` from that response and would
|
||||
// otherwise ignore `force_redirect`, leaving the membership intercept as a
|
||||
// silent no-op for the JSON path.
|
||||
//
|
||||
// The standard `#add_to_cart` button on the product page posts to
|
||||
// `/shop/cart/update` (HTTP), handled by `cart_update`, which already raises
|
||||
// an HTTP redirect — that path is unaffected here.
|
||||
//
|
||||
// Why a front-end handler and not an HTTP redirect raised from the controller:
|
||||
// `_addToCartInPage` calls `rpc("/shop/cart/update_json", ...)` and `rpc` does
|
||||
// `fetch(...).then(r => r.json())` with the default `redirect: "follow"`. A
|
||||
// `werkzeug.exceptions.Redirect` (3xx) from the JSON route would be silently
|
||||
// followed by `fetch`, the `/web/signup` HTML would be parsed as JSON, and the
|
||||
// frontend would break with an uncaught error. The front-end handler is
|
||||
// therefore the standard, non-intrusive approach (only acts when
|
||||
// `data.force_redirect` exists).
|
||||
|
||||
import "@website_sale/js/website_sale";
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
|
||||
publicWidget.registry.WebsiteSale.include({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async _addToCartInPage(params) {
|
||||
const data = await this._super.apply(this, arguments);
|
||||
if (data && data.force_redirect) {
|
||||
window.location.href = data.force_redirect;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import * as tourUtils from "@website_sale/js/tours/tour_utils";
|
||||
|
||||
const PRODUCT_NAME = "Membership Test Product";
|
||||
|
||||
registry.category("web_tour.tours").add("website_membership_signup_required_tour", {
|
||||
url: "/shop",
|
||||
steps: () => [
|
||||
// -- Anonymous visitor, add a membership product to cart -----------
|
||||
{
|
||||
content: "Search the membership product",
|
||||
trigger: 'form input[name="search"]',
|
||||
run: `edit ${PRODUCT_NAME}`,
|
||||
},
|
||||
{
|
||||
content: "Run the search",
|
||||
trigger: 'form:has(input[name="search"]) .oe_search_button',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Open the membership product page",
|
||||
trigger: `.oe_product_cart:first a:text(${PRODUCT_NAME})`,
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Click Add to Cart as anonymous user",
|
||||
trigger: "#add_to_cart",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
// -- On /web/signup with firstname / lastname ----------------------
|
||||
{
|
||||
content: "Signup page shows firstname field (b2c re-enabled by marker)",
|
||||
trigger: ".oe_signup_form input[name='firstname']",
|
||||
run: "edit Tour",
|
||||
},
|
||||
{
|
||||
trigger: ".oe_signup_form input[name='lastname']",
|
||||
run: "edit Member",
|
||||
},
|
||||
{
|
||||
content: "Type a unique email login",
|
||||
trigger: ".oe_signup_form input[name='login']",
|
||||
run: () => {
|
||||
const email = `membership.tour.${Date.now()}@test.example.com`;
|
||||
document.querySelector(".oe_signup_form input[name='login']").value = email;
|
||||
},
|
||||
},
|
||||
{
|
||||
trigger: ".oe_signup_form input[name='password']",
|
||||
run: "edit TourMember1!",
|
||||
},
|
||||
{
|
||||
trigger: ".oe_signup_form input[name='confirm_password']",
|
||||
run: "edit TourMember1!",
|
||||
},
|
||||
{
|
||||
content: "Submit the signup form -> redirect back to product page",
|
||||
trigger: ".oe_signup_form button[type='submit']",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
// -- Back on the product page, now authenticated --------------------
|
||||
{
|
||||
content: "We're back on the membership product page (authenticated)",
|
||||
trigger: `#product_details h1:contains("${PRODUCT_NAME}")`,
|
||||
},
|
||||
{
|
||||
content: "Add to cart as authenticated user",
|
||||
trigger: "#add_to_cart",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
tourUtils.goToCart(),
|
||||
tourUtils.assertCartContains({ productName: PRODUCT_NAME }),
|
||||
],
|
||||
});
|
||||
|
||||
registry.category("web_tour.tours").add("website_membership_signup_required_non_intercept_tour", {
|
||||
url: "/shop",
|
||||
steps: () => [
|
||||
{
|
||||
content: "Search the regular product",
|
||||
trigger: 'form input[name="search"]',
|
||||
run: "edit Regular Test Product",
|
||||
},
|
||||
{
|
||||
content: "Run the search",
|
||||
trigger: 'form:has(input[name="search"]) .oe_search_button',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Open the regular product page",
|
||||
trigger: `.oe_product_cart:first a:text("Regular Test Product")`,
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Add to cart as anonymous (no signup interception)",
|
||||
trigger: "#add_to_cart",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
tourUtils.goToCart(),
|
||||
tourUtils.assertCartContains({ productName: "Regular Test Product" }),
|
||||
],
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue