Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2025 Carlos Lopez - Tecnativa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade


def _utm_campaign_fill_ab_testing_winner_mailing_id(env):
openupgrade.logged_query(
env.cr,
"""
WITH winner_mailing AS (
SELECT
campaign_id,
MAX(id) AS mailing_id
FROM
mailing_mailing
WHERE
ab_testing_enabled IS TRUE
AND state = 'done'
AND ab_testing_pc = 100
GROUP BY
campaign_id
)
UPDATE utm_campaign
SET ab_testing_winner_mailing_id = winner_mailing.mailing_id
FROM winner_mailing
WHERE utm_campaign.id = winner_mailing.campaign_id
AND utm_campaign.ab_testing_completed IS TRUE
""",
)


@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(env, "mass_mailing", "17.0.2.7/noupdate_changes.xml")
openupgrade.delete_record_translations(
env.cr, "mass_mailing", ["mass_mailing_mail_layout"], field_list=["arch_db"]
)
_utm_campaign_fill_ab_testing_winner_mailing_id(env)
91 changes: 91 additions & 0 deletions openupgrade_scripts/scripts/mass_mailing/17.0.2.7/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright 2025 Carlos Lopez - Tecnativa
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from openupgradelib import openupgrade

_xmlids_renames = [
(
"mass_mailing.access_mailing_contact_subscription_mm_user",
"mass_mailing.access_mailing_subscription_mm_user",
),
("mass_mailing.view", "mass_mailing.mailing_view"),
("mass_mailing.unsubscribe", "mass_mailing.unsubscribe_form"),
("mass_mailing.page_unsubscribe", "mass_mailing.page_mailing_unsubscribe"),
(
"mass_mailing.mailing_contact_subscription_view_form",
"mass_mailing.mailing_subscription_view_form",
),
(
"mass_mailing.mailing_contact_subscription_view_search",
"mass_mailing.mailing_subscription_view_search",
),
(
"mass_mailing.mailing_contact_subscription_view_tree",
"mass_mailing.mailing_subscription_view_tree",
),
("mass_mailing.mass_mailing_contact_0", "mass_mailing.mass_mail_contact_0"),
]
_models_renames = [
("mailing.contact.subscription", "mailing.subscription"),
]
_tables_renames = [
("mailing_contact_list_rel", "mailing_subscription"),
]
_fields_renames = [
(
"mailing.subscription",
"mailing_subscription",
"unsubscription_date",
"opt_out_datetime",
),
]


def _mailing_subscription_add_xmlid_contact_0(env):
"""
Add XML ID to prevent SQL unique constraint error
because in V16, a record was added without an XML ID:
https://github.com/odoo/odoo/blob/f7db1775af3cb641f6cc88607b2d9dce611fb049/addons/mass_mailing/data/mailing_list_data.xml#L10
and now, in V17, a new record is created using an XML ID:
https://github.com/odoo/odoo/blob/8ec4108b978f00b0a373a28f602780d87aa0d000/addons/mass_mailing/data/mailing_subscription.xml#L4
"""
env.cr.execute(
"""
WITH contact_0 AS (
SELECT res_id
FROM ir_model_data imd
WHERE imd.module = 'mass_mailing'
AND imd.name = 'mass_mail_contact_0'
AND imd.model = 'mailing.contact'
),
list_0 AS (
SELECT res_id
FROM ir_model_data imd
WHERE imd.module = 'mass_mailing'
AND imd.name = 'mailing_list_data'
AND imd.model = 'mailing.list'
)
SELECT id
FROM mailing_subscription
JOIN contact_0 ON mailing_subscription.contact_id = contact_0.res_id
JOIN list_0 ON mailing_subscription.list_id = list_0.res_id
"""
)
res = env.cr.fetchone()
if res:
openupgrade.add_xmlid(
env.cr,
"mass_mailing",
"mailing_list_data_sub_contact_0",
"mailing.subscription",
res[0],
)


@openupgrade.migrate()
def migrate(env, version):
openupgrade.rename_xmlids(env.cr, _xmlids_renames)
openupgrade.rename_models(env.cr, _models_renames)
openupgrade.rename_tables(env.cr, _tables_renames)
openupgrade.rename_fields(env, _fields_renames)
_mailing_subscription_add_xmlid_contact_0(env)
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---Models in module 'mass_mailing'---
obsolete model mailing.contact.subscription
new model mailing.subscription
# DONE: pre-migration: Renamed to mailing.subscription according https://github.com/odoo/odoo/commit/46ab1e38fcae2054a54bd0081528f3f05dd79e10
new model mailing.subscription.optout
# NOTHING TO DO: new feature

---Fields in module 'mass_mailing'---
mass_mailing / mail.blacklist / opt_out_reason_id (many2one) : NEW relation: mailing.subscription.optout
# NOTHING TO DO: new feature
mass_mailing / mailing.contact / _order : _order is now 'name ASC, id DESC' ('email')
# NOTHING TO DO:

