mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	[bug] Custom state fix (#9858)
* Set status correctly when returning from customer * Fix for stock item status change - Reduced set of changes from #9781 * Handle API updates * Fix variable shadowing * More intelligent comparison * Remove debug statement
This commit is contained in:
		| @@ -301,6 +301,13 @@ class StatusCodeMixin: | ||||
|         """Return the custom status code for this object.""" | ||||
|         return getattr(self, f'{self.STATUS_FIELD}_custom_key', None) | ||||
|  | ||||
|     def compare_status(self, status: int) -> bool: | ||||
|         """Determine if the current status matches the provided status code.""" | ||||
|         if status == self.get_status(): | ||||
|             return True | ||||
|  | ||||
|         return status is not None and status == self.get_custom_status() | ||||
|  | ||||
|     def set_status(self, status: int) -> bool: | ||||
|         """Set the status code for this object.""" | ||||
|         if not self.status_class: | ||||
|   | ||||
| @@ -1067,6 +1067,11 @@ class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): | ||||
|         # Do this regardless of results above | ||||
|         data.pop('use_pack_size', None) | ||||
|  | ||||
|         # Extract 'status' flag from data | ||||
|         status_raw = data.pop('status', None) | ||||
|         status_custom = data.pop('status_custom_key', None) | ||||
|         status_value = status_custom or status_raw | ||||
|  | ||||
|         # Assign serial numbers for a trackable part | ||||
|         if serial_numbers: | ||||
|             if not part.trackable: | ||||
| @@ -1130,10 +1135,14 @@ class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): | ||||
|                 tracking = [] | ||||
|  | ||||
|                 for item in items: | ||||
|                     if status_value and not item.compare_status(status_value): | ||||
|                         item.set_status(status_value) | ||||
|                         item.save() | ||||
|  | ||||
|                     if entry := item.add_tracking_entry( | ||||
|                         StockHistoryCode.CREATED, | ||||
|                         user, | ||||
|                         deltas={'status': item.status}, | ||||
|                         deltas={'status': status_value}, | ||||
|                         location=location, | ||||
|                         quantity=float(item.quantity), | ||||
|                         commit=False, | ||||
| @@ -1152,6 +1161,10 @@ class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): | ||||
|                 # Create a single StockItem object | ||||
|                 # Note: This automatically creates a tracking entry | ||||
|                 item = serializer.save() | ||||
|  | ||||
|                 if status_value and not item.compare_status(status_value): | ||||
|                     item.set_status(status_value) | ||||
|  | ||||
|                 item.save(user=user) | ||||
|  | ||||
|                 response_data = serializer.data | ||||
|   | ||||
| @@ -1332,9 +1332,10 @@ class StockItem( | ||||
|         self.sales_order = None | ||||
|         self.location = location | ||||
|  | ||||
|         if status := kwargs.get('status'): | ||||
|             self.status = status | ||||
|             tracking_info['status'] = status | ||||
|         if status := kwargs.pop('status', None): | ||||
|             if not self.compare_status(status): | ||||
|                 self.set_status(status) | ||||
|                 tracking_info['status'] = status | ||||
|  | ||||
|         self.save() | ||||
|  | ||||
| @@ -2240,7 +2241,7 @@ class StockItem( | ||||
|  | ||||
|         status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) | ||||
|  | ||||
|         if status and status != self.status: | ||||
|         if status and not self.compare_status(status): | ||||
|             self.set_status(status) | ||||
|             tracking_info['status'] = status | ||||
|  | ||||
| @@ -2325,7 +2326,7 @@ class StockItem( | ||||
|  | ||||
|         status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) | ||||
|  | ||||
|         if status and status != self.status: | ||||
|         if status and not self.compare_status(status): | ||||
|             self.set_status(status) | ||||
|             tracking_info['status'] = status | ||||
|  | ||||
| @@ -2388,7 +2389,7 @@ class StockItem( | ||||
|  | ||||
|         status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) | ||||
|  | ||||
|         if status and status != self.status: | ||||
|         if status and not self.compare_status(status): | ||||
|             self.set_status(status) | ||||
|             tracking_info['status'] = status | ||||
|  | ||||
| @@ -2442,7 +2443,7 @@ class StockItem( | ||||
|  | ||||
|         status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) | ||||
|  | ||||
|         if status and status != self.status: | ||||
|         if status and not self.compare_status(status): | ||||
|             self.set_status(status) | ||||
|             deltas['status'] = status | ||||
|  | ||||
|   | ||||
| @@ -521,7 +521,17 @@ class StockItemSerializer( | ||||
|         """Custom update method to pass the user information through to the instance.""" | ||||
|         instance._user = self.context['user'] | ||||
|  | ||||
|         return super().update(instance, validated_data) | ||||
|         status_custom_key = validated_data.pop('status_custom_key', None) | ||||
|         status = validated_data.pop('status', None) | ||||
|  | ||||
|         instance = super().update(instance, validated_data=validated_data) | ||||
|  | ||||
|         if status_code := status_custom_key or status: | ||||
|             if not instance.compare_status(status_code): | ||||
|                 instance.set_status(status_code) | ||||
|                 instance.save() | ||||
|  | ||||
|         return instance | ||||
|  | ||||
|     @staticmethod | ||||
|     def annotate_queryset(queryset): | ||||
| @@ -1123,7 +1133,6 @@ class StockChangeStatusSerializer(serializers.Serializer): | ||||
|  | ||||
|         note = data.get('note', '') | ||||
|  | ||||
|         items_to_update = [] | ||||
|         transaction_notes = [] | ||||
|  | ||||
|         deltas = {'status': status} | ||||
| @@ -1135,12 +1144,11 @@ class StockChangeStatusSerializer(serializers.Serializer): | ||||
|  | ||||
|         for item in items: | ||||
|             # Ignore items which are already in the desired status | ||||
|             if item.status == status: | ||||
|             if item.compare_status(status): | ||||
|                 continue | ||||
|  | ||||
|             item.updated = now | ||||
|             item.status = status | ||||
|             items_to_update.append(item) | ||||
|             item.set_status(status) | ||||
|             item.save(add_note=False) | ||||
|  | ||||
|             # Create a new transaction note for each item | ||||
|             transaction_notes.append( | ||||
| @@ -1154,10 +1162,7 @@ class StockChangeStatusSerializer(serializers.Serializer): | ||||
|                 ) | ||||
|             ) | ||||
|  | ||||
|         # Update status | ||||
|         StockItem.objects.bulk_update(items_to_update, ['status', 'updated']) | ||||
|  | ||||
|         # Create entries | ||||
|         # Create tracking entries | ||||
|         StockItemTracking.objects.bulk_create(transaction_notes) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from users.models import Owner | ||||
|  | ||||
|  | ||||
| class StockViewTestCase(InvenTreeTestCase): | ||||
|     """Mixin for Stockview tests.""" | ||||
|     """Mixin for StockView tests.""" | ||||
|  | ||||
|     fixtures = ['category', 'part', 'company', 'location', 'supplier_part', 'stock'] | ||||
|  | ||||
| @@ -46,7 +46,7 @@ class StockOwnershipTest(StockViewTestCase): | ||||
|         """Helper function to get response to API change.""" | ||||
|         return self.client.patch( | ||||
|             reverse('api-stock-detail', args=(self.test_item_id,)), | ||||
|             {'status': StockStatus.DAMAGED.value}, | ||||
|             {'status_custom_key': StockStatus.DAMAGED.value}, | ||||
|             content_type='application/json', | ||||
|         ) | ||||
|  | ||||
| @@ -96,7 +96,7 @@ class StockOwnershipTest(StockViewTestCase): | ||||
|         self.assertTrue(location.check_ownership(self.user))  # Owner is group -> True | ||||
|         self.assertContains( | ||||
|             self.assert_api_change(), | ||||
|             f'"status":{StockStatus.DAMAGED.value}', | ||||
|             f'"status_custom_key":{StockStatus.DAMAGED.value}', | ||||
|             status_code=200, | ||||
|         ) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user