mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Use the hash for each line item to calculate the total BOM hash
This commit is contained in:
parent
7671eb2b22
commit
0508c2dcaf
InvenTree/part
@ -631,24 +631,15 @@ class Part(models.Model):
|
||||
""" Return a checksum hash for the BOM for this part.
|
||||
Used to determine if the BOM has changed (and needs to be signed off!)
|
||||
|
||||
For hash is calculated from the following fields of each BOM item:
|
||||
The hash is calculated by hashing each line item in the BOM.
|
||||
|
||||
- Part.full_name (if the part name changes, the BOM checksum is invalidated)
|
||||
- Quantity
|
||||
- Reference field
|
||||
- Note field
|
||||
|
||||
returns a string representation of a hash object which can be compared with a stored value
|
||||
"""
|
||||
|
||||
hash = hashlib.md5(str(self.id).encode())
|
||||
|
||||
for item in self.bom_items.all().prefetch_related('sub_part'):
|
||||
hash.update(str(item.sub_part.id).encode())
|
||||
hash.update(str(item.sub_part.full_name).encode())
|
||||
hash.update(str(item.quantity).encode())
|
||||
hash.update(str(item.note).encode())
|
||||
hash.update(str(item.reference).encode())
|
||||
hash.update(str(item.get_item_hash()).encode())
|
||||
|
||||
return str(hash.digest())
|
||||
|
||||
@ -667,6 +658,10 @@ class Part(models.Model):
|
||||
- Saves the current date and the checking user
|
||||
"""
|
||||
|
||||
# Validate each line item too
|
||||
for item in self.bom_items.all():
|
||||
item.validate_hash()
|
||||
|
||||
self.bom_checksum = self.get_bom_hash()
|
||||
self.bom_checked_by = user
|
||||
self.bom_checked_date = datetime.now().date()
|
||||
@ -1157,6 +1152,42 @@ class BomItem(models.Model):
|
||||
|
||||
checksum = models.CharField(max_length=128, blank=True, help_text='BOM line checksum')
|
||||
|
||||
def get_item_hash(self):
|
||||
""" Calculate the checksum hash of this BOM line item:
|
||||
|
||||
The hash is calculated from the following fields:
|
||||
|
||||
- Part.full_name (if the part name changes, the BOM checksum is invalidated)
|
||||
- Quantity
|
||||
- Reference field
|
||||
- Note field
|
||||
|
||||
"""
|
||||
|
||||
# Seed the hash with the ID of this BOM item
|
||||
hash = hashlib.md5(str(self.id).encode())
|
||||
|
||||
# Update the hash based on line information
|
||||
hash.update(str(self.sub_part.id).encode())
|
||||
hash.update(str(self.sub_part.full_name).encode())
|
||||
hash.update(str(self.quantity).encode())
|
||||
hash.update(str(self.note).encode())
|
||||
hash.update(str(self.reference).encode())
|
||||
|
||||
return str(hash.digest())
|
||||
|
||||
def validate_hash(self):
|
||||
""" Mark this item as 'valid' (store the checksum hash) """
|
||||
|
||||
self.checksum = str(self.get_item_hash())
|
||||
self.save()
|
||||
|
||||
@property
|
||||
def is_line_valid(self):
|
||||
""" Check if this line item has been validated by the user """
|
||||
|
||||
return self.get_item_hash() == self.checksum
|
||||
|
||||
def clean(self):
|
||||
""" Check validity of the BomItem model.
|
||||
|
||||
|
@ -131,6 +131,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
||||
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
||||
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
|
||||
price_range = serializers.CharField(read_only=True)
|
||||
validated = serializers.BooleanField(read_only=True, source='is_line_valid')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# part_detail and sub_part_detail serializers are only included if requested.
|
||||
@ -171,4 +172,5 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
||||
'price_range',
|
||||
'overage',
|
||||
'note',
|
||||
'validated',
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user