mass_mailing / mailing.contact / list_ids (many2many) : table is now 'mailing_subscription' ('mailing_contact_list_rel')
mass_mailing / mailing.contact / message_main_attachment_id (many2one): DEL relation: ir.attachment
mass_mailing / mailing.contact / rating_ids (one2many) : NEW relation: rating.rating
mass_mailing / mailing.contact / subscription_ids (one2many) : NEW relation: mailing.subscription
mass_mailing / mailing.contact / subscription_list_ids (one2many): DEL relation: mailing.contact.subscription
mass_mailing / mailing.contact.subscription / contact_id (many2one) : DEL relation: mailing.contact, required
mass_mailing / mailing.contact.subscription / list_id (many2one) : DEL relation: mailing.list, required
mass_mailing / mailing.contact.subscription / opt_out (boolean) : DEL
mass_mailing / mailing.contact.subscription / unsubscription_date (datetime): DEL
# DONE: handle in pre-migration with rename from mailing.contact.subscription to mailing.subscription

mass_mailing / mailing.list / contact_ids (many2many) : table is now 'mailing_subscription' ('mailing_contact_list_rel')
mass_mailing / mailing.list / subscription_ids (one2many) : relation is now 'mailing.subscription' ('mailing.contact.subscription') [nothing to do]
# NOTHING TO DO:

mass_mailing / mailing.mailing / ab_testing_completed (boolean): not stored anymore
mass_mailing / mailing.mailing / activity_user_id (many2one) : not related anymore
mass_mailing / mailing.mailing / activity_user_id (many2one) : now a function
mass_mailing / mailing.mailing / message_main_attachment_id (many2one): DEL relation: ir.attachment
mass_mailing / mailing.mailing / rating_ids (one2many) : NEW relation: rating.rating
mass_mailing / mailing.mailing / schedule_date (datetime) : not a function anymore
# NOTHING TO DO:
mass_mailing / mailing.mailing / bounced_ratio (integer) : type is now 'float' ('integer')
mass_mailing / mailing.mailing / clicks_ratio (integer) : type is now 'float' ('integer')
mass_mailing / mailing.mailing / opened_ratio (integer) : type is now 'float' ('integer')
mass_mailing / mailing.mailing / received_ratio (integer) : type is now 'float' ('integer')
mass_mailing / mailing.mailing / replied_ratio (integer) : type is now 'float' ('integer')
# NOTHING TO DO: Postgres handles the type casting

mass_mailing / mailing.subscription / contact_id (many2one) : NEW relation: mailing.contact, required
mass_mailing / mailing.subscription / list_id (many2one) : NEW relation: mailing.list, required
mass_mailing / mailing.subscription / opt_out (boolean) : NEW hasdefault: default
# NOTHING TO DO: just moved from mailing.contact.subscription to mailing.subscription

mass_mailing / mailing.subscription / opt_out_datetime (datetime) : NEW hasdefault: compute
DONE: renamed from unsubscription_date according to https://github.com/odoo/odoo/commit/b4d7eda6e03446f9763b05d27d5aef6cea618635

mass_mailing / mailing.subscription / opt_out_reason_id (many2one) : NEW relation: mailing.subscription.optout
# NOTHING TO DO: new feature

mass_mailing / mailing.subscription.optout / is_feedback (boolean) : NEW
mass_mailing / mailing.subscription.optout / name (char) : NEW
mass_mailing / mailing.subscription.optout / sequence (integer) : NEW hasdefault: default
# NOTHING TO DO: new feature

mass_mailing / mailing.trace / failure_reason (text) : NEW
mass_mailing / mailing.trace / failure_type (selection) : selection_keys is now '['mail_bl', 'mail_bounce', 'mail_dup', 'mail_email_invalid', 'mail_email_missing', 'mail_from_invalid', 'mail_from_missing', 'mail_optout', 'mail_smtp', 'unknown']' ('['mail_bl', 'mail_dup', 'mail_email_invalid', 'mail_email_missing', 'mail_optout', 'mail_smtp', 'unknown']')
mass_mailing / mailing.trace / trace_status (selection) : selection_keys is now '['bounce', 'cancel', 'error', 'open', 'outgoing', 'pending', 'process', 'reply', 'sent']' ('['bounce', 'cancel', 'error', 'open', 'outgoing', 'reply', 'sent']')
# NOTHING TO DO: new feature

mass_mailing / utm.campaign / ab_testing_completed (boolean): now a function
# NOTHING TO DO: The field already exists in V16; it is now computed with store=True, but recomputation is not necessary
mass_mailing / utm.campaign / ab_testing_total_pc (integer) : DEL
# NOTHING TO DO: Removed in https://github.com/odoo/odoo/commit/37348521ced0ae094962661d84994a147c9b884c

