From bb9895ab484b05d977f37fa348b358866218c253 Mon Sep 17 00:00:00 2001 From: mav-adhoc Date: Tue, 15 Sep 2026 12:38:45 +0000 Subject: [PATCH] [FIX] website_hr_recruitment_ux: do not expose recruiter contact on public job form The public check_recent_application route appended the recruiter name, email and phone to the duplicate application warning, so any visitor could enumerate them from the job form. Override it to return the same warning without the contact, as the core does from Odoo 20 on. --- website_hr_recruitment_ux/__init__.py | 1 + website_hr_recruitment_ux/__manifest__.py | 2 +- .../controllers/__init__.py | 1 + website_hr_recruitment_ux/controllers/main.py | 73 +++++++++++++++++++ website_hr_recruitment_ux/i18n/es.po | 33 +++++++++ website_hr_recruitment_ux/i18n/es_419.po | 55 ++++++++++++++ .../i18n/website_hr_recruitment_ux.pot | 25 +++++++ website_hr_recruitment_ux/tests/__init__.py | 1 + .../tests/test_check_recent_application.py | 32 ++++++++ 9 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 website_hr_recruitment_ux/controllers/__init__.py create mode 100644 website_hr_recruitment_ux/controllers/main.py create mode 100644 website_hr_recruitment_ux/i18n/es_419.po create mode 100644 website_hr_recruitment_ux/tests/__init__.py create mode 100644 website_hr_recruitment_ux/tests/test_check_recent_application.py diff --git a/website_hr_recruitment_ux/__init__.py b/website_hr_recruitment_ux/__init__.py index e69de29..e046e49 100644 --- a/website_hr_recruitment_ux/__init__.py +++ b/website_hr_recruitment_ux/__init__.py @@ -0,0 +1 @@ +from . import controllers diff --git a/website_hr_recruitment_ux/__manifest__.py b/website_hr_recruitment_ux/__manifest__.py index 1bf5a99..e27333a 100644 --- a/website_hr_recruitment_ux/__manifest__.py +++ b/website_hr_recruitment_ux/__manifest__.py @@ -24,7 +24,7 @@ "author": "ADHOC SA", "website": "www.adhoc.com.ar", "license": "AGPL-3", - "summary": "Fixes phone field validation in the public job application form", + "summary": "Fixes on the public job application form", "depends": [ "website_hr_recruitment", ], diff --git a/website_hr_recruitment_ux/controllers/__init__.py b/website_hr_recruitment_ux/controllers/__init__.py new file mode 100644 index 0000000..12a7e52 --- /dev/null +++ b/website_hr_recruitment_ux/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/website_hr_recruitment_ux/controllers/main.py b/website_hr_recruitment_ux/controllers/main.py new file mode 100644 index 0000000..81b3883 --- /dev/null +++ b/website_hr_recruitment_ux/controllers/main.py @@ -0,0 +1,73 @@ +from datetime import datetime + +from dateutil.relativedelta import relativedelta +from odoo import _, http +from odoo.addons.website_hr_recruitment.controllers.main import WebsiteHrRecruitment +from odoo.fields import Domain +from odoo.tools import email_normalize, escape_psql + + +class WebsiteHrRecruitment(WebsiteHrRecruitment): + @http.route() + def check_recent_application(self, field, value, job_id): + """Copia del nativo sin el contacto del reclutador: la ruta es publica y el + aviso de postulacion duplicada exponia su nombre, email y telefono.""" + + def refused_applicants_condition(applicant): + return ( + not applicant.active + and applicant.job_id.id == int(job_id) + and applicant.create_date >= (datetime.now() - relativedelta(months=6)) + ) + + field_domain = { + "name": [("partner_name", "=ilike", escape_psql(value))], + "email": [("email_normalized", "=", email_normalize(value))], + "phone": [("partner_phone", "=", value)], + "linkedin": [("linkedin_profile", "=ilike", escape_psql(value))], + }.get(field, Domain.FALSE) + + applications_by_status = ( + http.request.env["hr.applicant"] + .sudo() + .search( + Domain.AND( + [ + field_domain, + [ + ("job_id.website_id", "in", [http.request.website.id, False]), + ("application_status", "in", ["ongoing", "refused"]), + ], + ] + ), + order="create_date DESC", + ) + .grouped("application_status") + ) + refused_applicants = applications_by_status.get("refused", http.request.env["hr.applicant"]) + if any(applicant for applicant in refused_applicants if refused_applicants_condition(applicant)): + return { + "message": _( + "We've found a previous closed application in our system within the last 6 months." + " Please consider before applying in order not to duplicate efforts." + ) + } + + if "ongoing" not in applications_by_status: + return {"message": None} + + ongoing_application = applications_by_status.get("ongoing")[0] + if ongoing_application.job_id.id == int(job_id): + return { + "message": _( + "An application already exists for %(value)s. Duplicates might be rejected.", + value=value, + ) + } + + return { + "message": _( + "We found a recent application with a similar name, email, phone number." + " You can continue if it's not a mistake." + ) + } diff --git a/website_hr_recruitment_ux/i18n/es.po b/website_hr_recruitment_ux/i18n/es.po index aa28d13..c2df71c 100644 --- a/website_hr_recruitment_ux/i18n/es.po +++ b/website_hr_recruitment_ux/i18n/es.po @@ -16,6 +16,39 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: website_hr_recruitment_ux +#. odoo-javascript #: code:addons/website_hr_recruitment_ux/static/src/interactions/hr_recruitment_form.js:0 msgid "Please enter a valid phone number." msgstr "Por favor ingresá un número de teléfono válido." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"An application already exists for %(value)s. Duplicates might be " +"rejected." +msgstr "" +"Ya existe una aplicación para %(value)s. Es posible que los " +"duplicados se rechacen." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We found a recent application with a similar name, email, phone " +"number. You can continue if it's not a mistake." +msgstr "" +"Encontramos una solicitud reciente con un nombre, correo electrónico " +"y número de teléfono similares. Continúe si no se trata de un error." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We've found a previous closed application in our system within the " +"last 6 months. Please consider before applying in order not to " +"duplicate efforts." +msgstr "" +"Encontramos una solicitud anterior cerrada en nuestro sistema dentro " +"de los próximos 6 meses. Considere esto antes de volver a " +"presentarse para no duplicar esfuerzos." diff --git a/website_hr_recruitment_ux/i18n/es_419.po b/website_hr_recruitment_ux/i18n/es_419.po new file mode 100644 index 0000000..3dcf248 --- /dev/null +++ b/website_hr_recruitment_ux/i18n/es_419.po @@ -0,0 +1,55 @@ +# Latin American Spanish translation of website_hr_recruitment_ux. +# Copyright (C) 2026 ADHOC SA +# This file is distributed under the same license as the website_hr_recruitment_ux package. +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-06-19 00:00+0000\n" +"PO-Revision-Date: 2026-06-19 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: es_419 \n" +"Language: es_419\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: website_hr_recruitment_ux +#. odoo-javascript +#: code:addons/website_hr_recruitment_ux/static/src/interactions/hr_recruitment_form.js:0 +msgid "Please enter a valid phone number." +msgstr "Por favor ingresá un número de teléfono válido." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"An application already exists for %(value)s. Duplicates might be " +"rejected." +msgstr "" +"Ya hay una postulación para %(value)s y si está duplicada podría ser " +"rechazada." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We found a recent application with a similar name, email, phone " +"number. You can continue if it's not a mistake." +msgstr "" +"Encontramos una postulación reciente con un nombre, correo " +"electrónico y número de teléfono similares. Continúe si no se trata " +"de un error." + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We've found a previous closed application in our system within the " +"last 6 months. Please consider before applying in order not to " +"duplicate efforts." +msgstr "" +"Encontramos una postulación anterior cerrada en nuestro sistema " +"dentro de los próximos 6 meses. Considere esto antes de volver a " +"postularse para no duplicar esfuerzos." diff --git a/website_hr_recruitment_ux/i18n/website_hr_recruitment_ux.pot b/website_hr_recruitment_ux/i18n/website_hr_recruitment_ux.pot index 2a54728..2688d1a 100644 --- a/website_hr_recruitment_ux/i18n/website_hr_recruitment_ux.pot +++ b/website_hr_recruitment_ux/i18n/website_hr_recruitment_ux.pot @@ -20,3 +20,28 @@ msgstr "" #: code:addons/website_hr_recruitment_ux/static/src/interactions/hr_recruitment_form.js:0 msgid "Please enter a valid phone number." msgstr "" + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"An application already exists for %(value)s. Duplicates might be " +"rejected." +msgstr "" + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We found a recent application with a similar name, email, phone " +"number. You can continue if it's not a mistake." +msgstr "" + +#. module: website_hr_recruitment_ux +#. odoo-python +#: code:addons/website_hr_recruitment_ux/controllers/main.py:0 +msgid "" +"We've found a previous closed application in our system within the " +"last 6 months. Please consider before applying in order not to " +"duplicate efforts." +msgstr "" diff --git a/website_hr_recruitment_ux/tests/__init__.py b/website_hr_recruitment_ux/tests/__init__.py new file mode 100644 index 0000000..e2b56b3 --- /dev/null +++ b/website_hr_recruitment_ux/tests/__init__.py @@ -0,0 +1 @@ +from . import test_check_recent_application diff --git a/website_hr_recruitment_ux/tests/test_check_recent_application.py b/website_hr_recruitment_ux/tests/test_check_recent_application.py new file mode 100644 index 0000000..2d8ba2f --- /dev/null +++ b/website_hr_recruitment_ux/tests/test_check_recent_application.py @@ -0,0 +1,32 @@ +from odoo.tests import HttpCase, tagged + + +@tagged("post_install", "-at_install") +class TestCheckRecentApplication(HttpCase): + def test_duplicate_warning_hides_recruiter_contact(self): + recruiter = self.env["res.users"].create( + { + "name": "Zzrecruiter Uxtest", + "login": "zzrecruiter_uxtest", + "email": "zzrecruiter@example.com", + "phone": "+54 341 000-0000", + } + ) + job = self.env["hr.job"].create({"name": "Uxtest Job", "is_published": True}) + self.env["hr.applicant"].create( + { + "job_id": job.id, + "partner_name": "Uxtest Candidate", + "partner_phone": "+54 341 111-1111", + "user_id": recruiter.id, + } + ) + + message = self.make_jsonrpc_request( + "/website_hr_recruitment/check_recent_application", + {"field": "phone", "value": "+54 341 111-1111", "job_id": job.id}, + )["message"] + + self.assertNotIn("zzrecruiter@example.com", message) + self.assertNotIn("+54 341 000-0000", message) + self.assertNotIn("Zzrecruiter Uxtest", message)