Merge pull request #2090 from SchrodingersGat/po-api-fix

Fix for purchase order API
This commit is contained in:
Oliver 2021-10-03 01:33:23 +10:00 committed by GitHub
commit b7ff50ca87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 26 deletions

View File

@ -8,11 +8,13 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf.urls import url, include from django.conf.urls import url, include
from django.db import transaction from django.db import transaction
from django.core.exceptions import ValidationError as DjangoValidationError
from django_filters import rest_framework as rest_filters from django_filters import rest_framework as rest_filters
from rest_framework import generics from rest_framework import generics
from rest_framework import filters, status from rest_framework import filters, status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
@ -243,10 +245,11 @@ class POReceive(generics.CreateAPIView):
pk = self.kwargs.get('pk', None) pk = self.kwargs.get('pk', None)
if pk is None: try:
return None order = PurchaseOrder.objects.get(pk=pk)
else: except (PurchaseOrder.DoesNotExist, ValueError):
order = PurchaseOrder.objects.get(pk=self.kwargs['pk']) raise ValidationError(_("Matching purchase order does not exist"))
return order return order
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
@ -259,9 +262,14 @@ class POReceive(generics.CreateAPIView):
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
# Receive the line items # Receive the line items
try:
self.receive_items(serializer) self.receive_items(serializer)
except DjangoValidationError as exc:
# Re-throw a django error as a DRF error
raise ValidationError(detail=serializers.as_serializer_error(exc))
headers = self.get_success_headers(serializer.data) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@transaction.atomic @transaction.atomic

View File

@ -418,16 +418,24 @@ class PurchaseOrder(Order):
barcode = '' barcode = ''
if not self.status == PurchaseOrderStatus.PLACED: if not self.status == PurchaseOrderStatus.PLACED:
raise ValidationError({"status": _("Lines can only be received against an order marked as 'Placed'")}) raise ValidationError(
"Lines can only be received against an order marked as 'PLACED'"
)
try: try:
if not (quantity % 1 == 0): if not (quantity % 1 == 0):
raise ValidationError({"quantity": _("Quantity must be an integer")}) raise ValidationError({
"quantity": _("Quantity must be an integer")
})
if quantity < 0: if quantity < 0:
raise ValidationError({"quantity": _("Quantity must be a positive number")}) raise ValidationError({
"quantity": _("Quantity must be a positive number")
})
quantity = int(quantity) quantity = int(quantity)
except (ValueError, TypeError): except (ValueError, TypeError):
raise ValidationError({"quantity": _("Invalid quantity provided")}) raise ValidationError({
"quantity": _("Invalid quantity provided")
})
# Create a new stock item # Create a new stock item
if line.part and quantity > 0: if line.part and quantity > 0:

View File

@ -401,10 +401,7 @@ class PurchaseOrderReceiveTest(OrderTest):
self.assertEqual(line_1.received, 0) self.assertEqual(line_1.received, 0)
self.assertEqual(line_2.received, 50) self.assertEqual(line_2.received, 50)
# Receive two separate line items against this order valid_data = {
self.post(
self.url,
{
'items': [ 'items': [
{ {
'line_item': 1, 'line_item': 1,
@ -419,7 +416,30 @@ class PurchaseOrderReceiveTest(OrderTest):
} }
], ],
'location': 1, # Default location 'location': 1, # Default location
}, }
# Before posting "valid" data, we will mark the purchase order as "pending"
# In this case we do expect an error!
order = PurchaseOrder.objects.get(pk=1)
order.status = PurchaseOrderStatus.PENDING
order.save()
response = self.post(
self.url,
valid_data,
expected_code=400
)
self.assertIn('can only be received against', str(response.data))
# Now, set the PO back to "PLACED" so the items can be received
order.status = PurchaseOrderStatus.PLACED
order.save()
# Receive two separate line items against this order
self.post(
self.url,
valid_data,
expected_code=201, expected_code=201,
) )