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
|
2016-10-14 13:02:25 +02:00
|
|
|
|
2018-08-02 17:55:27 +02:00
|
|
|
from .fields import IdField
|
|
|
|
|
2018-07-26 15:53:42 +02:00
|
|
|
from taggit.managers import TaggableManager
|
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
|
|
|
|
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,
|
|
|
|
help_text=_("merci de ne pas faire de référence cyclique"),
|
|
|
|
)
|
2018-08-06 17:06:38 +02:00
|
|
|
|
2018-08-09 17:52:28 +02:00
|
|
|
def full_name(self):
|
2018-08-09 16:06:24 +02:00
|
|
|
if self.parent is None:
|
|
|
|
return "-"
|
|
|
|
current = self
|
|
|
|
res = ""
|
|
|
|
for k in range(100):
|
|
|
|
if current.parent is None:
|
|
|
|
break
|
|
|
|
res = "/{current}{old}".format(
|
|
|
|
current=current.name,
|
|
|
|
old=res)
|
|
|
|
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
|
|
|
|
elif current.parent == None:
|
|
|
|
done = True
|
|
|
|
current = current.parent
|
|
|
|
return super().save(*args, **kwargs)
|
|
|
|
|
|
|
|
|
2018-08-06 17:06:38 +02:00
|
|
|
|
2017-07-18 19:08:09 +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,
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
)
|
2018-08-06 17:06:38 +02:00
|
|
|
category = models.ForeignKey(
|
|
|
|
EquipmentCategory,
|
2018-08-08 16:56:24 +02:00
|
|
|
on_delete=models.PROTECT,
|
2018-08-06 17:06:38 +02:00
|
|
|
)
|
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-09 17:52:28 +02:00
|
|
|
def ids_aviable(self):
|
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():
|
|
|
|
res = [ x
|
|
|
|
for x in res
|
|
|
|
if x not in lost.ids ]
|
|
|
|
# TODO cassé
|
|
|
|
# TODO utilisés
|
|
|
|
return res
|
|
|
|
|
|
|
|
def ids_lost(self):
|
|
|
|
res = []
|
|
|
|
for lost in self.losts.all():
|
|
|
|
res = res + [ x
|
|
|
|
for x in lost.ids
|
|
|
|
if x not in res]
|
|
|
|
return res
|
|
|
|
|
|
|
|
def stock_aviable(self):
|
|
|
|
return len(self.ids_available())
|
|
|
|
|
|
|
|
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")
|
|
|
|
stock_aviable.short_description= _("quantité disponible")
|
|
|
|
stock_lost.short_description = _("quantité perdue")
|
2018-08-09 16:06:24 +02:00
|
|
|
|
2018-08-09 17:52:28 +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)
|
|
|
|
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
|
|
|
|
2017-07-18 19:08:09 +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
|
|
|
|
|
|
|
|
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",
|
|
|
|
help_text=_("Matériel concerné par le defaut"),
|
|
|
|
)
|
|
|
|
attribute = models.ForeignKey(
|
|
|
|
EquipmentAttribute,
|
|
|
|
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):
|
2017-07-18 19:08:09 +02:00
|
|
|
equipment = models.ForeignKey(Equipment)
|
2016-10-14 13:02:25 +02:00
|
|
|
activity = models.ForeignKey(Activity)
|
2018-08-02 17:55:27 +02:00
|
|
|
amount = models.BigIntegerField(_("quantité attribuée"))
|
2017-07-15 17:44:15 +02:00
|
|
|
remarks = models.TextField(_("remarques concernant l'attribution"))
|
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,
|
|
|
|
self.amout,
|
|
|
|
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):
|
|
|
|
if self.equipment.event and self.equipment.event != self.activity.event:
|
|
|
|
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(
|
2017-07-18 19:08:09 +02:00
|
|
|
Equipment,
|
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-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-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)
|