2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-04-05 19:10:54 +00:00

Receive virtual parts (#11627)

* Handle receive of virtual parts

- Update line item quantity
- Do not add any stock

* Add unit test

* Additional unit test

* UI form improvements

* Add playwright test

* Updated playwright tests
This commit is contained in:
Oliver
2026-03-30 19:10:56 +11:00
committed by GitHub
parent b4f230753f
commit dab4319033
7 changed files with 145 additions and 30 deletions

View File

@@ -1038,6 +1038,29 @@ class PurchaseOrder(TotalPriceMixin, Order):
base_part = supplier_part.part
# Update the line item quantity
line.received += quantity
line_items_to_update.append(line)
# Extract optional serial numbers
serials = item.get('serials', None)
if serials and type(serials) is list and len(serials) > 0:
serialize = True
else:
serialize = False
serials = [None]
if base_part.virtual:
# Virtual parts are not received into stock, so skip the rest of the loop
if serialize:
raise ValidationError(
_('Serial numbers cannot be assigned to virtual parts')
)
continue
stock_location = item.get('location', location) or line.get_destination()
# Calculate the received quantity in base part units
@@ -1052,15 +1075,6 @@ class PurchaseOrder(TotalPriceMixin, Order):
else:
purchase_price = None
# Extract optional serial numbers
serials = item.get('serials', None)
if serials and type(serials) is list and len(serials) > 0:
serialize = True
else:
serialize = False
serials = [None]
# Construct dataset for creating a new StockItem instances
stock_data = {
'part': supplier_part.part,
@@ -1144,10 +1158,6 @@ class PurchaseOrder(TotalPriceMixin, Order):
bulk_create_items.append(new_item)
# Update the line item quantity
line.received += quantity
line_items_to_update.append(line)
# Bulk create new stock items
if len(bulk_create_items) > 0:
stock.models.StockItem.objects.bulk_create(bulk_create_items)

View File

@@ -1336,6 +1336,47 @@ class PurchaseOrderReceiveTest(OrderTest):
# Check that the expected number of stock items has been created
self.assertEqual(n + 4, StockItem.objects.count())
def test_virtual(self):
"""Test receipt of "virtual" items (i.e. items which do not create a StockItem)."""
line = models.PurchaseOrderLineItem.objects.get(pk=1)
base_part = line.part.part
base_part.virtual = True
base_part.save()
self.assertEqual(line.received, 0)
N_ITEMS = base_part.stock_entries().count()
N_STOCK = base_part.get_stock_count()
# Try with serial numbers (expect to fail)
data = {
'items': [{'line_item': line.pk, 'quantity': 1, 'serial_numbers': '999'}],
'location': 1,
}
response = self.post(self.url, data, expected_code=400)
self.assertIn(
'Serial numbers cannot be assigned to virtual parts',
str(response.data['non_field_errors']),
)
# Try without serial numbers (expect to succeed)
data = {
'items': [{'line_item': line.pk, 'quantity': line.quantity}],
'location': 1,
}
self.post(self.url, data, expected_code=201)
# No new stock items should have been created
self.assertEqual(base_part.stock_entries().count(), N_ITEMS)
self.assertEqual(base_part.get_stock_count(), N_STOCK)
# Check that the line item has been fully received
line.refresh_from_db()
self.assertEqual(line.received, line.quantity)
class SalesOrderTest(OrderTest):
"""Tests for the SalesOrder API."""