Add 'overage' field to BOM item

- Accepts absolute or percentage numbers
- Default = blank
- Now with custom validator! (for limited time only, limit one per customer)
This commit is contained in:
Oliver Walters 2019-05-15 00:16:34 +10:00
parent 35d32fd2ff
commit f6baf5d2ae
4 changed files with 101 additions and 2 deletions

View File

@ -7,9 +7,56 @@ from django.utils.translation import gettext_lazy as _
def validate_part_name(value):
# Prevent some illegal characters in part names
for c in ['|', '#', '$']:
""" Prevent some illegal characters in part names.
"""
for c in ['|', '#', '$', '{', '}']:
if c in str(value):
raise ValidationError(
_('Invalid character in part name')
)
def validate_overage(value):
""" Validate that a BOM overage string is properly formatted.
An overage string can look like:
- An integer number ('1' / 3 / 4)
- A percentage ('5%' / '10 %')
"""
value = str(value).lower().strip()
# First look for a simple integer value
try:
i = int(value)
if i < 0:
raise ValidationError(_("Overage value must not be negative"))
# Looks like an integer!
return True
except ValueError:
pass
# Now look for a percentage value
if value.endswith('%'):
v = value[:-1].strip()
# Does it look like a number?
try:
f = float(v)
if f < 0:
raise ValidationError(_("Overage value must not be negative"))
elif f > 100:
raise ValidationError(_("Overage must not exceed 100%"))
return True
except ValueError:
pass
raise ValidationError(
_("Overage must be an integer value or a percentage")
)

View File

@ -133,6 +133,7 @@ class EditBomItemForm(HelperForm):
'part',
'sub_part',
'quantity',
'overage',
'note'
]

View File

@ -0,0 +1,46 @@
# Generated by Django 2.2 on 2019-05-14 14:12
import InvenTree.validators
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('part', '0024_partcategory_default_keywords'),
]
operations = [
migrations.AddField(
model_name='bomitem',
name='overage',
field=models.CharField(blank=True, help_text='Estimated build wastage quantity (absolute or percentage)', max_length=24, validators=[InvenTree.validators.validate_overage]),
),
migrations.AlterField(
model_name='bomitem',
name='note',
field=models.CharField(blank=True, help_text='BOM item notes', max_length=100),
),
migrations.AlterField(
model_name='bomitem',
name='part',
field=models.ForeignKey(help_text='Select parent part', limit_choices_to={'active': True, 'buildable': True}, on_delete=django.db.models.deletion.CASCADE, related_name='bom_items', to='part.Part'),
),
migrations.AlterField(
model_name='bomitem',
name='quantity',
field=models.PositiveIntegerField(default=1, help_text='BOM quantity for this BOM item', validators=[django.core.validators.MinValueValidator(0)]),
),
migrations.AlterField(
model_name='bomitem',
name='sub_part',
field=models.ForeignKey(help_text='Select part to be used in BOM', limit_choices_to={'active': True, 'consumable': True}, on_delete=django.db.models.deletion.CASCADE, related_name='used_in', to='part.Part'),
),
migrations.AlterField(
model_name='supplierpart',
name='URL',
field=models.URLField(blank=True, help_text='URL for external supplier part link'),
),
]

View File

@ -661,6 +661,7 @@ class BomItem(models.Model):
part: Link to the parent part (the part that will be produced)
sub_part: Link to the child part (the part that will be consumed)
quantity: Number of 'sub_parts' consumed to produce one 'part'
overage: Estimated losses for a Build. Can be expressed as absolute value (e.g. '7') or a percentage (e.g. '2%')
note: Note field for this BOM item
"""
@ -688,6 +689,10 @@ class BomItem(models.Model):
# Quantity required
quantity = models.PositiveIntegerField(default=1, validators=[MinValueValidator(0)], help_text='BOM quantity for this BOM item')
overage = models.CharField(max_length=24, blank=True, validators=[validators.validate_overage],
help_text='Estimated build wastage quantity (absolute or percentage)'
)
# Note attached to this BOM line item
note = models.CharField(max_length=100, blank=True, help_text='BOM item notes')