diff --git a/addons/crm/data/digest_data.xml b/addons/crm/data/digest_data.xml index 9da9d78e512..d044815d18e 100644 --- a/addons/crm/data/digest_data.xml +++ b/addons/crm/data/digest_data.xml @@ -16,9 +16,9 @@
Tip: Convert incoming emails into opportunities
-Did you know emails sent to
- Try sending an email to your CRM. This email address is configurable by sales team members.
Did you know emails sent to
+ Try sending an email to your CRM. This email address is configurable by sales team members.
Did you know emails sent to a Sales Team alias generate opportunities in your pipeline?
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 1bcea9ed084..d8c789384e1 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -1276,10 +1276,9 @@ class Lead(models.Model): ('alias_force_thread_id', '=', False) ], limit=1) - if alias_record and alias_record.alias_domain and alias_record.alias_name: - email = f'{alias_record.alias_name}@{alias_record.alias_domain}' + if alias_record.alias_domain and alias_record.alias_name: sub_title = Markup(_('Use the New button, or send an email to %(email_link)s to test the email gateway.')) % { - 'email_link': Markup("%s") % (email, email), + 'email_link': Markup("%s") % (alias_record.display_name, alias_record.display_name), } return super().get_empty_list_help( f'{help_title}
{sub_title}
' diff --git a/addons/crm/models/crm_team.py b/addons/crm/models/crm_team.py index 4ada6a3b3b2..40ccee93b3d 100644 --- a/addons/crm/models/crm_team.py +++ b/addons/crm/models/crm_team.py @@ -24,9 +24,7 @@ class Team(models.Model): use_leads = fields.Boolean('Leads', help="Check this box to filter and qualify incoming requests as leads before converting them into opportunities and assigning them to a salesperson.") use_opportunities = fields.Boolean('Pipeline', default=True, help="Check this box to manage a presales process with opportunities.") - alias_id = fields.Many2one( - 'mail.alias', string='Alias', ondelete="restrict", required=True, - help="The email address associated with this channel. New emails received will automatically create new leads assigned to the channel.") + alias_id = fields.Many2one(help="The email address associated with this channel. New emails received will automatically create new leads assigned to the channel.") # assignment assignment_enabled = fields.Boolean('Lead Assign', compute='_compute_assignment_enabled') assignment_auto_enabled = fields.Boolean('Auto Assignment', compute='_compute_assignment_enabled') diff --git a/addons/crm/tests/test_crm_lead.py b/addons/crm/tests/test_crm_lead.py index 0b5e33f0492..8cf4b4a20f3 100644 --- a/addons/crm/tests/test_crm_lead.py +++ b/addons/crm/tests/test_crm_lead.py @@ -627,7 +627,7 @@ class TestCRMLead(TestCrmCommon): new_lead = self.format_and_process( INCOMING_EMAIL, 'unknown.sender@test.example.com', - '%s@%s' % (self.sales_team_1.alias_name, self.alias_domain), + self.sales_team_1.alias_email, subject='Delivery cost inquiry', target_model='crm.lead', ) diff --git a/addons/crm/tests/test_crm_lead_multicompany.py b/addons/crm/tests/test_crm_lead_multicompany.py index 7b6118d5b3a..ff1d57f9544 100644 --- a/addons/crm/tests/test_crm_lead_multicompany.py +++ b/addons/crm/tests/test_crm_lead_multicompany.py @@ -314,7 +314,7 @@ class TestCRMLeadMultiCompany(TestCrmCommon): new_lead = self.format_and_process( INCOMING_EMAIL, customer_company.email, - '%s@%s' % (self.sales_team_1.alias_name, self.alias_domain), + self.sales_team_1.alias_email, subject='Team having partner in company', target_model='crm.lead', ) diff --git a/addons/crm/views/crm_helper_templates.xml b/addons/crm/views/crm_helper_templates.xml index f3610e25e58..6cd44f01253 100644 --- a/addons/crm/views/crm_helper_templates.xml +++ b/addons/crm/views/crm_helper_templates.xml @@ -1,11 +1,11 @@Create an opportunity to start playing with your pipeline.
Use the New button, or send an email to
-
%(send_string)s %(alias_email)s
""" ) % { - 'alias_email': alias_email, + 'alias_email': expense_alias.display_name, 'params': params, 'send_string': _("Or send your receipts at"), } diff --git a/addons/hr_recruitment/data/digest_data.xml b/addons/hr_recruitment/data/digest_data.xml index 9434c1ee7a9..683ff349912 100644 --- a/addons/hr_recruitment/data/digest_data.xml +++ b/addons/hr_recruitment/data/digest_data.xml @@ -17,8 +17,8 @@
By setting an alias to a job position, emails sent to this address create applications automatically. You can even use multiple trackers to get statistics according to the source of the application: LinkedIn, Monster, Indeed, etc.
%(help_title)s
@@ -350,11 +350,10 @@ class Applicant(models.Model): 'para_2': _("You can search into attachment's content, like resumes, with the searchbar."), } - if alias_id and alias_id.alias_domain and alias_id.alias_name: - email = alias_id.display_name + if hr_job.alias_email: nocontent_body += Markup('%(helper_email)s %(email)s
') % { 'helper_email': _("Create new applications by sending an email to"), - 'email': email + 'email': hr_job.alias_email, } return super().get_empty_list_help(nocontent_body) diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index f1292f83805..8b6e1b2ddec 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -49,9 +49,7 @@ class Job(models.Model): help="Person responsible of validating the employee's contracts.") document_ids = fields.One2many('ir.attachment', compute='_compute_document_ids', string="Documents", readonly=True) documents_count = fields.Integer(compute='_compute_document_ids', string="Document Count") - alias_id = fields.Many2one( - 'mail.alias', "Alias", ondelete="restrict", required=True, - help="Email alias for this job position. New emails will automatically create new applicants for this job position.") + alias_id = fields.Many2one(help="Email alias for this job position. New emails will automatically create new applicants for this job position.") color = fields.Integer("Color Index") is_favorite = fields.Boolean(compute='_compute_is_favorite', inverse='_inverse_is_favorite') favorite_user_ids = fields.Many2many('res.users', 'job_favorite_user_rel', 'job_id', 'user_id', default=_get_default_favorite_user_ids) diff --git a/addons/hr_recruitment/models/hr_recruitment_source.py b/addons/hr_recruitment/models/hr_recruitment_source.py index 7bd11eb8428..ca65cec23b2 100644 --- a/addons/hr_recruitment/models/hr_recruitment_source.py +++ b/addons/hr_recruitment/models/hr_recruitment_source.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import api, fields, models +from odoo import fields, models class RecruitmentSource(models.Model): @@ -12,11 +12,12 @@ class RecruitmentSource(models.Model): email = fields.Char(related='alias_id.display_name', string="Email", readonly=True) has_domain = fields.Char(compute='_compute_has_domain') job_id = fields.Many2one('hr.job', "Job", ondelete='cascade') - alias_id = fields.Many2one('mail.alias', "Alias ID") + alias_id = fields.Many2one('mail.alias', "Alias ID", ondelete='restrict') medium_id = fields.Many2one('utm.medium', default=lambda self: self.env.ref('utm.utm_medium_website')) def _compute_has_domain(self): - self.has_domain = bool(self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")) + for source in self: + source.has_domain = bool(source.alias_id.alias_domain) def create_alias(self): campaign = self.env.ref('hr_recruitment.utm_campaign_job') @@ -36,10 +37,9 @@ class RecruitmentSource(models.Model): } source.alias_id = self.env['mail.alias'].create(vals) - @api.model - def _get_view(self, view_id=None, view_type='form', **options): - arch, view = super()._get_view(view_id, view_type, **options) - if view_type == 'tree' and not bool(self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")): - email = arch.xpath("//field[@name='email']")[0] - email.getparent().remove(email) - return arch, view + def unlink(self): + """ Cascade delete aliases to avoid useless / badly configured aliases. """ + aliases = self.alias_id + res = super().unlink() + aliases.sudo().unlink() + return res diff --git a/addons/hr_recruitment/views/hr_recruitment_source_views.xml b/addons/hr_recruitment/views/hr_recruitment_source_views.xml index 9843d6cb7c0..280871825c6 100644 --- a/addons/hr_recruitment/views/hr_recruitment_source_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_source_views.xml @@ -46,7 +46,8 @@Tip: Create tasks from incoming emails
-Emails sent to
Create tasks by sending an email to the email address of your project.
diff --git a/addons/project/models/project_project.py b/addons/project/models/project_project.py index e07d0aeb8ba..e4ca767ebf6 100644 --- a/addons/project/models/project_project.py +++ b/addons/project/models/project_project.py @@ -130,10 +130,8 @@ class Project(models.Model): color = fields.Integer(string='Color Index') user_id = fields.Many2one('res.users', string='Project Manager', default=lambda self: self.env.user, tracking=True) alias_enabled = fields.Boolean(string='Use Email Alias', compute='_compute_alias_enabled', readonly=False) - alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True, - help="Internal email associated with this project. Incoming emails are automatically synchronized " - "with Tasks (or optionally Issues if the Issue Tracker module is installed).") - alias_value = fields.Char(string='Alias email', compute='_compute_alias_value') + alias_id = fields.Many2one(help="Internal email associated with this project. Incoming emails are automatically synchronized " + "with Tasks (or optionally Issues if the Issue Tracker module is installed).") privacy_visibility = fields.Selection([ ('followers', 'Invited internal users (private)'), ('employees', 'All internal users'), @@ -217,7 +215,7 @@ class Project(models.Model): def _compute_alias_enabled(self): for project in self: - project.alias_enabled = project.alias_domain and project.alias_id.alias_name + project.alias_enabled = bool(project.alias_email) def _compute_access_url(self): super(Project, self)._compute_access_url() @@ -337,14 +335,6 @@ class Project(models.Model): operator_new = 'not inselect' return [('id', operator_new, (query, ()))] - @api.depends('alias_name', 'alias_domain') - def _compute_alias_value(self): - for project in self: - if not project.alias_name or not project.alias_domain: - project.alias_value = '' - else: - project.alias_value = "%s@%s" % (project.alias_name, project.alias_domain) - @api.depends('collaborator_ids', 'privacy_visibility') def _compute_collaborator_count(self): project_sharings = self.filtered(lambda project: project.privacy_visibility == 'portal') diff --git a/addons/project/views/project_project_views.xml b/addons/project/views/project_project_views.xml index 7417738bbf9..d21cc8dec6b 100644 --- a/addons/project/views/project_project_views.xml +++ b/addons/project/views/project_project_views.xml @@ -96,7 +96,7 @@