diff --git a/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/post-migration.py b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/post-migration.py new file mode 100644 index 000000000000..dbaadad9df3f --- /dev/null +++ b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/post-migration.py @@ -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) diff --git a/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/pre-migration.py b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/pre-migration.py new file mode 100644 index 000000000000..b47dd55ffd47 --- /dev/null +++ b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/pre-migration.py @@ -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) diff --git a/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/upgrade_analysis_work.txt new file mode 100644 index 000000000000..570d46b32698 --- /dev/null +++ b/openupgrade_scripts/scripts/mass_mailing/17.0.2.7/upgrade_analysis_work.txt @@ -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