aboutsummaryrefslogtreecommitdiffstats
path: root/servo/models/queue.py
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
committerFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
commit63b0fc6269b38edf7234b9f151b80d81f614c0a3 (patch)
tree555de3068f33f8dddb4619349bbea7d9b7c822fd /servo/models/queue.py
downloadServo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.gz
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.bz2
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.zip
Initial commit
First public commit
Diffstat (limited to 'servo/models/queue.py')
-rw-r--r--servo/models/queue.py296
1 files changed, 296 insertions, 0 deletions
diff --git a/servo/models/queue.py b/servo/models/queue.py
new file mode 100644
index 0000000..d3eb0f6
--- /dev/null
+++ b/servo/models/queue.py
@@ -0,0 +1,296 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, First Party Software
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+from datetime import timedelta
+from django.conf import settings
+
+from django.db import models
+from django.utils import timezone
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.sites.models import Site
+from django.contrib.sites.managers import CurrentSiteManager
+from django.core.urlresolvers import reverse
+
+from servo import defaults
+from servo.models.common import Location
+
+
+class Queue(models.Model):
+
+ site = models.ForeignKey(
+ Site,
+ editable=False,
+ default=defaults.site_id
+ )
+
+ title = models.CharField(
+ max_length=255,
+ default=_('New Queue'),
+ verbose_name=_('Title')
+ )
+
+ keywords = models.TextField(
+ default='',
+ blank=True,
+ help_text=_('Orders with devices matching these keywords will be automatically assigned to this queue')
+ )
+
+ locations = models.ManyToManyField(
+ Location,
+ verbose_name=_('locations'),
+ help_text=_("Pick the locations you want this queue to appear in.")
+ )
+
+ description = models.TextField(
+ blank=True,
+ verbose_name=_('description')
+ )
+
+ PRIO_LOW = 0
+ PRIO_NORMAL = 1
+ PRIO_HIGH = 2
+
+ PRIORITIES = (
+ (PRIO_HIGH, _("High")),
+ (PRIO_NORMAL, _("Normal")),
+ (PRIO_LOW, _("Low"))
+ )
+
+ priority = models.IntegerField(
+ default=PRIO_NORMAL,
+ choices=PRIORITIES,
+ verbose_name=_("priority")
+ )
+
+ status_created = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_(u'Order Created'),
+ help_text=_("Order has ben placed to a queue")
+ )
+
+ status_assigned = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_(u'Order Assigned'),
+ help_text=_("Order has ben assigned to a user")
+ )
+
+ status_products_ordered = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_("Products Ordered"),
+ help_text=_("Purchase Order for this Service Order has been submitted")
+ )
+ status_products_received = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_("Products Received"),
+ help_text=_("Products have been received")
+ )
+ status_repair_completed = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_("Repair Completed"),
+ help_text=_("GSX repair completed")
+ )
+
+ status_dispatched = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_("Order Dispatched")
+ )
+
+ status_closed = models.ForeignKey(
+ 'QueueStatus',
+ null=True,
+ blank=True,
+ related_name='+',
+ verbose_name=_("Order Closed")
+ )
+
+ gsx_soldto = models.CharField(
+ blank=True,
+ default='',
+ max_length=10,
+ verbose_name=_("Sold-To"),
+ help_text=_("GSX queries of an order in this queue will be made using this Sold-To")
+ )
+
+ order_template = models.FileField(
+ null=True,
+ blank=True,
+ upload_to="templates",
+ verbose_name=_("order template"),
+ help_text=_("HTML template for Service Order/Work Confirmation")
+ )
+ quote_template = models.FileField(
+ null=True,
+ blank=True,
+ upload_to="templates",
+ verbose_name=_("quote template"),
+ help_text=_("HTML template for cost estimate")
+ )
+ receipt_template = models.FileField(
+ null=True,
+ blank=True,
+ upload_to="templates",
+ verbose_name=_("receipt template"),
+ help_text=_("HTML template for Sales Order Receipt")
+ )
+ dispatch_template = models.FileField(
+ null=True,
+ blank=True,
+ upload_to="templates",
+ verbose_name=_("dispatch template"),
+ help_text=_("HTML template for dispatched order")
+ )
+
+ objects = CurrentSiteManager()
+
+ def get_admin_url(self):
+ return reverse('admin-edit_queue', args=[self.pk])
+
+ def get_order_count(self, max_state=2):
+ count = self.order_set.filter(state__lt=max_state).count()
+ return count if count > 0 else ''
+
+ def __unicode__(self):
+ return self.title
+
+ class Meta:
+ ordering = ['title']
+ app_label = "servo"
+ verbose_name = _("Queue")
+ verbose_name_plural = _("Queues")
+ unique_together = ('title', 'site',)
+
+
+class Status(models.Model):
+ site = models.ForeignKey(
+ Site,
+ editable=False,
+ default=defaults.site_id
+ )
+
+ FACTORS = (
+ (60, _('Minutes')),
+ (3600, _('Hours')),
+ (86400, _('Days')),
+ (604800, _('Weeks')),
+ (2419200, _('Months')),
+ )
+
+ title = models.CharField(
+ max_length=255,
+ default=_(u'New Status'),
+ verbose_name=_(u'name')
+ )
+ description = models.TextField(
+ null=True,
+ blank=True,
+ verbose_name=_(u'description')
+ )
+ limit_green = models.IntegerField(
+ default=1,
+ verbose_name=_(u'green limit')
+ )
+ limit_yellow = models.IntegerField(
+ default=15,
+ verbose_name=_(u'yellow limit')
+ )
+ limit_factor = models.IntegerField(
+ choices=FACTORS,
+ default=FACTORS[0],
+ verbose_name=_(u'time unit')
+ )
+ queue = models.ManyToManyField(
+ Queue,
+ editable=False,
+ through='QueueStatus'
+ )
+
+ def is_enabled(self, queue):
+ return self in queue.queuestatus_set.all()
+
+ def get_admin_url(self):
+ return reverse('admin-edit_status', args=[self.pk])
+
+ def __unicode__(self):
+ return self.title
+
+ class Meta:
+ app_label = 'servo'
+ ordering = ('title',)
+ verbose_name = _('Status')
+ verbose_name_plural = _('Statuses')
+ unique_together = ('title', 'site',)
+
+
+class QueueStatus(models.Model):
+ """
+ A status bound to a queue.
+ This allows us to set time limits for each status per indiviudal queue
+ """
+ queue = models.ForeignKey(Queue)
+ status = models.ForeignKey(Status)
+
+ limit_green = models.IntegerField(default=1, verbose_name=_(u'green limit'))
+ limit_yellow = models.IntegerField(default=15, verbose_name=_(u'yellow limit'))
+ limit_factor = models.IntegerField(
+ choices=Status().FACTORS,
+ verbose_name=_(u'time unit'),
+ default=Status().FACTORS[0][0]
+ )
+
+ def get_green_limit(self):
+ """
+ Gets the green time limit for this QS
+ """
+ return timezone.now() + timedelta(seconds=self.limit_green*self.limit_factor)
+
+ def get_yellow_limit(self):
+ return timezone.now() + timedelta(seconds=self.limit_yellow*self.limit_factor)
+
+ def __unicode__(self):
+ return self.status.title
+
+ class Meta:
+ app_label = 'servo'
+ # A status should only be defined once per queue
+ unique_together = ('queue', 'status',)