2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 11:10:54 +00:00

Part units (#4854)

* Add validation to part units field

* Add "pack_units" field to the SupplierPart model

* Migrate old units to new units, and remove old field

* Table fix

* Fixture fix

* Update migration

* Improve "hook" for loading custom unit database

* Display part units column in part table

- Also allow ordering by part units
- Allow filtering to show parts which have defined units

* Adds data migration for converting units to valid values

* Add "pack_units_native" field to company.SupplierPart model

* Clean pack units when saving a SupplierPart

- Convert to native part units
- Handle empty units value
- Add unit tests

* Add background function to rebuild supplier parts when a part is saved

- Required to ensure that the "pack_size_native" is up to date

* Template updates

* Sort by native units first

* Bump API version

* Rename "pack_units" to "pack_quantity"

* Update migration file

- Allow reverse migration

* Fix for currency migration

- Handle case where no currencies are provided
- Handle case where base currency is not in provided options

* Adds unit test for data migration

* Add unit test for part.units data migration

- Check that units fields are updated correctly

* Add some extra "default units"

- each / piece
- dozen / hundred / thousand
- Add unit testing also

* Update references to "pack_size"

- Replace with "pack_quantity" or "pack_quantity_native" as appropriate

* Improvements based on unit testing

* catch error

* Docs updates

* Fixes for pricing tests

* Update unit tests for part migrations · 1b6b6d9d

* Bug fix for conversion code

* javascript updates

* JS formatting fix
This commit is contained in:
Oliver
2023-05-26 16:57:23 +10:00
committed by GitHub
parent 717bb07dcf
commit 5dd6f18495
39 changed files with 878 additions and 251 deletions

View File

@ -602,11 +602,13 @@ class PurchaseOrder(TotalPriceMixin, Order):
# Create a new stock item
if line.part and quantity > 0:
# Take the 'pack_size' of the SupplierPart into account
pack_quantity = Decimal(quantity) * Decimal(line.part.pack_size)
# Calculate received quantity in base units
stock_quantity = line.part.base_quantity(quantity)
# Calculate unit purchase price (in base units)
if line.purchase_price:
unit_purchase_price = line.purchase_price / line.part.pack_size
unit_purchase_price = line.purchase_price
unit_purchase_price /= line.part.base_quantity(1)
else:
unit_purchase_price = None
@ -623,7 +625,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
part=line.part.part,
supplier_part=line.part,
location=location,
quantity=1 if serialize else pack_quantity,
quantity=1 if serialize else stock_quantity,
purchase_order=self,
status=status,
batch=batch_code,
@ -656,7 +658,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
)
# Update the number of parts received against the particular line item
# Note that this quantity does *not* take the pack_size into account, it is "number of packs"
# Note that this quantity does *not* take the pack_quantity into account, it is "number of packs"
line.received += quantity
line.save()

View File

@ -558,14 +558,12 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
serial_numbers = data.get('serial_numbers', '').strip()
base_part = line_item.part.part
pack_size = line_item.part.pack_size
pack_quantity = pack_size * quantity
base_quantity = line_item.part.base_quantity(quantity)
# Does the quantity need to be "integer" (for trackable parts?)
if base_part.trackable:
if Decimal(pack_quantity) != int(pack_quantity):
if Decimal(base_quantity) != int(base_quantity):
raise ValidationError({
'quantity': _('An integer quantity must be provided for trackable parts'),
})
@ -576,7 +574,7 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
# Pass the serial numbers through to the parent serializer once validated
data['serials'] = extract_serial_numbers(
serial_numbers,
pack_quantity,
base_quantity,
base_part.get_latest_serial_number()
)
except DjangoValidationError as e:

View File

@ -228,7 +228,7 @@ class OrderTest(TestCase):
part=prt,
supplier=sup,
SKU='SKUx10',
pack_size=10,
pack_quantity='10',
)
# Create a new supplier part with smaller pack size
@ -236,7 +236,7 @@ class OrderTest(TestCase):
part=prt,
supplier=sup,
SKU='SKUx0.1',
pack_size=0.1,
pack_quantity='0.1',
)
# Record values before we start