diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py
index 2d6648fb54b..9930b981f80 100644
--- a/addons/mass_mailing/models/mailing.py
+++ b/addons/mass_mailing/models/mailing.py
@@ -461,13 +461,7 @@ class MassMailing(models.Model):
at = fields.Datetime.from_string(values['ab_testing_schedule_datetime'])
ab_testing_cron._trigger(at=at)
mailings = super().create(vals_list)
- campaign_vals = [
- mailing._get_default_ab_testing_campaign_values()
- for mailing in mailings
- if mailing.ab_testing_enabled and not mailing.campaign_id
- ]
- self.env['utm.campaign'].create(campaign_vals)
-
+ mailings._create_ab_testing_utm_campaigns()
mailings._fix_attachment_ownership()
return mailings
@@ -475,15 +469,13 @@ class MassMailing(models.Model):
def write(self, values):
if values.get('body_html'):
values['body_html'] = self._convert_inline_images_to_urls(values['body_html'])
- # When ab_testing_enabled is checked we create a campaign if there is none set.
- if values.get('ab_testing_enabled') and not values.get('campaign_id'):
- # Compute the values of the A/B test campaign based on the first mailing
- values['campaign_id'] = self.env['utm.campaign'].create(self[0]._get_default_ab_testing_campaign_values(values)).id
# If ab_testing is already enabled on a mailing and the campaign is removed, we raise a ValidationError
if values.get('campaign_id') is False and any(mailing.ab_testing_enabled for mailing in self) and 'ab_testing_enabled' not in values:
raise ValidationError(_("A campaign should be set when A/B test is enabled"))
result = super(MassMailing, self).write(values)
+ if values.get('ab_testing_enabled'):
+ self._create_ab_testing_utm_campaigns()
self._fix_attachment_ownership()
if any(self.mapped('ab_testing_schedule_datetime')):
@@ -493,6 +485,14 @@ class MassMailing(models.Model):
return result
+ def _create_ab_testing_utm_campaigns(self):
+ """ Creates the A/B test campaigns for the mailings that do not have campaign set already """
+ campaign_vals = [
+ mailing._get_default_ab_testing_campaign_values()
+ for mailing in self.filtered(lambda mailing: mailing.ab_testing_enabled and not mailing.campaign_id)
+ ]
+ return self.env['utm.campaign'].create(campaign_vals)
+
def _fix_attachment_ownership(self):
for record in self:
record.attachment_ids.write({'res_model': record._name, 'res_id': record.id})
diff --git a/addons/mass_mailing/models/utm_campaign.py b/addons/mass_mailing/models/utm_campaign.py
index 7913cc44bdc..90505e4b389 100644
--- a/addons/mass_mailing/models/utm_campaign.py
+++ b/addons/mass_mailing/models/utm_campaign.py
@@ -22,7 +22,7 @@ class UtmCampaign(models.Model):
# A/B Testing
ab_testing_mailings_count = fields.Integer("A/B Test Mailings #", compute="_compute_mailing_mail_count")
- ab_testing_completed = fields.Boolean("A/B Testing Campaign Finished")
+ ab_testing_completed = fields.Boolean("A/B Testing Campaign Finished", copy=False)
ab_testing_schedule_datetime = fields.Datetime('Send Final On',
default=lambda self: fields.Datetime.now() + relativedelta(days=1),
help="Date that will be used to know when to determine and send the winner mailing")
@@ -66,8 +66,8 @@ class UtmCampaign(models.Model):
mapped_data = dict()
ab_testing_mapped_data = dict()
for campaign in self:
- campaign.mailing_mail_count = sum(mapped_data.get(campaign.id, []))
- campaign.ab_testing_mailings_count = sum(ab_testing_mapped_data.get(campaign.id, []))
+ campaign.mailing_mail_count = sum(mapped_data.get(campaign._origin.id or campaign.id, []))
+ campaign.ab_testing_mailings_count = sum(ab_testing_mapped_data.get(campaign._origin.id or campaign.id, []))
@api.constrains('ab_testing_total_pc', 'ab_testing_completed')
def _check_ab_testing_total_pc(self):
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.scss b/addons/mass_mailing/static/src/scss/mass_mailing.scss
index 1b0de618a99..e80cb417b1d 100644
--- a/addons/mass_mailing/static/src/scss/mass_mailing.scss
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.scss
@@ -215,23 +215,6 @@
font-size: 90%;
}
-@media only screen and (min-width: 1200px) {
- .o_utm_campaign_mass_mailing_substats {
- padding-right: 210px;
- div {
- margin-left: 50px;
- }
- }
-}
-
-@media only screen and (min-width: 768px) and (max-width: 1200px) {
- .o_utm_campaign_mass_mailing_substats {
- padding-right: 180px;
- div {
- margin-left: 30px;
- }
- }
-}
.o_mailing_contact_import_list {
min-height: 150px;
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss b/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss
index 4c04e47f4a0..7ea9713d05e 100644
--- a/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss
+++ b/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss
@@ -1,9 +1,4 @@
@include media-breakpoint-down(md) {
- .o_utm_campaign_mass_mailing_substats {
- width: 80%;
- margin: 0 auto;
- justify-content: space-between !important;
- }
// For field to occupy full width in small devices. We need '!important'
// here because of the 'w-auto' class used in the view.
.o_form_editable div[name="mailing_filter_id"] {
diff --git a/addons/mass_mailing/tests/test_mailing_ab_testing.py b/addons/mass_mailing/tests/test_mailing_ab_testing.py
index 5d3880c9a13..da89ee73e47 100644
--- a/addons/mass_mailing/tests/test_mailing_ab_testing.py
+++ b/addons/mass_mailing/tests/test_mailing_ab_testing.py
@@ -103,11 +103,35 @@ class TestMailingABTesting(MassMailCommon):
})
ab_mailing.invalidate_recordset()
- # Check if the campaign is correclty created and the values set on the mailing are still the same
+ # Check if the campaign is correctly created and the values set on the mailing are still the same
self.assertTrue(ab_mailing.campaign_id, "A campaign id is present for the A/B test mailing")
self.assertEqual(ab_mailing.ab_testing_winner_selection, 'manual', "The selection winner has been propagated correctly")
self.assertEqual(ab_mailing.ab_testing_schedule_datetime, schedule_datetime, "The schedule date has been propagated correctly")
+ # Check that while enabling the A/B testing, if campaign is already set, new one should not be created
+ created_mailing_campaign = ab_mailing.campaign_id
+ ab_mailing.ab_testing_enabled = False
+ ab_mailing.ab_testing_enabled = True
+ self.assertEqual(ab_mailing.campaign_id, created_mailing_campaign, "No new campaign should have been created")
+
+ # Check that while enabling the A/B testing, if user manually selects a campaign, it should be saved
+ # rather than being replaced with the automatically created one
+ ab_mailing.write({'ab_testing_enabled': False, 'campaign_id': False})
+ ab_mailing.write({'ab_testing_enabled': True, 'campaign_id': created_mailing_campaign})
+ self.assertEqual(ab_mailing.campaign_id, created_mailing_campaign, "No new campaign should have been created")
+
+ ab_mailing_2 = self.env['mailing.mailing'].create({
+ 'subject': 'A/B Testing V2',
+ 'contact_list_ids': self.mailing_list.ids,
+ })
+ ab_mailing_2.invalidate_recordset()
+
+ ab_mailing_2.ab_testing_enabled = True
+ # Check if the campaign is correctly created with default values
+ self.assertTrue(ab_mailing.campaign_id, "A campaign id is present for the A/B test mailing")
+ self.assertTrue(ab_mailing.ab_testing_winner_selection, "The selection winner has been set to default value")
+ self.assertTrue(ab_mailing.ab_testing_schedule_datetime, "The schedule date has been set to default value")
+
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('user_marketing')
def test_mailing_ab_testing_manual_flow(self):
diff --git a/addons/mass_mailing/views/utm_campaign_views.xml b/addons/mass_mailing/views/utm_campaign_views.xml
index 48afe6c1b12..8e4281cdeae 100644
--- a/addons/mass_mailing/views/utm_campaign_views.xml
+++ b/addons/mass_mailing/views/utm_campaign_views.xml
@@ -9,7 +9,7 @@
+ groups="mass_mailing.group_mass_mailing_user" string="Send Mailing"/>
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-