poulpe/equipment/models.py

338 lines
9.8 KiB
Python
Raw Normal View History

2016-10-14 13:02:25 +02:00
from django.db import models
2017-07-21 16:18:19 +02:00
from django.core.exceptions import ValidationError
2016-10-14 13:02:25 +02:00
from django.utils.translation import ugettext_lazy as _
2018-08-07 20:29:37 +02:00
from django.contrib.auth.models import Group
2017-07-21 16:18:19 +02:00
from event.models import Activity, EventSpecificMixin
2018-08-20 13:17:10 +02:00
from django.db.models import Q
2016-10-14 13:02:25 +02:00
2018-08-02 17:55:27 +02:00
from .fields import IdField
2018-08-04 05:38:03 +02:00
from datetime import date
2018-07-26 15:53:42 +02:00
2016-10-14 13:02:25 +02:00
2019-03-18 14:01:44 +01:00
class EquipmentStorage(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
)
class Meta:
verbose_name = _("stockage")
verbose_name_plural = _("stockages")
def __str__(self):
return self.name
2018-08-06 17:06:38 +02:00
class EquipmentCategory(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
)
2018-08-08 16:02:23 +02:00
parent = models.ForeignKey(
'self',
blank=True,
null=True,
default=None,
2018-08-27 00:02:33 +02:00
on_delete=models.SET_NULL,
2018-08-20 13:17:10 +02:00
related_name="children",
2018-08-08 16:02:23 +02:00
help_text=_("merci de ne pas faire de référence cyclique"),
2018-08-20 13:17:10 +02:00
verbose_name=_("parent"),
2018-08-08 16:02:23 +02:00
)
2018-08-06 17:06:38 +02:00
2018-08-20 13:17:10 +02:00
def has_parent(self, cat):
current = self
for k in range(100):
if current is None:
return False
if current == cat:
return True
current = current.parent
2018-08-09 17:52:28 +02:00
def full_name(self):
2018-08-09 16:06:24 +02:00
current = self
res = ""
for k in range(100):
res = "/{current}{old}".format(
current=current.name,
old=res)
2018-08-20 13:17:10 +02:00
if current.parent is None:
break
2018-08-09 16:06:24 +02:00
current = current.parent
return res
2018-08-09 17:52:28 +02:00
full_name.short_description = _("Chemin complet")
full_name_p = property(full_name)
2018-08-09 16:06:24 +02:00
2018-08-06 17:06:38 +02:00
class Meta:
2018-08-06 19:31:34 +02:00
verbose_name = _("catégories")
verbose_name_plural = _("catégories")
2018-08-06 17:06:38 +02:00
def __str__(self):
return self.name
2018-08-09 15:11:20 +02:00
def save(self, *args, **kwargs):
if self.pk:
done = False
current = self
while not done:
if current.parent == self:
self.parent = None
done = True
2018-08-27 00:02:33 +02:00
elif current.parent is None:
2018-08-09 15:11:20 +02:00
done = True
current = current.parent
return super().save(*args, **kwargs)
2018-08-20 13:17:10 +02:00
class EquipmentQuerySet(models.QuerySet):
def in_category(self, cat):
filtre = Q(id__lt=0)
2018-08-27 00:02:33 +02:00
childs_id = [c.id for c in EquipmentCategory.objects.all()
if c.has_parent(cat)]
2018-08-20 13:17:10 +02:00
for pk in childs_id:
filtre |= Q(category__id=pk)
return self.filter(filtre)
2018-08-06 17:06:38 +02:00
class Equipment(EventSpecificMixin, models.Model):
2016-10-14 13:02:25 +02:00
name = models.CharField(
2017-07-15 17:44:15 +02:00
_("nom du matériel"),
2016-10-14 13:02:25 +02:00
max_length=200,
)
2018-08-09 14:36:12 +02:00
stock = models.PositiveSmallIntegerField(_("quantité totale"))
2018-08-09 16:06:24 +02:00
description = models.TextField(
_("description"),
blank=True,
)
2016-10-14 13:02:25 +02:00
activities = models.ManyToManyField(
Activity,
related_name="equipment",
through="EquipmentAttribution",
)
2018-08-07 20:44:57 +02:00
owner = models.ForeignKey(
Group,
2018-08-20 13:17:10 +02:00
verbose_name=_("propriétaire"),
2018-08-07 20:44:57 +02:00
blank=True,
null=True,
2018-08-27 00:02:33 +02:00
on_delete=models.SET_NULL,
2018-08-07 20:44:57 +02:00
)
2018-08-06 17:06:38 +02:00
category = models.ForeignKey(
EquipmentCategory,
2018-08-20 13:17:10 +02:00
verbose_name=_("catégorie"),
2018-08-08 16:56:24 +02:00
on_delete=models.PROTECT,
2018-08-06 17:06:38 +02:00
)
2019-03-18 14:01:44 +01:00
storage = models.ForeignKey(
EquipmentStorage,
blank=True,
null=True,
default=None,
verbose_name=_("stockage"),
on_delete=models.PROTECT,
)
2018-07-26 15:53:42 +02:00
2018-08-09 14:06:40 +02:00
added_at = models.DateTimeField(
_("ajouté le"),
auto_now_add=True,
)
modified_at = models.DateTimeField(
_("dernière modification"),
auto_now=True,
)
2018-08-27 00:02:33 +02:00
2018-08-20 13:17:10 +02:00
objects = EquipmentQuerySet.as_manager()
def is_in_category(self, cat):
current = self.category
for k in range(100):
if current is None:
return False
if current == cat:
return True
current = current.parent
2018-08-09 14:06:40 +02:00
2018-08-09 17:52:28 +02:00
def ids_aviable(self):
2018-08-20 13:17:10 +02:00
if self.stock is None:
return []
2018-08-09 17:56:54 +02:00
res = list(map(lambda x: x+1, range(self.stock)))
2018-08-09 17:52:28 +02:00
for lost in self.losts.all():
2018-08-27 00:02:33 +02:00
res = [x
for x in res
if x not in lost.ids]
2018-08-09 17:52:28 +02:00
# TODO cassé
# TODO utilisés
return res
def ids_lost(self):
res = []
for lost in self.losts.all():
2018-08-27 00:02:33 +02:00
res = res + [x
for x in lost.ids
if x not in res]
2018-08-09 17:52:28 +02:00
return res
def stock_aviable(self):
2018-08-20 13:17:10 +02:00
aviable = self.ids_aviable()
return len(aviable)
2018-08-09 17:52:28 +02:00
def stock_lost(self):
return len(self.ids_lost())
def full_category(self):
return self.category.full_name()
full_category.short_description = _("Chemin complet")
ids_aviable.short_description = _("disponibles")
ids_lost.short_description = _("perdus")
2018-08-27 00:02:33 +02:00
stock_aviable.short_description = _("quantité disponible")
2018-08-09 17:52:28 +02:00
stock_lost.short_description = _("quantité perdue")
2018-08-09 16:06:24 +02:00
2018-08-27 00:02:33 +02:00
full_category_p = property(full_category)
ids_aviable_p = property(ids_aviable)
ids_lost_p = property(ids_lost)
stock_aviable_p = property(stock_aviable)
2018-08-09 17:52:28 +02:00
stock_lost_p = property(stock_lost)
2018-08-09 16:06:24 +02:00
2016-10-14 13:02:25 +02:00
class Meta:
2017-07-21 16:18:19 +02:00
verbose_name = _("matériel")
verbose_name_plural = _("matériels")
2016-10-14 13:02:25 +02:00
def __str__(self):
return self.name
2016-10-14 13:02:25 +02:00
2018-08-08 16:45:29 +02:00
class EquipmentAttribute(models.Model):
name = models.CharField(
_("nom"),
max_length=200,
unique=True,
)
class Meta:
verbose_name = _("attribut")
verbose_name_plural = _("attributs")
def __str__(self):
return self.name
2018-08-27 00:02:33 +02:00
2018-08-08 16:45:29 +02:00
class EquipmentAttributeValue(models.Model):
equipment = models.ForeignKey(
Equipment,
2018-08-08 16:56:24 +02:00
on_delete=models.CASCADE,
2018-08-08 16:45:29 +02:00
related_name="attributes",
2018-08-20 13:17:10 +02:00
verbose_name=_("matériel"),
2018-08-08 16:45:29 +02:00
help_text=_("Matériel concerné par le defaut"),
)
attribute = models.ForeignKey(
EquipmentAttribute,
2018-08-20 13:17:10 +02:00
verbose_name=_("attribut"),
2018-08-08 16:45:29 +02:00
on_delete=models.CASCADE,
)
value = models.CharField(
_("valeur"),
max_length=200,
)
class Meta:
verbose_name = _("attribut de matériel")
verbose_name_plural = _("attributs de matériel")
def __str__(self):
return "{attr}={value}".format(attr=self.attribute.name,
value=self.value)
2016-10-14 13:02:25 +02:00
class EquipmentAttribution(models.Model):
2018-08-27 00:02:33 +02:00
equipment = models.ForeignKey(
Equipment,
verbose_name=_("matériel"),
on_delete=models.CASCADE,
)
activity = models.ForeignKey(
Activity,
on_delete=models.CASCADE,
)
2018-08-02 17:55:27 +02:00
amount = models.BigIntegerField(_("quantité attribuée"))
2018-08-26 21:18:51 +02:00
remarks = models.TextField(
_("remarques concernant l'attribution"),
blank=True,
)
2016-10-14 13:02:25 +02:00
class Meta:
verbose_name = _("attribution de matériel")
verbose_name_plural = _("attributions de matériel")
def __str__(self):
2016-10-21 18:49:46 +02:00
return "%s (%d) -> %s" % (self.equipment.name,
2018-08-26 21:18:51 +02:00
self.amount,
2016-10-21 18:49:46 +02:00
self.activity.get_herited('title'))
2016-10-14 13:02:25 +02:00
2017-07-21 16:18:19 +02:00
def save(self, *args, **kwargs):
2018-08-27 00:02:33 +02:00
if (self.equipment.event
and self.equipment.event != self.activity.event):
2017-07-21 16:18:19 +02:00
raise ValidationError
super(EquipmentAttribution, self).save(*args, **kwargs)
2016-10-14 13:02:25 +02:00
2018-08-07 19:08:20 +02:00
class EquipmentDefault(models.Model):
remark = models.TextField(_("remarque sur le défaut"))
2016-10-14 13:02:25 +02:00
equipment = models.ForeignKey(
Equipment,
2018-08-20 13:17:10 +02:00
verbose_name=_("matériel"),
2018-08-08 16:56:24 +02:00
on_delete=models.CASCADE,
2016-10-14 13:02:25 +02:00
related_name="remarks",
2018-08-07 19:08:20 +02:00
help_text=_("Matériel concerné par le defaut"),
2016-10-14 13:02:25 +02:00
)
2018-08-06 18:34:07 +02:00
ids = IdField()
2018-08-07 19:08:20 +02:00
is_unusable = models.BooleanField(_("inutilisable"))
send_repare = models.BooleanField(_("à envoyer réparareur"))
2016-10-14 13:02:25 +02:00
class Meta:
2018-08-07 19:08:20 +02:00
verbose_name = _("defaut matériel")
verbose_name_plural = _("défauts sur le matériel")
2016-10-14 13:02:25 +02:00
def __str__(self):
2016-10-21 18:49:46 +02:00
return "%s : %s" % (self.equipment.name,
self.remark)
2018-08-04 05:38:03 +02:00
2018-08-07 19:08:20 +02:00
class EquipmentLost(models.Model):
lost_at = models.DateField(
_("perdu le"),
default=date.today,
)
equipment = models.ForeignKey(
Equipment,
2018-08-20 13:17:10 +02:00
verbose_name=_("matériel"),
2018-08-08 16:56:24 +02:00
on_delete=models.CASCADE,
2018-08-07 19:08:20 +02:00
related_name="losts",
help_text=_("Matériel concerné par la perte"),
)
ids = IdField()
2018-08-04 05:38:03 +02:00
class EquipmentRevision(models.Model):
date = models.DateField(
_("date"),
default=date.today,
)
equipment = models.ForeignKey(
Equipment,
2018-08-20 13:17:10 +02:00
verbose_name=_("matériel"),
2018-08-08 16:56:24 +02:00
on_delete=models.CASCADE,
2018-08-04 05:38:03 +02:00
related_name="revisions",
help_text=_("Matériel concerné par les révisions"),
)
remark = models.TextField(_("remarque sur la révision"))
2018-08-06 18:34:07 +02:00
ids = IdField()
2018-08-04 05:38:03 +02:00
class Meta:
verbose_name = _("révision de matériel")
verbose_name_plural = _("révisions de matériel")
def __str__(self):
return "%s : %s" % (self.equipment.name,
self.remark)