mass_mailing / utm.campaign / ab_testing_winner_mailing_id (many2one): NEW relation: mailing.mailing
# DONE: post-migration: fill the field where mailing_mailing related to campain with ab_testing_pc=100. We can only deduce a winning A/B in the case only one is done, as the rest of the cases can't be deduced.

mass_mailing / utm.campaign / bounced_ratio (integer) : type is now 'float' ('integer')
mass_mailing / utm.campaign / opened_ratio (integer) : type is now 'float' ('integer')
mass_mailing / utm.campaign / received_ratio (integer) : type is now 'float' ('integer')
mass_mailing / utm.campaign / replied_ratio (integer) : type is now 'float' ('integer')
# NOTHING TO DO: Postgres handles the type casting

---XML records in module 'mass_mailing'---
NEW ir.actions.act_window: mass_mailing.mailing_subscription_action_report_optout
NEW ir.actions.act_window: mass_mailing.mailing_subscription_optout_action
# NOTHING TO DO

NEW ir.model.access: mass_mailing.access_mailing_subscription_optout_mm_user
# NOTHING TO DO: new access right

NEW ir.model.access: mass_mailing.access_mailing_subscription_mm_user
DEL ir.model.access: mass_mailing.access_mailing_contact_subscription_mm_user
# DONE: pre-migration: Rename xml-id

NEW ir.model.constraint: mass_mailing.constraint_mailing_subscription_unique_contact_list
DEL ir.model.constraint: mass_mailing.constraint_mailing_contact_list_rel_unique_contact_list
# DONE: pre-migration: handle in rename_tables

NEW ir.ui.menu: mass_mailing.mailing_menu_report_mailing
NEW ir.ui.menu: mass_mailing.mailing_menu_report_subscribe_reason
NEW ir.ui.menu: mass_mailing.mailing_subscription_optout_menu
# NOTHING TO DO: new feature

NEW ir.ui.view: mass_mailing.mail_blacklist_view_form
NEW ir.ui.view: mass_mailing.mail_blacklist_view_search
NEW ir.ui.view: mass_mailing.mail_blacklist_view_tree
NEW ir.ui.view: mass_mailing.mailing_subscription_optout_view_form
NEW ir.ui.view: mass_mailing.mailing_subscription_optout_view_search
NEW ir.ui.view: mass_mailing.mailing_subscription_optout_view_tree
# NOTHING TO DO: new feature

NEW ir.ui.view: mass_mailing.mailing_view
NEW ir.ui.view: mass_mailing.page_mailing_unsubscribe
NEW ir.ui.view: mass_mailing.unsubscribe_form
DEL ir.ui.view: mass_mailing.view
DEL ir.ui.view: mass_mailing.page_unsubscribe
DEL ir.ui.view: mass_mailing.unsubscribe
NEW ir.ui.view: mass_mailing.mailing_subscription_view_form
NEW ir.ui.view: mass_mailing.mailing_subscription_view_search
NEW ir.ui.view: mass_mailing.mailing_subscription_view_tree
DEL ir.ui.view: mass_mailing.mailing_contact_subscription_view_form
DEL ir.ui.view: mass_mailing.mailing_contact_subscription_view_search
DEL ir.ui.view: mass_mailing.mailing_contact_subscription_view_tree
# DONE: pre-migration: Rename xml-id

NEW ir.ui.view: mass_mailing.preview_content_mobile
# NOTHING TO DO: new feature

DEL ir.ui.view: mass_mailing.iframe_css_assets_edit
DEL ir.ui.view: mass_mailing.iframe_css_assets_readonly
# NOTHING TO DO: assets view moved to manifest

DEL ir.ui.view: mass_mailing.mass_mailing_mail_style (noupdate)
DEL ir.ui.view: mass_mailing.page_unsubscribed
DEL ir.ui.view: mass_mailing.snippet_options_extra_shapes
DEL ir.ui.view: mass_mailing.snippet_options_image_styles
DEL ir.ui.view: mass_mailing.unsubscribed
# NOTHING TO DO: Odoo removed this

NEW mailing.contact: mass_mailing.mass_mail_contact_0 (noupdate)
DEL mailing.contact: mass_mailing.mass_mailing_contact_0 (noupdate)
# DONE: pre-migration: Rename xml-id

NEW mailing.subscription: mass_mailing.mailing_list_data_sub_contact_0 (noupdate)
NEW mailing.subscription.optout: mass_mailing.mailing_subscription_optout_data_0
NEW mailing.subscription.optout: mass_mailing.mailing_subscription_optout_data_1
NEW mailing.subscription.optout: mass_mailing.mailing_subscription_optout_data_2
NEW mailing.subscription.optout: mass_mailing.mailing_subscription_optout_data_3
NEW mailing.subscription.optout: mass_mailing.mailing_subscription_optout_data_4
# NOTHING TO DO new data
Loading