# -*- 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.db import models
from django.db.models import Q
from django.utils.encoding import python_2_unicode_compatible
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from enumfields import Enum, EnumIntegerField
from parler.models import TranslatableModel, TranslatedFields
from shuup.core.fields import InternalIdentifierField
from shuup.utils.analog import LogEntryKind, define_log_model
from shuup.utils.django_compat import force_text
[docs]class TaskStatus(Enum):
NEW = 1
IN_PROGRESS = 2
COMPLETED = 3
DELETED = 4
class Labels:
NEW = _("New")
IN_PROGRESS = _("In progress")
COMPLETED = _("Completed")
DELETED = _("Deleted")
@python_2_unicode_compatible
[docs]class TaskType(TranslatableModel):
identifier = InternalIdentifierField(unique=False, blank=True, null=True, editable=True)
shop = models.ForeignKey(
on_delete=models.CASCADE, to="shuup.Shop", verbose_name=_("shop"), related_name="task_types"
)
translations = TranslatedFields(name=models.TextField(verbose_name=_("name")))
class Meta:
unique_together = ("shop", "identifier")
verbose_name = _("task type")
verbose_name_plural = _("task types")
def __str__(self):
return self.name
[docs]class TaskQuerySet(models.QuerySet):
[docs] def completed(self):
return self.filter(status=TaskStatus.COMPLETED)
[docs] def in_progress(self):
return self.filter(status=TaskStatus.IN_PROGRESS)
[docs] def is_new(self):
return self.filter(tatus=TaskStatus.NEW)
[docs] def for_shop(self, shop):
return self.filter(shop=shop)
[docs] def delete(self):
self.update(status=TaskStatus.DELETED)
[docs] def assigned_to(self, contact):
return self.filter(assigned_to=contact)
@python_2_unicode_compatible
[docs]class Task(models.Model):
shop = models.ForeignKey(on_delete=models.CASCADE, to="shuup.Shop", verbose_name=_("shop"), related_name="tasks")
name = models.CharField(verbose_name=_("name"), max_length=60)
type = models.ForeignKey(on_delete=models.CASCADE, to=TaskType, verbose_name=_("task type"), related_name="tasks")
status = EnumIntegerField(TaskStatus, default=TaskStatus.NEW, verbose_name=_("status"))
priority = models.PositiveIntegerField(default=0, verbose_name=_("priority"), db_index=True)
creator = models.ForeignKey(
on_delete=models.CASCADE,
to="shuup.Contact",
blank=True,
null=True,
related_name="creted_tasks",
verbose_name=_("creator"),
)
assigned_to = models.ForeignKey(
on_delete=models.CASCADE,
to="shuup.Contact",
blank=True,
null=True,
related_name="assigned_tasks",
verbose_name=_("assigned to"),
)
completed_by = models.ForeignKey(
on_delete=models.CASCADE,
to="shuup.Contact",
blank=True,
null=True,
related_name="completed_tasks",
verbose_name=_("completed by"),
)
completed_on = models.DateTimeField(verbose_name=_("completed on"), null=True, blank=True)
created_on = models.DateTimeField(auto_now_add=True, editable=False, db_index=True, verbose_name=_("created on"))
modified_on = models.DateTimeField(auto_now=True, editable=False, db_index=True, verbose_name=_("modified on"))
objects = TaskQuerySet.as_manager()
def __str__(self):
return self.name
[docs] def assign(self, user):
self.assigned_to = user
self.status = TaskStatus.IN_PROGRESS
self.save()
[docs] def delete(self):
self.status = TaskStatus.DELETED
self.save(update_fields=["status"])
self.add_log_entry("Success! Deleted (soft).", kind=LogEntryKind.DELETION)
[docs] def set_in_progress(self):
self.status = TaskStatus.IN_PROGRESS
self.add_log_entry("Info! In progress.", kind=LogEntryKind.EDIT)
self.save()
[docs] def set_completed(self, contact):
self.completed_by = contact
self.completed_on = now()
self.status = TaskStatus.COMPLETED
self.add_log_entry("Success! Completed.", kind=LogEntryKind.EDIT)
self.save()
[docs] def get_completion_time(self):
if self.completed_on:
return self.completed_on - self.created_on
TaskLogEntry = define_log_model(Task)