mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2090 from SchrodingersGat/po-api-fix
Fix for purchase order API
This commit is contained in:
commit
b7ff50ca87
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user