From 37d9c59a0ea63fe08836a271658804df6f89d38f Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 5 Sep 2019 19:29:51 +1000 Subject: [PATCH] Add API endpoint for validating a BOM item --- InvenTree/part/api.py | 41 +++++++++++++++++++++++++++++++++++--- InvenTree/part/models.py | 18 ++++++++++++++--- InvenTree/part/test_api.py | 2 +- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 1c6678f2d3..e9c6d32f0d 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -12,7 +12,7 @@ from django.db.models import Sum from rest_framework import status from rest_framework.response import Response -from rest_framework import filters +from rest_framework import filters, serializers from rest_framework import generics, permissions from django.conf.urls import url, include @@ -303,7 +303,7 @@ class BomList(generics.ListCreateAPIView): filter_fields = [ 'part', - 'sub_part' + 'sub_part', ] @@ -318,6 +318,35 @@ class BomDetail(generics.RetrieveUpdateDestroyAPIView): ] +class BomItemValidate(generics.UpdateAPIView): + """ API endpoint for validating a BomItem """ + + # Very simple serializers + class BomItemValidationSerializer(serializers.Serializer): + + valid = serializers.BooleanField(default=False) + + queryset = BomItem.objects.all() + serializer_class = BomItemValidationSerializer + + def update(self, request, *args, **kwargs): + """ Perform update request """ + + partial = kwargs.pop('partial', False) + + valid = request.data.get('valid', False) + + instance = self.get_object() + + serializer = self.get_serializer(instance, data=request.data, partial=partial) + serializer.is_valid(raise_exception=True) + + if type(instance) == BomItem: + instance.validate_hash(valid) + + return Response(serializer.data) + + cat_api_urls = [ url(r'^(?P\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'), @@ -345,10 +374,16 @@ part_api_urls = [ url(r'^.*$', PartList.as_view(), name='api-part-list'), ] +bom_item_urls = [ + + url(r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'), + + url(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'), +] bom_api_urls = [ # BOM Item Detail - url(r'^(?P\d+)/?', BomDetail.as_view(), name='api-bom-detail'), + url(r'^(?P\d+)/', include(bom_item_urls)), # Catch-all url(r'^.*$', BomList.as_view(), name='api-bom-list'), diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 5627375a48..b13b6632c1 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -1176,16 +1176,28 @@ class BomItem(models.Model): return str(hash.digest()) - def validate_hash(self): - """ Mark this item as 'valid' (store the checksum hash) """ + def validate_hash(self, valid=True): + """ Mark this item as 'valid' (store the checksum hash). + + Args: + valid: If true, validate the hash, otherwise invalidate it (default = True) + """ + + if valid: + self.checksum = str(self.get_item_hash()) + else: + self.checksum = '' - self.checksum = str(self.get_item_hash()) self.save() @property def is_line_valid(self): """ Check if this line item has been validated by the user """ + # Ensure an empty checksum returns False + if len(self.checksum) == 0: + return False + return self.get_item_hash() == self.checksum def clean(self): diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py index b0859e5c1e..1b1ef3bc07 100644 --- a/InvenTree/part/test_api.py +++ b/InvenTree/part/test_api.py @@ -120,7 +120,7 @@ class PartAPITest(APITestCase): def test_get_bom_detail(self): # Get the detail for a single BomItem - url = reverse('api-bom-detail', kwargs={'pk': 3}) + url = reverse('api-bom-item-detail', kwargs={'pk': 3}) response = self.client.get(url, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['quantity'], 25)