@@ -179,7 +179,7 @@ def _read_group_personal_stage_type_ids(self, stages, domain):
179
179
help = "Date on which the state of your task has last been modified.\n "
180
180
"Based on this information you can identify tasks that are stalling and get statistics on the time it usually takes to move tasks from one stage/state to another." )
181
181
182
- project_id = fields .Many2one ('project.project' , string = 'Project' , domain = "['|', ('company_id', '=', False), ('company_id', '=?', company_id), ('is_template', '= ', is_template)]" ,
182
+ project_id = fields .Many2one ('project.project' , string = 'Project' , domain = "['|', ('company_id', '=', False), ('company_id', '=?', company_id), ('is_template', 'in ', [ is_template, False] )]" ,
183
183
compute = "_compute_project_id" , store = True , precompute = True , recursive = True , readonly = False , index = True , tracking = True , change_default = True , falsy_value_label = _lt ("🔒 Private" ))
184
184
display_in_project = fields .Boolean (compute = '_compute_display_in_project' , store = True , export_string_translation = False )
185
185
task_properties = fields .Properties ('Properties' , definition = 'project_id.task_properties_definition' , copy = True )
@@ -230,8 +230,8 @@ def _read_group_personal_stage_type_ids(self, stages, domain):
230
230
# In the domain of displayed_image_id, we couln't use attachment_ids because a one2many is represented as a list of commands so we used res_model & res_id
231
231
displayed_image_id = fields .Many2one ('ir.attachment' , domain = "[('res_model', '=', 'project.task'), ('res_id', '=', id), ('mimetype', 'ilike', 'image')]" , string = 'Cover Image' )
232
232
233
- parent_id = fields .Many2one ('project.task' , string = 'Parent Task' , inverse = "_inverse_parent_id" , index = True , domain = "[('is_template', '=', is_template), '!', ('id', 'child_of', id)]" , tracking = True )
234
- child_ids = fields .One2many ('project.task' , 'parent_id' , string = "Sub-tasks" , domain = "[('recurring_task', '=', False), ('is_template', '=', is_template) ]" , export_string_translation = False )
233
+ parent_id = fields .Many2one ('project.task' , string = 'Parent Task' , inverse = "_inverse_parent_id" , index = True , domain = "['!', ('id', 'child_of', id)]" , tracking = True )
234
+ child_ids = fields .One2many ('project.task' , 'parent_id' , string = "Sub-tasks" , domain = "[('recurring_task', '=', False)]" , export_string_translation = False )
235
235
subtask_count = fields .Integer ("Sub-task Count" , compute = '_compute_subtask_count' , export_string_translation = False )
236
236
closed_subtask_count = fields .Integer ("Closed Sub-tasks Count" , compute = '_compute_subtask_count' , export_string_translation = False )
237
237
project_privacy_visibility = fields .Selection (related = 'project_id.privacy_visibility' , string = "Project Visibility" , tracking = False )
@@ -265,12 +265,12 @@ def _read_group_personal_stage_type_ids(self, stages, domain):
265
265
# Tracking of this field is done in the write function
266
266
depend_on_ids = fields .Many2many ('project.task' , relation = "task_dependencies_rel" , column1 = "task_id" ,
267
267
column2 = "depends_on_id" , string = "Blocked By" , tracking = True , copy = False ,
268
- domain = "[('project_id', '!=', False), ('id', '!=', id), ('is_template', '=', is_template) ]" )
268
+ domain = "[('project_id', '!=', False), ('id', '!=', id)]" )
269
269
depend_on_count = fields .Integer (string = "Depending on Tasks" , compute = '_compute_depend_on_count' , compute_sudo = True )
270
270
closed_depend_on_count = fields .Integer (string = "Closed Depending on Tasks" , compute = '_compute_depend_on_count' , compute_sudo = True )
271
271
dependent_ids = fields .Many2many ('project.task' , relation = "task_dependencies_rel" , column1 = "depends_on_id" ,
272
272
column2 = "task_id" , string = "Block" , copy = False ,
273
- domain = "[('project_id', '!=', False), ('id', '!=', id), ('is_template', '=', is_template) ]" , export_string_translation = False )
273
+ domain = "[('project_id', '!=', False), ('id', '!=', id)]" , export_string_translation = False )
274
274
dependent_tasks_count = fields .Integer (string = "Dependent Tasks" , compute = '_compute_dependent_tasks_count' , export_string_translation = False )
275
275
276
276
# Project sharing fields
@@ -306,6 +306,7 @@ def _read_group_personal_stage_type_ids(self, stages, domain):
306
306
)
307
307
link_preview_name = fields .Char (compute = '_compute_link_preview_name' , export_string_translation = False )
308
308
is_template = fields .Boolean (copy = False , export_string_translation = False )
309
+ has_project_template = fields .Boolean (related = 'project_id.is_template' , string = "Has Project Template" , export_string_translation = False )
309
310
has_template_ancestor = fields .Boolean (compute = '_compute_has_template_ancestor' , search = '_search_has_template_ancestor' ,
310
311
recursive = True , export_string_translation = False )
311
312
@@ -1285,7 +1286,7 @@ def write(self, vals):
1285
1286
1286
1287
# rating on stage
1287
1288
if 'stage_id' in vals and vals .get ('stage_id' ):
1288
- self .sudo ().filtered (lambda x : x .project_id .rating_active and x .project_id .rating_status == 'stage' and not x . is_template )._send_task_rating_mail (force_send = True )
1289
+ self .sudo ().filtered (lambda x : x .project_id .rating_active and x .project_id .rating_status == 'stage' )._send_task_rating_mail (force_send = True )
1289
1290
1290
1291
if 'state' in vals :
1291
1292
# specific use case: when the blocked task goes from 'forced' done state to a not closed state, we fix the state back to waiting
@@ -1920,8 +1921,6 @@ def action_convert_to_template(self):
1920
1921
'task_id' : self .id ,
1921
1922
},
1922
1923
}
1923
- if not self .project_id .is_template :
1924
- raise UserError (self .env ._ ("Tasks in a regular project cannot be converted into task templates." ))
1925
1924
self .is_template = True
1926
1925
self .message_post (body = _ ("Task converted to template" ))
1927
1926
return {
0 commit comments