123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # -*- coding: utf-8 -*-
- from __future__ import unicode_literals
- from django.db import models
- from django.db.models import Q
- from django.conf import settings
- from django.utils import timezone
- from .fields import MACAddressField
- class ItemType(models.Model):
- name = models.CharField(max_length=100, verbose_name="nom")
- def __unicode__(self):
- return self.name
- class Meta:
- verbose_name = "type d’objet"
- verbose_name_plural = "types d’objet"
- class ItemQuerySet(models.QuerySet):
- def _get_borrowed_pks(self):
- return Loan.objects.running().values_list("item", flat=True)
- def available(self):
- return self.exclude(pk__in=self._get_borrowed_pks()).exclude(deployed=True)
- def borrowed(self):
- return self.filter(pk__in=self._get_borrowed_pks())
- def deployed(self):
- return self.filter(deployed=True)
- def unavailable(self):
- """ deployed or borrowed
- """
- return self.filter(Q(pk__in=self._get_borrowed_pks()) | Q(deployed=True))
- class Item(models.Model):
- type = models.ForeignKey(
- ItemType, verbose_name="type de matériel", related_name="items"
- )
- designation = models.CharField(max_length=100, verbose_name="désignation")
- storage = models.ForeignKey(
- "Storage",
- related_name="items",
- verbose_name="Lieu de stockage",
- null=True,
- blank=True,
- help_text="Laisser vide si inconnu",
- )
- mac_address = MACAddressField(
- verbose_name="adresse MAC",
- blank=True,
- null=True,
- unique=True,
- help_text="préférable au n° de série si possible",
- )
- serial = models.CharField(
- verbose_name="N° de série",
- max_length=250,
- blank=True,
- null=True,
- unique=True,
- help_text="ou toute autre référence unique",
- )
- buy_date = models.DateField(verbose_name="date d’achat", blank=True, null=True)
- owner = models.ForeignKey(
- settings.AUTH_USER_MODEL,
- verbose_name="Propriétaire",
- related_name="items",
- null=True,
- blank=True,
- help_text="dans le cas de matériel n'appartenant pas à l'association",
- )
- deployed = models.BooleanField(
- verbose_name="déployé",
- default=False,
- help_text="Cocher si le matériel est en production",
- )
- comment = models.TextField(verbose_name="commentaire", blank=True, null=True)
- objects = ItemQuerySet().as_manager()
- def __unicode__(self):
- return self.designation
- def save(self, *args, **kwargs):
- # workaround for unique=True, null=True
- # see https://code.djangoproject.com/ticket/4136#comment:33
- self.mac_address = self.mac_address or None
- self.serial = self.serial or None
- return super(Item, self).save(*args, **kwargs)
- def get_current_loan(self):
- """
- Returns the current Loan for this Item, if exists, or None.
- """
- try:
- return self.loans.get(loan_date_end__isnull=True)
- except Loan.DoesNotExist:
- return None
- def is_available(self):
- """
- Returns the status of the Item. If a running loan exists,
- or if the item is deployed, returns False (else True).
- """
- return (not self.deployed) and (not self.loans.running().exists())
- is_available.boolean = True
- is_available.short_description = "disponible"
- def get_mac_and_serial(self):
- mac = self.mac_address
- serial = self.serial
- if mac and serial:
- return "{} / {}".format(mac, serial)
- else:
- return mac or serial or ""
- class Meta:
- verbose_name = "objet"
- ordering = ["designation", "mac_address", "serial"]
- def give_back(self, storage=None):
- self.storage = storage
- self.save()
- self.loans.running().update(loan_date_end=timezone.now())
- class LoanQuerySet(models.QuerySet):
- @staticmethod
- def _running_filter():
- return models.Q(loan_date_end__gt=timezone.now()) | models.Q(
- loan_date_end__isnull=True
- )
- def running(self):
- return self.filter(self._running_filter())
- def finished(self):
- return self.exclude(self._running_filter())
- class Loan(models.Model):
- item = models.ForeignKey(Item, verbose_name="objet", related_name="loans")
- user = models.ForeignKey(
- settings.AUTH_USER_MODEL, verbose_name="membre", related_name="loans"
- )
- loan_date = models.DateTimeField(verbose_name="date de prêt")
- loan_date_end = models.DateTimeField(
- verbose_name="date de fin de prêt", null=True, blank=True
- )
- notes = models.TextField(null=True, blank=True)
- def __unicode__(self):
- return "prêt de {item} à {user}".format(item=self.item, user=self.user)
- def get_mac_and_serial(self):
- return self.item.get_mac_and_serial()
- get_mac_and_serial.short_description = "Adresse MAC / n° de série"
- def user_can_close(self, user):
- return (not self.item.is_available()) and (self.user == user)
- def is_running(self):
- return not self.loan_date_end or self.loan_date_end > timezone.now()
- is_running.boolean = True
- is_running.short_description = "En cours ?"
- class Meta:
- verbose_name = "prêt d’objet"
- verbose_name_plural = "prêts d’objets"
- objects = LoanQuerySet().as_manager()
- class Storage(models.Model):
- name = models.CharField(max_length=100, verbose_name="nom")
- notes = models.TextField(blank=True, help_text="Lisible par tous les adhérents")
- def __unicode__(self):
- return self.name
- def items_count(self):
- return self.items.count()
- items_count.short_description = "Nb. items stockés"
- class Meta:
- verbose_name = "lieu de stockage"
- verbose_name_plural = "lieux de stockage"
|