kopia lustrzana https://github.com/jedie/PyInventory
228 wiersze
6.9 KiB
Python
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',)
|