74 lines
No EOL
3.5 KiB
Python
74 lines
No EOL
3.5 KiB
Python
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from odoo import http
|
|
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
|
|
from odoo.addons.web.controllers.home import SIGN_UP_REQUEST_PARAMS
|
|
from odoo.http import request
|
|
|
|
# partner_firstname exposes `firstname` / `lastname` on res.users and
|
|
# res.partner; we need them as accepted qcontext params so the signup form
|
|
# roundtrips them transparently through `get_auth_signup_qcontext`.
|
|
SIGN_UP_REQUEST_PARAMS.add("firstname")
|
|
SIGN_UP_REQUEST_PARAMS.add("lastname")
|
|
|
|
# Session keys used by the membership signup flow.
|
|
MEMBERSHIP_SIGNUP_SESSION_KEYS = ("membership_signup_active", "membership_signup_product_id")
|
|
|
|
|
|
class AuthSignupHomeMembership(AuthSignupHome):
|
|
|
|
def _prepare_signup_values(self, qcontext):
|
|
values = super()._prepare_signup_values(qcontext)
|
|
# partner_firstname: the signup form collects `firstname` / `lastname`
|
|
# separately. We inject both into the signup values so the resulting
|
|
# partner/user has them populated.
|
|
#
|
|
# We ALSO keep a composed `name` (firstname + " " + lastname) in the
|
|
# values, on purpose. The core's `_create_user_from_template`
|
|
# (`auth_signup/models/res_users.py`) rejects the signup with
|
|
# `ValueError: Signup: no name or partner given for new user` if
|
|
# neither `partner_id` nor `name` is present in the values — that
|
|
# check runs BEFORE `template_user.copy(values)` reaches
|
|
# `res.partner.create`, where `partner_firstname` would otherwise
|
|
# recompute `name` from the split fields.
|
|
#
|
|
# By providing the composed `name`, the check passes; then, inside
|
|
# `res.partner.create`, partner_firstname's override detects that both
|
|
# `firstname` and `lastname` are in the vals and DISCARDS the composed
|
|
# `name` (see `partner_firstname/models/res_partner.py:_name_fields_in_vals`
|
|
# branch `del vals["name"]`), recomputing it from the split fields.
|
|
# Net effect: the partner ends up with the proper `firstname`,
|
|
# `lastname` and a recomputed `name`, exactly as intended.
|
|
firstname = qcontext.get("firstname", "")
|
|
lastname = qcontext.get("lastname", "")
|
|
if firstname or lastname:
|
|
values["firstname"] = firstname
|
|
values["lastname"] = lastname
|
|
partner_model = request.env["res.partner"]
|
|
values["name"] = partner_model._get_computed_name(
|
|
lastname, firstname
|
|
)
|
|
return values
|
|
|
|
@http.route()
|
|
def web_auth_signup(self, *args, **kw):
|
|
response = super().web_auth_signup(*args, **kw)
|
|
# On a successful signup the user is now authenticated (session.uid
|
|
# set) and the redirect to the product page will happen. Drop the
|
|
# membership markers from the session so they cannot leak into later
|
|
# /web/signup attempts by other visitors sharing the session (defence
|
|
# in depth).
|
|
if request.session.uid:
|
|
for key in MEMBERSHIP_SIGNUP_SESSION_KEYS:
|
|
request.session.pop(key, None)
|
|
return response
|
|
|
|
@http.route()
|
|
def web_login(self, *args, **kw):
|
|
response = super().web_login(*args, **kw)
|
|
# Same cleanup on explicit login (covers the "Already have an
|
|
# account?" branch from the signup page).
|
|
if request.session.uid:
|
|
for key in MEMBERSHIP_SIGNUP_SESSION_KEYS:
|
|
request.session.pop(key, None)
|
|
return response |