diff --git a/addons/hr_timesheet/__init__.py b/addons/hr_timesheet/__init__.py index 6aab6c417a5..0fa9235b104 100644 --- a/addons/hr_timesheet/__init__.py +++ b/addons/hr_timesheet/__init__.py @@ -11,6 +11,11 @@ from odoo import api, fields, SUPERUSER_ID, _ def create_internal_project(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) + + # allow_timesheets is set by default, but erased for existing projects at + # installation, as there is no analytic account for them. + env['project.project'].search([]).write({'allow_timesheets': True}) + admin = env.ref('base.user_admin', raise_if_not_found=False) if not admin: return diff --git a/addons/project/models/res_config_settings.py b/addons/project/models/res_config_settings.py index 1831c1cd0ca..ae12e7efb23 100644 --- a/addons/project/models/res_config_settings.py +++ b/addons/project/models/res_config_settings.py @@ -14,6 +14,20 @@ class ResConfigSettings(models.TransientModel): group_project_recurring_tasks = fields.Boolean("Recurring Tasks", implied_group="project.group_project_recurring_tasks") def set_values(self): - if self.user_has_groups('project.group_project_recurring_tasks') != self.group_project_recurring_tasks: - self.env['project.project'].sudo().search([]).write({'allow_recurring_tasks': self.group_project_recurring_tasks}) + + # Ensure that settings on existing projects match the above fields + projects = self.env["project.project"].search([]) + features = ( + # Pairs of associated (config_flag, project_flag) + ("group_subtask_project", "allow_subtasks"), + ("group_project_rating", "rating_active"), + ("group_project_recurring_tasks", "allow_recurring_tasks"), + ) + for (config_flag, project_flag) in features: + config_flag_global = "project." + config_flag + config_feature_enabled = self[config_flag] + if (self.user_has_groups(config_flag_global) + is not config_feature_enabled): + projects[project_flag] = config_feature_enabled + super(ResConfigSettings, self).set_values() diff --git a/addons/project/tests/__init__.py b/addons/project/tests/__init__.py index aadb3c31f42..d5c89ac7b9d 100644 --- a/addons/project/tests/__init__.py +++ b/addons/project/tests/__init__.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- -from . import test_project_base, test_project_flow, test_access_rights, test_project_recurrence, test_project_ui +from . import test_access_rights +from . import test_project_base +from . import test_project_config +from . import test_project_flow +from . import test_project_recurrence +from . import test_project_ui from . import test_multicompany diff --git a/addons/project/tests/test_project_config.py b/addons/project/tests/test_project_config.py new file mode 100644 index 00000000000..e84c648aa22 --- /dev/null +++ b/addons/project/tests/test_project_config.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +import logging + +from .test_project_base import TestProjectCommon + +_logger = logging.getLogger(__name__) + + +class TestProjectConfig(TestProjectCommon): + """Test module configuration and its effects on projects.""" + + @classmethod + def setUpClass(cls): + super(TestProjectConfig, cls).setUpClass() + cls.Project = cls.env["project.project"] + cls.Settings = cls.env["res.config.settings"] + cls.features = ( + # Pairs of associated (config_flag, project_flag) + ("group_subtask_project", "allow_subtasks"), + ("group_project_recurring_tasks", "allow_recurring_tasks"), + ("group_project_rating", "rating_active"), + ) + + # Start with a known value on feature flags to ensure validity of tests + cls._set_feature_status(is_enabled=False) + + @classmethod + def _set_feature_status(cls, is_enabled): + """Set enabled/disabled status of all optional features in the + project app config to is_enabled (boolean). + """ + features_config = cls.Settings.create( + {feature[0]: is_enabled for feature in cls.features}) + features_config.execute() + + def test_existing_projects_enable_features(self): + """Check that *existing* projects have features enabled when + the user enables them in the module configuration. + """ + self._set_feature_status(is_enabled=True) + for config_flag, project_flag in self.features: + self.assertTrue( + self.project_pigs[project_flag], + "Existing project failed to adopt activation of " + f"{config_flag}/{project_flag} feature") + + def test_new_projects_enable_features(self): + """Check that after the user enables features in the module + configuration, *newly created* projects have those features + enabled as well. + """ + self._set_feature_status(is_enabled=True) + project_cows = self.Project.create({ + "name": "Cows", + "partner_id": self.partner_1.id}) + for config_flag, project_flag in self.features: + self.assertTrue( + project_cows[project_flag], + f"Newly created project failed to adopt activation of " + f"{config_flag}/{project_flag} feature")