Source code for shuup.tasks.admin_module.views.edit
# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals
from django.contrib import messages
from django.db.models import Q
from django.db.transaction import atomic
from django.forms.models import ModelForm
from django.http.response import HttpResponseNotAllowed, HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DeleteView
from django.views.generic.detail import BaseDetailView
from shuup.admin.forms.widgets import QuickAddRelatedObjectSelect
from shuup.admin.shop_provider import get_shop
from shuup.admin.toolbar import PostActionButton, get_default_edit_toolbar
from shuup.admin.utils.views import CreateOrUpdateView
from shuup.core.models import Contact, get_person_contact
from shuup.tasks.models import Task, TaskComment, TaskStatus, TaskType
from shuup.utils.analog import LogEntryKind
from shuup.utils.django_compat import reverse_lazy
from shuup.utils.form_group import FormGroup
from shuup.utils.multilanguage_model_form import MultiLanguageModelForm
[docs]class QuickAddTaskTypeSelect(QuickAddRelatedObjectSelect):
url = reverse_lazy("shuup_admin:task_type.new")
[docs]class TaskTypeForm(MultiLanguageModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(TaskTypeForm, self).__init__(*args, **kwargs)
[docs] def save(self, **kwargs):
if not self.instance.pk:
self.instance.shop = get_shop(self.request)
return super(TaskTypeForm, self).save(**kwargs)
[docs]class TaskForm(ModelForm):
[docs] class Meta:
model = Task
exclude = ("shop", "created_on", "modified_on", "status", "completed_on", "completed_by", "creator")
widgets = {"type": QuickAddTaskTypeSelect(editable_model="shuup_tasks.TaskType")}
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(TaskForm, self).__init__(*args, **kwargs)
shop = get_shop(self.request)
self.fields["assigned_to"].queryset = Contact.objects.filter(
Q(shops=shop) | Q(id__in=shop.staff_members.values_list("id"))
).distinct()
self.fields["assigned_to"].widget.editable_model = "shuup.Contact"
[docs] def save(self, **kwargs):
is_new = not self.instance.pk
old_assigned = None
if not is_new:
old_assigned = Task.objects.get(id=self.instance.pk).assigned_to
if is_new:
self.instance.creator = get_person_contact(self.request.user)
self.instance.shop = get_shop(self.request)
result = super(TaskForm, self).save(**kwargs)
if not is_new and old_assigned != self.instance.assigned_to:
self.instance.add_log_entry(
_("Changed assigment from {from_contact_name} to {to_contact_name}.").format(
**dict(from_contact_name=old_assigned, to_contact_name=self.instance.assigned_to)
),
kind=LogEntryKind.EDIT,
)
return result
[docs]class TaskCommentForm(ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
self.task = kwargs.pop("task")
super(TaskCommentForm, self).__init__(*args, **kwargs)
[docs] def save(self, **kwargs):
if not self.instance.pk:
self.instance.task = self.task
self.instance.author = get_person_contact(self.request.user)
return super(TaskCommentForm, self).save(**kwargs)
[docs]class BaseTaskViewMixin(object):
[docs] def get_queryset(self):
tasks = Task.objects.for_shop(get_shop(self.request))
if not self.request.user.is_superuser:
tasks = tasks.exclude(status=TaskStatus.DELETED)
return tasks
[docs]class TaskTypeEditView(CreateOrUpdateView):
model = TaskType
form_class = TaskTypeForm
template_name = "shuup/admin/tasks/task_type_edit.jinja"
context_object_name = "task_type"
[docs] def get_form_kwargs(self, **kwargs):
args = super(TaskTypeEditView, self).get_form_kwargs(**kwargs)
args["request"] = self.request
return args
[docs]class TaskEditView(BaseTaskViewMixin, CreateOrUpdateView):
model = Task
template_name = "shuup/admin/tasks/task_edit.jinja"
context_object_name = "task"
fields = ()
[docs] def get_toolbar(self):
save_form_id = self.get_save_form_id()
obj = self.get_object()
delete_url = reverse_lazy("shuup_admin:task.delete", kwargs={"pk": obj.pk}) if obj.pk else None
toolbar = get_default_edit_toolbar(self, save_form_id, delete_url=delete_url)
if obj and obj.pk:
if obj.status == TaskStatus.NEW:
toolbar.append(
PostActionButton(
post_url=reverse_lazy("shuup_admin:task.set_status", kwargs=dict(pk=obj.pk)),
icon="fa fa-check",
name="status",
value=TaskStatus.IN_PROGRESS.value,
text=_("Set In Progress"),
extra_css_class="btn-success",
)
)
if obj.status == TaskStatus.IN_PROGRESS:
toolbar.append(
PostActionButton(
post_url=reverse_lazy("shuup_admin:task.set_status", kwargs=dict(pk=obj.pk)),
icon="fa fa-check",
name="status",
value=TaskStatus.COMPLETED.value,
text=_("Set Completed"),
extra_css_class="btn-success",
)
)
return toolbar
[docs] def get_form(self, form_class=None):
kwargs = self.get_form_kwargs()
instance = kwargs.pop("instance", None)
form_group = FormGroup(**kwargs)
form_group.add_form_def(name="base", form_class=TaskForm, kwargs=dict(instance=instance, request=self.request))
if self.object.pk:
form_group.add_form_def(
name="comment",
form_class=TaskCommentForm,
kwargs=dict(request=self.request, task=instance),
required=False,
)
return form_group
@atomic
[docs] def save_form(self, form):
is_new = not self.object.pk
form.forms["base"].save()
if not is_new and form.forms["comment"].cleaned_data.get("body"):
form.forms["comment"].save()
[docs] def get_context_data(self, **kwargs):
context = super(TaskEditView, self).get_context_data(**kwargs)
comments = []
task = self.get_object()
if task:
comments = task.comments.for_contact(get_person_contact(self.request.user)).order_by("created_on")
context["comments"] = comments
return context
[docs]class TaskDeleteView(BaseTaskViewMixin, DeleteView):
model = Task
success_url = reverse_lazy("shuup_admin:task.list")
[docs]class TaskSetStatusView(BaseTaskViewMixin, BaseDetailView):
[docs] def get(self, request, *args, **kwargs):
return HttpResponseNotAllowed(permitted_methods=["post"])
[docs] def post(self, request, *args, **kwargs):
status = int(request.POST.get("status", 0))
obj = self.get_object()
redirect_url = reverse_lazy("shuup_admin:task.edit", kwargs=dict(pk=obj.pk))
possible_status = [TaskStatus.COMPLETED.value, TaskStatus.IN_PROGRESS.value]
if not status or status not in possible_status:
messages.error(request, _("Invalid status."))
return HttpResponseRedirect(redirect_url)
if status == TaskStatus.COMPLETED.value:
obj.set_completed(get_person_contact(request.user))
elif status == TaskStatus.IN_PROGRESS.value:
obj.set_in_progress()
obj.save()
messages.success(request, _("Status changed."))
return HttpResponseRedirect(redirect_url)