mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Update BomItem 'validated' field (#4486)
* Adds new "validated" field to the BomItem model - Previously this was dynamically calculated (very expensive) - Now cached and updated whenever a BomItem instance is saved - Will make the BOM API much more responsive - Cleanup BomItem list API code also * Adds data migration to update existing BomItem objects * Exclude 'validated' field from BomItemResource class
This commit is contained in:
parent
06f8a50956
commit
1ba51e51c3
@ -259,6 +259,7 @@ class BomItemResource(InvenTreeResource):
|
||||
'id',
|
||||
'part',
|
||||
'sub_part',
|
||||
'validated',
|
||||
]
|
||||
|
||||
level = Field(attribute='level', column_name=_('BOM Level'), readonly=True)
|
||||
|
@ -1598,11 +1598,17 @@ class PartStocktakeReportGenerate(CreateAPI):
|
||||
class BomFilter(rest_filters.FilterSet):
|
||||
"""Custom filters for the BOM list."""
|
||||
|
||||
# Boolean filters for BOM item
|
||||
optional = rest_filters.BooleanFilter(label='BOM item is optional')
|
||||
consumable = rest_filters.BooleanFilter(label='BOM item is consumable')
|
||||
inherited = rest_filters.BooleanFilter(label='BOM item gets inherited')
|
||||
allow_variants = rest_filters.BooleanFilter(label='Variants are allowed')
|
||||
class Meta:
|
||||
"""Metaclass options"""
|
||||
|
||||
model = BomItem
|
||||
fields = [
|
||||
'optional',
|
||||
'consumable',
|
||||
'inherited',
|
||||
'allow_variants',
|
||||
'validated',
|
||||
]
|
||||
|
||||
# Filters for linked 'part'
|
||||
part_active = rest_filters.BooleanFilter(label='Master part is active', field_name='part__active')
|
||||
@ -1612,29 +1618,6 @@ class BomFilter(rest_filters.FilterSet):
|
||||
sub_part_trackable = rest_filters.BooleanFilter(label='Sub part is trackable', field_name='sub_part__trackable')
|
||||
sub_part_assembly = rest_filters.BooleanFilter(label='Sub part is an assembly', field_name='sub_part__assembly')
|
||||
|
||||
validated = rest_filters.BooleanFilter(label='BOM line has been validated', method='filter_validated')
|
||||
|
||||
def filter_validated(self, queryset, name, value):
|
||||
"""Filter by which lines have actually been validated"""
|
||||
pks = []
|
||||
|
||||
value = str2bool(value)
|
||||
|
||||
# Shortcut for quicker filtering - BomItem with empty 'checksum' values are not validated
|
||||
if value:
|
||||
queryset = queryset.exclude(checksum=None).exclude(checksum='')
|
||||
|
||||
for bom_item in queryset.all():
|
||||
if bom_item.is_line_valid:
|
||||
pks.append(bom_item.pk)
|
||||
|
||||
if value:
|
||||
queryset = queryset.filter(pk__in=pks)
|
||||
else:
|
||||
queryset = queryset.exclude(pk__in=pks)
|
||||
|
||||
return queryset
|
||||
|
||||
available_stock = rest_filters.BooleanFilter(label="Has available stock", method="filter_available_stock")
|
||||
|
||||
def filter_available_stock(self, queryset, name, value):
|
||||
@ -1814,9 +1797,6 @@ class BomList(ListCreateDestroyAPIView):
|
||||
InvenTreeOrderingFilter,
|
||||
]
|
||||
|
||||
filterset_fields = [
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
'reference',
|
||||
'sub_part__name',
|
||||
|
18
InvenTree/part/migrations/0101_bomitem_validated.py
Normal file
18
InvenTree/part/migrations/0101_bomitem_validated.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.2.18 on 2023-03-14 01:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('part', '0100_alter_bomitem_reference'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='bomitem',
|
||||
name='validated',
|
||||
field=models.BooleanField(default=False, help_text='This BOM item has been validated', verbose_name='Validated'),
|
||||
),
|
||||
]
|
40
InvenTree/part/migrations/0102_auto_20230314_0112.py
Normal file
40
InvenTree/part/migrations/0102_auto_20230314_0112.py
Normal file
@ -0,0 +1,40 @@
|
||||
# Generated by Django 3.2.18 on 2023-03-14 01:12
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
def update_bom_item(apps, schema_editor):
|
||||
"""Update all existing BomItem instances"""
|
||||
|
||||
from part.models import BomItem
|
||||
|
||||
if n := BomItem.objects.count():
|
||||
|
||||
for item in BomItem.objects.all():
|
||||
item.save()
|
||||
|
||||
logger.info(f"Updated 'validated' flag for {n} BomItem objects")
|
||||
|
||||
|
||||
def meti_mob_etadpu(apps, schema_editor):
|
||||
"""Provided for reverse compatibility"""
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('part', '0101_bomitem_validated'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
update_bom_item,
|
||||
reverse_code=meti_mob_etadpu
|
||||
)
|
||||
]
|
@ -3543,6 +3543,10 @@ class BomItem(DataImportMixin, models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
"""Enforce 'clean' operation when saving a BomItem instance"""
|
||||
self.clean()
|
||||
|
||||
# Update the 'validated' field based on checksum calculation
|
||||
self.validated = self.is_line_valid
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# A link to the parent part
|
||||
@ -3588,7 +3592,16 @@ class BomItem(DataImportMixin, models.Model):
|
||||
# Note attached to this BOM line item
|
||||
note = models.CharField(max_length=500, blank=True, verbose_name=_('Note'), help_text=_('BOM item notes'))
|
||||
|
||||
checksum = models.CharField(max_length=128, blank=True, verbose_name=_('Checksum'), help_text=_('BOM line checksum'))
|
||||
checksum = models.CharField(
|
||||
max_length=128, blank=True,
|
||||
verbose_name=_('Checksum'), help_text=_('BOM line checksum')
|
||||
)
|
||||
|
||||
validated = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name=_('Validated'),
|
||||
help_text=_('This BOM item has been validated')
|
||||
)
|
||||
|
||||
inherited = models.BooleanField(
|
||||
default=False,
|
||||
|
@ -1099,8 +1099,6 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
||||
|
||||
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
|
||||
|
||||
validated = serializers.BooleanField(read_only=True, source='is_line_valid')
|
||||
|
||||
on_order = serializers.FloatField(read_only=True)
|
||||
|
||||
# Cached pricing fields
|
||||
|
Loading…
Reference in New Issue
Block a user