From ddcfc8996cb46317f1805de730f7a0b4487d1a71 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 5 Oct 2021 12:12:37 +1100 Subject: [PATCH] Further fixes for API / serializer classes - Correctly catch and re-throw errors - Provide request to serializer context --- InvenTree/build/api.py | 1 + InvenTree/build/serializers.py | 22 +++++++++++++--------- InvenTree/build/test_api.py | 2 +- InvenTree/order/api.py | 4 +--- InvenTree/order/serializers.py | 22 ++++++++++++++-------- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index 3973272944..cc897d6ec9 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -222,6 +222,7 @@ class BuildAllocate(generics.CreateAPIView): context = super().get_serializer_context() context['build'] = self.get_build() + context['request'] = self.request return context diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index 7dc8b7b9d0..53e71dbd27 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -6,7 +6,7 @@ JSON serializers for Build API from __future__ import unicode_literals from django.db import transaction - +from django.core.exceptions import ValidationError as DjangoValidationError from django.utils.translation import ugettext_lazy as _ from django.db.models import Case, When, Value @@ -270,14 +270,18 @@ class BuildAllocationSerializer(serializers.Serializer): quantity = item['quantity'] output = item.get('output', None) - # Create a new BuildItem to allocate stock - BuildItem.objects.create( - build=build, - bom_item=bom_item, - stock_item=stock_item, - quantity=quantity, - install_into=output - ) + try: + # Create a new BuildItem to allocate stock + BuildItem.objects.create( + build=build, + bom_item=bom_item, + stock_item=stock_item, + quantity=quantity, + install_into=output + ) + except (ValidationError, DjangoValidationError) as exc: + # Catch model errors and re-throw as DRF errors + raise ValidationError(detail=serializers.as_serializer_error(exc)) class BuildItemSerializer(InvenTreeModelSerializer): diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py index 4b5b04fca9..017f0126c5 100644 --- a/InvenTree/build/test_api.py +++ b/InvenTree/build/test_api.py @@ -111,7 +111,7 @@ class BuildAllocationTest(BuildAPITest): expected_code=400 ).data - self.assertIn('Allocation items must be provided', str(data['items'])) + self.assertIn('Allocation items must be provided', str(data)) # No new BuildItem objects have been created during this test self.assertEqual(self.n, BuildItem.objects.count()) diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index fc19610320..b8f54ba72b 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -7,14 +7,11 @@ from __future__ import unicode_literals from django.utils.translation import ugettext_lazy as _ from django.conf.urls import url, include -from django.db import transaction -from django.core.exceptions import ValidationError as DjangoValidationError from django_filters import rest_framework as rest_filters from rest_framework import generics from rest_framework import filters, status from rest_framework.response import Response -from rest_framework import serializers from rest_framework.serializers import ValidationError @@ -235,6 +232,7 @@ class POReceive(generics.CreateAPIView): # Pass the purchase order through to the serializer for validation context['order'] = self.get_order() + context['request'] = self.request return context diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 9600e2acaf..742f759f82 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -7,6 +7,7 @@ from __future__ import unicode_literals from django.utils.translation import ugettext_lazy as _ +from django.core.exceptions import ValidationError as DjangoValidationError from django.db import models, transaction from django.db.models import Case, When, Value from django.db.models import BooleanField, ExpressionWrapper, F @@ -305,6 +306,7 @@ class POReceiveSerializer(serializers.Serializer): data = self.validated_data + request = self.context['request'] order = self.context['order'] items = data['items'] @@ -331,15 +333,19 @@ class POReceiveSerializer(serializers.Serializer): # Now we can actually receive the items into stock with transaction.atomic(): for item in items: - order.receive_line_item( - item['line_item'], - item['location'], - item['quantity'], - self.request.user, - status=item['status'], - barcode=item.get('barcode', ''), - ) + try: + order.receive_line_item( + item['line_item'], + item['location'], + item['quantity'], + request.user, + status=item['status'], + barcode=item.get('barcode', ''), + ) + except (ValidationError, DjangoValidationError) as exc: + # Catch model errors and re-throw as DRF errors + raise ValidationError(detail=serializers.as_serializer_error(exc)) class Meta: fields = [