2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-22 01:06:50 +00:00

Normalize BomItem quantity (#11975)

- Limit decimal places before save
- Prevents error in BomItem validation
This commit is contained in:
Oliver
2026-05-21 16:43:49 +10:00
committed by GitHub
parent f768bb38a0
commit 3f3433685d
+11 -7
View File
@@ -2,14 +2,13 @@
from __future__ import annotations from __future__ import annotations
import decimal
import hashlib import hashlib
import inspect import inspect
import math import math
import os import os
import re import re
from datetime import timedelta from datetime import timedelta
from decimal import Decimal, InvalidOperation from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
from typing import TypedDict, cast from typing import TypedDict, cast
from django.conf import settings from django.conf import settings
@@ -2052,8 +2051,9 @@ class Part(
'part', 'sub_part' 'part', 'sub_part'
) )
if valid:
for item in bom_items: for item in bom_items:
item.validate_hash(valid=valid) item.validate_hash(valid=True)
self.bom_validated = valid self.bom_validated = valid
self.bom_checksum = self.get_bom_hash() if valid else '' self.bom_checksum = self.get_bom_hash() if valid else ''
@@ -2233,8 +2233,8 @@ class Part(
logger.warning('WARNING: BomItem ID %s contains itself in BOM', item.pk) logger.warning('WARNING: BomItem ID %s contains itself in BOM', item.pk)
continue continue
q = decimal.Decimal(quantity) q = Decimal(quantity)
i = decimal.Decimal(item.quantity) i = Decimal(item.quantity)
prices = item.sub_part.get_price_range( prices = item.sub_part.get_price_range(
q * i, internal=internal, purchase=purchase q * i, internal=internal, purchase=purchase
@@ -3934,14 +3934,18 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel):
'raw_amount': _('Quantity must be greater than zero') 'raw_amount': _('Quantity must be greater than zero')
}) })
self.quantity = Decimal(quantity.magnitude) # Normalize the quantity, to maximum 5 decimal places
quantity = Decimal(quantity.magnitude)
except ValidationError as e: except ValidationError as e:
raise ValidationError({'raw_amount': e.messages}) raise ValidationError({'raw_amount': e.messages})
# Ensure that the raw_amount is converted to a Decimal value # Ensure that the raw_amount is converted to a Decimal value
# and quantized to a maximum of 5 decimal places (to avoid floating point issues)
try: try:
self.quantity = Decimal(self.quantity) self.quantity = Decimal(quantity).quantize(
Decimal('0.00001'), rounding=ROUND_HALF_UP
)
except InvalidOperation: except InvalidOperation:
msg = _('Invalid quantity provided') msg = _('Invalid quantity provided')
raise ValidationError({'quantity': msg, 'raw_amount': msg}) raise ValidationError({'quantity': msg, 'raw_amount': msg})