Merge pull request #511 from taigaio/Issue/3448/finished-date-not-set-correctly-in-tasks
Setting finished date correctly on tasksremotes/origin/logger
commit
25e0dc91a4
|
@ -33,6 +33,7 @@ from taiga.base.api.mixins import CreateModelMixin
|
|||
from taiga.base.api.viewsets import GenericViewSet
|
||||
from taiga.projects.models import Project, Membership
|
||||
from taiga.projects.issues.models import Issue
|
||||
from taiga.projects.tasks.models import Task
|
||||
from taiga.projects.serializers import ProjectSerializer
|
||||
|
||||
from . import mixins
|
||||
|
@ -238,6 +239,9 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
|
|||
project = self.get_object_or_none()
|
||||
self.check_permissions(request, 'import_item', project)
|
||||
|
||||
signals.pre_save.disconnect(sender=Task,
|
||||
dispatch_uid="set_finished_date_when_edit_task")
|
||||
|
||||
task = service.store_task(project, request.DATA.copy())
|
||||
|
||||
errors = service.get_errors()
|
||||
|
|
|
@ -23,6 +23,10 @@ from taiga.projects.custom_attributes import signals as custom_attributes_handle
|
|||
from . import signals as handlers
|
||||
|
||||
def connect_tasks_signals():
|
||||
# Finished date
|
||||
signals.pre_save.connect(handlers.set_finished_date_when_edit_task,
|
||||
sender=apps.get_model("tasks", "Task"),
|
||||
dispatch_uid="set_finished_date_when_edit_task")
|
||||
# Tags
|
||||
signals.pre_save.connect(generic_handlers.tags_normalization,
|
||||
sender=apps.get_model("tasks", "Task"),
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import connection, migrations, models
|
||||
|
||||
def set_finished_date_for_tasks(apps, schema_editor):
|
||||
# Updates the finished date from tasks according to the history_entries associated
|
||||
# It takes the last history change updateing the status of a task and if it's a closed
|
||||
# one it updates the finished_date attribute
|
||||
sql="""
|
||||
WITH status_update AS(
|
||||
WITH status_update AS(
|
||||
WITH history_entries AS (
|
||||
SELECT
|
||||
diff#>>'{status, 1}' new_status_id,
|
||||
regexp_split_to_array(key, ':') as split_key,
|
||||
created_at as date
|
||||
FROM history_historyentry
|
||||
WHERE diff#>>'{status, 1}' != ''
|
||||
)
|
||||
SELECT
|
||||
split_key[2] as object_id,
|
||||
new_status_id::int,
|
||||
MAX(date) as status_change_datetime
|
||||
FROM history_entries
|
||||
WHERE split_key[1] = 'tasks.task'
|
||||
GROUP BY object_id, new_status_id, date
|
||||
)
|
||||
SELECT status_update.*
|
||||
FROM status_update
|
||||
INNER JOIN projects_taskstatus
|
||||
ON projects_taskstatus.id = new_status_id AND projects_taskstatus.is_closed = True
|
||||
)
|
||||
UPDATE tasks_task
|
||||
SET finished_date = status_update.status_change_datetime
|
||||
FROM status_update
|
||||
WHERE tasks_task.id = status_update.object_id::int
|
||||
"""
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(sql)
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tasks', '0008_remove_task_watchers'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(set_finished_date_for_tasks),
|
||||
]
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
from contextlib import suppress
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils import timezone
|
||||
|
||||
####################################
|
||||
# Signals for cached prev task
|
||||
|
@ -92,3 +93,13 @@ def _try_to_close_milestone_when_delete_task(instance):
|
|||
with suppress(ObjectDoesNotExist):
|
||||
if instance.milestone_id and services.calculate_milestone_is_closed(instance.milestone):
|
||||
services.close_milestone(instance.milestone)
|
||||
|
||||
####################################
|
||||
# Signals for set finished date
|
||||
####################################
|
||||
|
||||
def set_finished_date_when_edit_task(sender, instance, **kwargs):
|
||||
if instance.status.is_closed and not instance.finished_date:
|
||||
instance.finished_date = timezone.now()
|
||||
elif not instance.status.is_closed and instance.finished_date:
|
||||
instance.finished_date = None
|
||||
|
|
Loading…
Reference in New Issue