From 15582369d248f31cc9cd0fb3e7ad7aafbd3cc3d8 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 11 Apr 2017 18:58:44 +1000 Subject: [PATCH] API for stock app --- InvenTree/part/models.py | 1 - InvenTree/stock/admin.py | 6 ++-- InvenTree/stock/models.py | 12 ++++++-- InvenTree/stock/serializers.py | 52 ++++++++++++++++++++++++++++++++++ InvenTree/stock/urls.py | 9 +++++- InvenTree/stock/views.py | 33 +++++++++++++++++---- 6 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 InvenTree/stock/serializers.py diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 740bcd0cfd..b664688bd8 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -17,7 +17,6 @@ class PartCategory(InvenTreeTree): @property def parts(self): parts_list = self.part_set.all() - print(parts_list) return parts_list diff --git a/InvenTree/stock/admin.py b/InvenTree/stock/admin.py index 7bfd55fe3c..6ce4df95c5 100644 --- a/InvenTree/stock/admin.py +++ b/InvenTree/stock/admin.py @@ -1,9 +1,9 @@ from django.contrib import admin -from .models import Warehouse, StockItem +from .models import StockLocation, StockItem -class WarehouseAdmin(admin.ModelAdmin): +class LocationAdmin(admin.ModelAdmin): list_display = ('name', 'path', 'description') @@ -11,5 +11,5 @@ class StockItemAdmin(admin.ModelAdmin): list_display = ('part', 'quantity', 'location', 'status', 'updated') -admin.site.register(Warehouse, WarehouseAdmin) +admin.site.register(StockLocation, LocationAdmin) admin.site.register(StockItem, StockItemAdmin) diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 40d95a5676..dc5f412420 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -6,15 +6,21 @@ from part.models import Part from InvenTree.models import InvenTreeTree -class Warehouse(InvenTreeTree): - pass +class StockLocation(InvenTreeTree): + """ Organization tree for StockItem objects + """ + + @property + def items(self): + stock_list = self.stockitem_set.all() + return stock_list class StockItem(models.Model): part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations') - location = models.ForeignKey(Warehouse, on_delete=models.CASCADE) + location = models.ForeignKey(StockLocation, on_delete=models.CASCADE) quantity = models.PositiveIntegerField() updated = models.DateField(auto_now=True) diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py new file mode 100644 index 0000000000..bf07dfa1de --- /dev/null +++ b/InvenTree/stock/serializers.py @@ -0,0 +1,52 @@ +from rest_framework import serializers + +from .models import StockItem, StockLocation + + +class StockItemSerializer(serializers.ModelSerializer): + """ Serializer for a StockItem + """ + + class Meta: + model = StockItem + fields = ('pk', + 'part', + 'location', + 'quantity', + 'status', + 'updated', + 'last_checked', + 'review_needed', + 'expected_arrival') + + +class LocationBriefSerializer(serializers.ModelSerializer): + """ Brief information about a stock location + """ + + class Meta: + model = StockLocation + fields = ('pk', + 'name', + 'description') + + +class LocationDetailSerializer(serializers.ModelSerializer): + """ Detailed information about a stock location + """ + + # List of all stock items in this location + items = StockItemSerializer(many=True) + + # List of all child locations under this one + children = LocationBriefSerializer(many=True) + + class Meta: + model = StockLocation + fields = ('pk', + 'name', + 'description', + 'parent', + 'path', + 'children', + 'items') diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index 9cb3403af4..a9dc1bc09e 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -3,5 +3,12 @@ from django.conf.urls import url from . import views urlpatterns = [ - url(r'^$', views.index, name='index') + # List all stock quantities for a given part + url(r'^part/(?P[0-9]+)$', views.PartStockDetail.as_view()), + + # List all stock items in a given location + url(r'^location/(?P[0-9]+)$', views.LocationDetail.as_view()), + + # List all top-level locations + url(r'^location/$', views.LocationList.as_view()) ] diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 3fbebb9bd0..5f76cbebf1 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -1,10 +1,33 @@ -from django.shortcuts import render +from rest_framework import generics -from .models import Warehouse +from .models import StockLocation, StockItem + +from .serializers import StockItemSerializer, LocationDetailSerializer -def index(request): +class PartStockDetail(generics.ListAPIView): + """ Return a list of all stockitems for a given part + """ - warehouses = Warehouse.objects.filter(parent=None) + serializer_class = StockItemSerializer - return render(request, 'stock/index.html', {'warehouses': warehouses}) + def get_queryset(self): + part_id = self.kwargs['part'] + return StockItem.objects.filter(part=part_id) + + +class LocationDetail(generics.RetrieveAPIView): + """ Return information on a specific stock location + """ + + queryset = StockLocation.objects.all() + serializer_class = LocationDetailSerializer + + +class LocationList(generics.ListAPIView): + """ Return a list of top-level locations + Locations are considered "top-level" if they do not have a parent + """ + + queryset = StockLocation.objects.filter(parent=None) + serializer_class = LocationDetailSerializer