mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +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) | ||||
|  | ||||
|         """ | ||||
|         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 | ||||
|  | ||||
|         if user is None: | ||||
| @@ -99,6 +118,8 @@ class InvenTreeMetadata(SimpleMetadata): | ||||
|         to any fields whose Meta.model specifies a default value | ||||
|         """ | ||||
|  | ||||
|         self.serializer = serializer | ||||
|  | ||||
|         serializer_info = super().get_serializer_info(serializer) | ||||
|  | ||||
|         model_class = None | ||||
|   | ||||
| @@ -286,7 +286,37 @@ class PurchaseOrderDetail(generics.RetrieveUpdateDestroyAPIView): | ||||
|         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. | ||||
|  | ||||
| @@ -303,20 +333,6 @@ class PurchaseOrderReceive(generics.CreateAPIView): | ||||
|  | ||||
|     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): | ||||
|     """ | ||||
| @@ -1107,6 +1123,7 @@ order_api_urls = [ | ||||
|         # Individual purchase order detail URLs | ||||
|         re_path(r'^(?P<pk>\d+)/', include([ | ||||
|             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'), | ||||
|         ])), | ||||
|  | ||||
|   | ||||
| @@ -380,6 +380,7 @@ class PurchaseOrder(Order): | ||||
|             PurchaseOrderStatus.PENDING | ||||
|         ] | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def cancel_order(self): | ||||
|         """ 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): | ||||
|  | ||||
|     @staticmethod | ||||
|   | ||||
		Reference in New Issue
	
	Block a user