diff --git a/docsource/modules170-180.rst b/docsource/modules170-180.rst index d2f0c3e84d77..dd57b5f76e28 100644 --- a/docsource/modules170-180.rst +++ b/docsource/modules170-180.rst @@ -642,7 +642,7 @@ Module coverage 17.0 -> 18.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | lunch | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| mail | | | +| mail | |Done | +---------------------------------------------------+----------------------+-------------------------------------------------+ | mail_bot | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/apriori.py b/openupgrade_scripts/apriori.py index 6217efc095c0..f0684f602e75 100644 --- a/openupgrade_scripts/apriori.py +++ b/openupgrade_scripts/apriori.py @@ -23,6 +23,10 @@ # only used here for upgrade_analysis renamed_models = { # odoo + # mail + "mail.notification.web.push": "web.push", + "mail.partner.device": "mail.push.device", + "mail.shortcode": "mail.canned.response", # OCA/... } diff --git a/openupgrade_scripts/scripts/mail/18.0.1.18/post-migration.py b/openupgrade_scripts/scripts/mail/18.0.1.18/post-migration.py new file mode 100644 index 000000000000..a765414df50a --- /dev/null +++ b/openupgrade_scripts/scripts/mail/18.0.1.18/post-migration.py @@ -0,0 +1,75 @@ +# Copyright 2025 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +def discuss_channel_last_interest(env): + """ + Set last interest date of channel from newest message posted + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE discuss_channel + SET last_interest_dt=mail_message.create_date + FROM + ( + SELECT res_id, max(create_date) create_date + FROM mail_message + WHERE model='discuss.channel' + GROUP BY res_id + ) mail_message + WHERE mail_message.res_id=discuss_channel.id + """, + ) + + +def discuss_channel_member_new_message_separator(env): + """ + Set new_message_separator to the id of the first message after last_interest_id + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE discuss_channel_member + SET new_message_separator=COALESCE(mail_message.id, 0) + FROM + ( + SELECT res_id, min(mail_message.id) id + FROM mail_message + JOIN discuss_channel + ON discuss_channel.id=mail_message.res_id + AND mail_message.model='discuss.channel' + JOIN discuss_channel_member + ON discuss_channel_member.channel_id=discuss_channel.id + WHERE + mail_message.create_date > discuss_channel_member.last_interest_dt + GROUP BY mail_message.res_id + ) mail_message + WHERE + discuss_channel_member.channel_id=mail_message.res_id + """, + ) + + +def discuss_channel_member_unpin_dt(env): + """ + Set to now if v17 is_pinned has been unset + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE discuss_channel_member + SET unpin_dt=CURRENT_TIMESTAMP + WHERE not is_pinned + """, + ) + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.load_data(env, "mail", "18.0.1.18/noupdate_changes.xml") + discuss_channel_last_interest(env) + discuss_channel_member_new_message_separator(env) + discuss_channel_member_unpin_dt(env) diff --git a/openupgrade_scripts/scripts/mail/18.0.1.18/pre-migration.py b/openupgrade_scripts/scripts/mail/18.0.1.18/pre-migration.py new file mode 100644 index 000000000000..ba4be566d30f --- /dev/null +++ b/openupgrade_scripts/scripts/mail/18.0.1.18/pre-migration.py @@ -0,0 +1,27 @@ +# Copyright 2025 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +model_renames = [ + ("mail.notification.web.push", "web.push"), + ("mail.partner.device", "mail.push.device"), + ("mail.shortcode", "mail.canned.response"), +] + +table_renames = [ + ("mail_notification_web_push", "web_push"), + ("mail_partner_device", "mail_push_device"), + ("mail_shortcode", "mail_canned_response"), +] + +field_renames = [ + ("web.push", "web_push", "user_device", "mail_push_device_id"), +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_models(env.cr, model_renames) + openupgrade.rename_tables(env.cr, table_renames) + openupgrade.rename_fields(env, field_renames) diff --git a/openupgrade_scripts/scripts/mail/18.0.1.18/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/mail/18.0.1.18/upgrade_analysis_work.txt new file mode 100644 index 000000000000..29bac423e1ee --- /dev/null +++ b/openupgrade_scripts/scripts/mail/18.0.1.18/upgrade_analysis_work.txt @@ -0,0 +1,196 @@ +---Models in module 'mail'--- +obsolete model mail.notification.web.push + +DONE: renamed to web.push + +obsolete model mail.partner.device + +DONE: renamed to mail.push.device + +obsolete model mail.shortcode + +DONE: renamed to mail.canned.response + +new model mail.canned.response + +DONE: renamed from mail.shortcode + +new model mail.push + +DONE: renamed from mail.notification.web.push + +new model mail.push.device + +DONE: renamed from mail.push.device + +new model mail.scheduled.message + +NOTHING TO DO + +---Fields in module 'mail'--- +mail / discuss.channel / from_message_id (many2one) : NEW relation: mail.message + +# NOTHING TO DO: start message for subchannel, new functionality + +mail / discuss.channel / last_interest_dt (datetime) : NEW + +# DONE: filled from date of last message + +mail / discuss.channel / parent_channel_id (many2one) : NEW relation: discuss.channel +mail / discuss.channel / sub_channel_ids (one2many) : NEW relation: discuss.channel + +# NOTHING TO DO: new functionality + +mail / discuss.channel.member / custom_notifications (selection): selection_keys is now '['all', 'mentions', 'no_notif']' ('['mentions', 'no_notif']') + +# NOTHING TO DO: added value + +mail / discuss.channel.member / is_minimized (boolean) : DEL + +# NOTHING TO DO + +mail / discuss.channel.member / is_pinned (boolean) : not stored anymore +mail / discuss.channel.member / is_pinned (boolean) : now a function + +# DONE: see unpin_dt below + +mail / discuss.channel.member / new_message_separator (integer): NEW required, hasdefault: default + +# DONE: set to the id of the first message older than last_interest_dt + +mail / discuss.channel.member / unpin_dt (datetime) : NEW + +# DONE: set to now if v17 is_pinned has been unset + +mail / ir.actions.act_window.view / view_mode (False) : selection_keys is now '['activity', 'calendar', 'form', 'graph', 'hierarchy', 'kanban', 'list', 'pivot']' ('['activity', 'calendar', 'form', 'gantt', 'graph', 'hierarchy', 'kanban', 'pivot', 'tree']') +mail / ir.ui.view / type (False) : selection_keys is now '['activity', 'calendar', 'form', 'graph', 'hierarchy', 'kanban', 'list', 'pivot', 'qweb', 'search']' ('['activity', 'calendar', 'form', 'gantt', 'graph', 'hierarchy', 'kanban', 'pivot', 'qweb', 'search', 'tree']') +mail / mail.activity / user_tz (selection) : NEW selection_keys: function, isrelated: related, stored + +# NOTHING TO DO: change comes from base + +mail / mail.activity.plan.template / delay_count (integer) : NEW hasdefault: default +mail / mail.activity.plan.template / delay_from (selection) : NEW required, selection_keys: ['after_plan_date', 'before_plan_date'], hasdefault: default +mail / mail.activity.plan.template / delay_unit (selection) : NEW required, selection_keys: ['days', 'months', 'weeks'], hasdefault: default + +# NOTHING TO DO: new functionality + +mail / mail.canned.response / description (char) : NEW +mail / mail.canned.response / group_ids (many2many) : NEW relation: res.groups +mail / mail.canned.response / is_shared (boolean) : NEW isfunction: function, stored +mail / mail.canned.response / last_used (datetime) : NEW +mail / mail.canned.response / source (char) : NEW required +mail / mail.canned.response / substitution (text) : NEW required + +# NOTHING TO DO: field from renamed mail.shortcode/new functionality + +mail / mail.link.preview / is_hidden (boolean) : NEW + +# NOTHING TO DO: new funcitonality + +mail / mail.notification.web.push / payload (text) : DEL +mail / mail.notification.web.push / user_device (many2one) : DEL relation: mail.partner.device, required + +# NOTHING TO DO: model was renamed to mail.push + +mail / mail.partner.device / endpoint (char) : DEL required +mail / mail.partner.device / expiration_time (datetime) : DEL +mail / mail.partner.device / keys (char) : DEL required +mail / mail.partner.device / partner_id (many2one) : DEL relation: res.partner, required + +# NOTHING TO DO: model was renamed to mail.push.device + +mail / mail.push / mail_push_device_id (many2one): NEW relation: mail.push.device, required + +# DONE: renamed from mail.notification.web.push#user_device + +mail / mail.push / payload (text) : NEW + +# NOTHING TO DO + +mail / mail.push.device / endpoint (char) : NEW required +mail / mail.push.device / expiration_time (datetime) : NEW +mail / mail.push.device / keys (char) : NEW required +mail / mail.push.device / partner_id (many2one) : NEW relation: res.partner, required, hasdefault: default + +# NOTHING TO DO: model was renamed from mail.partner.device + +mail / mail.scheduled.message / attachment_ids (many2many) : NEW relation: ir.attachment +mail / mail.scheduled.message / author_id (many2one) : NEW relation: res.partner, required +mail / mail.scheduled.message / body (html) : NEW +mail / mail.scheduled.message / is_note (boolean) : NEW hasdefault: default +mail / mail.scheduled.message / model (char) : NEW required +mail / mail.scheduled.message / notification_parameters (text): NEW +mail / mail.scheduled.message / partner_ids (many2many) : NEW relation: res.partner +mail / mail.scheduled.message / res_id (many2one_reference) : NEW relation: model, required +mail / mail.scheduled.message / scheduled_date (datetime) : NEW required +mail / mail.scheduled.message / subject (char) : NEW + +# NOTHING TO DO: new functionality + +mail / mail.shortcode / description (char) : DEL +mail / mail.shortcode / last_used (datetime) : DEL +mail / mail.shortcode / source (char) : DEL required +mail / mail.shortcode / substitution (text) : DEL required + +# NOTHING TO DO: model was renamed to mail.canned.response + +mail / res.users.settings / channel_notifications (selection): NEW selection_keys: ['all', 'no_notif'] +mail / res.users.settings / mute_until_dt (datetime) : NEW + +# NOTHING TO DO: new functionality + +---XML records in module 'mail'--- +NEW discuss.channel: mail.channel_admin (noupdate) +NEW ir.actions.act_window: mail.mail_activity_action_my +NEW ir.actions.act_window: mail.mail_canned_response_action +DEL ir.actions.act_window: mail.mail_shortcode_action +NEW ir.actions.act_window.view: mail.mail_activity_action_my_view_kanban +NEW ir.actions.act_window.view: mail.mail_activity_action_my_view_tree +NEW ir.actions.client: mail.discuss_call_settings_action +NEW ir.actions.client: mail.discuss_notification_settings_action +NEW ir.config_parameter: mail.restrict_template_rendering (noupdate) +NEW ir.cron: mail.ir_cron_discuss_users_settings_unmute (noupdate) +NEW ir.cron: mail.ir_cron_post_scheduled_message (noupdate) +NEW ir.model.access: mail.access_mail_canned_reponse +NEW ir.model.access: mail.access_mail_push_device_system +NEW ir.model.access: mail.access_mail_push_system +NEW ir.model.access: mail.access_mail_scheduled_message +DEL ir.model.access: mail.access_mail_compose_message_portal +DEL ir.model.access: mail.access_mail_notification_web_push +DEL ir.model.access: mail.access_mail_partner_device +DEL ir.model.access: mail.access_mail_shortcode +DEL ir.model.access: mail.access_mail_shortcode_portal +NEW ir.model.constraint: mail.constraint_discuss_channel_from_message_id_unique +NEW ir.model.constraint: mail.constraint_discuss_channel_sub_channel_no_group_public_id +NEW ir.model.constraint: mail.constraint_mail_push_device_endpoint_unique +DEL ir.model.constraint: mail.constraint_mail_partner_device_endpoint_unique +NEW ir.module.category: mail.module_category_canned_response (noupdate) +NEW ir.rule: mail.ir_rule_mail_canned_response_admin (noupdate) +NEW ir.rule: mail.ir_rule_mail_canned_response_user_read (noupdate) +NEW ir.rule: mail.ir_rule_mail_canned_response_user_update (noupdate) +NEW ir.rule: mail.ir_rule_mail_scheduled_message_user (noupdate) +NEW ir.ui.menu: mail.menu_call_settings +NEW ir.ui.menu: mail.menu_canned_responses +NEW ir.ui.menu: mail.menu_configuration +NEW ir.ui.menu: mail.menu_mail_activities_section +NEW ir.ui.menu: mail.menu_notification_settings +NEW ir.ui.view: mail.mail_activity_plan_view_kanban +NEW ir.ui.view: mail.mail_activity_plan_view_tree_detailed +NEW ir.ui.view: mail.mail_activity_type_view_kanban +NEW ir.ui.view: mail.mail_activity_view_kanban_open_target +NEW ir.ui.view: mail.mail_activity_view_tree_open_target +NEW ir.ui.view: mail.mail_attachment_links +NEW ir.ui.view: mail.mail_canned_response_view_form +NEW ir.ui.view: mail.mail_canned_response_view_search +NEW ir.ui.view: mail.mail_canned_response_view_tree +NEW ir.ui.view: mail.mail_message_subtype_view_search +NEW ir.ui.view: mail.mail_notification_invite +NEW ir.ui.view: mail.mail_scheduled_message_view_form +DEL ir.ui.view: mail.mail_shortcode_view_form +DEL ir.ui.view: mail.mail_shortcode_view_search +DEL ir.ui.view: mail.mail_shortcode_view_tree +NEW mail.canned.response: mail.mail_canned_response_data_hello (noupdate) +NEW res.groups: mail.group_mail_canned_response_admin (noupdate) +NEW web_tour.tour: mail.discuss_channel_tour + +# NOTHING TO DO diff --git a/openupgrade_scripts/scripts/mail/tests/data.py b/openupgrade_scripts/scripts/mail/tests/data.py new file mode 100644 index 000000000000..22425b40ac04 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/tests/data.py @@ -0,0 +1,7 @@ +env = locals().get("env") +# new message in employee channel +env.ref("mail.channel_all_employees").message_post( + body="test", + subject="This message should become demo's new_message_separator", +) +env.cr.commit() diff --git a/openupgrade_scripts/scripts/mail/tests/test_migration.py b/openupgrade_scripts/scripts/mail/tests/test_migration.py new file mode 100644 index 000000000000..52ff0af60ec7 --- /dev/null +++ b/openupgrade_scripts/scripts/mail/tests/test_migration.py @@ -0,0 +1,28 @@ +from odoo.tests import TransactionCase + +from odoo.addons.openupgrade_framework import openupgrade_test + + +@openupgrade_test +class TestBaseMigration(TransactionCase): + def test_new_message_separator(self): + """ + Test that discuss channel members get correct new_message_separator + """ + channel_member_demo = self.env["discuss.channel.member"].search( + [ + ("partner_id", "=", self.env.ref("base.user_demo").partner_id.id), + ("channel_id", "=", self.env.ref("mail.channel_all_employees").id), + ] + ) + message = self.env["mail.message"].search( + [ + ( + "subject", + "=", + "This message should become demo's new_message_separator", + ), + ] + ) + self.assertTrue(message) + self.assertEqual(channel_member_demo.new_message_separator, message.id)