PyInventory/inventory/models/item.py

228 wiersze
6.9 KiB
Python

import logging
from pathlib import Path
import tagulous.models
from bx_django_utils.filename import clean_filename
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django_tools.model_version_protect.models import VersionProtectBaseModel
from django_tools.serve_media_app.models import user_directory_path
from tinymce.models import HTMLField
from inventory.models.base import BaseItemAttachmentModel, BaseParentTreeModel
from inventory.models.links import BaseLink
logger = logging.getLogger(__name__)
class ItemQuerySet(models.QuerySet):
def sort(self):
return self.order_by('kind', 'producer', 'name')
class ItemModel(BaseParentTreeModel, VersionProtectBaseModel):
"""
A Item that can be described and store somewhere ;)
"""
objects = ItemQuerySet.as_manager()
kind = tagulous.models.TagField(
case_sensitive=False,
force_lowercase=False,
space_delimiter=False,
max_count=3,
verbose_name=_('ItemModel.kind.verbose_name'),
help_text=_('ItemModel.kind.help_text'),
)
producer = tagulous.models.TagField(
blank=True,
case_sensitive=False,
force_lowercase=False,
space_delimiter=False,
max_count=1,
verbose_name=_('ItemModel.producer.verbose_name'),
help_text=_('ItemModel.producer.help_text'),
)
description = HTMLField(
blank=True,
null=True,
verbose_name=_('ItemModel.description.verbose_name'),
help_text=_('ItemModel.description.help_text'),
)
fcc_id = models.CharField(
max_length=20,
blank=True,
null=True,
verbose_name=_('ItemModel.fcc_id.verbose_name'),
help_text=_('ItemModel.fcc_id.help_text'),
)
location = models.ForeignKey(
'inventory.LocationModel',
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='items',
verbose_name=_('ItemModel.location.verbose_name'),
help_text=_('ItemModel.location.help_text'),
)
# ________________________________________________________________________
# lent
lent_to = models.CharField(
max_length=64,
blank=True,
null=True,
verbose_name=_('ItemModel.lent_to.verbose_name'),
help_text=_('ItemModel.lent_to.help_text'),
)
lent_from_date = models.DateField(
blank=True,
null=True,
verbose_name=_('ItemModel.lent_from_date.verbose_name'),
help_text=_('ItemModel.lent_from_date.help_text'),
)
lent_until_date = models.DateField(
blank=True,
null=True,
verbose_name=_('ItemModel.lent_until_date.verbose_name'),
help_text=_('ItemModel.lent_until_date.help_text'),
)
# ________________________________________________________________________
# received
received_from = models.CharField(
max_length=64,
blank=True,
null=True,
verbose_name=_('ItemModel.received_from.verbose_name'),
help_text=_('ItemModel.received_from.help_text'),
)
received_date = models.DateField(
blank=True,
null=True,
verbose_name=_('ItemModel.received_date.verbose_name'),
help_text=_('ItemModel.received_date.help_text'),
)
received_price = models.DecimalField(
decimal_places=2,
max_digits=6, # up to 9999 with a resolution of 2 decimal places
blank=True,
null=True,
verbose_name=_('ItemModel.received_price.verbose_name'),
help_text=_('ItemModel.received_price.help_text'),
)
# ________________________________________________________________________
# handed over
handed_over_to = models.CharField(
max_length=64,
blank=True,
null=True,
verbose_name=_('ItemModel.handed_over_to.verbose_name'),
help_text=_('ItemModel.handed_over_to.help_text'),
)
handed_over_date = models.DateField(
blank=True,
null=True,
verbose_name=_('ItemModel.handed_over_date.verbose_name'),
help_text=_('ItemModel.handed_over_date.help_text'),
)
handed_over_price = models.DecimalField(
decimal_places=2,
max_digits=6, # up to 9999 with a resolution of 2 decimal places
blank=True,
null=True,
verbose_name=_('ItemModel.handed_over_price.verbose_name'),
help_text=_('ItemModel.handed_over_price.help_text'),
)
def local_admin_link(self):
url = reverse('admin:inventory_itemmodel_change', args=[self.id])
return url
def verbose_name(self):
parts = [str(part) for part in (self.kind, self.producer, self.name)]
return ' - '.join(part for part in parts if part)
class Meta:
ordering = ('path_str',)
verbose_name = _('ItemModel.verbose_name')
verbose_name_plural = _('ItemModel.verbose_name_plural')
class ItemLinkModel(BaseLink):
item = models.ForeignKey(ItemModel, on_delete=models.CASCADE)
def full_clean(self, **kwargs):
if self.user_id is None:
# inherit owner of this link from item instance
self.user_id = self.item.user_id
return super().full_clean(**kwargs)
class Meta:
verbose_name = _('ItemLinkModel.verbose_name')
verbose_name_plural = _('ItemLinkModel.verbose_name_plural')
ordering = ('position',)
class ItemImageModel(BaseItemAttachmentModel):
"""
Store images to Items
"""
image = models.ImageField(
upload_to=user_directory_path,
verbose_name=_('ItemImageModel.image.verbose_name'),
help_text=_('ItemImageModel.image.help_text'),
)
def __str__(self):
return self.name or self.image.name
def full_clean(self, **kwargs):
# Set name by image filename:
if not self.name:
filename = Path(self.image.name).name
self.name = clean_filename(filename)
return super().full_clean(**kwargs)
class Meta:
verbose_name = _('ItemImageModel.verbose_name')
verbose_name_plural = _('ItemImageModel.verbose_name_plural')
ordering = ('position',)
class ItemFileModel(BaseItemAttachmentModel):
"""
Store files to Items
"""
file = models.FileField(
upload_to=user_directory_path,
verbose_name=_('ItemFileModel.file.verbose_name'),
help_text=_('ItemFileModel.file.help_text'),
)
def __str__(self):
return self.name or self.file.name
def full_clean(self, **kwargs):
# Set name by filename:
if not self.name:
filename = Path(self.file.name).name
self.name = clean_filename(filename)
return super().full_clean(**kwargs)
class Meta:
verbose_name = _('ItemFileModel.verbose_name')
verbose_name_plural = _('ItemFileModel.verbose_name_plural')
ordering = ('position',)