From 1cc996a47980827302f926c5349a661e59dc7e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Taymans?= Date: Mon, 5 Jun 2023 16:54:33 +0200 Subject: [PATCH] [OU-ADD] hr Move elements from `hr_contract` to `hr`. Replace M2M relation between hr.plan and hr.plan.activity.type to O2M and warn about data loss. Import noupdate_changes --- docsource/modules150-160.rst | 2 +- .../scripts/hr/16.0.1.1/post-migration.py | 116 ++++++++++++++++++ .../scripts/hr/16.0.1.1/pre-migration.py | 29 +++++ .../hr/16.0.1.1/upgrade_analysis_work.txt | 59 +++++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py create mode 100644 openupgrade_scripts/scripts/hr/16.0.1.1/pre-migration.py create mode 100644 openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt diff --git a/docsource/modules150-160.rst b/docsource/modules150-160.rst index 82a2f9756360..a5919f6c9d35 100644 --- a/docsource/modules150-160.rst +++ b/docsource/modules150-160.rst @@ -164,7 +164,7 @@ Module coverage 15.0 -> 16.0 +-------------------------------------------------+----------------------+-------------------------------------------------+ | |del| google_spreadsheet | | | +-------------------------------------------------+----------------------+-------------------------------------------------+ -| hr | | | +| hr | Done | | +-------------------------------------------------+----------------------+-------------------------------------------------+ | hr_attendance | | | +-------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py b/openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py new file mode 100644 index 000000000000..074a288099db --- /dev/null +++ b/openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py @@ -0,0 +1,116 @@ +# Copyright 2023 Coop IT Easy (https://coopiteasy.be) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +from openupgradelib import openupgrade + +_logger = logging.getLogger(__name__) + + +def warn_about_dataloss(cr, source_relation_table, relation_comodel_field): + """Warn user about data loss when migrating data from many2many to + many2one. + + :param source_relation_table: The many2many relation table + of the model that will on the 'one' side of the relation + :param relation_comodel_field: The name of the column containing ids + of the 'many' part of the new relation. + """ + openupgrade.logged_query( + cr, + """ + SELECT DISTINCT %(relation_comodel_field)s + FROM %(source_relation_table)s + WHERE %(relation_comodel_field)s IN ( + SELECT %(relation_comodel_field)s + FROM %(source_relation_table)s + GROUP BY %(relation_comodel_field)s + HAVING COUNT(*) > 1 + ) + """ + % { + "source_relation_table": source_relation_table, + "relation_comodel_field": relation_comodel_field, + }, + ) + for res in cr.fetchall(): + _logger.error( + "hr.plan.activity.type(%s,) is linked to several hr.plan. " + "hr.plan.activity.type can only be linked to one hr.plan. " + "Fix these data before migrating to avoid data loss.", + res[0], + ) + + +def m2m_to_o2m( + env, + model, + field, + source_relation_table, + relation_source_field, + relation_comodel_field, +): + """Transform many2many relations into one2many (with possible data + loss). + + Use rename_tables in your pre-migrate script to keep the many2many + relation table and give them as 'source_relation_table' argument. + + :param model: The target registery model + :param field: The field that changes from m2m to o2m + :param source_relation_table: The (renamed) many2many relation table + :param relation_source_field: The column name of the 'model' id + in the relation table + :param relation_comodel_field: The column name of the comodel id in + the relation table + """ + columns = env[model]._fields.get(field) + target_table = env[columns.comodel_name]._table + target_field = columns.inverse_name + openupgrade.logged_query( + env.cr, + """ + UPDATE %(target_table)s AS target + SET %(target_field)s=source.%(relation_source_field)s + FROM %(source_relation_table)s AS source + WHERE source.%(relation_comodel_field)s=target.id + """ + % { + "target_table": target_table, + "target_field": target_field, + "source_relation_table": source_relation_table, + "relation_source_field": relation_source_field, + "relation_comodel_field": relation_comodel_field, + }, + ) + + +def drop_table(cr, table): + """Drop table + + :param table: the name of the table that will be dropped + """ + openupgrade.logged_query( + cr, + "DROP TABLE IF EXISTS %(table)s CASCADE" % {"table": table}, + ) + + +@openupgrade.migrate() +def migrate(env, version): + warn_about_dataloss( + env.cr, + "hr_plan_hr_plan_activity_type_rel", + "hr_plan_activity_type_id", + ) + m2m_to_o2m( + env, + "hr.plan", + "plan_activity_type_ids", + "hr_plan_hr_plan_activity_type_rel", + "hr_plan_id", + "hr_plan_activity_type_id", + ) + drop_table(env.cr, "hr_plan_hr_plan_activity_type_rel") + openupgrade.load_data(env.cr, "hr", "16.0.1.1/noupdate_changes.xml") diff --git a/openupgrade_scripts/scripts/hr/16.0.1.1/pre-migration.py b/openupgrade_scripts/scripts/hr/16.0.1.1/pre-migration.py new file mode 100644 index 000000000000..edacfca2b181 --- /dev/null +++ b/openupgrade_scripts/scripts/hr/16.0.1.1/pre-migration.py @@ -0,0 +1,29 @@ +# Copyright 2023 Coop IT Easy (https://coopiteasy.be) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + +_moved_fields = [ + "__last_update", + "_order", + "display_name", + "name", +] + +_xmlid_renames = [ + ( + "hr_contract.access_hr_contract_type_manager", + "hr.access_hr_contract_type_manager", + ), +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.update_module_moved_models( + env.cr, "hr.contract.type", "hr_contract", "hr" + ) + openupgrade.update_module_moved_fields( + env.cr, "hr.contract.type", _moved_fields, "hr_contract", "hr" + ) + openupgrade.rename_xmlids(env.cr, _xmlid_renames) diff --git a/openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt new file mode 100644 index 000000000000..5a9662efecad --- /dev/null +++ b/openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt @@ -0,0 +1,59 @@ +---Models in module 'hr'--- +model hr.contract.type (moved from hr_contract) +# DONE: moved from hr_contract to hr +---Fields in module 'hr'--- +hr / hr.contract.type / __last_update (datetime) : previously in module hr_contract +hr / hr.contract.type / _order : previously in module hr_contract +hr / hr.contract.type / display_name (char) : previously in module hr_contract +hr / hr.contract.type / name (char) : previously in module hr_contract +# DONE: moved from hr_contract to hr +hr / hr.contract.type / sequence (integer) : NEW +# NOTHING TO DO +hr / hr.department / master_department_id (many2one): NEW relation: hr.department, isfunction: function, stored +hr / hr.department / parent_path (char) : NEW +hr / hr.department / plan_ids (one2many) : NEW relation: hr.plan +# NOTHING TO DO +hr / hr.employee / mobile_phone (char) : now a function +hr / hr.employee / work_contact_id (many2one) : NEW relation: res.partner +hr / hr.employee / work_email (char) : now a function +# NOTHING TO DO +hr / hr.job / active (boolean) : NEW hasdefault: default +hr / hr.job / contract_type_id (many2one) : NEW relation: hr.contract.type +hr / hr.job / state (selection) : DEL required, selection_keys: ['open', 'recruit'] +# NOTHING TO DO: hr.job does not work with sate anymore. +hr / hr.plan / company_id (many2one) : NEW relation: res.company, hasdefault: default +hr / hr.plan / department_id (many2one) : NEW relation: hr.department +# NOTHING TO DO +hr / hr.plan / plan_activity_type_ids (many2many): table is now 'False' ('hr_plan_hr_plan_activity_type_rel') +hr / hr.plan / plan_activity_type_ids (many2many): type is now 'one2many' ('many2many') +# DONE: move data from many2many table to plan_id colomn in hr.plan.activity.type +hr / hr.plan.activity.type / company_id (many2one) : NEW relation: res.company, hasdefault: default +# NOTHING TO DO: not a required field so no default to set +hr / hr.plan.activity.type / plan_id (many2one) : NEW relation: hr.plan +# DONE: see plan_activity_type_ids from hr.plan +hr / res.users / create_employee (boolean) : NEW hasdefault: default +hr / res.users / create_employee_id (many2one) : NEW relation: hr.employee +# NOTHING TO DO +hr / resource.resource / employee_id (one2many) : NEW relation: hr.employee +# NOTHING TO DO +---XML records in module 'hr'--- +NEW ir.actions.act_window: hr.hr_contract_type_action +# NOTHING TO DO +NEW ir.actions.server: hr.action_hr_employee_create_user +# NOTHING TO DO +NEW ir.model.access: hr.access_hr_contract_type_manager [renamed from hr_contract module] +# DONE: renamed +NEW ir.rule: hr.hr_plan_activity_type_company_rule (noupdate) +NEW ir.rule: hr.hr_plan_company_rule (noupdate) +# NOTHING TO DO +NEW ir.ui.menu: hr.menu_config_employee +NEW ir.ui.menu: hr.menu_config_recruitment +NEW ir.ui.menu: hr.menu_view_hr_contract_type +DEL ir.ui.menu: hr.menu_config_plan_types +DEL ir.ui.menu: hr.menu_human_resources_configuration_employee +NEW ir.ui.view: hr.hr_contract_type_view_form +NEW ir.ui.view: hr.hr_contract_type_view_tree +NEW ir.ui.view: hr.view_employee_form_smartbutton +NEW ir.ui.view: hr.view_users_simple_form +NEW ir.ui.view: hr.view_users_simple_form_inherit_hr +# NOTHING TO DO