mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-14 00:09:56 +00:00
Feature/location types (#5588)
* Added model changes for StockLocationTypes * Implement icon for CUI * Added location type to location table with filters * Fix ruleset * Added tests * Bump api version to v136 * trigger: ci * Bump api version variable too
This commit is contained in:
@@ -41,6 +41,66 @@ from plugin.events import trigger_event
|
||||
from users.models import Owner
|
||||
|
||||
|
||||
class StockLocationType(MetadataMixin, models.Model):
|
||||
"""A type of stock location like Warehouse, room, shelf, drawer.
|
||||
|
||||
Attributes:
|
||||
name: brief name
|
||||
description: longer form description
|
||||
icon: icon class
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""Metaclass defines extra model properties."""
|
||||
|
||||
verbose_name = _("Stock Location type")
|
||||
verbose_name_plural = _("Stock Location types")
|
||||
|
||||
@staticmethod
|
||||
def get_api_url():
|
||||
"""Return API url."""
|
||||
return reverse('api-location-type-list')
|
||||
|
||||
def __str__(self):
|
||||
"""String representation of a StockLocationType."""
|
||||
return self.name
|
||||
|
||||
name = models.CharField(
|
||||
blank=False,
|
||||
max_length=100,
|
||||
verbose_name=_("Name"),
|
||||
help_text=_("Name"),
|
||||
)
|
||||
|
||||
description = models.CharField(
|
||||
blank=True,
|
||||
max_length=250,
|
||||
verbose_name=_("Description"),
|
||||
help_text=_("Description (optional)")
|
||||
)
|
||||
|
||||
icon = models.CharField(
|
||||
blank=True,
|
||||
max_length=100,
|
||||
verbose_name=_("Icon"),
|
||||
help_text=_("Default icon for all locations that have no icon set (optional)")
|
||||
)
|
||||
|
||||
|
||||
class StockLocationManager(TreeManager):
|
||||
"""Custom database manager for the StockLocation class.
|
||||
|
||||
StockLocation querysets will automatically select related fields for performance.
|
||||
"""
|
||||
|
||||
def get_queryset(self):
|
||||
"""Prefetch queryset to optimize db hits.
|
||||
|
||||
- Joins the StockLocationType by default for speedier icon access
|
||||
"""
|
||||
return super().get_queryset().select_related("location_type")
|
||||
|
||||
|
||||
class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
|
||||
"""Organization tree for StockItem objects.
|
||||
|
||||
@@ -48,6 +108,8 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
|
||||
Stock locations can be hierarchical as required
|
||||
"""
|
||||
|
||||
objects = StockLocationManager()
|
||||
|
||||
class Meta:
|
||||
"""Metaclass defines extra model properties"""
|
||||
|
||||
@@ -107,11 +169,12 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
|
||||
"""Return API url."""
|
||||
return reverse('api-location-list')
|
||||
|
||||
icon = models.CharField(
|
||||
custom_icon = models.CharField(
|
||||
blank=True,
|
||||
max_length=100,
|
||||
verbose_name=_("Icon"),
|
||||
help_text=_("Icon (optional)")
|
||||
help_text=_("Icon (optional)"),
|
||||
db_column="icon",
|
||||
)
|
||||
|
||||
owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True,
|
||||
@@ -133,6 +196,38 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
|
||||
help_text=_('This is an external stock location')
|
||||
)
|
||||
|
||||
location_type = models.ForeignKey(
|
||||
StockLocationType,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name=_("Location type"),
|
||||
related_name="stock_locations",
|
||||
null=True, blank=True,
|
||||
help_text=_("Stock location type of this location"),
|
||||
)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Get the current icon used for this location.
|
||||
|
||||
The icon field on this model takes precedences over the possibly assigned stock location type
|
||||
"""
|
||||
if self.custom_icon:
|
||||
return self.custom_icon
|
||||
|
||||
if self.location_type:
|
||||
return self.location_type.icon
|
||||
|
||||
return ""
|
||||
|
||||
@icon.setter
|
||||
def icon(self, value):
|
||||
"""Setter to keep model API compatibility. But be careful:
|
||||
|
||||
If the field gets loaded as default value by any form which is later saved,
|
||||
the location no longer inherits its icon from the location type.
|
||||
"""
|
||||
self.custom_icon = value
|
||||
|
||||
def get_location_owner(self):
|
||||
"""Get the closest "owner" for this location.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user