diff --git a/src/backend/InvenTree/order/models.py b/src/backend/InvenTree/order/models.py index 6563bf1bc0..f83c9d7d55 100644 --- a/src/backend/InvenTree/order/models.py +++ b/src/backend/InvenTree/order/models.py @@ -1048,6 +1048,12 @@ class PurchaseOrder(TotalPriceMixin, Order): # List of line items to update line_items_to_update: list[PurchaseOrderLineItem] = [] + # Set of users to notify (subscribers to any received part) + notify_users = set() + + # Cache of subscribers per part, to avoid repeated queries for the same part + part_subscribers_cache: dict[int, list] = {} + convert_purchase_price = get_global_setting('PURCHASEORDER_CONVERT_CURRENCY') default_currency = currency_code_default() @@ -1106,6 +1112,13 @@ class PurchaseOrder(TotalPriceMixin, Order): line.received += quantity line_items_to_update.append(line) + # Track subscribers to this part, to notify them later + # (cache the result per-part, as multiple lines may reference the same part) + if base_part.pk not in part_subscribers_cache: + part_subscribers_cache[base_part.pk] = base_part.get_subscribers() + + notify_users.update(part_subscribers_cache[base_part.pk]) + # Extract optional serial numbers serials = item.get('serials', None) @@ -1200,13 +1213,15 @@ class PurchaseOrder(TotalPriceMixin, Order): serials=serials, **stock_data ) - for item in new_items: - item.set_status(status, custom_values=custom_stock_status_values) + for new_item in new_items: + new_item.set_status( + status, custom_values=custom_stock_status_values + ) # run validation for serialized items plugin.validate_batch_code - item.validate_batch_code() + new_item.validate_batch_code() # run validation for serialized items plugin.validate_model_instance - item.run_plugin_validation() - stock_items.append(item) + new_item.run_plugin_validation() + stock_items.append(new_item) else: new_item = stock.models.StockItem( @@ -1292,7 +1307,7 @@ class PurchaseOrder(TotalPriceMixin, Order): PurchaseOrder, exclude=user, content=InvenTreeNotificationBodies.ItemsReceived, - extra_users=line.part.part.get_subscribers(), + extra_users=notify_users, ) # Return a list of the created stock items