Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docsource/modules150-160.rst
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ Module coverage 15.0 -> 16.0
+-------------------------------------------------+----------------------+-------------------------------------------------+
| product_matrix | | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| project | | |
| project | Done | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| |del| project_account | | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
Expand Down
18 changes: 18 additions & 0 deletions openupgrade_scripts/scripts/project/16.0.1.2/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 Trần Trường Sơn
# Copyright 2023 Rémy Taymans
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade

_translations_to_delete = [
"mail_template_data_project_task",
"project_manager_all_project_tasks_rule",
"project_message_user_assigned",
"rating_project_request_email_template",
]


@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(env.cr, "project", "16.0.1.2/noupdate_changes.xml")
openupgrade.delete_record_translations(env.cr, "project", _translations_to_delete)
170 changes: 170 additions & 0 deletions openupgrade_scripts/scripts/project/16.0.1.2/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Copyright 2023 Trần Trường Sơn
# Copyright 2023 Rémy Taymans
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade

_new_fields = [
(
"is_closed", # Field name
"project.task", # Model name
"project_task", # Table name
"boolean", # Odoo Field type (in lower case)
False, # [Optional] SQL type (if custom fields)
"project", # Module name
False, # [Optional] Default value
),
(
"ancestor_id", # Field name
"project.task", # Model name
"project_task", # Table name
"many2one", # Odoo Field type (in lower case)
False, # [Optional] SQL type (if custom fields)
"project", # Module name
False, # [Optional] Default value
),
(
"is_analytic_account_id_changed", # Field name
"project.task", # Model name
"project_task", # Table name
"boolean", # Odoo Field type (in lower case)
False, # [Optional] SQL type (if custom fields)
"project", # Module name
False, # [Optional] Default value
),
(
"allow_milestones", # Field name
"project.project", # Model name
"project_project", # Table name
"boolean", # Odoo Field type (in lower case)
False, # [Optional] SQL type (if custom fields)
"project", # Module name
False, # [Optional] Default value
),
]


def _set_task_type_fold_if_is_closed(env):
"""Field `is_closed` on project.task.type is removed. The field
`fold` can be used instead.
"""
openupgrade.logged_query(
env.cr,
"""
UPDATE project_task_type
SET fold = TRUE
WHERE is_closed = TRUE;
""",
)


def _fill_project_task_is_closed(env):
"""Field `is_closed` on project.task is now a stored field."""
openupgrade.logged_query(
env.cr,
"""
UPDATE project_task task
SET is_closed = stage.fold
FROM project_task_type stage
WHERE task.stage_id = stage.id;
""",
)


def _fill_project_last_update_status_if_null(env):
"""In some cases, the user can go to the DB and reset the
`last_update_status` field to NULL. In version 16.0 it is necessary
to reset it to `to_define` because it has a `required` attribute.
"""
openupgrade.logged_query(
env.cr,
"""
UPDATE project_project project
SET last_update_status = 'to_define'
WHERE last_update_status IS NULL;
""",
)


def _compute_project_task_ancestor_id(env):
"""
New column at version 16.0. valid as the ancestor of the current task
"""
openupgrade.logged_query(
env.cr,
"""
WITH RECURSIVE task_ancestors AS (
SELECT id, parent_id, id AS ancestor_id
FROM project_task
WHERE parent_id IS NULL

UNION ALL

SELECT pt.id, pt.parent_id, ta.ancestor_id
FROM project_task pt
INNER JOIN task_ancestors ta ON pt.parent_id = ta.id
)
UPDATE project_task pt
SET ancestor_id = ta.ancestor_id
FROM task_ancestors ta
WHERE pt.id = ta.id;

UPDATE project_task pt
SET ancestor_id = NULL
WHERE id = ancestor_id;
""",
)


def _compute_project_task_is_analytic_account_id_changed(env):
"""
`is_analytic_account_id_changed` is a new field at version 16.0.
It has a value of False if you have the same admin account as the project,
otherwise it will have a value of True
"""
openupgrade.logged_query(
env.cr,
"""
UPDATE project_task task
SET is_analytic_account_id_changed = CASE
WHEN project_id IS NOT NULL
AND task.project_id = project.id
AND task.analytic_account_id != project.analytic_account_id
THEN TRUE
ELSE FALSE
END
FROM project_project as project;
""",
)


