Add update issue milestone in bulk
parent
bfdff0af24
commit
0d50c16ed4
|
@ -28,6 +28,7 @@ from taiga.base.api.mixins import BlockedByProjectMixin
|
||||||
from taiga.base.api.utils import get_object_or_404
|
from taiga.base.api.utils import get_object_or_404
|
||||||
|
|
||||||
from taiga.projects.history.mixins import HistoryResourceMixin
|
from taiga.projects.history.mixins import HistoryResourceMixin
|
||||||
|
from taiga.projects.milestones.models import Milestone
|
||||||
from taiga.projects.mixins.by_ref import ByRefMixin
|
from taiga.projects.mixins.by_ref import ByRefMixin
|
||||||
from taiga.projects.models import Project, IssueStatus, Severity, Priority, IssueType
|
from taiga.projects.models import Project, IssueStatus, Severity, Priority, IssueType
|
||||||
from taiga.projects.notifications.mixins import AssignedToSignalMixin
|
from taiga.projects.notifications.mixins import AssignedToSignalMixin
|
||||||
|
@ -252,6 +253,22 @@ class IssueViewSet(AssignedToSignalMixin, OCCResourceMixin, VotedResourceMixin,
|
||||||
|
|
||||||
return response.BadRequest(validator.errors)
|
return response.BadRequest(validator.errors)
|
||||||
|
|
||||||
|
@list_route(methods=["POST"])
|
||||||
|
def bulk_update_milestone(self, request, **kwargs):
|
||||||
|
validator = validators.UpdateMilestoneBulkValidator(data=request.DATA)
|
||||||
|
if not validator.is_valid():
|
||||||
|
return response.BadRequest(validator.errors)
|
||||||
|
|
||||||
|
data = validator.data
|
||||||
|
project = get_object_or_404(Project, pk=data["project_id"])
|
||||||
|
milestone = get_object_or_404(Milestone, pk=data["milestone_id"])
|
||||||
|
|
||||||
|
self.check_permissions(request, "bulk_update_milestone", project)
|
||||||
|
|
||||||
|
ret = services.update_tasks_milestone_in_bulk(data["bulk_issues"], milestone)
|
||||||
|
|
||||||
|
return response.Ok(ret)
|
||||||
|
|
||||||
|
|
||||||
class IssueVotersViewSet(VotersViewSetMixin, ModelListViewSet):
|
class IssueVotersViewSet(VotersViewSetMixin, ModelListViewSet):
|
||||||
permission_classes = (permissions.IssueVotersPermission,)
|
permission_classes = (permissions.IssueVotersPermission,)
|
||||||
|
|
|
@ -35,6 +35,7 @@ class IssuePermission(TaigaResourcePermission):
|
||||||
filters_data_perms = AllowAny()
|
filters_data_perms = AllowAny()
|
||||||
csv_perms = AllowAny()
|
csv_perms = AllowAny()
|
||||||
bulk_create_perms = HasProjectPerm('add_issue')
|
bulk_create_perms = HasProjectPerm('add_issue')
|
||||||
|
bulk_update_milestone_perms = HasProjectPerm('modify_issue')
|
||||||
delete_comment_perms= HasProjectPerm('modify_issue')
|
delete_comment_perms= HasProjectPerm('modify_issue')
|
||||||
upvote_perms = IsAuthenticated() & HasProjectPerm('view_issues')
|
upvote_perms = IsAuthenticated() & HasProjectPerm('view_issues')
|
||||||
downvote_perms = IsAuthenticated() & HasProjectPerm('view_issues')
|
downvote_perms = IsAuthenticated() & HasProjectPerm('view_issues')
|
||||||
|
|
|
@ -26,6 +26,9 @@ from django.db import connection
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from taiga.base.utils import db, text
|
from taiga.base.utils import db, text
|
||||||
|
from taiga.events import events
|
||||||
|
|
||||||
|
from taiga.projects.history.services import take_snapshot
|
||||||
from taiga.projects.issues.apps import (
|
from taiga.projects.issues.apps import (
|
||||||
connect_issues_signals,
|
connect_issues_signals,
|
||||||
disconnect_issues_signals)
|
disconnect_issues_signals)
|
||||||
|
@ -72,6 +75,33 @@ def create_issues_in_bulk(bulk_data, callback=None, precall=None, **additional_f
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
def snapshot_issues_in_bulk(bulk_data, user):
|
||||||
|
for issue_data in bulk_data:
|
||||||
|
try:
|
||||||
|
issue = models.Issue.objects.get(pk=issue_data['issue_id'])
|
||||||
|
take_snapshot(issue, user=user)
|
||||||
|
except models.Issue.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def update_tasks_milestone_in_bulk(bulk_data: list, milestone: object):
|
||||||
|
"""
|
||||||
|
Update the milestone some issues adding
|
||||||
|
`bulk_data` should be a list of dicts with the following format:
|
||||||
|
[{'task_id': <value>}, ...]
|
||||||
|
"""
|
||||||
|
issue_milestones = {e["issue_id"]: milestone.id for e in bulk_data}
|
||||||
|
issue_ids = issue_milestones.keys()
|
||||||
|
|
||||||
|
events.emit_event_for_ids(ids=issue_ids,
|
||||||
|
content_type="issues.issues",
|
||||||
|
projectid=milestone.project.pk)
|
||||||
|
|
||||||
|
db.update_attr_in_bulk_for_ids(issue_milestones, "milestone_id",
|
||||||
|
model=models.Issue)
|
||||||
|
|
||||||
|
return issue_milestones
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# CSV
|
# CSV
|
||||||
#####################################################
|
#####################################################
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
|
|
||||||
from taiga.base.api import serializers
|
from taiga.base.api import serializers
|
||||||
from taiga.base.api import validators
|
from taiga.base.api import validators
|
||||||
|
from taiga.base.exceptions import ValidationError
|
||||||
from taiga.base.fields import PgArrayField
|
from taiga.base.fields import PgArrayField
|
||||||
|
from taiga.projects.milestones.models import Milestone
|
||||||
from taiga.projects.mixins.validators import AssignedToValidator
|
from taiga.projects.mixins.validators import AssignedToValidator
|
||||||
from taiga.projects.notifications.mixins import EditableWatchedResourceSerializer
|
from taiga.projects.notifications.mixins import EditableWatchedResourceSerializer
|
||||||
from taiga.projects.notifications.validators import WatchersValidator
|
from taiga.projects.notifications.validators import WatchersValidator
|
||||||
|
@ -43,3 +45,35 @@ class IssuesBulkValidator(ProjectExistsValidator, validators.Validator):
|
||||||
project_id = serializers.IntegerField()
|
project_id = serializers.IntegerField()
|
||||||
milestone_id = serializers.IntegerField(required=False)
|
milestone_id = serializers.IntegerField(required=False)
|
||||||
bulk_issues = serializers.CharField()
|
bulk_issues = serializers.CharField()
|
||||||
|
|
||||||
|
|
||||||
|
# Milestone bulk validators
|
||||||
|
|
||||||
|
class _IssueMilestoneBulkValidator(validators.Validator):
|
||||||
|
issue_id = serializers.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateMilestoneBulkValidator(ProjectExistsValidator, validators.Validator):
|
||||||
|
project_id = serializers.IntegerField()
|
||||||
|
milestone_id = serializers.IntegerField()
|
||||||
|
bulk_issues = _IssueMilestoneBulkValidator(many=True)
|
||||||
|
|
||||||
|
def validate_milestone_id(self, attrs, source):
|
||||||
|
filters = {
|
||||||
|
"project__id": attrs["project_id"],
|
||||||
|
"id": attrs[source]
|
||||||
|
}
|
||||||
|
if not Milestone.objects.filter(**filters).exists():
|
||||||
|
raise ValidationError(_("The milestone isn't valid for the project"))
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
def validate_bulk_tasks(self, attrs, source):
|
||||||
|
filters = {
|
||||||
|
"project__id": attrs["project_id"],
|
||||||
|
"id__in": [issue["issue_id"] for issue in attrs[source]]
|
||||||
|
}
|
||||||
|
|
||||||
|
if models.Issue.objects.filter(**filters).count() != len(filters["id__in"]):
|
||||||
|
raise ValidationError(_("All the issues must be from the same project"))
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
|
@ -120,7 +120,6 @@ def update_tasks_milestone_in_bulk(bulk_data: list, milestone: object):
|
||||||
[{'task_id': <value>, 'order': <value>}, ...]
|
[{'task_id': <value>, 'order': <value>}, ...]
|
||||||
"""
|
"""
|
||||||
tasks = milestone.tasks.all()
|
tasks = milestone.tasks.all()
|
||||||
print('taskss', tasks)
|
|
||||||
task_orders = {task.id: getattr(task, "taskboard_order") for task in tasks}
|
task_orders = {task.id: getattr(task, "taskboard_order") for task in tasks}
|
||||||
new_task_orders = {}
|
new_task_orders = {}
|
||||||
for e in bulk_data:
|
for e in bulk_data:
|
||||||
|
|
Loading…
Reference in New Issue