Skip to content

Commit

Permalink
[OU-ADD] hr
Browse files Browse the repository at this point in the history
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
remytms committed Jun 22, 2023
1 parent 37494be commit 6f3997e
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docsource/modules150-160.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Module coverage 15.0 -> 16.0
+-------------------------------------------------+----------------------+-------------------------------------------------+
| |del| google_spreadsheet | | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| hr | | |
| hr | Done | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| hr_attendance | | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
Expand Down
186 changes: 186 additions & 0 deletions openupgrade_scripts/scripts/hr/16.0.1.1/post-migration.py
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")
32 changes: 32 additions & 0 deletions openupgrade_scripts/scripts/hr/16.0.1.1/pre-migration.py
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 openupgrade_scripts/scripts/hr/16.0.1.1/upgrade_analysis_work.txt
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

0 comments on commit 6f3997e

Please sign in to comment.