mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Part: Extend logic for "latest" serial number
- Return value if it is a string - Remove 'getNextSerialNumber' function - Improve functionality of function which returns serial number placeholder string
This commit is contained in:
parent
e6c0a04131
commit
74f25ee7f9
@ -197,12 +197,8 @@ class BuildComplete(AjaxUpdateView):
|
||||
if not build.part.trackable:
|
||||
form.fields.pop('serial_numbers')
|
||||
else:
|
||||
if build.quantity == 1:
|
||||
text = _('Next available serial number is')
|
||||
else:
|
||||
text = _('Next available serial numbers are')
|
||||
|
||||
form.field_placeholder['serial_numbers'] = text + " " + build.part.getSerialNumberString(build.quantity)
|
||||
form.field_placeholder['serial_numbers'] = build.part.getSerialNumberString(build.quantity)
|
||||
|
||||
form.rebuild_layout()
|
||||
|
||||
|
@ -319,9 +319,12 @@ class Part(MPTTModel):
|
||||
|
||||
return stock.exists()
|
||||
|
||||
def getHighestSerialNumber(self):
|
||||
def getLatestSerialNumber(self):
|
||||
"""
|
||||
Return the highest serial number for this Part.
|
||||
Return the "latest" serial number for this Part.
|
||||
|
||||
If *all* the serial numbers are integers, then this will return the highest one.
|
||||
Otherwise, it will simply return the serial number most recently added.
|
||||
|
||||
Note: Serial numbers must be unique across an entire Part "tree",
|
||||
so we filter by the entire tree.
|
||||
@ -330,51 +333,61 @@ class Part(MPTTModel):
|
||||
parts = Part.objects.filter(tree_id=self.tree_id)
|
||||
stock = StockModels.StockItem.objects.filter(part__in=parts).exclude(serial=None)
|
||||
|
||||
# There are no matchin StockItem objects (skip further tests)
|
||||
if not stock.exists():
|
||||
return None
|
||||
|
||||
# Attempt to coerce the returned serial numbers to integers
|
||||
# If *any* are not integers, fail!
|
||||
try:
|
||||
ordered = sorted(stock.all(), reverse=True, key=lambda n: int(n.serial))
|
||||
|
||||
if len(ordered) > 0:
|
||||
return ordered[0].serial
|
||||
|
||||
# Non-numeric serials, so don't suggest one.
|
||||
# One or more of the serial numbers was non-numeric
|
||||
# In this case, the "best" we can do is return the most recent
|
||||
except ValueError:
|
||||
return None
|
||||
return stock.last().serial
|
||||
|
||||
# No serial numbers found
|
||||
return 0
|
||||
|
||||
def getNextSerialNumber(self):
|
||||
"""
|
||||
Return the next-available serial number for this Part.
|
||||
"""
|
||||
|
||||
n = self.getHighestSerialNumber()
|
||||
|
||||
if n is None:
|
||||
return None
|
||||
else:
|
||||
return int(n) + 1
|
||||
|
||||
def getSerialNumberString(self, quantity):
|
||||
def getSerialNumberString(self, quantity=1):
|
||||
"""
|
||||
Return a formatted string representing the next available serial numbers,
|
||||
given a certain quantity of items.
|
||||
"""
|
||||
|
||||
sn = self.getNextSerialNumber()
|
||||
latest = self.getLatestSerialNumber()
|
||||
|
||||
if sn is None:
|
||||
return None
|
||||
quantity = int(quantity)
|
||||
|
||||
# No serial numbers can be found, assume 1 as the first serial
|
||||
if latest is None:
|
||||
latest = 0
|
||||
|
||||
# Attempt to turn into an integer
|
||||
try:
|
||||
latest = int(latest)
|
||||
except:
|
||||
pass
|
||||
|
||||
if type(latest) is int:
|
||||
|
||||
if quantity >= 2:
|
||||
sn = "{n}-{m}".format(
|
||||
n=sn,
|
||||
m=int(sn + quantity - 1)
|
||||
)
|
||||
else:
|
||||
sn = str(sn)
|
||||
text = '{n} - {m}'.format(n=latest+1, m=latest+1+quantity)
|
||||
|
||||
return sn
|
||||
return _('Next available serial numbers are') + ' ' + text
|
||||
else:
|
||||
text = str(latest)
|
||||
|
||||
return _('Next available serial number is') + ' ' + text
|
||||
|
||||
else:
|
||||
# Non-integer values, no option but to return latest
|
||||
|
||||
return _('Most recent serial number is') + ' ' + str(latest)
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
|
@ -36,8 +36,14 @@
|
||||
{% if part.trackable %}
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td><b>{% trans "Next Serial Number" %}</b></td>
|
||||
<td>{{ part.getNextSerialNumber }}</td>
|
||||
<td><b>{% trans "Latest Serial Number" %}</b></td>
|
||||
<td>
|
||||
{% if part.getLatestSerialNumber %}
|
||||
{{ part.getLatestSerialNumber }}
|
||||
{% else %}
|
||||
{% trans "No serial numbers recorded" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
|
@ -372,14 +372,14 @@ class VariantTest(StockTest):
|
||||
|
||||
self.assertFalse(chair.checkIfSerialNumberExists(30))
|
||||
|
||||
self.assertEqual(chair.getNextSerialNumber(), 23)
|
||||
self.assertEqual(chair.getLatestSerialNumber(), '22')
|
||||
|
||||
# Same operations on a sub-item
|
||||
variant = Part.objects.get(pk=10003)
|
||||
self.assertEqual(variant.getNextSerialNumber(), 23)
|
||||
self.assertEqual(variant.getLatestSerialNumber(), '22')
|
||||
|
||||
# Create a new serial number
|
||||
n = variant.getHighestSerialNumber()
|
||||
n = variant.getLatestSerialNumber()
|
||||
|
||||
item = StockItem(
|
||||
part=variant,
|
||||
@ -394,10 +394,8 @@ class VariantTest(StockTest):
|
||||
# Verify items with a non-numeric serial don't offer a next serial.
|
||||
item.serial = "string"
|
||||
item.save()
|
||||
self.assertEqual(variant.getNextSerialNumber(), None)
|
||||
|
||||
# And the same for the range when serializing.
|
||||
self.assertEqual(variant.getSerialNumberString(5), None)
|
||||
self.assertEqual(variant.getLatestSerialNumber(), "string")
|
||||
|
||||
# This should pass, although not strictly an int field now.
|
||||
item.serial = int(n) + 1
|
||||
|
@ -1234,8 +1234,9 @@ class StockItemCreate(AjaxCreateView):
|
||||
part = self.get_part(form=form)
|
||||
|
||||
if part is not None:
|
||||
sn = part.getNextSerialNumber()
|
||||
form.field_placeholder['serial_numbers'] = _('Next available serial number is') + ' ' + str(sn)
|
||||
|
||||
# Add placeholder text for the serial number field
|
||||
form.field_placeholder['serial_numbers'] = part.getSerialNumberString()
|
||||
|
||||
form.rebuild_layout()
|
||||
|
||||
@ -1353,11 +1354,6 @@ class StockItemCreate(AjaxCreateView):
|
||||
part = Part.objects.get(id=part_id)
|
||||
quantity = Decimal(form['quantity'].value())
|
||||
|
||||
sn = part.getNextSerialNumber()
|
||||
form.field_placeholder['serial_numbers'] = _("Next available serial number is") + " " + str(sn)
|
||||
|
||||
form.rebuild_layout()
|
||||
|
||||
except (Part.DoesNotExist, ValueError, InvalidOperation):
|
||||
part = None
|
||||
quantity = 1
|
||||
|
Loading…
Reference in New Issue
Block a user