mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	Adds ability to add custom serializer context information to the OPTIONS endpoint
- Will be useful for constructing prettier forms with information about the endpoint
This commit is contained in:
		| @@ -37,6 +37,25 @@ class InvenTreeMetadata(SimpleMetadata): | |||||||
|  |  | ||||||
|         metadata = super().determine_metadata(request, view) |         metadata = super().determine_metadata(request, view) | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         Custom context information to pass through to the OPTIONS endpoint, | ||||||
|  |         if the "context=True" is supplied to the OPTIONS requst | ||||||
|  |          | ||||||
|  |         Serializer class can supply either: | ||||||
|  |  | ||||||
|  |         - get_context_data() (method) | ||||||
|  |         - CONTEXT_DATA (dict) | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         context = {} | ||||||
|  |  | ||||||
|  |         if hasattr(self.serializer, 'get_context_data'): | ||||||
|  |             context = self.serializer.get_context_data() | ||||||
|  |         elif hasattr(self.erializer, 'CONTEXT_DATA'): | ||||||
|  |             context = self.serializer.CONTEXT_DATA | ||||||
|  |  | ||||||
|  |         metadata['context'] = context | ||||||
|  |  | ||||||
|         user = request.user |         user = request.user | ||||||
|  |  | ||||||
|         if user is None: |         if user is None: | ||||||
| @@ -99,6 +118,8 @@ class InvenTreeMetadata(SimpleMetadata): | |||||||
|         to any fields whose Meta.model specifies a default value |         to any fields whose Meta.model specifies a default value | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|  |         self.serializer = serializer | ||||||
|  |  | ||||||
|         serializer_info = super().get_serializer_info(serializer) |         serializer_info = super().get_serializer_info(serializer) | ||||||
|  |  | ||||||
|         model_class = None |         model_class = None | ||||||
|   | |||||||
| @@ -286,7 +286,37 @@ class PurchaseOrderDetail(generics.RetrieveUpdateDestroyAPIView): | |||||||
|         return queryset |         return queryset | ||||||
|  |  | ||||||
|  |  | ||||||
| class PurchaseOrderReceive(generics.CreateAPIView): | class PurchaseOrderContextMixin: | ||||||
|  |  | ||||||
|  |     def get_serializer_context(self): | ||||||
|  |         """ Add the PurchaseOrder object to the serializer context """ | ||||||
|  |  | ||||||
|  |         context = super().get_serializer_context() | ||||||
|  |  | ||||||
|  |         # Pass the purchase order through to the serializer for validation | ||||||
|  |         try: | ||||||
|  |             context['order'] = models.PurchaseOrder.objects.get(pk=self.kwargs.get('pk', None)) | ||||||
|  |         except: | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |         context['request'] = self.request | ||||||
|  |  | ||||||
|  |         return context | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PurchaseOrderCancel(PurchaseOrderContextMixin, generics.CreateAPIView): | ||||||
|  |     """ | ||||||
|  |     API endpoint to 'cancel' a purchase order. | ||||||
|  |  | ||||||
|  |     The purchase order must be in a state which can be cancelled | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     queryset = models.PurchaseOrderLineItem.objects.all() | ||||||
|  |  | ||||||
|  |     serializer_class = serializers.PurchaseOrderCancelSerializer | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PurchaseOrderReceive(PurchaseOrderContextMixin, generics.CreateAPIView): | ||||||
|     """ |     """ | ||||||
|     API endpoint to receive stock items against a purchase order. |     API endpoint to receive stock items against a purchase order. | ||||||
|  |  | ||||||
| @@ -303,20 +333,6 @@ class PurchaseOrderReceive(generics.CreateAPIView): | |||||||
|  |  | ||||||
|     serializer_class = serializers.PurchaseOrderReceiveSerializer |     serializer_class = serializers.PurchaseOrderReceiveSerializer | ||||||
|  |  | ||||||
|     def get_serializer_context(self): |  | ||||||
|  |  | ||||||
|         context = super().get_serializer_context() |  | ||||||
|  |  | ||||||
|         # Pass the purchase order through to the serializer for validation |  | ||||||
|         try: |  | ||||||
|             context['order'] = models.PurchaseOrder.objects.get(pk=self.kwargs.get('pk', None)) |  | ||||||
|         except: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|         context['request'] = self.request |  | ||||||
|  |  | ||||||
|         return context |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class PurchaseOrderLineItemFilter(rest_filters.FilterSet): | class PurchaseOrderLineItemFilter(rest_filters.FilterSet): | ||||||
|     """ |     """ | ||||||
| @@ -1107,6 +1123,7 @@ order_api_urls = [ | |||||||
|         # Individual purchase order detail URLs |         # Individual purchase order detail URLs | ||||||
|         re_path(r'^(?P<pk>\d+)/', include([ |         re_path(r'^(?P<pk>\d+)/', include([ | ||||||
|             re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'), |             re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'), | ||||||
|  |             re_path(r'^cancel/', PurchaseOrderCancel.as_view(), name='api-po-cancel'), | ||||||
|             re_path(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'), |             re_path(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'), | ||||||
|         ])), |         ])), | ||||||
|  |  | ||||||
|   | |||||||
| @@ -380,6 +380,7 @@ class PurchaseOrder(Order): | |||||||
|             PurchaseOrderStatus.PENDING |             PurchaseOrderStatus.PENDING | ||||||
|         ] |         ] | ||||||
|  |  | ||||||
|  |     @transaction.atomic | ||||||
|     def cancel_order(self): |     def cancel_order(self): | ||||||
|         """ Marks the PurchaseOrder as CANCELLED. """ |         """ Marks the PurchaseOrder as CANCELLED. """ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -179,6 +179,35 @@ class PurchaseOrderSerializer(AbstractOrderSerializer, ReferenceIndexingSerializ | |||||||
|         ] |         ] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PurchaseOrderCancelSerializer(serializers.Serializer): | ||||||
|  |     """ | ||||||
|  |     Serializer for cancelling a PurchaseOrder | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         fields = [], | ||||||
|  |  | ||||||
|  |     def get_context_data(self): | ||||||
|  |         """ | ||||||
|  |         Return custom context information about the order | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         self.order = self.context['order'] | ||||||
|  |  | ||||||
|  |         return { | ||||||
|  |             'can_cancel': self.order.can_cancel(), | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     def save(self): | ||||||
|  |  | ||||||
|  |         order = self.context['order'] | ||||||
|  |  | ||||||
|  |         if not order.can_cancel(): | ||||||
|  |             raise ValidationError(_("Order cannot be cancelled")) | ||||||
|  |          | ||||||
|  |         order.cancel_order() | ||||||
|  |  | ||||||
|  |  | ||||||
| class PurchaseOrderLineItemSerializer(InvenTreeModelSerializer): | class PurchaseOrderLineItemSerializer(InvenTreeModelSerializer): | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user