diff --git a/docsource/modules150-160.rst b/docsource/modules150-160.rst index 0ba9a65687ca..944c74150a25 100644 --- a/docsource/modules150-160.rst +++ b/docsource/modules150-160.rst @@ -460,7 +460,7 @@ Module coverage 15.0 -> 16.0 +-------------------------------------------------+----------------------+-------------------------------------------------+ | lunch | | | +-------------------------------------------------+----------------------+-------------------------------------------------+ -| mail | | | +| mail | Done | | +-------------------------------------------------+----------------------+-------------------------------------------------+ | mail_bot | |No DB layout changes. | +-------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/mail/16.0.1.10/post-migration.py b/openupgrade_scripts/scripts/mail/16.0.1.10/post-migration.py new file mode 100644 index 000000000000..eba47d81ef37 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/16.0.1.10/post-migration.py @@ -0,0 +1,16 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.load_data(env.cr, "mail", "16.0.1.10/noupdate_changes.xml") + openupgrade.delete_records_safely_by_xml_id( + env, + [ + "mail.ir_rule_mail_channel_partner_group_user", + "mail.ir_rule_mail_channel_partner_group_system", + ], + ) diff --git a/openupgrade_scripts/scripts/mail/16.0.1.10/pre-migration.py b/openupgrade_scripts/scripts/mail/16.0.1.10/pre-migration.py new file mode 100644 index 000000000000..045c58e5b9cc --- /dev/null +++ b/openupgrade_scripts/scripts/mail/16.0.1.10/pre-migration.py @@ -0,0 +1,92 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_fields_renames = [ + ( + "mail.channel", + "mail_channel", + "channel_last_seen_partner_ids", + "channel_member_ids", + ) +] +_models_renames = [("mail.channel.partner", "mail.channel.member")] +_tables_renames = [("mail_channel_partner", "mail_channel_member")] +_columns_renames = { + "mail_message": [("add_sign", "email_add_signature")], +} +_xmlids_renames = [ + ( + "channel_partner_general_channel_for_admin", + "channel_member_general_channel_for_admin", + ) +] +_columns_copies = { + "mail_channel_rtc_session": [ + ("channel_partner_id", "channel_member_id", "integer") + ], +} + + +def ir_act_server_rename_state_email(env): + """ + ir.actions.server state selection key 'email' is now 'mail_post'. + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE ir_act_server + SET state='mail_post' + WHERE state='email'; + """, + ) + + +def mail_channel_channel_type_required(env): + """ + channel_type is now required on mail.channel. + Set default value 'channel' if no value was set. + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE mail_channel + SET channel_type='channel' + WHERE channel_type IS NULL; + """, + ) + + +def scheduled_date_set_empty_strings_to_null(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE mail_mail + SET scheduled_date = NULL + WHERE scheduled_date = ''; + """, + ) + + +def delete_obsolete_constraints(env): + openupgrade.delete_sql_constraint_safely( + env, "mail", "mail_channel_partner", "partner_or_guest_exists" + ) + openupgrade.delete_sql_constraint_safely( + env, "mail", "mail_channel_rtc_session", "channel_partner_unique" + ) + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_fields(env, _fields_renames) + openupgrade.rename_models(env.cr, _models_renames) + openupgrade.rename_tables(env.cr, _tables_renames) + openupgrade.rename_columns(env.cr, _columns_renames) + openupgrade.copy_columns(env.cr, _columns_copies) + openupgrade.rename_xmlids(env.cr, _xmlids_renames) + ir_act_server_rename_state_email(env) + mail_channel_channel_type_required(env) + scheduled_date_set_empty_strings_to_null(env) + delete_obsolete_constraints(env) diff --git a/openupgrade_scripts/scripts/mail/16.0.1.10/tests/data.py b/openupgrade_scripts/scripts/mail/16.0.1.10/tests/data.py new file mode 100644 index 000000000000..87163fcf5257 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/16.0.1.10/tests/data.py @@ -0,0 +1,8 @@ +env = locals().get("env") +# create a mail with a scheduled date as char to be sure it was correctly +# migrated as datetime field in v16. +env["mail.mail"].create( + {"body_html": "TEST date", "scheduled_date": "2023-04-12 10:05:01"} +) +env["mail.mail"].create({"body_html": "TEST empty date", "scheduled_date": ""}) +env.cr.commit() diff --git a/openupgrade_scripts/scripts/mail/16.0.1.10/tests/test_mail_migration.py b/openupgrade_scripts/scripts/mail/16.0.1.10/tests/test_mail_migration.py new file mode 100644 index 000000000000..a7c09a0b53d1 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/16.0.1.10/tests/test_mail_migration.py @@ -0,0 +1,23 @@ +from datetime import datetime + +from odoo.tests import TransactionCase + + +class TestMailMigration(TransactionCase): + def test_mail_scheduled_date(self): + """Make sure that the scheduled date was preserved as changing + the field type from char to datetime. + """ + mail_with_date = self.env["mail.mail"].search( + [("body_html", "=", "TEST date")], limit=1 + ) + self.assertEqual(len(mail_with_date), 1) + self.assertEqual( + mail_with_date.scheduled_date, + datetime(2023, 4, 12, 10, 5, 1), + ) + mail_without_date = self.env["mail.mail"].search( + [("body_html", "=", "TEST empty date")], limit=1 + ) + self.assertEqual(len(mail_without_date), 1) + self.assertFalse(mail_without_date.scheduled_date) diff --git a/openupgrade_scripts/scripts/mail/16.0.1.10/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/mail/16.0.1.10/upgrade_analysis_work.txt new file mode 100644 index 000000000000..646855d69732 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/16.0.1.10/upgrade_analysis_work.txt @@ -0,0 +1,223 @@ +---Models in module 'mail'--- +obsolete model mail.channel.partner +obsolete model mail.resend.cancel [transient] +model fetchmail.server (moved from fetchmail) +new model mail.channel.member +new model mail.gateway.allowed +new model mail.link.preview +new model mail.message.schedule +new model mail.template.reset [transient] +new model template.reset.mixin [abstract] +---Fields in module 'mail'--- +mail / fetchmail.server / __last_update (datetime) : previously in module fetchmail +mail / fetchmail.server / _order : previously in module fetchmail +mail / fetchmail.server / active (boolean) : previously in module fetchmail +mail / fetchmail.server / attach (boolean) : previously in module fetchmail +mail / fetchmail.server / configuration (text) : previously in module fetchmail +mail / fetchmail.server / date (datetime) : previously in module fetchmail +mail / fetchmail.server / display_name (char) : previously in module fetchmail +mail / fetchmail.server / is_ssl (boolean) : previously in module fetchmail +mail / fetchmail.server / message_ids (one2many) : previously in module fetchmail +mail / fetchmail.server / name (char) : previously in module fetchmail +mail / fetchmail.server / object_id (many2one) : previously in module fetchmail +mail / fetchmail.server / original (boolean) : previously in module fetchmail +mail / fetchmail.server / password (char) : previously in module fetchmail +mail / fetchmail.server / port (integer) : previously in module fetchmail +mail / fetchmail.server / priority (integer) : previously in module fetchmail +mail / fetchmail.server / script (char) : previously in module fetchmail +mail / fetchmail.server / server (char) : previously in module fetchmail +mail / fetchmail.server / server_type (selection) : previously in module fetchmail +mail / fetchmail.server / state (selection) : previously in module fetchmail +mail / fetchmail.server / user (char) : previously in module fetchmail +# NOTHING TO DO: modules merged in apriori.py + +mail / ir.actions.server / mail_post_autofollow (boolean): NEW hasdefault: compute +mail / ir.actions.server / mail_post_method (selection) : NEW selection_keys: ['comment', 'email', 'note'], hasdefault: compute +# NOTHING TO DO: New fields +mail / ir.actions.server / state (False) : selection_keys is now '['code', 'followers', 'mail_post', 'multi', 'next_activity', 'object_create', 'object_write']' ('['code', 'email', 'followers', 'multi', 'next_activity', 'object_create', 'object_write']') +# DONE (pre-migration): selection_key 'email' has been renamed 'mail_post' + +mail / ir.mail_server / mail_template_ids (one2many) : NEW relation: mail.template +# NOTHING TO DO: new field + +mail / mail.channel / _inherits : DEL _inherits: {'mail.alias': 'alias_id'} +mail / mail.channel / alias_id (many2one) : DEL relation: mail.alias, required +# NOTHING TO DO: removed mail.alias.mixin from channel. See commit https://github.com/odoo/odoo/commit/ac00d19c8db572932a3863ab21a9a1f432dd93b5 +mail / mail.channel / channel_last_seen_partner_ids (one2many): DEL relation: mail.channel.partner +mail / mail.channel / channel_member_ids (one2many) : NEW relation: mail.channel.member +# DONE (pre-migration): field was renamed when calling rename_models +mail / mail.channel / channel_type (selection) : now required +# DONE (pre-migration): set default value where no value was set +mail / mail.channel / public (selection) : DEL required, selection_keys: ['groups', 'private', 'public'] +# DONE (post-migration): load new data for mail.mail_channel_rule ir.rule in which this field was involved + +mail / mail.channel.member / channel_id (many2one) : NEW relation: mail.channel, required +mail / mail.channel.member / custom_channel_name (char) : NEW +mail / mail.channel.member / fetched_message_id (many2one) : NEW relation: mail.message +mail / mail.channel.member / fold_state (selection) : NEW selection_keys: ['closed', 'folded', 'open'], hasdefault: default +mail / mail.channel.member / guest_id (many2one) : NEW relation: mail.guest +mail / mail.channel.member / is_minimized (boolean) : NEW +mail / mail.channel.member / is_pinned (boolean) : NEW hasdefault: default +mail / mail.channel.member / last_interest_dt (datetime) : NEW hasdefault: default +mail / mail.channel.member / last_seen_dt (datetime) : NEW +mail / mail.channel.member / partner_id (many2one) : NEW relation: res.partner +mail / mail.channel.member / rtc_inviting_session_id (many2one): NEW relation: mail.channel.rtc.session +mail / mail.channel.member / rtc_session_ids (one2many) : NEW relation: mail.channel.rtc.session +mail / mail.channel.member / seen_message_id (many2one) : NEW relation: mail.message +mail / mail.channel.partner / channel_id (many2one) : DEL relation: mail.channel, required +mail / mail.channel.partner / custom_channel_name (char) : DEL +mail / mail.channel.partner / fetched_message_id (many2one) : DEL relation: mail.message +mail / mail.channel.partner / fold_state (selection) : DEL selection_keys: ['closed', 'folded', 'open'] +mail / mail.channel.partner / guest_id (many2one) : DEL relation: mail.guest +mail / mail.channel.partner / is_minimized (boolean) : DEL +mail / mail.channel.partner / is_pinned (boolean) : DEL +mail / mail.channel.partner / last_interest_dt (datetime) : DEL +mail / mail.channel.partner / partner_id (many2one) : DEL relation: res.partner +mail / mail.channel.partner / rtc_inviting_session_id (many2one): DEL relation: mail.channel.rtc.session +mail / mail.channel.partner / rtc_session_ids (one2many) : DEL relation: mail.channel.rtc.session +mail / mail.channel.partner / seen_message_id (many2one) : DEL relation: mail.message +# DONE (pre-migration): mail.channel.partner renamed to mail.channel.member. +# New datetime field last_seen_dt: NOTHING TO DO + +mail / mail.channel.rtc.session / channel_member_id (many2one) : NEW relation: mail.channel.member, required +mail / mail.channel.rtc.session / channel_partner_id (many2one) : DEL relation: mail.channel.partner, required +# DONE (pre-migration): copy column channel_partner_id into channel_member_id + +mail / mail.gateway.allowed / email (char) : NEW +mail / mail.gateway.allowed / email_normalized (char) : NEW isfunction: function, stored +# NOTHING TO DO: new model + +mail / mail.guest / channel_ids (many2many) : table is now 'mail_channel_member' ('mail_channel_partner') +# DONE in pre-migrate script when renaming the model + +mail / mail.link.preview / image_mimetype (char) : NEW +mail / mail.link.preview / message_id (many2one) : NEW relation: mail.message, required +mail / mail.link.preview / og_description (text) : NEW +mail / mail.link.preview / og_image (char) : NEW +mail / mail.link.preview / og_mimetype (char) : NEW +mail / mail.link.preview / og_title (char) : NEW +mail / mail.link.preview / og_type (char) : NEW +mail / mail.link.preview / source_url (char) : NEW required +# NOTHING TO DO: new model + +mail / mail.mail / fetchmail_server_id (many2one): previously in module fetchmail +# NOTHING TO DO +mail / mail.mail / scheduled_date (char) : type is now 'datetime' ('char') +# NOTHING TO DO: values were already encoded in standard datetime format in psql +mail / mail.mail / to_delete (boolean) : NEW +# NOTHING TO DO: new field + +mail / mail.message / add_sign (boolean) : DEL +mail / mail.message / email_add_signature (boolean) : NEW hasdefault: default +# DONE in pre-migration: Rename 'add_sign' into 'email_add_signature' +mail / mail.message / link_preview_ids (one2many) : NEW relation: mail.link.preview +# NOTHING TO DO: new relation to new model + +mail / mail.message.schedule / mail_message_id (many2one) : NEW relation: mail.message, required +mail / mail.message.schedule / notification_parameters (text): NEW +mail / mail.message.schedule / scheduled_datetime (datetime) : NEW required +# NOTHING TO DO: new model + +mail / mail.message.subtype / track_recipients (boolean) : NEW +# NOTHING TO DO + +mail / mail.notification / author_id (many2one) : NEW relation: res.partner +# NOTHING TO DO + +mail / mail.template / active (boolean) : NEW hasdefault: default +mail / mail.template / copyvalue (char) : DEL +mail / mail.template / description (text) : NEW +mail / mail.template / model_object_field (many2one) : DEL relation: ir.model.fields +mail / mail.template / null_value (char) : DEL +mail / mail.template / sub_model_object_field (many2one): DEL relation: ir.model.fields +mail / mail.template / sub_object (many2one) : DEL relation: ir.model +mail / mail.template / template_fs (char) : NEW +# NOTHING TO DO + + +mail / res.partner / channel_ids (many2many) : table is now 'mail_channel_member' ('mail_channel_partner') +# DONE in pre-migration script when renaming the model + +---XML records in module 'mail'--- +NEW ir.actions.act_window: mail.act_server_history [renamed from fetchmail module] +NEW ir.actions.act_window: mail.action_email_server_tree [renamed from fetchmail module] +NEW ir.actions.act_window: mail.mail_channel_member_action +NEW ir.actions.act_window: mail.mail_gateway_allowed_action +NEW ir.actions.act_window: mail.mail_link_preview_action +NEW ir.actions.act_window: mail.mail_message_schedule_action +NEW ir.actions.act_window: mail.mail_template_reset_action +DEL ir.actions.act_window: mail.mail_channel_partner_action +DEL ir.actions.act_window: mail.mail_resend_cancel_action +# NOTHING TO DO: noupdate="0" records + +NEW ir.cron: mail.ir_cron_mail_gateway_action [renamed from fetchmail module] (noupdate) +# NOTHING TO DO: modules merged in apriori.py + +NEW ir.cron: mail.ir_cron_send_scheduled_message (noupdate) +# NOTHING TO DO: New noupdate="1" records + +NEW ir.model.access: mail.access_fetchmail_server [renamed from fetchmail module] +NEW ir.model.access: mail.access_mail_channel_member_portal +NEW ir.model.access: mail.access_mail_channel_member_public +NEW ir.model.access: mail.access_mail_channel_member_user +NEW ir.model.access: mail.access_mail_gateway_allowed_system +NEW ir.model.access: mail.access_mail_link_preview_admin +NEW ir.model.access: mail.access_mail_message_scheduled_all +NEW ir.model.access: mail.access_mail_message_scheduled_system +NEW ir.model.access: mail.access_mail_template_reset +DEL ir.model.access: mail.access_mail_channel_partner_portal +DEL ir.model.access: mail.access_mail_channel_partner_public +DEL ir.model.access: mail.access_mail_channel_partner_user +DEL ir.model.access: mail.access_mail_resend_cancel +NEW ir.model.constraint: mail.constraint_mail_activity_check_res_id_is_set +NEW ir.model.constraint: mail.constraint_mail_channel_channel_type_not_null +NEW ir.model.constraint: mail.constraint_mail_channel_group_public_id_check +NEW ir.model.constraint: mail.constraint_mail_channel_member_partner_or_guest_exists +NEW ir.model.constraint: mail.constraint_mail_channel_rtc_session_channel_member_unique +NEW ir.model.constraint: mail.constraint_res_users_notification_type + +DEL ir.model.constraint: mail.constraint_mail_channel_partner_partner_or_guest_exists +DEL ir.model.constraint: mail.constraint_mail_channel_rtc_session_channel_partner_unique +# DONE (pre-migration): safely deleting the constraints + +NEW ir.rule: mail.ir_rule_mail_channel_member_group_system (noupdate) +NEW ir.rule: mail.ir_rule_mail_channel_member_group_user (noupdate) +# NOTHING TO DO: New noupdate="1" records + +DEL ir.rule: mail.ir_rule_mail_channel_partner_group_system (noupdate) +DEL ir.rule: mail.ir_rule_mail_channel_partner_group_user (noupdate) +# DONE (post-migration): try to delete + +NEW ir.ui.menu: mail.mail_channel_member_menu +NEW ir.ui.menu: mail.mail_gateway_allowed_menu +NEW ir.ui.menu: mail.mail_link_preview_menu +NEW ir.ui.menu: mail.mail_message_schedule_menu +NEW ir.ui.menu: mail.menu_action_fetchmail_server_tree [renamed from fetchmail module] +DEL ir.ui.menu: mail.mail_channel_partner_menu +NEW ir.ui.view: mail.mail_channel_member_view_form +NEW ir.ui.view: mail.mail_channel_member_view_tree +NEW ir.ui.view: mail.mail_gateway_allowed_view_search +NEW ir.ui.view: mail.mail_gateway_allowed_view_tree +NEW ir.ui.view: mail.mail_link_preview_view_tree +NEW ir.ui.view: mail.mail_message_schedule_view_form +NEW ir.ui.view: mail.mail_message_schedule_view_search +NEW ir.ui.view: mail.mail_message_schedule_view_tree +NEW ir.ui.view: mail.mail_notification_layout +NEW ir.ui.view: mail.mail_notification_layout_with_responsible_signature +NEW ir.ui.view: mail.mail_template_reset_view_form +NEW ir.ui.view: mail.message_notification_limit_email +NEW ir.ui.view: mail.notification_preview +NEW ir.ui.view: mail.view_email_server_form +NEW ir.ui.view: mail.view_email_server_search +NEW ir.ui.view: mail.view_email_server_tree +DEL ir.ui.view: mail.mail_channel_partner_view_form +DEL ir.ui.view: mail.mail_channel_partner_view_tree +DEL ir.ui.view: mail.mail_notification_borders +DEL ir.ui.view: mail.mail_notification_paynow +DEL ir.ui.view: mail.mail_resend_cancel_view_form +DEL ir.ui.view: mail.message_notification_email +# NOTHING TO DO: noupdate="0" records + +NEW mail.channel.member: mail.channel_member_general_channel_for_admin (noupdate) +DEL mail.channel.partner: mail.channel_partner_general_channel_for_admin (noupdate) +# DONE (pre-migration): rename xmlid \ No newline at end of file