-
-
Notifications
You must be signed in to change notification settings - Fork 699
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
4 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
186 changes: 186 additions & 0 deletions
186
openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# 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 | ||
from psycopg2.extensions import AsIs | ||
|
||
_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": AsIs(source_relation_table), | ||
"relation_comodel_field": AsIs(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. | ||
And remove foreign keys constraints with remove_tables_fks(). | ||
: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": AsIs(target_table), | ||
"target_field": AsIs(target_field), | ||
"source_relation_table": AsIs(source_relation_table), | ||
"relation_source_field": AsIs(relation_source_field), | ||
"relation_comodel_field": AsIs(relation_comodel_field), | ||
}, | ||
) | ||
|
||
|
||
def create_work_contact(env): | ||
"""Create work_contact_id for model hr.employee.base""" | ||
# Get employee | ||
openupgrade.logged_query( | ||
env.cr, | ||
""" | ||
SELECT id, name, work_email, mobile_phone, company_id | ||
FROM hr_employee | ||
""", | ||
) | ||
for employee_values in env.cr.fetchall(): | ||
# Create partner | ||
openupgrade.logged_query( | ||
env.cr, | ||
""" | ||
INSERT INTO res_partner (name, email, mobile, company_id) | ||
VALUES (%s, %s, %s, %s) | ||
RETURNING id | ||
""", | ||
( | ||
employee_values[1], | ||
employee_values[2], | ||
employee_values[3], | ||
employee_values[4], | ||
), | ||
) | ||
partner_values = env.cr.fetchall() | ||
# Update employee | ||
openupgrade.logged_query( | ||
env.cr, | ||
"UPDATE hr_employee SET work_contact_id = %s WHERE id = %s", | ||
(partner_values[0][0], employee_values[0]), | ||
) | ||
# Create image | ||
openupgrade.logged_query( | ||
env.cr, | ||
""" | ||
SELECT | ||
name, description, res_model, res_field, res_id, | ||
company_id, type, url, public, db_datas, store_fname, | ||
file_size, checksum, mimetype, index_content | ||
FROM ir_attachment | ||
WHERE | ||
res_model = 'hr.employee' | ||
AND res_field = 'image_1920' | ||
AND res_id = %s | ||
""", | ||
(employee_values[0],), | ||
) | ||
for attachment_values in env.cr.fetchall(): | ||
openupgrade.logged_query( | ||
env.cr, | ||
""" | ||
INSERT INTO ir_attachment ( | ||
name, description, res_model, res_field, res_id, | ||
company_id, type, url, public, db_datas, store_fname, | ||
file_size, checksum, mimetype, index_content | ||
) VALUES ( | ||
%s, %s, 'res.partner', 'image_1920', %s, %s, %s, %s, | ||
%s, %s, %s, %s, %s, %s, %s | ||
) | ||
""", | ||
( | ||
attachment_values[0], | ||
attachment_values[1], | ||
attachment_values[4], | ||
attachment_values[5], | ||
attachment_values[6], | ||
attachment_values[7], | ||
attachment_values[8], | ||
attachment_values[9], | ||
attachment_values[10], | ||
attachment_values[11], | ||
attachment_values[12], | ||
attachment_values[13], | ||
attachment_values[14], | ||
), | ||
) | ||
|
||
|
||
@openupgrade.migrate() | ||
def migrate(env, version): | ||
warn_about_dataloss( | ||
env.cr, | ||
openupgrade.get_legacy_name("hr_plan_hr_plan_activity_type_rel"), | ||
"hr_plan_activity_type_id", | ||
) | ||
m2m_to_o2m( | ||
env, | ||
"hr.plan", | ||
"plan_activity_type_ids", | ||
openupgrade.get_legacy_name("hr_plan_hr_plan_activity_type_rel"), | ||
"hr_plan_id", | ||
"hr_plan_activity_type_id", | ||
) | ||
openupgrade.load_data(env.cr, "hr", "16.0.1.1/noupdate_changes.xml") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# 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) | ||
# Backup Many2many relation between hr.plan and hr.plan.activity.type | ||
openupgrade.remove_tables_fks(env.cr, ["hr_plan_hr_plan_activity_type_rel"]) | ||
openupgrade.rename_tables(env.cr, [("hr_plan_hr_plan_activity_type_rel", None)]) |
75 changes: 75 additions & 0 deletions
75
openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
---Models in module 'hr'--- | ||
model hr.contract.type (moved from hr_contract) | ||
# DONE: pre-migration: 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: pre-migration: 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 | ||
# TODO: post-migration: create work_contact_id for each employee | ||
|
||
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 state 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: pre-migration and post-migration: 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: pre-migration: 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 |