From 4efd10ecdbf02c90d0ee590712ee9dd3481612a6 Mon Sep 17 00:00:00 2001 From: RaulOForgeFlow Date: Tue, 4 May 2021 13:32:37 +0200 Subject: [PATCH 1/3] [14.0][MIG] calendar --- .../calendar/14.0.1.0/post-migration.py | 31 ++++++ .../calendar/14.0.1.0/pre-migration.py | 39 +++++++ .../14.0.1.0/upgrade_analysis_work.txt | 105 ++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py create mode 100644 openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py create mode 100644 openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py new file mode 100644 index 000000000000..e456799280b3 --- /dev/null +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py @@ -0,0 +1,31 @@ +# Copyright 2021 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + + +def update_follow_recurrence_field(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE calendar_event ce + SET follow_recurrence = True + WHERE recurrency = True + """, + ) + + +def map_calendar_event_byday(env): + openupgrade.map_values( + env.cr, + openupgrade.get_legacy_name("byday"), + "byday", + [("5", "-1")], + table="calendar_event", + ) + + +@openupgrade.migrate() +def migrate(env, version): + update_follow_recurrence_field(env) + map_calendar_event_byday(env) + openupgrade.load_data(env.cr, "calendar", "14.0.1.0/noupdate_changes.xml") diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py b/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py new file mode 100644 index 000000000000..7f6264cda2c0 --- /dev/null +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py @@ -0,0 +1,39 @@ +# Copyright 2021 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + + +def delete_empty_event_id_pratner_id_records(env): + openupgrade.logged_query( + env.cr, + """ + DELETE FROM calendar_event + WHERE event_id is null OR partner_id is null + """, + ) + + +def fill_empty_privacy_and_show_as_fields(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE calendar_event + SET privacy = 'public' + WHERE privacy is null + """, + ) + openupgrade.logged_query( + env.cr, + """ + UPDATE calendar_event + SET show_as = 'busy' + WHERE show_as is null + """, + ) + + +@openupgrade.migrate() +def migrate(env, version): + delete_empty_event_id_pratner_id_records(env) + fill_empty_privacy_and_show_as_fields(env) + openupgrade.copy_columns(env.cr, {"calendar_event": [("byday", None, None)]}) diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt new file mode 100644 index 000000000000..566c3e7253f9 --- /dev/null +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt @@ -0,0 +1,105 @@ +---Models in module 'calendar'--- +new model calendar.recurrence +# NOTHING TO DO: new module to manage recurrent events + +---Fields in module 'calendar'--- +calendar / calendar.attendee / email (char) : not stored anymore +calendar / calendar.attendee / email (char) : now related +# NOTHING TO DO: Same functionality, now avoiding use of api.on_change() + +calendar / calendar.attendee / event_id (many2one) : now required +calendar / calendar.attendee / partner_id (many2one) : now required +# DONE: pre-migration: check for empty fields and deleted them as an event without these fields doesn't make sense. + +calendar / calendar.event / _order : _order is now 'start desc' ('id desc') +# NOTHING TO DO: ordered by starting date + +calendar / calendar.event / byday (selection) : selection_keys is now '['-1', '1', '2', '3', '4']' ('['-1', '1', '2', '3', '4', '5']') +# DONE: pre-migration: copied column byday to prevent data loss +# post-migration: replaced the 5th day option ("5") with last day option ("-1") + +calendar / calendar.event / byday (selection) : not stored anymore +calendar / calendar.event / byday (selection) : now a function +calendar / calendar.event / count (integer) : not stored anymore +calendar / calendar.event / count (integer) : now a function +calendar / calendar.event / day (integer) : not stored anymore +calendar / calendar.event / day (integer) : now a function +calendar / calendar.event / duration (float) : now a function +calendar / calendar.event / end_type (selection) : not stored anymore +calendar / calendar.event / end_type (selection) : now a function +calendar / calendar.event / event_tz (selection) : not stored anymore +calendar / calendar.event / event_tz (selection) : now a function +calendar / calendar.event / mo (boolean) : not stored anymore +calendar / calendar.event / mo (boolean) : now a function +calendar / calendar.event / tu (boolean) : not stored anymore +calendar / calendar.event / tu (boolean) : now a function +calendar / calendar.event / we (boolean) : not stored anymore +calendar / calendar.event / we (boolean) : now a function +calendar / calendar.event / th (boolean) : not stored anymore +calendar / calendar.event / th (boolean) : now a function +calendar / calendar.event / fr (boolean) : not stored anymore +calendar / calendar.event / fr (boolean) : now a function +calendar / calendar.event / sa (boolean) : not stored anymore +calendar / calendar.event / sa (boolean) : now a function +calendar / calendar.event / su (boolean) : not stored anymore +calendar / calendar.event / su (boolean) : now a function +calendar / calendar.event / rrule_type (selection) : not stored anymore +calendar / calendar.event / rrule_type (selection) : now a function +calendar / calendar.event / interval (integer) : not stored anymore +calendar / calendar.event / interval (integer) : now a function +calendar / calendar.event / month_by (selection) : not stored anymore +calendar / calendar.event / month_by (selection) : now a function +calendar / calendar.event / rrule (char) : not stored anymore +calendar / calendar.recurrence / byday (selection) : NEW selection_keys: ['-1', '1', '2', '3', '4'] +calendar / calendar.recurrence / calendar_event_ids (one2many) : NEW relation: calendar.event +calendar / calendar.recurrence / count (integer) : NEW hasdefault +calendar / calendar.recurrence / day (integer) : NEW hasdefault +calendar / calendar.recurrence / end_type (selection) : NEW selection_keys: ['count', 'end_date', 'forever'], hasdefault +calendar / calendar.recurrence / event_tz (selection) : NEW selection_keys: function, hasdefault +calendar / calendar.recurrence / fr (boolean) : NEW +calendar / calendar.recurrence / interval (integer) : NEW hasdefault +calendar / calendar.recurrence / mo (boolean) : NEW +calendar / calendar.recurrence / month_by (selection) : NEW selection_keys: ['date', 'day'], hasdefault +calendar / calendar.recurrence / name (char) : NEW isfunction: function, stored +calendar / calendar.recurrence / rrule (char) : NEW isfunction: function, stored +calendar / calendar.recurrence / rrule_type (selection) : NEW selection_keys: ['daily', 'monthly', 'weekly', 'yearly'], hasdefault +calendar / calendar.recurrence / sa (boolean) : NEW +calendar / calendar.recurrence / su (boolean) : NEW +calendar / calendar.recurrence / th (boolean) : NEW +calendar / calendar.recurrence / tu (boolean) : NEW +calendar / calendar.recurrence / until (date) : NEW +calendar / calendar.recurrence / we (boolean) : NEW +calendar / calendar.recurrence / weekday (selection) : NEW selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE'] +calendar / calendar.event / recurrence_id (many2one) : NEW relation: calendar.recurrence +calendar / calendar.recurrence / base_event_id (many2one) : NEW relation: calendar.event +# TO DO: Move this fields from event to recurrence and set relation from event to recurrence (recurrence_id) + +calendar / calendar.event / follow_recurrence (boolean) : NEW hasdefault +# DONE: post-migration: Set true all recurrent events (default=False) + +calendar / calendar.event / privacy (selection) : now required, req_default: function +calendar / calendar.event / show_as (selection) : now required, req_default: function +# DONE: pre-migration: Checking fields not empty and filling them with default ('public' and 'busy') if they are, in fact, empty + +calendar / calendar.event / display_start (char) : DEL +calendar / calendar.event / final_date (date) : DEL +calendar / calendar.event / recurrent_id (integer) : DEL +calendar / calendar.event / recurrent_id_date (datetime) : DEL +calendar / calendar.event / start_datetime (datetime) : DEL +calendar / calendar.event / state (selection) : DEL selection_keys: ['draft', 'open'] +calendar / calendar.event / stop_datetime (datetime) : DEL +calendar / calendar.event / week_list (selection) : DEL selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE'] +# NOTHING TO DO + +calendar / calendar.event / end_type (selection) : selection_keys is now '['count', 'end_date', 'forever']' ('['count', 'end_date']') +# NOTHING TO DO: new option when creating recurrent event + +calendar / calendar.event / stop (datetime) : now a function +# NOTHING TO DO: Computes when the event ends based on start and duration + +calendar / calendar.event / recurrence_update (selection) : NEW selection_keys: ['all_events', 'future_events', 'self_only'], hasdefault +# NOTHING TO DO: set of options to use when updating recurrent event + +---XML records in module 'calendar'--- +NEW ir.model.access: calendar.access_calendar_recurrence +# NOTHING TO DO: Add access to new model (noupdate="0") From 1bedaa201d016c37571e97e112130d0f29223421 Mon Sep 17 00:00:00 2001 From: mreficent Date: Tue, 4 May 2021 18:32:19 +0200 Subject: [PATCH 2/3] [OU-IMP] calendar: fill calendar_recurrence table --- .../calendar/14.0.1.0/post-migration.py | 36 +++++++++++++++++++ .../14.0.1.0/upgrade_analysis_work.txt | 10 +++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py index e456799280b3..0b95e3c14e08 100644 --- a/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py @@ -24,8 +24,44 @@ def map_calendar_event_byday(env): ) +def fill_calendar_recurrence_table(env): + openupgrade.logged_query( + env.cr, + """ + WITH recur AS ( + INSERT INTO calendar_recurrence (base_event_id, + event_tz,rrule,rrule_type,end_type,interval,count, + mo,tu,we,th,fr,sa,su,month_by,day,weekday,byday,until, + create_uid,create_date,write_uid,write_date) + SELECT id,event_tz,rrule,rrule_type,end_type,interval,count, + mo,tu,we,th,fr,sa,su,month_by,day,week_list,byday,final_date, + create_uid,create_date,write_uid,write_date) + FROM calendar_event + WHERE recurrency AND recurrence_id IS NULL + AND (recurrent_id IS NULL OR recurrent_id = '') + RETURNING id,base_event_id + ) + UPDATE calendar_event ce + SET recurrence_id = recur.id + FROM recur + WHERE recur.base_event_id = ce.id + """, + ) + openupgrade.logged_query( + env.cr, + """ + UPDATE calendar_event ce + SET recurrence_id = ce2.recurrence_id + FROM calendar_event ce2 + WHERE ce.recurrency AND ce.recurrence_id IS NULL + AND ce.recurrent_id = ce2.id || '' + """, + ) + + @openupgrade.migrate() def migrate(env, version): update_follow_recurrence_field(env) map_calendar_event_byday(env) + fill_calendar_recurrence_table(env) openupgrade.load_data(env.cr, "calendar", "14.0.1.0/noupdate_changes.xml") diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt index 566c3e7253f9..13a1aa308877 100644 --- a/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/upgrade_analysis_work.txt @@ -68,11 +68,16 @@ calendar / calendar.recurrence / su (boolean) : NEW calendar / calendar.recurrence / th (boolean) : NEW calendar / calendar.recurrence / tu (boolean) : NEW calendar / calendar.recurrence / until (date) : NEW +calendar / calendar.event / final_date (date) : DEL calendar / calendar.recurrence / we (boolean) : NEW calendar / calendar.recurrence / weekday (selection) : NEW selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE'] +calendar / calendar.event / week_list (selection) : DEL selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE'] calendar / calendar.event / recurrence_id (many2one) : NEW relation: calendar.recurrence calendar / calendar.recurrence / base_event_id (many2one) : NEW relation: calendar.event -# TO DO: Move this fields from event to recurrence and set relation from event to recurrence (recurrence_id) +# DONE: Moved these fields from event to recurrence and set relation from event to recurrence (recurrence_id) + +calendar / calendar.event / recurrent_id (integer) : DEL +# DONE: post-migration: used recurrent_id to map to others recurrences calendar / calendar.event / follow_recurrence (boolean) : NEW hasdefault # DONE: post-migration: Set true all recurrent events (default=False) @@ -82,13 +87,10 @@ calendar / calendar.event / show_as (selection) : now re # DONE: pre-migration: Checking fields not empty and filling them with default ('public' and 'busy') if they are, in fact, empty calendar / calendar.event / display_start (char) : DEL -calendar / calendar.event / final_date (date) : DEL -calendar / calendar.event / recurrent_id (integer) : DEL calendar / calendar.event / recurrent_id_date (datetime) : DEL calendar / calendar.event / start_datetime (datetime) : DEL calendar / calendar.event / state (selection) : DEL selection_keys: ['draft', 'open'] calendar / calendar.event / stop_datetime (datetime) : DEL -calendar / calendar.event / week_list (selection) : DEL selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE'] # NOTHING TO DO calendar / calendar.event / end_type (selection) : selection_keys is now '['count', 'end_date', 'forever']' ('['count', 'end_date']') From 05fbc7a0d7918d73b17c0f0f8f811dd64e9d02ce Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Mon, 7 Jun 2021 09:14:02 +0200 Subject: [PATCH 3/3] [FIX] calendar: Fix recurrence population + others - recurrent_id is an integer. - Missing recurrency = True for following recurrent events. - Populate missing recurrent occurrences. - Fix incorrect method name. - Remove translations for the mail templates. --- .../calendar/14.0.1.0/post-migration.py | 26 ++++++++++++++++--- .../calendar/14.0.1.0/pre-migration.py | 4 +-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py index 0b95e3c14e08..d43a35f1f0a5 100644 --- a/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/post-migration.py @@ -1,4 +1,5 @@ # Copyright 2021 ForgeFlow S.L. +# Copyright 2021 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openupgradelib import openupgrade @@ -38,7 +39,7 @@ def fill_calendar_recurrence_table(env): create_uid,create_date,write_uid,write_date) FROM calendar_event WHERE recurrency AND recurrence_id IS NULL - AND (recurrent_id IS NULL OR recurrent_id = '') + AND (recurrent_id IS NULL OR recurrent_id = 0) RETURNING id,base_event_id ) UPDATE calendar_event ce @@ -51,17 +52,34 @@ def fill_calendar_recurrence_table(env): env.cr, """ UPDATE calendar_event ce - SET recurrence_id = ce2.recurrence_id + SET recurrence_id = ce2.recurrence_id, recurrency = True FROM calendar_event ce2 - WHERE ce.recurrency AND ce.recurrence_id IS NULL - AND ce.recurrent_id = ce2.id || '' + WHERE ce.recurrence_id IS NULL AND ce.recurrent_id = ce2.id """, ) +@openupgrade.logging() +def create_recurrent_events(env): + """In v14, now all occurrences of recurrent events are created as real records, not + virtual ones, so we need to regenerate them for all the existing ones. + """ + env["calendar.event"].search([("base_event_id", "!=", False)])._apply_recurrence() + + @openupgrade.migrate() def migrate(env, version): update_follow_recurrence_field(env) map_calendar_event_byday(env) fill_calendar_recurrence_table(env) + create_recurrent_events(env) openupgrade.load_data(env.cr, "calendar", "14.0.1.0/noupdate_changes.xml") + openupgrade.delete_record_translations( + env.cr, + "calendar", + [ + "calendar_template_meeting_changedate", + "calendar_template_meeting_invitation", + "calendar_template_meeting_reminder", + ], + ) diff --git a/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py b/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py index 7f6264cda2c0..37b9a6dff3ed 100644 --- a/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py +++ b/openupgrade_scripts/scripts/calendar/14.0.1.0/pre-migration.py @@ -3,7 +3,7 @@ from openupgradelib import openupgrade -def delete_empty_event_id_pratner_id_records(env): +def delete_empty_event_id_partner_id_records(env): openupgrade.logged_query( env.cr, """ @@ -34,6 +34,6 @@ def fill_empty_privacy_and_show_as_fields(env): @openupgrade.migrate() def migrate(env, version): - delete_empty_event_id_pratner_id_records(env) + delete_empty_event_id_partner_id_records(env) fill_empty_privacy_and_show_as_fields(env) openupgrade.copy_columns(env.cr, {"calendar_event": [("byday", None, None)]})