def _fill_project_allow_milestones(env):
"""New field allow_milestones on project.project depends on the
value of the configuration (based on a group)
project.group_project_milestone.
Previously, milestone where visible by default on a project. To keep
this behaviour with existing project, allow_milestones need to be
set to True.
"""
openupgrade.logged_query(
env.cr,
"""
UPDATE project_project project
SET allow_milestones = true
""",
)


@openupgrade.migrate()
def migrate(env, version):
openupgrade.add_fields(env, _new_fields)
_set_task_type_fold_if_is_closed(env)
_fill_project_task_is_closed(env)
_fill_project_last_update_status_if_null(env)
_compute_project_task_ancestor_id(env)
_compute_project_task_is_analytic_account_id_changed(env)

# Remove SQL view project_task_burndown_chart_report not used anymore in Odoo v16.0
openupgrade.logged_query(
env.cr, "DROP VIEW IF EXISTS project_task_burndown_chart_report CASCADE"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_project_migration
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from odoo.tests import TransactionCase


class TestProjectMigration(TransactionCase):
def test_project_allow_milestones(self):
"""Test that the allow_milestones field on a project is correctly set.
On a database with demo data, project.group_project_milestone
option is set to true. So allow_milestones should be true on
projects.
"""
projects = self.env["project.project"].search([])
for project in projects:
self.assertTrue(project.allow_milestones)
101 changes: 101 additions & 0 deletions openupgrade_scripts/scripts/project/16.0.1.2/upgrade_analysis_work.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---Models in module 'project'---
obsolete model project.delete.wizard [transient]
# NOTHING TO DO: wizard removed

---Fields in module 'project'---
project / account.analytic.tag / task_ids (many2many) : DEL relation: project.task
project / project.task / analytic_tag_ids (many2many) : DEL relation: account.analytic.tag
# NOTHING TO DO: lost feature

project / project.milestone / task_ids (one2many) : NEW relation: project.task
project / project.project / task_properties_definition (properties_definition): NEW
project / project.task / task_properties (properties) : NEW hasdefault: compute
project / res.company / analytic_plan_id (many2one) : NEW relation: account.analytic.plan, hasdefault: compute
# NOTHING TO DO: new features

project / project.tags / project_ids (many2many) : NEW relation: project.project
project / project.tags / task_ids (many2many) : NEW relation: project.task
# NOTHING TO DO: reverse relation that already exists on project.project and project.task

pad_project / project.project / description_pad (char) : DEL
pad_project / project.project / use_pads (boolean) : DEL
pad_project / project.task / description_pad (char) : DEL
# TODO: Module pad_project has been removed
Comment on lines +20 to +23
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pedrobaeza I'm not sure what to do with this. Should I rename the table with a legacy name to ensure that data are not deleted ? Or should I just do nothing ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say "Nothing to do", as the content is dumped on save to the description fields, and the collaboration comes now from web editor itself.


project / project.project / allow_milestones (boolean) : NEW hasdefault: default
# DONE: pre-migration: create field and set default value.

project / project.project / last_update_status (selection): not a function anymore
project / project.project / last_update_status (selection): now required
project / project.project / last_update_status (selection): selection_keys is now '['at_risk', 'off_track', 'on_hold', 'on_track', 'to_define']' ('['at_risk', 'off_track', 'on_hold', 'on_track']')
# DONE: pre-migration: Set value of last_update_status to 'to_define' where field is empty

project / project.task.type / is_closed (boolean) : DEL
# DONE: pre-migration: Field removed, field 'fold' should be used instead. Moving values from 'is_closed' to 'fold'.

project / project.task / is_closed (boolean) : is now stored
# DONE: pre-migration: Add new column & set value for it

project / project.task / ancestor_id (many2one) : NEW relation: project.task, isfunction: function, stored
project / project.task / is_analytic_account_id_changed (boolean): NEW isfunction: function, stored
# DONE: pre-migration: pre-compute value for new computed fields

project / project.task / is_blocked (boolean) : NEW isfunction: function, stored
project / project.task / milestone_id (many2one) : NEW relation: project.milestone, hasdefault: compute
# TODO (speed improvement): pre-migration: pre-compute value for new computed fields
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this going to be done?

Copy link
Author

@remytms remytms Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'm not going to do this. I focus on getting something that works.



---XML records in module 'project'---
NEW digest.tip: project.digest_tip_project_1
NEW ir.actions.act_window: project.action_send_mail_project_project
NEW ir.actions.act_window: project.action_send_mail_project_task
NEW ir.actions.act_window: project.action_view_task_from_milestone
NEW ir.actions.act_window: project.open_view_project_all_config_group_stage
NEW ir.actions.act_window: project.project_sharing_project_task_action_sub_task
NEW ir.actions.act_window: project.project_task_action_sub_task
DEL ir.actions.act_window: project.project_milestone_all
NEW ir.actions.act_window.view: project.open_view_all_task_list_calendar
NEW ir.actions.act_window.view: project.open_view_all_task_list_kanban
NEW ir.actions.act_window.view: project.open_view_all_task_list_tree
NEW ir.actions.act_window.view: project.open_view_project_all_config_group_stage_kanban_action_view
NEW ir.actions.act_window.view: project.open_view_project_all_config_group_stage_tree_action_view
NEW ir.actions.act_window.view: project.project_all_task_activity_action_view
NEW ir.actions.act_window.view: project.project_all_task_calendar_action_view
NEW ir.actions.act_window.view: project.project_all_task_graph_action_view
NEW ir.actions.act_window.view: project.project_all_task_pivot_action_view
NEW ir.actions.act_window.view: project.project_sharing_subtasks_form_action_view
NEW ir.actions.act_window.view: project.project_sharing_subtasks_kanban_action_view
NEW ir.actions.act_window.view: project.project_sharing_subtasks_tree_action_view
NEW ir.actions.act_window.view: project.project_task_form_action_view
NEW ir.actions.act_window.view: project.project_task_kanban_action_view
NEW ir.actions.act_window.view: project.project_task_tree_action_view
NEW ir.actions.act_window.view: project.rating_rating_action_task_kanban
NEW ir.actions.act_window.view: project.rating_rating_action_view_project_rating_kanban
DEL ir.actions.server: project.unlink_project_action
NEW ir.model.access: project.access_project_task_burndown_chart_report_user
NEW ir.model.access: project.access_report_project_task_user_project_user
DEL ir.model.access: project.access_project_delete_wizard
NEW ir.rule: project.burndown_chart_project_manager_rule (noupdate)
NEW ir.rule: project.burndown_chart_project_user_rule (noupdate)
NEW ir.rule: project.report_project_task_manager_rule (noupdate)
NEW ir.rule: project.report_project_task_user_rule (noupdate)
NEW ir.ui.menu: project.menu_projects_config_group_stage
NEW ir.ui.view: project.rating_rating_project_view_kanban
NEW ir.ui.view: project.task_type_tree_inherited
NEW ir.ui.view: project.view_project_calendar
NEW ir.ui.view: project.view_project_config_kanban
NEW ir.ui.view: project.view_project_task_pivot_inherit
NEW ir.ui.view: project.view_project_task_type_unarchive_wizard
NEW ir.ui.view: project.view_task_all_calendar
NEW ir.ui.view: project.view_task_kanban_inherit_my_task
DEL ir.ui.view: pad_project.project_project_view_form
DEL ir.ui.view: pad_project.res_config_settings_view_form
DEL ir.ui.view: pad_project.view_task_form2_inherit_pad_project
DEL ir.ui.view: project.project_collaborator_view_form
DEL ir.ui.view: project.project_delete_wizard_form
DEL ir.ui.view: project.project_task_burndown_chart_report_view_pivot
NEW mail.message.subtype: project.mt_project_update_create (noupdate)
NEW mail.message.subtype: project.mt_task_progress (noupdate)
NEW mail.message.subtype: project.mt_update_create (noupdate)
NEW res.groups: project.group_project_milestone
# NOTHING TO DO