from django.db import models from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import Group from event.models import Activity, EventSpecificMixin from .fields import IdField from taggit.managers import TaggableManager from datetime import date class EquipmentCategory(models.Model): name = models.CharField( _("nom"), max_length=200, ) parent = models.ForeignKey( 'self', blank=True, null=True, default=None, help_text=_("merci de ne pas faire de référence cyclique"), ) def full_name(self): 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 full_name.short_description = _("Chemin complet") full_name_p = property(full_name) class Meta: verbose_name = _("catégories") verbose_name_plural = _("catégories") def __str__(self): return self.name 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) class Equipment(EventSpecificMixin, models.Model): name = models.CharField( _("nom du matériel"), max_length=200, ) stock = models.PositiveSmallIntegerField(_("quantité totale")) description = models.TextField( _("description"), blank=True, ) activities = models.ManyToManyField( Activity, related_name="equipment", through="EquipmentAttribution", ) owner = models.ForeignKey( Group, blank=True, null=True, ) category = models.ForeignKey( EquipmentCategory, on_delete=models.PROTECT, ) added_at = models.DateTimeField( _("ajouté le"), auto_now_add=True, ) modified_at = models.DateTimeField( _("dernière modification"), auto_now=True, ) def ids_aviable(self): res = list(map(lambda x: x+1, range(self.stock))) 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") 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) class Meta: verbose_name = _("matériel") verbose_name_plural = _("matériels") def __str__(self): return self.name 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, on_delete=models.CASCADE, 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) class EquipmentAttribution(models.Model): equipment = models.ForeignKey(Equipment) activity = models.ForeignKey(Activity) amount = models.BigIntegerField(_("quantité attribuée")) remarks = models.TextField(_("remarques concernant l'attribution")) class Meta: verbose_name = _("attribution de matériel") verbose_name_plural = _("attributions de matériel") def __str__(self): return "%s (%d) -> %s" % (self.equipment.name, self.amout, self.activity.get_herited('title')) def save(self, *args, **kwargs): if self.equipment.event and self.equipment.event != self.activity.event: raise ValidationError super(EquipmentAttribution, self).save(*args, **kwargs) class EquipmentDefault(models.Model): remark = models.TextField(_("remarque sur le défaut")) equipment = models.ForeignKey( Equipment, on_delete=models.CASCADE, related_name="remarks", help_text=_("Matériel concerné par le defaut"), ) ids = IdField() is_unusable = models.BooleanField(_("inutilisable")) send_repare = models.BooleanField(_("à envoyer réparareur")) class Meta: verbose_name = _("defaut matériel") verbose_name_plural = _("défauts sur le matériel") def __str__(self): return "%s : %s" % (self.equipment.name, self.remark) class EquipmentLost(models.Model): lost_at = models.DateField( _("perdu le"), default=date.today, ) equipment = models.ForeignKey( Equipment, on_delete=models.CASCADE, related_name="losts", help_text=_("Matériel concerné par la perte"), ) ids = IdField() class EquipmentRevision(models.Model): date = models.DateField( _("date"), default=date.today, ) equipment = models.ForeignKey( Equipment, on_delete=models.CASCADE, related_name="revisions", help_text=_("Matériel concerné par les révisions"), ) remark = models.TextField(_("remarque sur la révision")) ids = IdField() 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)