From 0e3e927042823afc94afc6b0c566fbef7f2d0667 Mon Sep 17 00:00:00 2001
From: Don Kendall <dkendall@ledoweb.com>
Date: Thu, 28 May 2026 17:32:29 -0400
Subject: [PATCH] [OU-ADD] hr_attendance/hr_skills: renames + noupdate reload
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- hr_attendance: hr.attendance.overtime → .overtime.line (rename_models +
  rename_tables); noupdate group/rule reloaded in post-migration.
- hr_attendance: rename hr.attendance in_city→in_location, out_city→out_location
  (preserve data; analyzer reports them as separate DEL+NEW).
- hr_attendance: precreate hr.attendance.overtime.line.status='approved' and
  manual_duration=duration on the renamed table's historical rows; backfill the
  now-required date. The status compute guards on `if not status`, so precreating
  keeps legacy lines approved instead of recomputing to to_approve.
- hr_attendance: delete the obsolete noupdate ir.rule records (not swept by the
  standard module update).
- hr_holidays_attendance: drop hr.leave / hr.leave.allocation overtime_id — the
  field is removed in 19.0 and the overtime rename invalidated its FK.
- hr_recruitment_skills: hr.candidate.skill → hr.applicant.skill rename;
  noupdate interviewer/officer rules reloaded.
- hr_holidays_attendance, hr_skills: noupdate security/config reloaded.
---
 docsource/modules180-190.rst                  |   8 +-
 .../hr_attendance/19.0.2.0/post-migration.py  |   6 +
 .../hr_attendance/19.0.2.0/pre-migration.py   |  54 ++++++++
 .../19.0.2.0/upgrade_analysis_work.txt        | 130 +++++++++++++++++
 .../19.0.1.0/post-migration.py                |   8 ++
 .../19.0.1.0/pre-migration.py                 |  12 ++
 .../19.0.1.0/upgrade_analysis_work.txt        |  45 ++++++
 .../19.0.1.0/post-migration.py                |   6 +
 .../19.0.1.0/pre-migration.py                 |  26 ++++
 .../19.0.1.0/upgrade_analysis_work.txt        |  41 ++++++
 .../hr_skills/19.0.1.0/post-migration.py      |   6 +
 .../19.0.1.0/upgrade_analysis_work.txt        | 131 ++++++++++++++++++
 12 files changed, 469 insertions(+), 4 deletions(-)
 create mode 100644 openupgrade_scripts/scripts/hr_attendance/19.0.2.0/post-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_attendance/19.0.2.0/pre-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_attendance/19.0.2.0/upgrade_analysis_work.txt
 create mode 100644 openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/post-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/pre-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/upgrade_analysis_work.txt
 create mode 100644 openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/post-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/pre-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/upgrade_analysis_work.txt
 create mode 100644 openupgrade_scripts/scripts/hr_skills/19.0.1.0/post-migration.py
 create mode 100644 openupgrade_scripts/scripts/hr_skills/19.0.1.0/upgrade_analysis_work.txt

diff --git a/docsource/modules180-190.rst b/docsource/modules180-190.rst
index e7f797ce0766..dffc2c71bb06 100644
--- a/docsource/modules180-190.rst
+++ b/docsource/modules180-190.rst
@@ -168,7 +168,7 @@ Module coverage 18.0 -> 19.0
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr                                                |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
-| hr_attendance                                     |                      |                                                 |
+| hr_attendance                                     |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr_calendar                                       |                      |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
@@ -182,7 +182,7 @@ Module coverage 18.0 -> 19.0
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr_holidays                                       |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
-| hr_holidays_attendance                            |                      |                                                 |
+| hr_holidays_attendance                            |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | |del| hr_holidays_contract                        |                      |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
@@ -202,13 +202,13 @@ Module coverage 18.0 -> 19.0
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr_recruitment                                    |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
-| hr_recruitment_skills                             |                      |                                                 |
+| hr_recruitment_skills                             |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr_recruitment_sms                                |                      |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | hr_recruitment_survey                             |                      |No DB layout changes.                            |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
-| hr_skills                                         |                      |                                                 |
+| hr_skills                                         |Done                  |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
 | |new| hr_skills_event                             |                      |                                                 |
 +---------------------------------------------------+----------------------+-------------------------------------------------+
