mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-04 06:18:48 +00:00
Refactor previous code for looking up "previous" and "next" serial numbers
- Old way was extremely inefficient, especially when large spaces existed between serial numbers - New method reduces O(n) to O(1)
This commit is contained in:
parent
d9f73ae05b
commit
2f3f57148a
@ -273,6 +273,55 @@ class StockItem(MPTTModel):
|
|||||||
|
|
||||||
self.serial_int = serial_int
|
self.serial_int = serial_int
|
||||||
|
|
||||||
|
def get_next_serial_number(self, include_variants=True, reverse=False):
|
||||||
|
"""
|
||||||
|
Get the "next" serial number for the part this stock item references.
|
||||||
|
|
||||||
|
e.g. if this stock item has a serial number 100, we may return the stock item with serial number 101
|
||||||
|
|
||||||
|
Note that this only works for "serialized" stock items with integer values
|
||||||
|
|
||||||
|
Args:
|
||||||
|
include_variants: True if we wish to include stock for variant parts
|
||||||
|
reverse: True if we want to return the "previous" (lower) serial number
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A StockItem object matching the requirements, or None
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not self.serialized:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Find only serialized stock items
|
||||||
|
items = StockItem.objects.exclude(serial=None).exclude(serial='')
|
||||||
|
|
||||||
|
if include_variants:
|
||||||
|
# Match against any part within the variant tree
|
||||||
|
items = items.filter(part__tree_id=self.part.tree_id)
|
||||||
|
else:
|
||||||
|
# Match only against the specific part
|
||||||
|
items = items.filter(part=self.part)
|
||||||
|
|
||||||
|
serial = self.serial_int
|
||||||
|
|
||||||
|
if reverse:
|
||||||
|
# Select only stock items with lower serial numbers, in decreasing order
|
||||||
|
items = items.filter(serial_int__lt=serial)
|
||||||
|
items = items.order_by('-serial_int')
|
||||||
|
else:
|
||||||
|
# Select only stock items with higher serial numbers, in increasing order
|
||||||
|
items = items.filter(serial_int__gt=serial)
|
||||||
|
items = items.order_by('serial_int')
|
||||||
|
|
||||||
|
if items.count() > 0:
|
||||||
|
item = items.first()
|
||||||
|
|
||||||
|
if item.serialized:
|
||||||
|
return item
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Save this StockItem to the database. Performs a number of checks:
|
Save this StockItem to the database. Performs a number of checks:
|
||||||
|
@ -101,43 +101,16 @@ class StockItemDetail(InvenTreeRoleMixin, DetailView):
|
|||||||
model = StockItem
|
model = StockItem
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
""" add previous and next item """
|
"""
|
||||||
|
Add information on the "next" and "previous" StockItem objects,
|
||||||
|
based on the serial numbers.
|
||||||
|
"""
|
||||||
|
|
||||||
data = super().get_context_data(**kwargs)
|
data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
if self.object.serialized:
|
if self.object.serialized:
|
||||||
|
data['previous'] = self.object.get_next_serial_number(reverse=True)
|
||||||
serial_elem = {}
|
data['next'] = self.object.get_next_serial_number()
|
||||||
|
|
||||||
try:
|
|
||||||
current = int(self.object.serial)
|
|
||||||
|
|
||||||
for item in self.object.part.stock_items.all():
|
|
||||||
|
|
||||||
if item.serialized:
|
|
||||||
try:
|
|
||||||
sn = int(item.serial)
|
|
||||||
serial_elem[sn] = item
|
|
||||||
except ValueError:
|
|
||||||
# We only support integer serial number progression
|
|
||||||
pass
|
|
||||||
|
|
||||||
serials = serial_elem.keys()
|
|
||||||
|
|
||||||
# previous
|
|
||||||
for nbr in range(current - 1, min(serials), -1):
|
|
||||||
if nbr in serials:
|
|
||||||
data['previous'] = serial_elem.get(nbr, None)
|
|
||||||
break
|
|
||||||
|
|
||||||
# next
|
|
||||||
for nbr in range(current + 1, max(serials) + 1):
|
|
||||||
if nbr in serials:
|
|
||||||
data['next'] = serial_elem.get(nbr, None)
|
|
||||||
break
|
|
||||||
|
|
||||||
except ValueError:
|
|
||||||
# We only support integer serial number progression
|
|
||||||
pass
|
|
||||||
|
|
||||||
data['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
|
data['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
|
||||||
data['item_owner'] = self.object.get_item_owner()
|
data['item_owner'] = self.object.get_item_owner()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user