From b57a18dfc77ab81a474eb8569e0543256a2ddaa4 Mon Sep 17 00:00:00 2001 From: manu Date: Wed, 23 Aug 2023 10:11:29 +0200 Subject: [PATCH] [ADD]website_contact_lastname: New module to set lastname from portal --- .../odoo/addons/website_contact_lastname | 1 + setup/website_contact_lastname/setup.py | 6 + website_contact_lastname/__init__.py | 5 + website_contact_lastname/__manifest__.py | 23 +++ .../controllers/__init__.py | 5 + website_contact_lastname/controllers/main.py | 137 ++++++++++++++++++ .../controllers/portal.py | 55 +++++++ website_contact_lastname/models/__init__.py | 5 + .../models/res_partner.py | 24 +++ website_contact_lastname/models/res_users.py | 37 +++++ website_contact_lastname/readme/CONFIGURE.rst | 1 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 2 + website_contact_lastname/readme/USAGE.rst | 2 + .../static/description/icon.png | Bin 0 -> 35820 bytes .../views/auth_signup_login_templates.xml | 20 +++ .../views/portal_templates.xml | 26 ++++ website_contact_lastname/views/templates.xml | 27 ++++ 18 files changed, 379 insertions(+) create mode 120000 setup/website_contact_lastname/odoo/addons/website_contact_lastname create mode 100644 setup/website_contact_lastname/setup.py create mode 100644 website_contact_lastname/__init__.py create mode 100644 website_contact_lastname/__manifest__.py create mode 100644 website_contact_lastname/controllers/__init__.py create mode 100644 website_contact_lastname/controllers/main.py create mode 100644 website_contact_lastname/controllers/portal.py create mode 100644 website_contact_lastname/models/__init__.py create mode 100644 website_contact_lastname/models/res_partner.py create mode 100644 website_contact_lastname/models/res_users.py create mode 100644 website_contact_lastname/readme/CONFIGURE.rst create mode 100644 website_contact_lastname/readme/CONTRIBUTORS.rst create mode 100644 website_contact_lastname/readme/DESCRIPTION.rst create mode 100644 website_contact_lastname/readme/USAGE.rst create mode 100644 website_contact_lastname/static/description/icon.png create mode 100644 website_contact_lastname/views/auth_signup_login_templates.xml create mode 100644 website_contact_lastname/views/portal_templates.xml create mode 100644 website_contact_lastname/views/templates.xml diff --git a/setup/website_contact_lastname/odoo/addons/website_contact_lastname b/setup/website_contact_lastname/odoo/addons/website_contact_lastname new file mode 120000 index 0000000000..c444f62428 --- /dev/null +++ b/setup/website_contact_lastname/odoo/addons/website_contact_lastname @@ -0,0 +1 @@ +../../../../website_contact_lastname \ No newline at end of file diff --git a/setup/website_contact_lastname/setup.py b/setup/website_contact_lastname/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/website_contact_lastname/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/website_contact_lastname/__init__.py b/website_contact_lastname/__init__.py new file mode 100644 index 0000000000..ea6bb1f80b --- /dev/null +++ b/website_contact_lastname/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import controllers +from . import models diff --git a/website_contact_lastname/__manifest__.py b/website_contact_lastname/__manifest__.py new file mode 100644 index 0000000000..054b7b0825 --- /dev/null +++ b/website_contact_lastname/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Website Contact Lastname", + "version": "15.0.1.0.0", + "category": "Website", + "website": "https://github.com/OCA/website", + "author": "Sygel Technology," "Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "auth_signup", + "website_account_fiscal_position_partner_type", + "partner_firstname" + ], + "data": [ + "views/templates.xml", + "views/auth_signup_login_templates.xml", + "views/portal_templates.xml", + ], +} diff --git a/website_contact_lastname/controllers/__init__.py b/website_contact_lastname/controllers/__init__.py new file mode 100644 index 0000000000..294141a404 --- /dev/null +++ b/website_contact_lastname/controllers/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import main +from . import portal diff --git a/website_contact_lastname/controllers/main.py b/website_contact_lastname/controllers/main.py new file mode 100644 index 0000000000..53538a704d --- /dev/null +++ b/website_contact_lastname/controllers/main.py @@ -0,0 +1,137 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _ +from odoo.http import request + +from odoo.addons.website_sale.controllers.main import WebsiteSale +from odoo.addons.auth_signup.controllers.main import AuthSignupHome + + +class WebsiteSale(WebsiteSale): + + def _get_mandatory_fields_shipping(self, country_id=False): + req = super()._get_mandatory_fields_shipping(country_id) + req += ['firstname'] + if 'name' in req: + req.remove('name') + return req + + def _get_mandatory_fields_billing(self, country_id=False): + req = super()._get_mandatory_fields_billing(country_id) + req.append('firstname') + if request.env.context.get('fiscal_position_type') == 'b2c': + req.append('lastname') + # Name is removed as this field cannot be explicitly edited + # It is edited in the backend through the fields first name + # and lastname + if 'name' in req: + req.remove('name') + return req + + def values_postprocess(self, order, mode, values, errors, error_msg): + new_values, errors, error_msg = super( + WebsiteSale, self + ).values_postprocess( + order=order, + mode=mode, + values=values, + errors=errors, + error_msg=error_msg + ) + new_values.update({ + "firstname": values.get("firstname") or '', + "lastname": values.get("lastname") or '', + }) + # Name is removed as this field cannot be explicitly edited + # It is edited in the backend through the fields first name + # and lastname + new_values.pop("name") + return new_values, errors, error_msg + + def checkout_form_validate(self, mode, all_form_values, data): + required_fields = [f for f in ( + all_form_values.get('field_required') or '' + ).split(',') if f] + # Name is removed as this field cannot be explicitly edited + # It is edited in the backend through the fields first name + # and lastname + if 'name' in required_fields: + required_fields.remove('name') + all_form_values['field_required'] = ','.join(required_fields) + error, error_message = super().checkout_form_validate( + mode, all_form_values, data + ) + if data.get('partner_id'): + partner_su = request.env['res.partner'].sudo().browse( + int(data['partner_id']) + ).exists() + can_edit_vat = partner_su.parent_id.can_edit_vat() if partner_su.parent_id else partner_su.can_edit_vat() + firstname_change = partner_su and 'firstname' in data \ + and data['firstname'] != partner_su.firstname + if firstname_change and not can_edit_vat: + error['firstname'] = 'error' + error_message.append(_( + "Changing your name is not allowed once invoices have been" + " issued for your account. Please contact us directly for " + "this operation." + )) + # When lastname field in form is empty, its values is False + # When lastname field in backend is empty, its values is '' + # In that case, if both are compared, they are considered to be + # different so data['lastname'] != partner_su.lastname would + # return True although no real change would have been applied. + lastname_change = partner_su and 'lastname' in data and \ + data['lastname'] != partner_su.lastname and ( + data['lastname'] or partner_su.lastname not in ['', False] + ) + if lastname_change and not can_edit_vat: + error['lastname'] = 'error' + error_message.append(_( + "Changing your last name is not allowed once invoices have" + " been issued for your account. Please contact us directly" + " for this operation." + )) + + # Prevent change the partner name, lastname if + # it is an internal user. + if ( + firstname_change or lastname_change + ) and not all(partner_su.user_ids.mapped('share')): + error.update({ + 'firstname': 'error' if firstname_change else None, + 'lastname': 'error' if lastname_change else None, + }) + error_message.append(_( + "If you are ordering for an external person, please place " + "your order via the backend. If you wish to change your " + "name or last name, please do so in the account settings " + "or contact your administrator." + )) + return error, error_message + + +class AuthSignupHome(AuthSignupHome): + + def get_auth_signup_qcontext(self): + qcontext = super().get_auth_signup_qcontext() + qcontext.update({k: v for (k, v) in request.params.items() if k in { + 'lastname', + }}) + if 'name' in qcontext: + qcontext['firstname'] = qcontext['name'] + if 'error' not in qcontext and \ + request.httprequest.method == 'POST' and \ + qcontext.get( + 'fiscal_position_type' + ) == 'b2c' and not qcontext.get('lastname'): + qcontext["error"] = _("Lastname is required for B2C users.") + return qcontext + + def _prepare_signup_values(self, qcontext): + values = super()._prepare_signup_values(qcontext) + if 'firstname' in qcontext: + values['firstname'] = qcontext['firstname'] + if 'lastname' in qcontext: + values['lastname'] = qcontext['lastname'] + return values diff --git a/website_contact_lastname/controllers/portal.py b/website_contact_lastname/controllers/portal.py new file mode 100644 index 0000000000..325bd3df2b --- /dev/null +++ b/website_contact_lastname/controllers/portal.py @@ -0,0 +1,55 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _ +from odoo.http import request +from odoo.addons.portal.controllers.portal import CustomerPortal + + +class CustomerPortal(CustomerPortal): + + CustomerPortal.OPTIONAL_BILLING_FIELDS += [ + 'firstname', + 'lastname', + ] + + def details_form_validate(self, data): + context = dict(request.env.context) + # 'name' field cannont be updated as it would recompute fields + # firstname and lastname. That is why it is set in context + # that changes in field name need to be ignored. + context.update({"name_ignore": True}) + request.env.context = context + error, error_message = super().details_form_validate(data) + partner = request.env.user.partner_id + if partner.can_edit_vat(): + if 'firstname' in data and not data.get('Name'): + error["firstname"] = 'error' + error_message.append(_('Firstname is mandatory.')) + if 'lastname' in data and not data.get('lastname') and(( + data.get('fiscal_position_type') == 'b2c' + ) or ( + partner.fiscal_position_type == 'b2c' and not data.get( + 'fiscal_position_type' + ) == 'b2b' + )): + error["lastname"] = 'error' + error["fiscal_position_type"] = 'error' + error_message.append(_('Lastname is mandatory for B2C users.')) + else: + if 'firstname' in data and \ + data.get('firstname') != partner.firstname: + error["firstname"] = 'error' + error_message.append(_( + 'Changing Name is not allowed once document(s) have been ' + 'issued for your account. Please contact us directly for ' + 'this operation.' + )) + if 'lastname' in data and data.get('lastname') != partner.lastname: + error["lastname"] = 'error' + error_message.append(_( + 'Changing Lastname is not allowed once document(s) have ' + 'been issued for your account. Please contact us directly ' + 'for this operation.' + )) + return error, error_message diff --git a/website_contact_lastname/models/__init__.py b/website_contact_lastname/models/__init__.py new file mode 100644 index 0000000000..a227d7676d --- /dev/null +++ b/website_contact_lastname/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import res_users +from . import res_partner diff --git a/website_contact_lastname/models/res_partner.py b/website_contact_lastname/models/res_partner.py new file mode 100644 index 0000000000..9161e6ec3e --- /dev/null +++ b/website_contact_lastname/models/res_partner.py @@ -0,0 +1,24 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3). + +from odoo import models, api +from odoo.http import request + + +class Partner(models.Model): + _inherit = "res.partner" + + @api.model + def signup_retrieve_info(self, token): + res = super().signup_retrieve_info(token) + partner = self._signup_retrieve_partner(token, raise_exception=True) + res.update({ + 'name': partner.firstname, + 'lastname': partner.lastname, + }) + return res + + def write(self, vals): + if vals.get('name') and request.env.context.get('name_ignore'): + vals.pop('name') + return super().write(vals) diff --git a/website_contact_lastname/models/res_users.py b/website_contact_lastname/models/res_users.py new file mode 100644 index 0000000000..7b6e5f7104 --- /dev/null +++ b/website_contact_lastname/models/res_users.py @@ -0,0 +1,37 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3). + +from odoo import models, api + + +class ResUsers(models.Model): + _inherit = "res.users" + + @api.model + def signup(self, values, token=None): + if token: + partner = self.env['res.partner']._signup_retrieve_partner( + token, + check_validity=True, + raise_exception=True + ) + partner_user = partner.user_ids and partner.user_ids[0] or False + # Don't update firstname and lastname if partner + # related to user exists (i.e. when resetting password) + if partner_user: + values.pop('firstname', None) + values.pop('lastname', None) + return super().signup(values, token) + + def _create_user_from_template(self, values): + user = super()._create_user_from_template(values) + # Because of the way the name is computed, it is important to + # reset the values so the final name is correct. + # It cannot be done before (the way would be setting the value of name + # if param. values to '') as the funcion _create_user_from_template + # checks that values contains a value for 'name' + user.write({ + 'firstname': values.get('firstname'), + 'lastname': values.get('lastname'), + }) + return user diff --git a/website_contact_lastname/readme/CONFIGURE.rst b/website_contact_lastname/readme/CONFIGURE.rst new file mode 100644 index 0000000000..05dcf8709a --- /dev/null +++ b/website_contact_lastname/readme/CONFIGURE.rst @@ -0,0 +1 @@ +No configuration needed. diff --git a/website_contact_lastname/readme/CONTRIBUTORS.rst b/website_contact_lastname/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..16fbee9816 --- /dev/null +++ b/website_contact_lastname/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Sygel `_: + + * Manuel Regidor \ No newline at end of file diff --git a/website_contact_lastname/readme/DESCRIPTION.rst b/website_contact_lastname/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..f77181f0df --- /dev/null +++ b/website_contact_lastname/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module allows users to introduce and edit their lastname +from the portal. diff --git a/website_contact_lastname/readme/USAGE.rst b/website_contact_lastname/readme/USAGE.rst new file mode 100644 index 0000000000..ebb8b7fb10 --- /dev/null +++ b/website_contact_lastname/readme/USAGE.rst @@ -0,0 +1,2 @@ +Lastname field is mandatory for B2C users in portal. +It can be left blank when the user is B2B. diff --git a/website_contact_lastname/static/description/icon.png b/website_contact_lastname/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..207fb7ad5535215836f426bcebfdccdbc51c0d27 GIT binary patch literal 35820 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 + + + + diff --git a/website_contact_lastname/views/portal_templates.xml b/website_contact_lastname/views/portal_templates.xml new file mode 100644 index 0000000000..32828353a5 --- /dev/null +++ b/website_contact_lastname/views/portal_templates.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/website_contact_lastname/views/templates.xml b/website_contact_lastname/views/templates.xml new file mode 100644 index 0000000000..082c0a597b --- /dev/null +++ b/website_contact_lastname/views/templates.xml @@ -0,0 +1,27 @@ + + + + +