diff --git a/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/post-migration.py b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/post-migration.py
new file mode 100644
index 000000000000..76b370d74b82
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/post-migration.py
@@ -0,0 +1,6 @@
+from openupgradelib import openupgrade
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.load_data(env, "hr_attendance", "19.0.2.0/noupdate_changes.xml")
diff --git a/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/pre-migration.py b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/pre-migration.py
new file mode 100644
index 000000000000..8baff6e8fcd9
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/pre-migration.py
@@ -0,0 +1,54 @@
+from openupgradelib import openupgrade
+
+_renamed_models = [
+    ("hr.attendance.overtime", "hr.attendance.overtime.line"),
+]
+
+_renamed_tables = [
+    ("hr_attendance_overtime", "hr_attendance_overtime_line"),
+]
+
+_renamed_fields = [
+    ("hr.attendance", "hr_attendance", "in_city", "in_location"),
+    ("hr.attendance", "hr_attendance", "out_city", "out_location"),
+]
+
+# Removed in 19.0 but noupdate, so not swept by the standard module update.
+_obsolete_rule_xmlids = [
+    "hr_attendance.hr_attendance_overtime_rule_employee_company",
+    "hr_attendance.hr_attendance_rule_attendance_officer_overtime_restrict",
+    "hr_attendance.hr_attendance_rule_attendance_overtime_admin",
+    "hr_attendance.hr_attendance_rule_attendance_overtime_simple_user",
+]
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.rename_models(env.cr, _renamed_models)
+    openupgrade.rename_tables(env.cr, _renamed_tables)
+    openupgrade.rename_fields(env, _renamed_fields)
+    openupgrade.delete_records_safely_by_xml_id(env, _obsolete_rule_xmlids)
+    # Precreate the new required/computed columns for the renamed table's rows.
+    openupgrade.logged_query(
+        env.cr,
+        """
+        ALTER TABLE hr_attendance_overtime_line
+            ADD COLUMN IF NOT EXISTS status varchar,
+            ADD COLUMN IF NOT EXISTS manual_duration double precision
+        """,
+    )
+    openupgrade.logged_query(
+        env.cr,
+        "UPDATE hr_attendance_overtime_line SET status = 'approved' "
+        "WHERE status IS NULL",
+    )
+    openupgrade.logged_query(
+        env.cr,
+        "UPDATE hr_attendance_overtime_line SET manual_duration = duration "
+        "WHERE manual_duration IS NULL",
+    )
+    openupgrade.logged_query(
+        env.cr,
+        "UPDATE hr_attendance_overtime_line SET date = create_date::date "
+        "WHERE date IS NULL",
+    )
diff --git a/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/upgrade_analysis_work.txt
new file mode 100644
index 000000000000..090a31dbc110
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_attendance/19.0.2.0/upgrade_analysis_work.txt
@@ -0,0 +1,130 @@
+---Models in module 'hr_attendance'---
+obsolete model hr.attendance.overtime (renamed to hr.attendance.overtime.line)
+new model hr.attendance.overtime.line (renamed from hr.attendance.overtime)
+
+# DONE: rename_models + rename_tables in pre-migration.py
+
+new model hr.attendance.overtime.rule
+new model hr.attendance.overtime.ruleset
+
+# NOTHING TO DO: new feature
+
+---Fields in module 'hr_attendance'---
+hr_attendance / hr.attendance            / date (date)                   : NEW required, isfunction: function, stored
+hr_attendance / hr.attendance            / in_city (char)                : DEL
+hr_attendance / hr.attendance            / in_country_name (char)        : DEL
+hr_attendance / hr.attendance            / in_location (char)            : NEW
+hr_attendance / hr.attendance            / linked_overtime_ids (many2many): NEW relation: hr.attendance.overtime.line, hasdefault: compute, stored: False
+hr_attendance / hr.attendance            / out_city (char)               : DEL
+hr_attendance / hr.attendance            / out_country_name (char)       : DEL
+hr_attendance / hr.attendance            / out_location (char)           : NEW
+hr_attendance / hr.attendance            / validated_overtime_hours (float): now a function
+
+# DONE: rename in_city->in_location, out_city->out_location in pre-migration
+
+hr_attendance / hr.attendance.overtime   / _order                        : _order is now 'time_start' ('date desc')
+hr_attendance / hr.attendance.overtime   / adjustment (boolean)          : DEL
+hr_attendance / hr.attendance.overtime   / date (date)                   : now required
+hr_attendance / hr.attendance.overtime   / duration_real (float)         : DEL
+
+# DONE: backfill overtime date (now required) in pre-migration
+
+hr_attendance / hr.attendance.overtime.line / amount_rate (float)           : NEW required, hasdefault: default
+hr_attendance / hr.attendance.overtime.line / manual_duration (float)       : NEW hasdefault: compute
+hr_attendance / hr.attendance.overtime.line / rule_ids (many2many)          : NEW relation: hr.attendance.overtime.rule
+hr_attendance / hr.attendance.overtime.line / status (selection)            : NEW required, selection_keys: ['approved', 'refused', 'to_approve'], hasdefault: compute
+hr_attendance / hr.attendance.overtime.line / time_start (datetime)         : NEW
+hr_attendance / hr.attendance.overtime.line / time_stop (datetime)          : NEW
+
+# DONE: precreate status='approved' + manual_duration=duration in pre-migration
+
+hr_attendance / hr.attendance.overtime.rule / amount_rate (float)           : NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / base_off (selection)          : NEW required, selection_keys: ['quantity', 'timing'], hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / description (html)            : NEW
+hr_attendance / hr.attendance.overtime.rule / employee_tolerance (float)    : NEW
+hr_attendance / hr.attendance.overtime.rule / employer_tolerance (float)    : NEW
+hr_attendance / hr.attendance.overtime.rule / expected_hours (float)        : NEW
+hr_attendance / hr.attendance.overtime.rule / expected_hours_from_contract (boolean): NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / name (char)                   : NEW required
+hr_attendance / hr.attendance.overtime.rule / paid (boolean)                : NEW
+hr_attendance / hr.attendance.overtime.rule / quantity_period (selection)   : NEW selection_keys: ['day', 'week'], hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / resource_calendar_id (many2one): NEW relation: resource.calendar
+hr_attendance / hr.attendance.overtime.rule / ruleset_id (many2one)         : NEW relation: hr.attendance.overtime.ruleset, required
+hr_attendance / hr.attendance.overtime.rule / sequence (integer)            : NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / timing_start (float)          : NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / timing_stop (float)           : NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.rule / timing_type (selection)       : NEW selection_keys: ['leave', 'non_work_days', 'schedule', 'work_days'], hasdefault: default
+hr_attendance / hr.attendance.overtime.ruleset / active (boolean)              : NEW hasdefault: default
+hr_attendance / hr.attendance.overtime.ruleset / company_id (many2one)         : NEW relation: res.company, hasdefault: default
+hr_attendance / hr.attendance.overtime.ruleset / country_id (many2one)         : NEW relation: res.country, hasdefault: default
+hr_attendance / hr.attendance.overtime.ruleset / description (html)            : NEW
+hr_attendance / hr.attendance.overtime.ruleset / name (char)                   : NEW required
+hr_attendance / hr.attendance.overtime.ruleset / rate_combination_mode (selection): NEW required, selection_keys: ['max', 'sum'], hasdefault: default
+hr_attendance / hr.attendance.overtime.ruleset / rule_ids (one2many)           : NEW relation: hr.attendance.overtime.rule
+hr_attendance / hr.employee              / overtime_ids (one2many)       : relation is now 'hr.attendance.overtime.line' ('hr.attendance.overtime') [nothing to do]
+hr_attendance / hr.version               / ruleset_id (many2one)         : NEW relation: hr.attendance.overtime.ruleset, hasdefault: default
+hr_attendance / res.company              / attendance_device_tracking (boolean): NEW hasdefault: default
+
+# NOTHING TO DO
+
+---XML records in module 'hr_attendance'---
+NEW hr.attendance.overtime.rule: hr_attendance.hr_attendance_overtime_employee_schedule_rule (noupdate)
+NEW hr.attendance.overtime.rule: hr_attendance.hr_attendance_overtime_non_working_days_rule (noupdate)
+NEW hr.attendance.overtime.ruleset: hr_attendance.hr_attendance_default_ruleset (noupdate)
+NEW ir.actions.act_window: hr_attendance.hr_attendance_overtime_rule_action
+NEW ir.actions.act_window: hr_attendance.hr_attendance_overtime_ruleset_action
+DEL ir.actions.act_window: hr_attendance.hr_attendance_overtime_action
+DEL ir.actions.client: hr_attendance.hr_attendance_action_install_kiosk_pwa
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_line_officer
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_line_own_reader
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_rule_admin
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_rule_officer
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_rule_user
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_ruleset_admin
+NEW ir.model.access: hr_attendance.access_hr_attendance_overtime_ruleset_hr_manager
+NEW ir.model.access: hr_attendance.access_hr_attendance_own_reader
+DEL ir.model.access: hr_attendance.access_hr_attendance_admin_overtime
+DEL ir.model.access: hr_attendance.access_hr_attendance_officer_overtime
+DEL ir.model.access: hr_attendance.access_hr_attendance_overtime_user
+NEW ir.model.constraint: hr_attendance.constraint_hr_attendance_overtime_line_overtime_start_before_end
+NEW ir.model.constraint: hr_attendance.constraint_hr_attendance_overtime_rule_timing_start_is_hour
+NEW ir.model.constraint: hr_attendance.constraint_hr_attendance_overtime_rule_timing_stop_is_hour
+NEW ir.rule: hr_attendance.hr_attendance_overtime_line_rule_admin (noupdate)
+NEW ir.rule: hr_attendance.hr_attendance_overtime_line_rule_employee_company (noupdate)
+NEW ir.rule: hr_attendance.hr_attendance_overtime_line_rule_officer (noupdate)
+NEW ir.rule: hr_attendance.hr_attendance_overtime_line_rule_own_reader (noupdate)
+NEW ir.rule: hr_attendance.hr_attendance_overtime_ruleset_rule (noupdate)
+NEW ir.rule: hr_attendance.hr_attendance_overtime_ruleset_rule_group_hr_attendance_manager (noupdate)
+DEL ir.rule: hr_attendance.hr_attendance_overtime_rule_employee_company (noupdate)
+DEL ir.rule: hr_attendance.hr_attendance_rule_attendance_officer_overtime_restrict (noupdate)
+DEL ir.rule: hr_attendance.hr_attendance_rule_attendance_overtime_admin (noupdate)
+DEL ir.rule: hr_attendance.hr_attendance_rule_attendance_overtime_simple_user (noupdate)
+
+# DONE: pre-migration deletes the obsolete noupdate ir.rule records
+
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_attendance_reporting
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_configuration
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_employee
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_onboarding
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_overtime_rulesets
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_overview
+NEW ir.ui.menu: hr_attendance.menu_hr_attendance_view_dashboard
+DEL ir.ui.menu: hr_attendance.menu_hr_attendance_view_attendances
+NEW ir.ui.view: hr_attendance.hr_attendance_employee_simple_form_view
+NEW ir.ui.view: hr_attendance.hr_attendance_overtime_rule_view_form
+NEW ir.ui.view: hr_attendance.hr_attendance_overtime_rule_view_list
+NEW ir.ui.view: hr_attendance.hr_attendance_overtime_ruleset_view_filter
+NEW ir.ui.view: hr_attendance.hr_attendance_overtime_ruleset_view_form
+NEW ir.ui.view: hr_attendance.hr_attendance_overtime_ruleset_view_list
+NEW ir.ui.view: hr_attendance.hr_employee_public_view_form
+NEW ir.ui.view: hr_attendance.hr_employee_search_view
+DEL ir.ui.view: hr_attendance.hr_attendance_overtime_view_pivot
+DEL ir.ui.view: hr_attendance.hr_attendance_validated_hours_employee_simple_tree_view
+DEL ir.ui.view: hr_attendance.hr_user_view_form
+DEL ir.ui.view: hr_attendance.view_attendance_overtime_graph
+DEL ir.ui.view: hr_attendance.view_attendance_overtime_search
+DEL ir.ui.view: hr_attendance.view_attendance_overtime_tree
+NEW res.groups: hr_attendance.group_hr_attendance_user
+NEW res.groups.privilege: hr_attendance.res_groups_privilege_attendances
+
+# NOTHING TO DO
diff --git a/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/post-migration.py b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/post-migration.py
new file mode 100644
index 000000000000..87785f41fda0
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/post-migration.py
@@ -0,0 +1,8 @@
+from openupgradelib import openupgrade
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.load_data(
+        env, "hr_holidays_attendance", "19.0.1.0/noupdate_changes.xml"
+    )
diff --git a/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/pre-migration.py b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/pre-migration.py
new file mode 100644
index 000000000000..732f3987406a
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/pre-migration.py
@@ -0,0 +1,12 @@
+from openupgradelib import openupgrade
+
+# overtime_id removed in 19.0; drop the column whose FK the overtime rename invalidated.
+_dropped_columns = [
+    ("hr_leave", "overtime_id"),
+    ("hr_leave_allocation", "overtime_id"),
+]
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.drop_columns(env.cr, _dropped_columns)
diff --git a/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/upgrade_analysis_work.txt
new file mode 100644
index 000000000000..9c4b7cea4e9a
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_holidays_attendance/19.0.1.0/upgrade_analysis_work.txt
@@ -0,0 +1,45 @@
+---Models in module 'hr_holidays_attendance'---
+new model hr.leave.attendance.report [sql_view]
+
+# NOTHING TO DO
+
+---Fields in module 'hr_holidays_attendance'---
+hr_holidays_attendance / hr.attendance.overtime.line / compensable_as_leave (boolean): NEW
+hr_holidays_attendance / hr.attendance.overtime.rule / compensable_as_leave (boolean): NEW hasdefault: default
+hr_holidays_attendance / hr.leave                 / employee_overtime (float)     : not related anymore
+hr_holidays_attendance / hr.leave                 / employee_overtime (float)     : now a function
+
+# NOTHING TO DO
+
+hr_holidays_attendance / hr.leave                 / overtime_id (many2one)        : DEL relation: hr.attendance.overtime
+
+# DONE: drop overtime_id column in pre-migration
+
+hr_holidays_attendance / hr.leave.accrual.level   / frequency (False)             : NEW selection_keys: ['bimonthly', 'biyearly', 'daily', 'hourly', 'monthly', 'weekly', 'worked_hours', 'yearly'], mode: modify
+hr_holidays_attendance / hr.leave.accrual.level   / frequency_hourly_source (selection): DEL selection_keys: ['attendance', 'calendar']
+hr_holidays_attendance / hr.leave.allocation      / employee_overtime (float)     : not related anymore
+hr_holidays_attendance / hr.leave.allocation      / employee_overtime (float)     : now a function
+
+# NOTHING TO DO
+
+hr_holidays_attendance / hr.leave.allocation      / overtime_id (many2one)        : DEL relation: hr.attendance.overtime
+
+# DONE: drop overtime_id column in pre-migration
+
+---XML records in module 'hr_holidays_attendance'---
+DEL hr.leave.type: hr_holidays_attendance.holiday_status_extra_hours [renamed to hr_holidays module] (noupdate)
+NEW ir.actions.act_window: hr_holidays_attendance.hr_leave_attendance_report_action
+DEL ir.actions.act_window: hr_holidays_attendance.hr_leave_allocation_overtime_action
+NEW ir.model.access: hr_holidays_attendance.access_hr_leave_attendance_report_manager
+NEW ir.ui.menu: hr_holidays_attendance.hr_leave_attendance_report
+NEW ir.ui.view: hr_holidays_attendance.hr_attendance_employee_simple_tree_view
+NEW ir.ui.view: hr_holidays_attendance.hr_attendance_overtime_rule_view_form
+NEW ir.ui.view: hr_holidays_attendance.hr_leave_attendance_report_view_form
+NEW ir.ui.view: hr_holidays_attendance.hr_leave_attendance_report_view_list
+NEW ir.ui.view: hr_holidays_attendance.hr_leave_attendance_report_view_pivot
+NEW ir.ui.view: hr_holidays_attendance.hr_leave_attendance_report_view_search
+NEW ir.ui.view: hr_holidays_attendance.view_attendance_overtime_line_list
+DEL ir.ui.view: hr_holidays_attendance.hr_leave_allocation_overtime_view_form
+DEL ir.ui.view: hr_holidays_attendance.res_users_view_form
+
+# NOTHING TO DO
diff --git a/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/post-migration.py b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/post-migration.py
new file mode 100644
index 000000000000..837c97e318f2
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/post-migration.py
@@ -0,0 +1,6 @@
+from openupgradelib import openupgrade
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.load_data(env, "hr_recruitment_skills", "19.0.1.0/noupdate_changes.xml")
diff --git a/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/pre-migration.py b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/pre-migration.py
new file mode 100644
index 000000000000..73b8328cd96c
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/pre-migration.py
@@ -0,0 +1,26 @@
+from openupgradelib import openupgrade
+
+_renamed_models = [
+    ("hr.candidate.skill", "hr.applicant.skill"),
+]
+
+_renamed_tables = [
+    ("hr_candidate_skill", "hr_applicant_skill"),
+    ("hr_candidate_hr_skill_rel", "hr_applicant_hr_skill_rel"),
+]
+
+_renamed_fields = [
+    ("hr.applicant.skill", "hr_applicant_skill", "candidate_id", "applicant_id"),
+]
+
+_renamed_columns = {
+    "hr_applicant_hr_skill_rel": [("hr_candidate_id", "hr_applicant_id")],
+}
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.rename_models(env.cr, _renamed_models)
+    openupgrade.rename_tables(env.cr, _renamed_tables)
+    openupgrade.rename_fields(env, _renamed_fields)
+    openupgrade.rename_columns(env.cr, _renamed_columns)
diff --git a/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/upgrade_analysis_work.txt
new file mode 100644
index 000000000000..497c8a23a4b4
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_recruitment_skills/19.0.1.0/upgrade_analysis_work.txt
@@ -0,0 +1,41 @@
+---Models in module 'hr_recruitment_skills'---
+obsolete model hr.candidate.skill (renamed to hr.applicant.skill)
+new model hr.applicant.skill (renamed from hr.candidate.skill)
+
+# DONE: rename_models + rename_tables in pre-migration.py
+
+---Fields in module 'hr_recruitment_skills'---
+hr_recruitment_skills / hr.applicant             / applicant_skill_ids (one2many): NEW relation: hr.applicant.skill
+hr_recruitment_skills / hr.applicant             / current_applicant_skill_ids (one2many): NEW relation: hr.applicant.skill, hasdefault: compute, stored: False
+hr_recruitment_skills / hr.applicant             / skill_ids (many2many)         : is now stored
+hr_recruitment_skills / hr.applicant             / skill_ids (many2many)         : not related anymore
+hr_recruitment_skills / hr.applicant             / skill_ids (many2many)         : now a function
+hr_recruitment_skills / hr.applicant             / skill_ids (many2many)         : table is now 'hr_applicant_hr_skill_rel' ('False')
+hr_recruitment_skills / hr.applicant.skill       / applicant_id (many2one)       : NEW relation: hr.applicant, required
+hr_recruitment_skills / hr.applicant.skill       / display_warning_message (boolean): NEW
+hr_recruitment_skills / hr.applicant.skill       / valid_from (date)             : NEW hasdefault: default
+hr_recruitment_skills / hr.applicant.skill       / valid_to (date)               : NEW
+hr_recruitment_skills / hr.candidate             / candidate_skill_ids (one2many): DEL relation: hr.candidate.skill
+hr_recruitment_skills / hr.candidate             / skill_ids (many2many)         : DEL relation: hr.skill
+hr_recruitment_skills / hr.candidate.skill       / _order                        : _order is now 'skill_type_id, skill_level_id desc' ('skill_level_id')
+hr_recruitment_skills / hr.candidate.skill       / candidate_id (many2one)       : DEL relation: hr.candidate, required
+hr_recruitment_skills / hr.job                   / skill_ids (many2many)         : module is now 'hr_skills' ('hr_recruitment_skills')
+
+# NOTHING TO DO
+
+---XML records in module 'hr_recruitment_skills'---
+NEW ir.actions.act_window: hr_recruitment_skills.action_find_matching_job
+NEW ir.model.access: hr_recruitment_skills.access_hr_applicant_skill_interviewer
+NEW ir.model.access: hr_recruitment_skills.access_hr_job_skill_recruitment_user
+DEL ir.model.access: hr_recruitment_skills.access_hr_candidate_skill_interviewer
+DEL ir.model.constraint: hr_recruitment_skills.constraint_hr_candidate_skill__unique_skill
+NEW ir.ui.view: hr_recruitment_skills.crm_case_tree_view_inherit_hr_recruitment_skills
+NEW ir.ui.view: hr_recruitment_skills.crm_case_tree_view_job
+NEW ir.ui.view: hr_recruitment_skills.hr_job_list_inherit_hr_recruitment_skills
+NEW ir.ui.view: hr_recruitment_skills.view_hr_job_form
+DEL ir.ui.view: hr_recruitment_skills.hr_candidate_view_form
+DEL ir.ui.view: hr_recruitment_skills.hr_candidate_view_search
+DEL ir.ui.view: hr_recruitment_skills.hr_candidate_view_tree
+DEL ir.ui.view: hr_recruitment_skills.hr_job_form_inherit_hr_recruitment_skills
+
+# NOTHING TO DO
diff --git a/openupgrade_scripts/scripts/hr_skills/19.0.1.0/post-migration.py b/openupgrade_scripts/scripts/hr_skills/19.0.1.0/post-migration.py
new file mode 100644
index 000000000000..9735a400b189
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_skills/19.0.1.0/post-migration.py
@@ -0,0 +1,6 @@
+from openupgradelib import openupgrade
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+    openupgrade.load_data(env, "hr_skills", "19.0.1.0/noupdate_changes.xml")
diff --git a/openupgrade_scripts/scripts/hr_skills/19.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr_skills/19.0.1.0/upgrade_analysis_work.txt
new file mode 100644
index 000000000000..b11a443c803c
--- /dev/null
+++ b/openupgrade_scripts/scripts/hr_skills/19.0.1.0/upgrade_analysis_work.txt
@@ -0,0 +1,131 @@
+---Models in module 'hr_skills'---
+obsolete model hr.employee.skill.log
+
+# NOTHING TO DO: obsolete snapshot model; legacy table left for database_cleanup
+
+new model hr.employee.certification.report [abstract]
+new model hr.employee.skill.history.report [abstract]
+new model hr.individual.skill.mixin [abstract]
+new model hr.job.skill
+
+# NOTHING TO DO: new models; abstract ones have no table, hr.job.skill is ORM-created and computed
+
+---Fields in module 'hr_skills'---
+hr_recruitment_skills / hr.job                   / skill_ids (many2many)         : now a function
+
+# NOTHING TO DO: skill_ids is now computed from the new job_skill_ids
+
+hr_skills    / hr.employee              / certification_ids (one2many)  : NEW relation: hr.employee.skill, hasdefault: compute, stored: False
+hr_skills    / hr.employee              / current_employee_skill_ids (one2many): NEW relation: hr.employee.skill, hasdefault: compute, stored: False
+hr_skills    / hr.employee.skill        / display_warning_message (boolean): NEW
+hr_skills    / hr.employee.skill        / valid_from (date)             : NEW hasdefault: default
+hr_skills    / hr.employee.skill        / valid_to (date)               : NEW
+
+# NOTHING TO DO: new fields (computed non-stored, or new validity range with defaults)
+
+hr_skills    / hr.employee.skill.log    / date (date)                   : DEL
+hr_skills    / hr.employee.skill.log    / department_id (many2one)      : DEL relation: hr.department
+hr_skills    / hr.employee.skill.log    / employee_id (many2one)        : DEL relation: hr.employee, required
+hr_skills    / hr.employee.skill.log    / level_progress (integer)      : DEL
+hr_skills    / hr.employee.skill.log    / skill_id (many2one)           : DEL relation: hr.skill, required
+hr_skills    / hr.employee.skill.log    / skill_level_id (many2one)     : DEL relation: hr.skill.level, required
+hr_skills    / hr.employee.skill.log    / skill_type_id (many2one)      : DEL relation: hr.skill.type, required
+
+# NOTHING TO DO: fields of the obsolete hr.employee.skill.log; left for database_cleanup
+
+hr_skills    / hr.job                   / current_job_skill_ids (one2many): NEW relation: hr.job.skill, hasdefault: compute, stored: False
+hr_skills    / hr.job                   / job_skill_ids (one2many)      : NEW relation: hr.job.skill
+hr_skills    / hr.job                   / skill_ids (many2many)         : previously in module hr_recruitment_skills
+
+# NOTHING TO DO
+
+hr_skills    / hr.job.skill             / display_warning_message (boolean): NEW
+hr_skills    / hr.job.skill             / job_id (many2one)             : NEW relation: hr.job, required
+hr_skills    / hr.job.skill             / skill_id (many2one)           : NEW relation: hr.skill, required, hasdefault: compute
+hr_skills    / hr.job.skill             / skill_level_id (many2one)     : NEW relation: hr.skill.level, required, hasdefault: compute
+hr_skills    / hr.job.skill             / skill_type_id (many2one)      : NEW relation: hr.skill.type, required, hasdefault: default
+hr_skills    / hr.job.skill             / valid_from (date)             : NEW hasdefault: default
+hr_skills    / hr.job.skill             / valid_to (date)               : NEW
+
+# NOTHING TO DO: new model hr.job.skill, created empty and populated by its own compute
+
+hr_skills    / hr.resume.line           / certificate_file (binary)     : NEW attachment: True
+hr_skills    / hr.resume.line           / certificate_filename (char)   : NEW
+hr_skills    / hr.resume.line           / course_type (selection)       : NEW required, selection_keys: ['external'], hasdefault: default
+hr_skills    / hr.resume.line           / department_id (many2one)      : previously in module hr_skills_survey
+hr_skills    / hr.resume.line           / display_type (selection)      : DEL selection_keys: ['classic']
+hr_skills    / hr.resume.line           / duration (integer)            : NEW
+hr_skills    / hr.resume.line           / external_url (char)           : NEW hasdefault: compute
+hr_skills    / hr.resume.line           / resume_line_properties (properties): NEW hasdefault: compute
+
+# NOTHING TO DO: new fields with defaults/compute; display_type removed (not renamed to course_type — different selection domains), column left for database_cleanup
+
+hr_skills    / hr.resume.line.type      / is_course (boolean)           : NEW hasdefault: default
+hr_skills    / hr.resume.line.type      / resume_line_type_properties_definition (properties_definition): NEW
+
+# NOTHING TO DO
+
+hr_skills    / hr.skill.level           / _order                        : _order is now 'level_progress' ('level_progress desc')
+hr_skills    / hr.skill.level           / technical_is_new_default (boolean): NEW hasdefault: compute, stored: False
+
+# NOTHING TO DO
+
+hr_skills    / hr.skill.type            / _order                        : _order is now 'sequence, name' ('name')
+hr_skills    / hr.skill.type            / is_certification (boolean)    : NEW
+hr_skills    / hr.skill.type            / levels_count (integer)        : NEW hasdefault: compute
+hr_skills    / hr.skill.type            / sequence (integer)            : NEW
+
+# NOTHING TO DO: new fields; levels_count is recomputed by the ORM
+
+hr_skills    / res.users                / employee_skill_ids (one2many) : module is now 'project_hr_skills' ('hr_skills')
+hr_skills_survey / hr.resume.line           / department_id (many2one)      : not stored anymore
+
+# NOTHING TO DO
+
+---XML records in module 'hr_skills'---
+NEW hr.resume.line.type: hr_skills.resume_type_training [renamed from hr_skills_slides module]
+DEL hr.resume.line.type: hr_skills.resume_type_social_media
+NEW ir.actions.act_window: hr_skills.action_hr_employee_skill_certification
+NEW ir.actions.act_window: hr_skills.hr_employee_certification_report_action [renamed from hr_skills_survey module] (deleted domain)
+NEW ir.actions.act_window: hr_skills.hr_resume_lines_training_action
+DEL ir.actions.act_window: hr_skills.action_hr_employee_skill_log_employee
+NEW ir.cron: hr_skills.hr_job_skills_cron_add_certification_activity_to_employees
+NEW ir.model.access: hr_skills.access_hr_employee_certification_report_user
+NEW ir.model.access: hr_skills.access_hr_employee_skill_history_report
+NEW ir.model.access: hr_skills.access_hr_employee_skill_history_report_manager
+NEW ir.model.access: hr_skills.access_hr_job_skill
+NEW ir.model.access: hr_skills.access_hr_job_skill_employee
+DEL ir.model.access: hr_skills.access_hr_employee_skill_log
+DEL ir.model.access: hr_skills.access_hr_employee_skill_log_manager
+DEL ir.model.constraint: hr_skills.constraint_hr_employee_skill__unique_skill
+DEL ir.model.constraint: hr_skills.constraint_hr_employee_skill_log__unique_skill_log
+NEW ir.rule: hr_skills.hr_employee_skill_history_report_hr_user (noupdate)
+NEW ir.rule: hr_skills.hr_employee_skill_history_report_manager (noupdate)
+NEW ir.ui.menu: hr_skills.hr_certification_menu
+NEW ir.ui.menu: hr_skills.hr_employee_certification_report_menu
+NEW ir.ui.menu: hr_skills.hr_employee_skill_inventory_report_menu
+NEW ir.ui.menu: hr_skills.hr_skill_learning_menu
+NEW ir.ui.menu: hr_skills.menu_learnings_training_attendances
+NEW ir.ui.view: hr_skills.employee_skill_view_inherit_certificate_form
+NEW ir.ui.view: hr_skills.hr_employee_certification_report_view_list
+NEW ir.ui.view: hr_skills.hr_employee_certification_report_view_pivot
+NEW ir.ui.view: hr_skills.hr_employee_certification_report_view_search
+NEW ir.ui.view: hr_skills.hr_employee_skill_history_report_view_graph
+NEW ir.ui.view: hr_skills.hr_employee_skill_history_report_view_search
+NEW ir.ui.view: hr_skills.hr_employee_skill_view_list
+NEW ir.ui.view: hr_skills.hr_employee_skill_view_search
+NEW ir.ui.view: hr_skills.hr_job_skill_view_form
+NEW ir.ui.view: hr_skills.hr_resume_line_calendar_view
+NEW ir.ui.view: hr_skills.hr_resume_line_kanban_view
+NEW ir.ui.view: hr_skills.hr_resume_line_list_view
+NEW ir.ui.view: hr_skills.resume_line_view_form_inherit
+NEW ir.ui.view: hr_skills.view_hr_job_form
+NEW ir.ui.view: hr_skills.view_resume_lines_filter
+DEL ir.ui.view: hr_skills.hr_employee_skill_log_view_graph_department
+DEL ir.ui.view: hr_skills.hr_employee_skill_log_view_graph_employee
+DEL ir.ui.view: hr_skills.hr_employee_skill_log_view_search
+DEL ir.ui.view: hr_skills.hr_employee_skill_log_view_tree
+DEL ir.ui.view: hr_skills.res_users_view_form
+NEW mail.activity.type: hr_skills.mail_activity_data_upload_certification (noupdate)
+
+# NOTHING TO DO: new/removed framework records handled by module update; noupdate xmlid reassignments loaded via noupdate_changes.xml
