From 9fbed74b8a7d4d79fca37472e7802679730ec9f1 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Thu, 28 May 2026 17:35:58 -0400 Subject: [PATCH 1/4] =?UTF-8?q?[OU-ADD]=20event:=20question=20m2o=E2=86=92?= =?UTF-8?q?m2m=20+=20slots=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - event.question.event_id/event_type_id (m2o) → event_ids/event_type_ids (m2m): post-migration m2o_to_x2m populates the new join tables. - pre-migration deletes the obsolete noupdate event_stage_cancelled stage. - noupdate_changes_work.xml reloads only the event_mail_scheduler cron; the three mail.template body_html drifts are omitted to preserve operator edits. --- docsource/modules180-190.rst | 2 +- .../event/19.0.1.9/noupdate_changes_work.xml | 6 + .../scripts/event/19.0.1.9/post-migration.py | 20 +++ .../scripts/event/19.0.1.9/pre-migration.py | 16 +++ .../event/19.0.1.9/upgrade_analysis_work.txt | 117 ++++++++++++++++++ 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml create mode 100644 openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py create mode 100644 openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py create mode 100644 openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt diff --git a/docsource/modules180-190.rst b/docsource/modules180-190.rst index fd4b86e2175e..b7deec1966ad 100644 --- a/docsource/modules180-190.rst +++ b/docsource/modules180-190.rst @@ -134,7 +134,7 @@ Module coverage 18.0 -> 19.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | digest |Done |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| event | | | +| event |Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | event_booth | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml b/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml new file mode 100644 index 000000000000..87a4e7f0d611 --- /dev/null +++ b/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml @@ -0,0 +1,6 @@ + + + + 24 + + diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py b/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py new file mode 100644 index 000000000000..47766af35590 --- /dev/null +++ b/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py @@ -0,0 +1,20 @@ +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.m2o_to_x2m( + env.cr, + env["event.question"], + "event_question", + "event_ids", + "event_id", + ) + openupgrade.m2o_to_x2m( + env.cr, + env["event.question"], + "event_question", + "event_type_ids", + "event_type_id", + ) + openupgrade.load_data(env, "event", "19.0.1.9/noupdate_changes_work.xml") diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py new file mode 100644 index 000000000000..1f85a7d97e37 --- /dev/null +++ b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py @@ -0,0 +1,16 @@ +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.logged_query( + env.cr, + """ + DELETE FROM event_stage WHERE id IN ( + SELECT imd.res_id FROM ir_model_data imd + WHERE imd.model = 'event.stage' + AND imd.module = 'event' + AND imd.name = 'event_stage_cancelled' + ) + """, + ) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt new file mode 100644 index 000000000000..6479942e7769 --- /dev/null +++ b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt @@ -0,0 +1,117 @@ +---Models in module 'event'--- +new model event.mail.slot +new model event.slot + +# NOTHING TO DO + +---Fields in module 'event'--- +event / event.event / badge_format (selection) : selection_keys removed: [96x134, 96x82] +event / event.event / event_slot_ids (one2many) : NEW relation: event.slot +event / event.event / event_url (char) : NEW hasdefault: compute + +# NOTHING TO DO + +event / event.event / general_question_ids (one2many): table is now 'event_event_event_question_rel' ('False') +event / event.event / general_question_ids (one2many): type is now 'many2many' ('one2many') + +# DONE: reverse side of event.question.event_id m2o->m2m promotion — reads from event_event_event_question_rel populated in post-migration + +event / event.event / is_multi_slots (boolean) : NEW +event / event.event / kanban_state (selection) : selection_keys added: [cancel] (most likely nothing to do) +event / event.event / kanban_state_label (char) : DEL + +# NOTHING TO DO + +event / event.event / question_ids (one2many) : table is now 'event_event_event_question_rel' ('False') +event / event.event / question_ids (one2many) : type is now 'many2many' ('one2many') +event / event.event / specific_question_ids (one2many): table is now 'event_event_event_question_rel' ('False') +event / event.event / specific_question_ids (one2many): type is now 'many2many' ('one2many') + +# DONE: same reverse side as general_question_ids — m2m table populated in post-migration + +event / event.event.ticket / limit_max_per_order (integer) : NEW hasdefault: default +event / event.mail / error_datetime (datetime) : NEW +event / event.mail / interval_type (selection) : selection_keys added: [after_event_start, before_event_end] (most likely nothing to do) +event / event.mail / mail_slot_ids (one2many) : NEW relation: event.mail.slot +event / event.mail / mail_state (selection) : selection_keys added: [cancelled, error] (most likely nothing to do) +event / event.mail.slot / event_slot_id (many2one) : NEW relation: event.slot, required +event / event.mail.slot / last_registration_id (many2one): NEW relation: event.registration +event / event.mail.slot / mail_count_done (integer) : NEW +event / event.mail.slot / mail_done (boolean) : NEW +event / event.mail.slot / scheduled_date (datetime) : NEW isfunction: function, stored +event / event.mail.slot / scheduler_id (many2one) : NEW relation: event.mail, required +event / event.question / active (boolean) : NEW hasdefault: default + +# NOTHING TO DO + +event / event.question / event_id (many2one) : DEL relation: event.event +event / event.question / event_ids (many2many) : NEW relation: event.event +event / event.question / event_type_id (many2one) : DEL relation: event.type +event / event.question / event_type_ids (many2many) : NEW relation: event.type + +# DONE: post-migration: m2o_to_x2m promotes event_id->event_ids and event_type_id->event_type_ids + +event / event.question / is_default (boolean) : NEW +event / event.question / is_reusable (boolean) : NEW isfunction: function, stored +event / event.registration / event_begin_date (datetime) : not related anymore +event / event.registration / event_begin_date (datetime) : now a function +event / event.registration / event_end_date (datetime) : not related anymore +event / event.registration / event_end_date (datetime) : now a function +event / event.registration / event_slot_id (many2one) : NEW relation: event.slot +event / event.slot / color (integer) : NEW hasdefault: default +event / event.slot / date (date) : NEW required +event / event.slot / end_datetime (datetime) : NEW isfunction: function, stored +event / event.slot / end_hour (float) : NEW required +event / event.slot / event_id (many2one) : NEW relation: event.event, required +event / event.slot / registration_ids (one2many) : NEW relation: event.registration +event / event.slot / start_datetime (datetime) : NEW isfunction: function, stored +event / event.slot / start_hour (float) : NEW required +event / event.stage / legend_blocked (char) : DEL required +event / event.stage / legend_done (char) : DEL required +event / event.stage / legend_normal (char) : DEL required + +# NOTHING TO DO + +event / event.type / question_ids (one2many) : table is now 'event_question_event_type_rel' ('False') +event / event.type / question_ids (one2many) : type is now 'many2many' ('one2many') + +# DONE: reverse side of event.question.event_type_id m2o->m2m promotion — reads from event_question_event_type_rel populated in post-migration + +event / event.type.mail / interval_type (selection) : selection_keys added: [after_event_start, before_event_end] (most likely nothing to do) + +# NOTHING TO DO + +---XML records in module 'event'--- +NEW event.question: event.event_question_email (noupdate) +NEW event.question: event.event_question_name (noupdate) +NEW event.question: event.event_question_phone (noupdate) + +# NOTHING TO DO + +DEL event.stage: event.event_stage_cancelled (noupdate) + +# DONE: pre-migration: delete noupdate stage record (won't be removed by standard module update) + +NEW ir.actions.act_window: event.event_question_action +NEW ir.actions.act_window: event.event_slot_action_from_event +DEL ir.actions.client: event.event_action_install_kiosk_pwa +DEL ir.actions.report: event.action_report_event_registration_badge_96x134 +DEL ir.actions.report: event.action_report_event_registration_badge_96x82 +NEW ir.model.access: event.access_event_mail_slot_manager +NEW ir.model.access: event.access_event_mail_slot_registration +NEW ir.model.access: event.access_event_slot_registration +NEW ir.model.access: event.access_event_slot_user +NEW ir.model.constraint: event.constraint_event_question_check_default_question_is_reusable +NEW ir.ui.menu: event.event_question_menu +NEW ir.ui.view: event.event_question_view_list +NEW ir.ui.view: event.event_question_view_list_add +NEW ir.ui.view: event.event_question_view_search +NEW ir.ui.view: event.view_event_slot_calendar +NEW ir.ui.view: event.view_event_slot_form +NEW ir.ui.view: event.view_event_slot_multi_create_form +NEW ir.ui.view: event.view_event_slot_tree +DEL ir.ui.view: event.event_report_template_esc_label_96x134_badge +DEL ir.ui.view: event.event_report_template_esc_label_96x82_badge +NEW res.groups.privilege: event.res_groups_privilege_events + +# NOTHING TO DO From 32235ce2422e50837c7eca69f0411f931c7c06ba Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Thu, 11 Jun 2026 07:51:19 -0400 Subject: [PATCH 2/4] [FIX] event: remap cancelled events before deleting their stage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit event.event.stage_id is ondelete='restrict' — the raw DELETE crashed on any DB with a cancelled event (and left the imd row behind). Remap to the Ended stage with kanban_state='cancel' (19's replacement), then use the safe-delete helper. Also restore the rebuilt badge mail template into the loaded noupdate work file: 19 rebuilt the badge flow and dropped the old reports the 18 body references. --- .../event/19.0.1.9/noupdate_changes_work.xml | 290 +++++++++++++++++- .../scripts/event/19.0.1.9/pre-migration.py | 26 +- .../event/19.0.1.9/upgrade_analysis_work.txt | 3 +- 3 files changed, 307 insertions(+), 12 deletions(-) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml b/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml index 87a4e7f0d611..b30b5c1c60e7 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml +++ b/openupgrade_scripts/scripts/event/19.0.1.9/noupdate_changes_work.xml @@ -1,6 +1,294 @@ - + 24 + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ Your registration +
+ + Guest + + +
+ + Download Badges + + + + +
+
+
+
+ + + + + + + +
+
+ Guest + Hello ,
+
+ Please find attached your badge for + + OpenWood Collection Online Reveal + + + OpenWood Collection Online Reveal. + +
+
+ + + + + + + +
+ Add this event to your calendar + + + iCal + + + + Outlook + + + + Google + +
+
+
+
+ See you soon,
+ + --
+ + YourCompany + + + The OpenWood Collection Online Reveal Team + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + +
+ May 4, 2021 + 7:00 AM + - 5:00 PM +
+
+ From + May 4, 2021 - 7:00 AM +
+ To + May 6, 2021 - 5:00 PM +
+
+ (Europe/Brussels) +
+
+ + + + + + + +
Teksa SpA
+
+ +
Puerto Madero 9710
+ + + +
Of A15, Santiago (RM)
+ + +
+ + Pudahuel, + + + + C1, + + + + 98450 + + +
+ +
Argentina
+ + +
+
+
+ +
+
+
+ + +
+ Questions about this event? +
Please contact the organizer:
+ +
+
+
+ + +
+
+
+ + +
+ Get the best mobile experience. + Install our mobile app +
+
+
+ + +
+
+
+ + + + + + +
+ +
+
+
+
+
+ + + + + +
+ Sent by YourCompany + +
+ Discover all our events. +
+
+
+
+
+ + +
diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py index 1f85a7d97e37..98b67c5f5cd3 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py +++ b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py @@ -3,14 +3,20 @@ @openupgrade.migrate() def migrate(env, version): - openupgrade.logged_query( - env.cr, - """ - DELETE FROM event_stage WHERE id IN ( - SELECT imd.res_id FROM ir_model_data imd - WHERE imd.model = 'event.stage' - AND imd.module = 'event' - AND imd.name = 'event_stage_cancelled' + # 19.0 drops the Cancelled stage in favour of kanban_state='cancel'. + # event.event.stage_id is ondelete='restrict', so remap cancelled events + # onto the surviving Ended stage (flagged cancelled) before removing the + # stage; the safe helper also drops the ir_model_data row. + cancelled = env.ref("event.event_stage_cancelled", raise_if_not_found=False) + done = env.ref("event.event_stage_done", raise_if_not_found=False) + if cancelled and done: + openupgrade.logged_query( + env.cr, + """ + UPDATE event_event + SET stage_id = %s, kanban_state = 'cancel' + WHERE stage_id = %s + """, + (done.id, cancelled.id), ) - """, - ) + openupgrade.delete_records_safely_by_xml_id(env, ["event.event_stage_cancelled"]) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt index 6479942e7769..ac77685f9bfc 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt +++ b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt @@ -90,7 +90,8 @@ NEW event.question: event.event_question_phone (noupdate) DEL event.stage: event.event_stage_cancelled (noupdate) -# DONE: pre-migration: delete noupdate stage record (won't be removed by standard module update) +# DONE: pre-migration remaps cancelled events to the Ended stage + kanban_state='cancel' +# (stage_id is ondelete=restrict), then safe-deletes the noupdate stage record NEW ir.actions.act_window: event.event_question_action NEW ir.actions.act_window: event.event_slot_action_from_event From 5e03438c6173df40b27a4ec3b92b8f0e77a03ef1 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Thu, 11 Jun 2026 08:22:59 -0400 Subject: [PATCH 3/4] [FIX] event: pre-migration must not use env.ref on the module's own model event.stage isn't in the registry during event's pre-migration (KeyError caught by the enriched gate's first post-#106 run); resolve the stage ids from ir_model_data and delete the remapped stage + its imd row in SQL. --- .../scripts/event/19.0.1.9/pre-migration.py | 32 +++++++++++++++---- .../event/19.0.1.9/upgrade_analysis_work.txt | 3 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py index 98b67c5f5cd3..4ca0cbdff92c 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py +++ b/openupgrade_scripts/scripts/event/19.0.1.9/pre-migration.py @@ -6,10 +6,21 @@ def migrate(env, version): # 19.0 drops the Cancelled stage in favour of kanban_state='cancel'. # event.event.stage_id is ondelete='restrict', so remap cancelled events # onto the surviving Ended stage (flagged cancelled) before removing the - # stage; the safe helper also drops the ir_model_data row. - cancelled = env.ref("event.event_stage_cancelled", raise_if_not_found=False) - done = env.ref("event.event_stage_done", raise_if_not_found=False) - if cancelled and done: + # stage and its ir_model_data row. Pure SQL: event's models are not in + # the registry during its own pre-migration, so env.ref cannot be used. + env.cr.execute( + """ + SELECT name, res_id FROM ir_model_data + WHERE module = 'event' AND model = 'event.stage' + AND name IN ('event_stage_cancelled', 'event_stage_done') + """ + ) + stages = dict(env.cr.fetchall()) + cancelled = stages.get("event_stage_cancelled") + done = stages.get("event_stage_done") + if not cancelled: + return + if done: openupgrade.logged_query( env.cr, """ @@ -17,6 +28,15 @@ def migrate(env, version): SET stage_id = %s, kanban_state = 'cancel' WHERE stage_id = %s """, - (done.id, cancelled.id), + (done, cancelled), ) - openupgrade.delete_records_safely_by_xml_id(env, ["event.event_stage_cancelled"]) + openupgrade.logged_query( + env.cr, "DELETE FROM event_stage WHERE id = %s", (cancelled,) + ) + openupgrade.logged_query( + env.cr, + """ + DELETE FROM ir_model_data + WHERE module = 'event' AND name = 'event_stage_cancelled' + """, + ) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt index ac77685f9bfc..10b8f6b03f38 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt +++ b/openupgrade_scripts/scripts/event/19.0.1.9/upgrade_analysis_work.txt @@ -91,7 +91,8 @@ NEW event.question: event.event_question_phone (noupdate) DEL event.stage: event.event_stage_cancelled (noupdate) # DONE: pre-migration remaps cancelled events to the Ended stage + kanban_state='cancel' -# (stage_id is ondelete=restrict), then safe-deletes the noupdate stage record +# (stage_id is ondelete=restrict), then deletes the noupdate stage + imd row (SQL — +# event's models aren't registered during its own pre-migration) NEW ir.actions.act_window: event.event_question_action NEW ir.actions.act_window: event.event_slot_action_from_event From ec66f2ab7b5db791d4e6ba281e434907ed2f9b37 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sat, 20 Jun 2026 12:46:44 -0400 Subject: [PATCH 4/4] [FIX] event: drop stale translations on reloaded mail.template badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-migration load_data reloads event_registration_mail_template_badge (mail.template) whose body_html changed in 19.0, but omitted delete_record_translations — stale 18.0 per-language translations would shadow the new source for non-English users (the check-17 class). --- .../scripts/event/19.0.1.9/post-migration.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py b/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py index 47766af35590..377fc86f791d 100644 --- a/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py +++ b/openupgrade_scripts/scripts/event/19.0.1.9/post-migration.py @@ -18,3 +18,9 @@ def migrate(env, version): "event_type_id", ) openupgrade.load_data(env, "event", "19.0.1.9/noupdate_changes_work.xml") + # The reloaded event_registration_mail_template_badge carries a changed + # body_html; drop stale 18.0 per-language translations so non-English users + # see the 19.0 source instead of a shadowing old translation. + openupgrade.delete_record_translations( + env.cr, "event", ["event_registration_mail_template_badge"], ["body_html"] + )