You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kompass/jdav_web/material/models.py

115 lines
3.7 KiB
Python

from datetime import datetime
from django.db import models
from django.utils import timezone
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
# maximum time in years of a material part until being replaced
MAX_TIME_MATERIAL = 5
class MaterialCategory(models.Model):
"""
Describes one kind of material
"""
name = models.CharField(max_length=40, verbose_name=_("Name"))
def __str__(self):
return self.name
class Meta:
verbose_name = _("Material category")
verbose_name_plural = _("Material categories")
# Create your models here.
class MaterialPart(models.Model):
"""
Represents one part of material, which is owned (and stored) by different
members of the association (Ownership)
"""
name = models.CharField(_("name"), max_length=30)
description = models.CharField(_("description"), default="", max_length=140)
quantity = models.IntegerField(_("quantity"), default=0)
buy_date = models.DateField(_("purchase date"), editable=True)
lifetime = models.DecimalField(_("lifetime (years)"), decimal_places=0, max_digits=3)
photo = models.ImageField(_("photo"), upload_to="images", blank=True)
material_cat = models.ManyToManyField(
MaterialCategory, default=None, verbose_name=_("Material category")
)
def __str__(self):
"""String representation"""
return self.name
def quantity_real(self):
real = sum([o.count for o in Ownership.objects.filter(material__id=self.pk)])
return str(real) + "/" + str(self.quantity)
quantity_real.admin_order_field = "quantity"
quantity_real.short_description = _("Quantity")
def admin_thumbnail(self):
if self.photo:
return format_html(
'<a href="{0}"><img src="{0}" height="60" style="image-orientation: from-image;"></a>'.format(
self.photo.url
)
)
else:
return format_html("<i>kein Bild</i>")
admin_thumbnail.short_description = _("Thumbnail")
def ownership_overview(self):
summary = ""
for owner in self.ownership_set.all():
summary += "<p>{}: {}</p>".format(str(owner.owner), owner.count)
return format_html(summary)
ownership_overview.short_description = _("Owners")
def not_too_old(self):
"""Returns wether the part should be replaced cause of age"""
buy_time = timezone.make_aware(datetime.combine(self.buy_date, datetime.min.time()))
return yearsago(self.lifetime) < buy_time
not_too_old.admin_order_field = "buy_date"
not_too_old.boolean = True
not_too_old.short_description = _("Not too old?")
class Meta:
verbose_name = _("material part")
verbose_name_plural = _("material parts")
class Ownership(models.Model):
"""Represents the connection between a MaterialPart and a Member"""
material = models.ForeignKey(MaterialPart, on_delete=models.CASCADE)
owner = models.ForeignKey("members.Member", verbose_name=_("owner"), on_delete=models.CASCADE)
count = models.IntegerField(_("count"), default=1)
def __str__(self):
"""String representation"""
return str(self.owner)
class Meta:
verbose_name = _("ownership")
verbose_name_plural = _("ownerships")
def yearsago(years, from_date=None):
"""Function to return the date with a delta of years in the past"""
if from_date is None:
from_date = timezone.now()
try:
return from_date.replace(year=from_date.year - years)
except ValueError:
# 29.02 -> use 28.02
assert from_date.month == 2 and from_date.day == 29
return from_date.replace(month=2, day=28, year=from_date.year - years)