You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
11 KiB
336 lines
11 KiB
from datetime import datetime
|
|
from django.contrib.auth.decorators import login_required, permission_required
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.db.models import Count
|
|
from django.shortcuts import redirect, get_object_or_404, resolve_url
|
|
from django.contrib import messages
|
|
from django.views.generic import ListView, CreateView
|
|
from django.utils.translation import ugettext as _
|
|
from django.conf import settings
|
|
from django.views.generic.edit import FormMixin, DeleteView, UpdateView
|
|
|
|
from guardian.shortcuts import assign_perm
|
|
from abonapp.models import Abon
|
|
from djing import httpresponse_to_referrer
|
|
from djing.lib import safe_int, MultipleException, RuTimedelta
|
|
from djing.lib.decorators import only_admins
|
|
from djing.lib.mixins import LoginAdminMixin, LoginAdminPermissionMixin
|
|
from .handle import TaskException
|
|
from .models import Task, ExtraComment
|
|
from .forms import TaskFrm, ExtraCommentForm
|
|
|
|
|
|
class NewTasksView(LoginAdminPermissionMixin, ListView):
|
|
"""
|
|
Show new tasks
|
|
"""
|
|
http_method_names = ('get',)
|
|
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
|
|
template_name = 'taskapp/tasklist.html'
|
|
context_object_name = 'tasks'
|
|
permission_required = 'taskapp.view_task'
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.filter(
|
|
recipients=self.request.user, state='S'
|
|
).annotate(
|
|
comment_count=Count('extracomment')
|
|
).select_related(
|
|
'abon', 'abon__street', 'abon__group', 'author'
|
|
)
|
|
|
|
|
|
class FailedTasksView(NewTasksView):
|
|
"""
|
|
Show crashed tasks
|
|
"""
|
|
template_name = 'taskapp/tasklist_failed.html'
|
|
context_object_name = 'tasks'
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.filter(
|
|
recipients=self.request.user, state='C'
|
|
).select_related(
|
|
'abon', 'abon__street', 'abon__group', 'author'
|
|
)
|
|
|
|
|
|
class FinishedTaskListView(NewTasksView):
|
|
template_name = 'taskapp/tasklist_finish.html'
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.filter(
|
|
recipients=self.request.user, state='F'
|
|
).select_related(
|
|
'abon', 'abon__street', 'abon__group', 'author'
|
|
)
|
|
|
|
|
|
class OwnTaskListView(NewTasksView):
|
|
template_name = 'taskapp/tasklist_own.html'
|
|
|
|
def get_queryset(self):
|
|
# Attached and not finished tasks
|
|
return Task.objects.filter(
|
|
author=self.request.user
|
|
).exclude(state='F').select_related(
|
|
'abon', 'abon__street', 'abon__group'
|
|
)
|
|
|
|
|
|
class MyTaskListView(NewTasksView):
|
|
template_name = 'taskapp/tasklist.html'
|
|
|
|
def get_queryset(self):
|
|
# Tasks in which I participated
|
|
return Task.objects.filter(
|
|
recipients=self.request.user
|
|
).select_related(
|
|
'abon', 'abon__street', 'abon__group', 'author'
|
|
)
|
|
|
|
|
|
class AllTasksListView(LoginAdminMixin, LoginRequiredMixin, ListView):
|
|
http_method_names = ('get',)
|
|
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
|
|
template_name = 'taskapp/tasklist_all.html'
|
|
context_object_name = 'tasks'
|
|
permission_required = 'taskapp.can_viewall'
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.annotate(
|
|
comment_count=Count('extracomment')
|
|
).select_related(
|
|
'abon', 'abon__street', 'abon__group', 'author'
|
|
)
|
|
|
|
|
|
class AllNewTasksListView(AllTasksListView):
|
|
|
|
def get_queryset(self):
|
|
return super(AllNewTasksListView, self).get_queryset().filter(state='S')
|
|
|
|
|
|
class EmptyTasksListView(NewTasksView):
|
|
template_name = 'taskapp/tasklist_empty.html'
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.annotate(
|
|
reccount=Count('recipients')
|
|
).filter(reccount__lt=1)
|
|
|
|
|
|
@login_required
|
|
@only_admins
|
|
@permission_required('taskapp.delete_task')
|
|
def task_delete(request, task_id):
|
|
task = get_object_or_404(Task, id=task_id)
|
|
# prevent to delete task that assigned to me
|
|
if request.user.is_superuser or request.user not in task.recipients.all():
|
|
task.delete()
|
|
else:
|
|
messages.warning(
|
|
request, _('You cannot delete task that assigned to you')
|
|
)
|
|
return redirect('taskapp:home')
|
|
|
|
|
|
class TaskUpdateView(LoginAdminMixin, UpdateView):
|
|
http_method_names = ('get', 'post')
|
|
template_name = 'taskapp/add_edit_task.html'
|
|
form_class = TaskFrm
|
|
context_object_name = 'task'
|
|
|
|
def get_object(self, queryset=None):
|
|
task_id = safe_int(self.kwargs.get('task_id'))
|
|
if task_id == 0:
|
|
uname = self.request.GET.get('uname')
|
|
if uname:
|
|
self.selected_abon = Abon.objects.get(username=uname)
|
|
return
|
|
else:
|
|
task = get_object_or_404(Task, pk=task_id)
|
|
self.selected_abon = task.abon
|
|
return task
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
task_id = safe_int(self.kwargs.get('task_id', 0))
|
|
if task_id == 0:
|
|
if not request.user.has_perm('taskapp.add_task'):
|
|
raise PermissionDenied
|
|
else:
|
|
if not request.user.has_perm('taskapp.change_task'):
|
|
raise PermissionDenied
|
|
|
|
# check if new task with user already exists
|
|
uname = request.GET.get('uname')
|
|
if uname and self.kwargs.get('task_id') is None:
|
|
exists_task = Task.objects.filter(abon__username=uname, state='S')
|
|
if exists_task.exists():
|
|
messages.info(request, _('New task with this user already exists.'
|
|
' You are redirected to it.'))
|
|
return redirect('taskapp:edit', exists_task.first().pk)
|
|
|
|
try:
|
|
return super(TaskUpdateView, self).dispatch(request, *args, **kwargs)
|
|
except TaskException as e:
|
|
messages.error(request, e)
|
|
return httpresponse_to_referrer(request)
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(TaskUpdateView, self).get_form_kwargs()
|
|
if hasattr(self, 'selected_abon'):
|
|
kwargs.update({'initial_abon': self.selected_abon})
|
|
return kwargs
|
|
|
|
def form_valid(self, form):
|
|
# check if new task with picked user already exists
|
|
if form.cleaned_data['state'] == 'S' and self.kwargs.get('task_id') is None:
|
|
exists_task = Task.objects.filter(abon=form.cleaned_data['abon'], state='S')
|
|
if exists_task.exists():
|
|
messages.info(self.request, _('New task with this user already exists.'
|
|
' You are redirected to it.'))
|
|
return redirect('taskapp:edit', exists_task.first().pk)
|
|
|
|
try:
|
|
self.object = form.save()
|
|
if self.object.author is None:
|
|
self.object.author = self.request.user
|
|
self.object.save(update_fields=('author',))
|
|
task_id = safe_int(self.kwargs.get('task_id', 0))
|
|
if task_id == 0:
|
|
log_text = _('Task has successfully created')
|
|
else:
|
|
log_text = _('Task has changed successfully')
|
|
messages.add_message(self.request, messages.SUCCESS, log_text)
|
|
self.object.send_notification()
|
|
except MultipleException as e:
|
|
for err in e.err_list:
|
|
messages.add_message(self.request, messages.WARNING, err)
|
|
except TaskException as e:
|
|
messages.add_message(self.request, messages.ERROR, e)
|
|
return FormMixin.form_valid(self, form)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
if hasattr(self, 'selected_abon'):
|
|
selected_abon = self.selected_abon
|
|
else:
|
|
selected_abon = None
|
|
|
|
now_date = datetime.now().date()
|
|
task = self.object
|
|
if task:
|
|
if task.out_date > now_date:
|
|
time_diff = "%s: %s" % (_('time left'), RuTimedelta(task.out_date - now_date))
|
|
else:
|
|
time_diff = _("Expired timeout -%(time_left)s") % {
|
|
'time_left': RuTimedelta(now_date - task.out_date)
|
|
}
|
|
else:
|
|
time_diff = None
|
|
|
|
context = {
|
|
'selected_abon': selected_abon,
|
|
'time_diff': time_diff,
|
|
'comments': ExtraComment.objects.filter(task=task),
|
|
'comment_form': ExtraCommentForm()
|
|
}
|
|
context.update(kwargs)
|
|
return super(TaskUpdateView, self).get_context_data(**context)
|
|
|
|
def get_success_url(self):
|
|
task_id = safe_int(self.kwargs.get('task_id'))
|
|
if task_id == 0:
|
|
return resolve_url('taskapp:own_tasks')
|
|
else:
|
|
return resolve_url('taskapp:edit', task_id)
|
|
|
|
def form_invalid(self, form):
|
|
messages.add_message(
|
|
self.request, messages.ERROR,
|
|
_('fix form errors')
|
|
)
|
|
return super(TaskUpdateView, self).form_invalid(form)
|
|
|
|
|
|
@login_required
|
|
@only_admins
|
|
def task_finish(request, task_id):
|
|
try:
|
|
task = get_object_or_404(Task, id=task_id)
|
|
task.finish(request.user)
|
|
task.send_notification()
|
|
except MultipleException as errs:
|
|
for err in errs.err_list:
|
|
messages.add_message(request, messages.constants.ERROR, err)
|
|
except TaskException as e:
|
|
messages.error(request, e)
|
|
return redirect('taskapp:home')
|
|
|
|
|
|
@login_required
|
|
@only_admins
|
|
def task_failed(request, task_id):
|
|
try:
|
|
task = get_object_or_404(Task, id=task_id)
|
|
task.do_fail(request.user)
|
|
task.send_notification()
|
|
except TaskException as e:
|
|
messages.error(request, e)
|
|
return redirect('taskapp:home')
|
|
|
|
|
|
@login_required
|
|
@only_admins
|
|
@permission_required('taskapp.can_remind')
|
|
def remind(request, task_id):
|
|
try:
|
|
task = get_object_or_404(Task, id=task_id)
|
|
task.save(update_fields=('state',))
|
|
task.send_notification()
|
|
messages.success(request, _('Task has been reminded'))
|
|
except MultipleException as errs:
|
|
for err in errs.err_list:
|
|
messages.add_message(request, messages.constants.ERROR, err)
|
|
except TaskException as e:
|
|
messages.error(request, e)
|
|
return redirect('taskapp:home')
|
|
|
|
|
|
class NewCommentView(LoginAdminMixin, LoginRequiredMixin, CreateView):
|
|
form_class = ExtraCommentForm
|
|
model = ExtraComment
|
|
http_method_names = ('get', 'post')
|
|
permission_required = 'taskapp.add_extracomment'
|
|
|
|
def form_valid(self, form):
|
|
self.task = get_object_or_404(Task, pk=self.kwargs.get('task_id'))
|
|
self.object = form.make_save(
|
|
author=self.request.user,
|
|
task=self.task
|
|
)
|
|
author = self.object.author
|
|
assign_perm('taskapp.change_extracomment', author, self.object)
|
|
assign_perm('taskapp.delete_extracomment', author, self.object)
|
|
assign_perm('taskapp.view_extracomment', author, self.object)
|
|
return FormMixin.form_valid(self, form)
|
|
|
|
|
|
class DeleteCommentView(LoginAdminPermissionMixin, DeleteView):
|
|
model = ExtraComment
|
|
pk_url_kwarg = 'comment_id'
|
|
http_method_names = ('get', 'post')
|
|
template_name = 'taskapp/comments/extracomment_confirm_delete.html'
|
|
permission_required = 'taskapp.delete_extracomment'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = {
|
|
'task_id': self.kwargs.get('task_id')
|
|
}
|
|
context.update(kwargs)
|
|
return super(DeleteCommentView, self).get_context_data(**context)
|
|
|
|
def get_success_url(self):
|
|
task_id = self.kwargs.get('task_id')
|
|
return resolve_url('taskapp:edit', task_id)
|