mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c0a18ef244
@ -42,6 +42,8 @@ class InvenTreeBarcodePlugin(BarcodePlugin):
|
||||
elif type(self.data) is str:
|
||||
try:
|
||||
self.data = json.loads(self.data)
|
||||
if type(self.data) is not dict:
|
||||
return False
|
||||
except json.JSONDecodeError:
|
||||
return False
|
||||
else:
|
||||
|
@ -56,6 +56,34 @@ class BarcodeAPITest(APITestCase):
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_integer_barcode(self):
|
||||
|
||||
response = self.postBarcode(self.scan_url, '123456789')
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
data = response.data
|
||||
self.assertIn('error', data)
|
||||
|
||||
self.assertIn('barcode_data', data)
|
||||
self.assertIn('hash', data)
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_array_barcode(self):
|
||||
|
||||
response = self.postBarcode(self.scan_url, "['foo', 'bar']")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
data = response.data
|
||||
self.assertIn('error', data)
|
||||
|
||||
self.assertIn('barcode_data', data)
|
||||
self.assertIn('hash', data)
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_barcode_generation(self):
|
||||
|
||||
item = StockItem.objects.get(pk=522)
|
||||
|
@ -2,30 +2,20 @@
|
||||
JSON serializers for Part app
|
||||
"""
|
||||
import imghdr
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Part, PartStar
|
||||
|
||||
from .models import PartCategory
|
||||
from .models import BomItem
|
||||
from .models import PartParameter, PartParameterTemplate
|
||||
from .models import PartAttachment
|
||||
from .models import PartTestTemplate
|
||||
from .models import PartSellPriceBreak
|
||||
|
||||
from stock.models import StockItem
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from sql_util.utils import SubquerySum, SubqueryCount
|
||||
|
||||
from django.db.models import Q
|
||||
from django.db.models.functions import Coalesce
|
||||
from InvenTree.serializers import (InvenTreeAttachmentSerializerField,
|
||||
InvenTreeModelSerializer)
|
||||
from InvenTree.status_codes import BuildStatus, PurchaseOrderStatus
|
||||
from rest_framework import serializers
|
||||
from sql_util.utils import SubqueryCount, SubquerySum
|
||||
from stock.models import StockItem
|
||||
|
||||
from InvenTree.status_codes import PurchaseOrderStatus, BuildStatus
|
||||
from InvenTree.serializers import InvenTreeModelSerializer
|
||||
from InvenTree.serializers import InvenTreeAttachmentSerializerField
|
||||
from .models import (BomItem, Part, PartAttachment, PartCategory,
|
||||
PartParameter, PartParameterTemplate, PartSellPriceBreak,
|
||||
PartStar, PartTestTemplate)
|
||||
|
||||
|
||||
class CategorySerializer(InvenTreeModelSerializer):
|
||||
@ -41,6 +31,7 @@ class CategorySerializer(InvenTreeModelSerializer):
|
||||
'pk',
|
||||
'name',
|
||||
'description',
|
||||
'default_location',
|
||||
'pathstring',
|
||||
'url',
|
||||
'parent',
|
||||
@ -304,6 +295,7 @@ class PartSerializer(InvenTreeModelSerializer):
|
||||
'category_detail',
|
||||
'component',
|
||||
'description',
|
||||
'default_location',
|
||||
'full_name',
|
||||
'image',
|
||||
'in_stock',
|
||||
|
@ -324,8 +324,31 @@ class StockList(generics.ListCreateAPIView):
|
||||
serializer_class = StockItemSerializer
|
||||
queryset = StockItem.objects.all()
|
||||
|
||||
# TODO - Override the 'create' method for this view,
|
||||
# to allow the user to be recorded when a new StockItem object is created
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""
|
||||
Create a new StockItem object via the API.
|
||||
|
||||
We override the default 'create' implementation.
|
||||
|
||||
If a location is *not* specified, but the linked *part* has a default location,
|
||||
we can pre-fill the location automatically.
|
||||
"""
|
||||
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
item = serializer.save()
|
||||
|
||||
# A location was *not* specified - try to infer it
|
||||
if 'location' not in request.data:
|
||||
location = item.part.get_default_location()
|
||||
if location is not None:
|
||||
item.location = location
|
||||
item.save()
|
||||
|
||||
# Return a response
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
"""
|
||||
|
@ -93,7 +93,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
|
||||
{% if item.uid %}
|
||||
<li><a href='#' id='unlink-barcode'><span class='fas fa-unlink'></span> {% trans "Unlink Barcode" %}</a></li>
|
||||
{% else %}
|
||||
<li><a href='#' id='link-barcode'><span class='fas fa-link'></span> {% trans "Link Barcode" %}</a></li>\
|
||||
<li><a href='#' id='link-barcode'><span class='fas fa-link'></span> {% trans "Link Barcode" %}</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -97,6 +97,53 @@ class StockItemTest(StockAPITestCase):
|
||||
response = self.client.get(self.list_url, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test_create_default_location(self):
|
||||
"""
|
||||
Test the default location functionality,
|
||||
if a 'location' is not specified in the creation request.
|
||||
"""
|
||||
|
||||
# The part 'R_4K7_0603' (pk=4) has a default location specified
|
||||
|
||||
response = self.client.post(
|
||||
self.list_url,
|
||||
data={
|
||||
'part': 4,
|
||||
'quantity': 10
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.data['location'], 2)
|
||||
|
||||
# What if we explicitly set the location to a different value?
|
||||
|
||||
response = self.client.post(
|
||||
self.list_url,
|
||||
data={
|
||||
'part': 4,
|
||||
'quantity': 20,
|
||||
'location': 1,
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.data['location'], 1)
|
||||
|
||||
# And finally, what if we set the location explicitly to None?
|
||||
|
||||
response = self.client.post(
|
||||
self.list_url,
|
||||
data={
|
||||
'part': 4,
|
||||
'quantity': 20,
|
||||
'location': '',
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.data['location'], None)
|
||||
|
||||
def test_stock_item_create(self):
|
||||
"""
|
||||
Test creation of a StockItem via the API
|
||||
|
Loading…
Reference in New Issue
Block a user