summaryrefslogtreecommitdiff
path: root/ishtar/ishtar_base/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar/ishtar_base/models.py')
-rw-r--r--ishtar/ishtar_base/models.py165
1 files changed, 164 insertions, 1 deletions
diff --git a/ishtar/ishtar_base/models.py b/ishtar/ishtar_base/models.py
index 2a8248804..cbf362b83 100644
--- a/ishtar/ishtar_base/models.py
+++ b/ishtar/ishtar_base/models.py
@@ -27,7 +27,7 @@ from django.core.validators import validate_slug
from django.utils.translation import ugettext_lazy as _, ugettext
from django.db.utils import DatabaseError
from django.utils.safestring import SafeUnicode, mark_safe
-from django.db.models import Q, Max
+from django.db.models import Q, Max, Count
from django.db.models.signals import m2m_changed
from django.contrib.auth.models import User
@@ -348,6 +348,77 @@ class LightHistorizedItem(BaseHistorizedItem):
super(LightHistorizedItem, self).save(*args, **kwargs)
return True
+class Dashboard:
+ def __init__(self, model):
+ self.model = model
+ self.total_number = model.get_total_number()
+ # years
+ self.years = model.get_years()
+ self.years.sort()
+ if not self.total_number or not self.years:
+ return
+ self.values = [('year', _(u"Year"), reversed(self.years))]
+ # numbers
+ self.numbers = [model.get_by_year(year).count() for year in self.years]
+ self.values += [('number', _(u"Number"), reversed(self.numbers))]
+ # calculate
+ self.average = self.get_average()
+ self.variance = self.get_variance()
+ self.standard_deviation = self.get_standard_deviation()
+ self.median = self.get_median()
+ self.mode = self.get_mode()
+ # by operation
+ if not hasattr(model, 'get_by_operation'):
+ return
+ operations = model.get_operations()
+ operation_numbers = [model.get_by_operation(op).count()
+ for op in operations]
+ # calculate
+ self.operation_average = self.get_average(operation_numbers)
+ self.operation_variance = self.get_variance(operation_numbers)
+ self.operation_standard_deviation = self.get_standard_deviation(
+ operation_numbers)
+ self.operation_median = self.get_median(operation_numbers)
+ operation_mode_pk = self.get_mode(dict(zip(operations,
+ operation_numbers)))
+ if operation_mode_pk:
+ self.operation_mode = unicode(Operation.objects.get(
+ pk=operation_mode_pk))
+
+ def get_average(self, vals=[]):
+ if not vals:
+ vals = self.numbers
+ return sum(vals)/len(vals)
+
+ def get_variance(self, vals=[]):
+ if not vals:
+ vals = self.numbers
+ avrg = self.get_average(vals)
+ return self.get_average([(x-avrg)**2 for x in vals])
+
+ def get_standard_deviation(self, vals=[]):
+ if not vals:
+ vals = self.numbers
+ return round(self.get_variance(vals)**0.5, 3)
+
+ def get_median(self, vals=[]):
+ if not vals:
+ vals = self.numbers
+ len_vals = len(vals)
+ vals.sort()
+ if (len_vals % 2) == 1:
+ return vals[len_vals/2]
+ else:
+ return (vals[len_vals/2-1] + vals[len_vals/2])/2.0
+
+ def get_mode(self, vals={}):
+ if not vals:
+ vals = dict(zip(self.years, self.numbers))
+ mx = max(vals.values())
+ for v in vals:
+ if vals[v] == mx:
+ return v
+
class Departement(models.Model):
label = models.CharField(_(u"Label"), max_length=30)
number = models.CharField(_(u"Number"), unique=True, max_length=3)
@@ -571,6 +642,19 @@ class File(BaseHistorizedItem, OwnPerms):
)
ordering = ['-year', '-numeric_reference']
+ @classmethod
+ def get_years(cls):
+ return [res['year'] for res in list(cls.objects.values('year').annotate(
+ Count("id")).order_by())]
+
+ @classmethod
+ def get_by_year(cls, year):
+ return cls.objects.filter(year=year)
+
+ @classmethod
+ def get_total_number(cls):
+ return cls.objects.count()
+
def __unicode__(self):
items = [unicode(_('Intercommunal'))]
if self.towns.count() == 1:
@@ -686,6 +770,19 @@ class Operation(BaseHistorizedItem, OwnPerms):
unicode(self.operation_code))))
return JOINT.join(items)
+ @classmethod
+ def get_years(cls):
+ return [res['year'] for res in list(cls.objects.values('year').annotate(
+ Count("id")).order_by())]
+
+ @classmethod
+ def get_by_year(cls, year):
+ return cls.objects.filter(year=year)
+
+ @classmethod
+ def get_total_number(cls):
+ return cls.objects.count()
+
year_index_lbl = _(u"Operation code")
@property
def year_index(self):
@@ -930,6 +1027,32 @@ class ContextRecord(BaseHistorizedItem, OwnPerms):
return JOINT.join([unicode(lbl) for lbl in [self.parcel.operation.year,
self.parcel.operation.operation_code,
self.label] if lbl])
+
+ @classmethod
+ def get_years(cls):
+ years = set()
+ for res in list(cls.objects.values('operation__start_date')):
+ yr = res['operation__start_date'].year
+ years.add(yr)
+ return list(years)
+
+ @classmethod
+ def get_by_year(cls, year):
+ return cls.objects.filter(operation__start_date__year=year)
+
+ @classmethod
+ def get_operations(cls):
+ return [dct['operation__pk']
+ for dct in cls.objects.values('operation__pk').distinct()]
+
+ @classmethod
+ def get_by_operation(cls, operation_id):
+ return cls.objects.filter(operation__pk=operation_id)
+
+ @classmethod
+ def get_total_number(cls):
+ return cls.objects.filter(operation__start_date__isnull=False).count()
+
class ContextRecordSource(Source):
class Meta:
verbose_name = _(u"Context record documentation")
@@ -1036,6 +1159,46 @@ class Item(BaseHistorizedItem, OwnPerms):
blank=True, null=True, related_name='items')
history = HistoricalRecords()
+ @classmethod
+ def get_years(cls):
+ years = set()
+ items = cls.objects.filter(downstream_treatment__isnull=True)
+ for item in items:
+ bi = item.base_items.all()
+ if not bi:
+ continue
+ bi = bi[0]
+ yr = bi.context_record.operation.start_date.year
+ years.add(yr)
+ return list(years)
+
+ @classmethod
+ def get_by_year(cls, year):
+ return cls.objects.filter(downstream_treatment__isnull=True,
+ base_items__context_record__operation__start_date__year=year)
+
+ @classmethod
+ def get_operations(cls):
+ operations = set()
+ items = cls.objects.filter(downstream_treatment__isnull=True)
+ for item in items:
+ bi = item.base_items.all()
+ if not bi:
+ continue
+ bi = bi[0]
+ pk = bi.context_record.operation.pk
+ operations.add(pk)
+ return list(operations)
+
+ @classmethod
+ def get_by_operation(cls, operation_id):
+ return cls.objects.filter(downstream_treatment__isnull=True,
+ base_items__context_record__operation__pk=operation_id)
+
+ @classmethod
+ def get_total_number(cls):
+ return cls.objects.filter(downstream_treatment__isnull=True).count()
+
def duplicate(self, user):
dct = dict([(attr, getattr(self, attr)) for attr in ('order', 'label',
'description', 'material_type', 'volume', 'weight',