# Copyright 2022 Le Filament (https://le-filament.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) import logging import werkzeug from odoo import _, fields, models from odoo.exceptions import UserError _logger = logging.getLogger(__name__) class ResPartner(models.Model): _inherit = "res.partner" # ------------------------------------------------------ # Fields declaration # ------------------------------------------------------ is_portal = fields.Boolean("Est un utilisateur portail") # ------------------------------------------------------ # SQL Constraints # ------------------------------------------------------ # ------------------------------------------------------ # Default methods # ------------------------------------------------------ # ------------------------------------------------------ # Computed fields / Search Fields # ------------------------------------------------------ # ------------------------------------------------------ # Onchange / Constraints # ------------------------------------------------------ # ------------------------------------------------------ # CRUD methods (ORM overrides) # ------------------------------------------------------ # ------------------------------------------------------ # Actions # ------------------------------------------------------ def acces_portal_app(self): for partner in self: if not partner.email: raise UserError( _( "Vous devez renseigner une adresse e-mail " "sur le contact pour la création d'un utilisateur." ) ) group_portal = self.env.ref("base.group_portal") # Vérifier si le contact a un utilisateur lié user = ( self.env["res.users"] .sudo() .with_context(active_test=False) .search([("login", "=ilike", partner.email)]) ) if not partner.is_portal: # ajouter un groupe de portail à l'utilisateur # relatif des contacts sélectionnés user_portal = None # create a user if necessary, and make sure it is in the portal group if not user: if partner.company_id: company_id = partner.company_id.id else: company_id = self.env.company.id user_portal = partner.sudo().with_company(company_id)._create_user() else: user_portal = user partner.is_portal = True user_portal.write({"active": True, "groups_id": [(4, group_portal.id)]}) # prepare for the signup process partner.signup_prepare() partner.with_context(active_test=True)._send_email(user_portal) else: # remove the user (if it exists) from the portal group if user and group_portal in user.groups_id: partner.is_portal = False # if user belongs to portal only, deactivate it if len(user.groups_id) <= 1: user.write( {"groups_id": [(3, group_portal.id)], "active": False} ) else: user.write({"groups_id": [(3, group_portal.id)]}) def _create_user(self): """Création d'un nouveal utilisateur pour un contact :returns enregistrement res.users """ return ( self.env["res.users"] .with_context(no_reset_password=True) ._create_user_from_template( { "email": self.email, "login": self.email, "partner_id": self.id, "company_id": self.env.company.id, "company_ids": [(6, 0, self.env.company.ids)], } ) ) def _send_email(self, user_portal): """ envoi d'un mail au nouvel utilisateur portail """ if not self.env.user.email: raise UserError( _( "Vous devez avoir une adresse e-mail dans vos " "Préférences utilisateur pour envoyer des e-mails." ) ) # determine subject and body in the portal user's language template = self.env.ref("acc_portal.acc_mail_template_data_portal_welcome") lang = user_portal.lang company_id = self.env.company portal_url = self.with_context( signup_force_type_in_url="", lang=lang )._get_signup_url_app()[self.id] self.signup_prepare() if template: template.with_context( dbname=self._cr.dbname, portal_url=portal_url, company_id=company_id, user_signup_url=user_portal.signup_url, lang=lang, ).send_mail(self.id, force_send=True) else: _logger.warning( "Aucun modèle d'e-mail trouvé pour l'envoi " "d'e-mails à l'utilisateur du portail" ) return True def _get_signup_url_app( self, url=None, action=None, view_type=None, menu_id=None, res_id=None, model=None, ): res = dict.fromkeys(self.ids, False) for partner in self: base_url = self.env.company.url_app # when required, make sure the partner has a valid signup token if self.env.context.get("signup_valid") and not partner.user_ids: partner.sudo().signup_prepare() route = "signup" # the parameters to encode for the query query = dict(db=self.env.cr.dbname) signup_type = self.env.context.get( "signup_force_type_in_url", partner.sudo().signup_type or "" ) if signup_type: route = "reset_password" if signup_type == "reset" else signup_type if partner.sudo().signup_token and signup_type: query["token"] = partner.sudo().signup_token elif partner.user_ids: query["login"] = partner.user_ids[0].login else: continue # no signup token, no user, thus no signup url! signup_url = "/%s?%s" % (route, werkzeug.urls.url_encode(query)) if not self.env.context.get("relative_url"): signup_url = werkzeug.urls.url_join(base_url, signup_url) res[partner.id] = signup_url return res # ------------------------------------------------------ # Business methods # ------------------------------------------------------