diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py new file mode 100644 index 0000000000..77f3b11357 --- /dev/null +++ b/InvenTree/part/api.py @@ -0,0 +1,174 @@ +from .serializers import PartSerializer +from .serializers import PartCategorySerializer + +from rest_framework import generics, permissions + +from django_filters.rest_framework import FilterSet, DjangoFilterBackend + +from .models import PartCategory, Part + +class PartDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return detail on a single Part + + post: + Update data for a single Part + + delete: + Remove a part from the database + + """ + queryset = Part.objects.all() + serializer_class = PartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +""" +class PartParamFilter(FilterSet): + + class Meta: + model = PartParameter + fields = ['part'] + +class PartParamList(generics.ListCreateAPIView): + " + + get: + Return a list of all part parameters (with optional filters) + + post: + Create a new part parameter + "" + + queryset = PartParameter.objects.all() + serializer_class = PartParameterSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = PartParamFilter + + +class PartParamDetail(generics.RetrieveUpdateDestroyAPIView): + "" + + get: + Detail view of a single PartParameter + + post: + Update data for a PartParameter + + delete: + Remove a PartParameter from the database + + " + + queryset = PartParameter.objects.all() + serializer_class = PartParameterSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) +""" + +class PartFilter(FilterSet): + + class Meta: + model = Part + fields = ['category'] + + +class PartList(generics.ListCreateAPIView): + """ + + get: + List of Parts, with optional filters + + post: + Create a new Part + """ + + queryset = Part.objects.all() + serializer_class = PartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = PartFilter + + +class PartCategoryDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return information on a single PartCategory + + post: + Update a PartCategory + + delete: + Remove a PartCategory + + """ + queryset = PartCategory.objects.all() + serializer_class = PartCategorySerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class PartCategoryList(generics.ListCreateAPIView): + """ + + get: + Return a list of all categories + (with optional filters) + + post: + Create a new PartCategory + """ + + def get_queryset(self): + params = self.request.query_params + + categories = PartCategory.objects.all() + + categories = FilterChildren(categories, params.get('parent', None)) + + return categories + + queryset = PartCategory.objects.filter(parent=None) + serializer_class = PartCategorySerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +""" +class PartTemplateDetail(generics.RetrieveUpdateDestroyAPIView): + "" + + get: + Return detail on a single PartParameterTemplate object + + post: + Update a PartParameterTemplate object + + delete: + Remove a PartParameterTemplate object + + "" + + queryset = PartParameterTemplate.objects.all() + serializer_class = PartTemplateSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class PartTemplateList(generics.ListCreateAPIView): + "" + + get: + Return a list of all PartParameterTemplate objects + (with optional query filters) + + post: + Create a new PartParameterTemplate object + + "" + + queryset = PartParameterTemplate.objects.all() + serializer_class = PartTemplateSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + +""" diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 866dc18f86..3205b992db 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -6,6 +6,8 @@ from django.core.validators import MinValueValidator from InvenTree.models import InvenTreeTree +#from django.db.models.signals.pre_delete +#from django.dispatch import receiver class PartCategory(InvenTreeTree): """ PartCategory provides hierarchical organization of Part objects. @@ -19,6 +21,15 @@ class PartCategory(InvenTreeTree): def parts(self): return self.part_set.all() +""" +@receiver(pre_delete, sender=PartCategory) +def reset_tag(sender, **kwargs): + cat = kwargs['instance'] + + for book in books.filter(tag=tag): + book.tag = book.author.tags.first() + book.save() +""" class Part(models.Model): """ Represents an abstract part @@ -36,7 +47,9 @@ class Part(models.Model): IPN = models.CharField(max_length=100, blank=True) # Part category - all parts must be assigned to a category - category = models.ForeignKey(PartCategory, on_delete=models.CASCADE, related_name='parts') + category = models.ForeignKey(PartCategory, related_name='parts', + null=True, blank=True, + on_delete=models.SET_NULL) # Minimum "allowed" stock level minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)]) diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 0a04241d5f..79aad236b2 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -2,6 +2,7 @@ from django.conf.urls import url, include from django.views.generic.base import RedirectView from . import views +from . import api app_nam='part' @@ -9,11 +10,11 @@ app_nam='part' part_cat_api_urls = [ # Part category detail - url(r'^(?P[0-9]+)/?$', views.PartCategoryDetail.as_view(), name='partcategory-detail'), + url(r'^(?P[0-9]+)/?$', api.PartCategoryDetail.as_view(), name='partcategory-detail'), # List of top-level categories - url(r'^\?*.*/?$', views.PartCategoryList.as_view()), - url(r'^$', views.PartCategoryList.as_view()) + url(r'^\?*.*/?$', api.PartCategoryList.as_view()), + url(r'^$', api.PartCategoryList.as_view()) ] @@ -21,11 +22,11 @@ part_cat_api_urls = [ part_api_urls = [ # Individual part - url(r'^(?P[0-9]+)/?$', views.PartDetail.as_view(), name='part-detail'), + url(r'^(?P[0-9]+)/?$', api.PartDetail.as_view(), name='part-detail'), # List parts with optional filters - url(r'^\?.*/?$', views.PartList.as_view()), - url(r'^$', views.PartList.as_view()), + url(r'^\?.*/?$', api.PartList.as_view()), + url(r'^$', api.PartList.as_view()), ] part_detail_urls = [ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index a50114fe06..c93d52bc00 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1,11 +1,8 @@ -from django_filters.rest_framework import FilterSet, DjangoFilterBackend # Template stuff (WIP) from django.http import HttpResponse from django.template import loader -from rest_framework import generics, permissions - from InvenTree.models import FilterChildren from .models import PartCategory, Part @@ -14,22 +11,6 @@ from django.http import HttpResponseRedirect from django.urls import reverse from django.views import generic -from .serializers import PartSerializer -from .serializers import PartCategorySerializer -#from .serializers import PartParameterSerializer -#from .serializers import PartTemplateSerializer - -""" -class IndexView(generic.ListView): - template_name = 'index.html' - context_object_name = 'parts' - - def get_queryset(self): - "Return the last five published questions." - return Part.objects.all() - -""" - def index(request): template = loader.get_template('part/index.html') @@ -79,174 +60,3 @@ def track(request, pk): return render(request, 'part/track.html', {'part': part}) - -#def results(request, question_id): -# response = "You're looking at the results of question %s." -# return HttpResponse(response % question_id) - - -class PartDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return detail on a single Part - - post: - Update data for a single Part - - delete: - Remove a part from the database - - """ - queryset = Part.objects.all() - serializer_class = PartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -""" -class PartParamFilter(FilterSet): - - class Meta: - model = PartParameter - fields = ['part'] - -class PartParamList(generics.ListCreateAPIView): - " - - get: - Return a list of all part parameters (with optional filters) - - post: - Create a new part parameter - "" - - queryset = PartParameter.objects.all() - serializer_class = PartParameterSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = PartParamFilter - - -class PartParamDetail(generics.RetrieveUpdateDestroyAPIView): - "" - - get: - Detail view of a single PartParameter - - post: - Update data for a PartParameter - - delete: - Remove a PartParameter from the database - - " - - queryset = PartParameter.objects.all() - serializer_class = PartParameterSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) -""" - -class PartFilter(FilterSet): - - class Meta: - model = Part - fields = ['category'] - - -class PartList(generics.ListCreateAPIView): - """ - - get: - List of Parts, with optional filters - - post: - Create a new Part - """ - - queryset = Part.objects.all() - serializer_class = PartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = PartFilter - - -class PartCategoryDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return information on a single PartCategory - - post: - Update a PartCategory - - delete: - Remove a PartCategory - - """ - queryset = PartCategory.objects.all() - serializer_class = PartCategorySerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class PartCategoryList(generics.ListCreateAPIView): - """ - - get: - Return a list of all categories - (with optional filters) - - post: - Create a new PartCategory - """ - - def get_queryset(self): - params = self.request.query_params - - categories = PartCategory.objects.all() - - categories = FilterChildren(categories, params.get('parent', None)) - - return categories - - queryset = PartCategory.objects.filter(parent=None) - serializer_class = PartCategorySerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -""" -class PartTemplateDetail(generics.RetrieveUpdateDestroyAPIView): - "" - - get: - Return detail on a single PartParameterTemplate object - - post: - Update a PartParameterTemplate object - - delete: - Remove a PartParameterTemplate object - - "" - - queryset = PartParameterTemplate.objects.all() - serializer_class = PartTemplateSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class PartTemplateList(generics.ListCreateAPIView): - "" - - get: - Return a list of all PartParameterTemplate objects - (with optional query filters) - - post: - Create a new PartParameterTemplate object - - "" - - queryset = PartParameterTemplate.objects.all() - serializer_class = PartTemplateSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - -""" diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py new file mode 100644 index 0000000000..874478bf1f --- /dev/null +++ b/InvenTree/stock/api.py @@ -0,0 +1,132 @@ +from django_filters.rest_framework import FilterSet, DjangoFilterBackend +from django_filters import NumberFilter + +from rest_framework import generics, permissions, response + + + + +# from InvenTree.models import FilterChildren +from .models import StockLocation, StockItem +from .serializers import StockItemSerializer, StockQuantitySerializer +from .serializers import LocationSerializer + + +class StockDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single StockItem object + + post: + Update a StockItem + + delete: + Remove a StockItem + """ + + queryset = StockItem.objects.all() + serializer_class = StockItemSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class StockFilter(FilterSet): + min_stock = NumberFilter(name='quantity', lookup_expr='gte') + max_stock = NumberFilter(name='quantity', lookup_expr='lte') + + class Meta: + model = StockItem + fields = ['quantity', 'part', 'location'] + + +class StockList(generics.ListCreateAPIView): + """ + + get: + Return a list of all StockItem objects + (with optional query filters) + + post: + Create a new StockItem + """ + + queryset = StockItem.objects.all() + serializer_class = StockItemSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = StockFilter + + +class StockStocktakeEndpoint(generics.UpdateAPIView): + + queryset = StockItem.objects.all() + serializer_class = StockQuantitySerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + def update(self, request, *args, **kwargs): + object = self.get_object() + object.stocktake(request.data['quantity'], request.user) + + serializer = self.get_serializer(object) + + return response.Response(serializer.data) + + +class AddStockEndpoint(generics.UpdateAPIView): + + queryset = StockItem.objects.all() + serializer_class = StockQuantitySerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + def update(self, request, *args, **kwargs): + object = self.get_object() + object.add_stock(request.data['quantity']) + + serializer = self.get_serializer(object) + + return response.Response(serializer.data) + + +class LocationDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single StockLocation object + + post: + Update a StockLocation object + + delete: + Remove a StockLocation object + + """ + + queryset = StockLocation.objects.all() + serializer_class = LocationSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class StockLocationFilter(FilterSet): + + class Meta: + model = StockLocation + fields = ['parent'] + + +class LocationList(generics.ListCreateAPIView): + """ + + get: + Return a list of all StockLocation objects + (with optional query filter) + + post: + Create a new StockLocation + + """ + + queryset = StockLocation.objects.all() + serializer_class = LocationSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = StockLocationFilter diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index 412bf23279..0ca312ebfc 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -1,13 +1,14 @@ from django.conf.urls import url, include from . import views +from . import api stock_endpoints = [ - url(r'^$', views.StockDetail.as_view(), name='stockitem-detail'), + url(r'^$', api.StockDetail.as_view(), name='stockitem-detail'), - url(r'^stocktake/?$', views.StockStocktakeEndpoint.as_view(), name='stockitem-stocktake'), + url(r'^stocktake/?$', api.StockStocktakeEndpoint.as_view(), name='stockitem-stocktake'), - url(r'^add-stock/?$', views.AddStockEndpoint.as_view(), name='stockitem-add-stock'), + url(r'^add-stock/?$', api.AddStockEndpoint.as_view(), name='stockitem-add-stock'), ] stock_urls = [ @@ -15,14 +16,14 @@ stock_urls = [ url(r'^(?P[0-9]+)/', include(stock_endpoints)), # List all stock items, with optional filters - url(r'^\?.*/?$', views.StockList.as_view()), - url(r'^$', views.StockList.as_view()), + url(r'^\?.*/?$', api.StockList.as_view()), + url(r'^$', api.StockList.as_view()), ] stock_loc_urls = [ - url(r'^(?P[0-9]+)/?$', views.LocationDetail.as_view(), name='stocklocation-detail'), + url(r'^(?P[0-9]+)/?$', api.LocationDetail.as_view(), name='stocklocation-detail'), - url(r'^\?.*/?$', views.LocationList.as_view()), + url(r'^\?.*/?$', api.LocationList.as_view()), - url(r'^$', views.LocationList.as_view()) + url(r'^$', api.LocationList.as_view()) ] diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 99c2a246da..e69de29bb2 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -1,129 +0,0 @@ -from django_filters.rest_framework import FilterSet, DjangoFilterBackend -from django_filters import NumberFilter - -from rest_framework import generics, permissions, response - -# from InvenTree.models import FilterChildren -from .models import StockLocation, StockItem -from .serializers import StockItemSerializer, StockQuantitySerializer -from .serializers import LocationSerializer - - -class StockDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single StockItem object - - post: - Update a StockItem - - delete: - Remove a StockItem - """ - - queryset = StockItem.objects.all() - serializer_class = StockItemSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class StockFilter(FilterSet): - min_stock = NumberFilter(name='quantity', lookup_expr='gte') - max_stock = NumberFilter(name='quantity', lookup_expr='lte') - - class Meta: - model = StockItem - fields = ['quantity', 'part', 'location'] - - -class StockList(generics.ListCreateAPIView): - """ - - get: - Return a list of all StockItem objects - (with optional query filters) - - post: - Create a new StockItem - """ - - queryset = StockItem.objects.all() - serializer_class = StockItemSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = StockFilter - - -class StockStocktakeEndpoint(generics.UpdateAPIView): - - queryset = StockItem.objects.all() - serializer_class = StockQuantitySerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - def update(self, request, *args, **kwargs): - object = self.get_object() - object.stocktake(request.data['quantity'], request.user) - - serializer = self.get_serializer(object) - - return response.Response(serializer.data) - - -class AddStockEndpoint(generics.UpdateAPIView): - - queryset = StockItem.objects.all() - serializer_class = StockQuantitySerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - def update(self, request, *args, **kwargs): - object = self.get_object() - object.add_stock(request.data['quantity']) - - serializer = self.get_serializer(object) - - return response.Response(serializer.data) - - -class LocationDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single StockLocation object - - post: - Update a StockLocation object - - delete: - Remove a StockLocation object - - """ - - queryset = StockLocation.objects.all() - serializer_class = LocationSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class StockLocationFilter(FilterSet): - - class Meta: - model = StockLocation - fields = ['parent'] - - -class LocationList(generics.ListCreateAPIView): - """ - - get: - Return a list of all StockLocation objects - (with optional query filter) - - post: - Create a new StockLocation - - """ - - queryset = StockLocation.objects.all() - serializer_class = LocationSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = StockLocationFilter diff --git a/InvenTree/supplier/api.py b/InvenTree/supplier/api.py new file mode 100644 index 0000000000..8f9b43e03a --- /dev/null +++ b/InvenTree/supplier/api.py @@ -0,0 +1,208 @@ +from django_filters.rest_framework import FilterSet, DjangoFilterBackend + +from rest_framework import generics, permissions + +from .models import Supplier, SupplierPart, SupplierPriceBreak +from .models import Manufacturer, Customer +from .serializers import SupplierSerializer +from .serializers import SupplierPartSerializer +from .serializers import SupplierPriceBreakSerializer +from .serializers import ManufacturerSerializer +from .serializers import CustomerSerializer + + +class ManufacturerDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single Manufacturer + + post: + Update a Manufacturer + + delete: + Remove a Manufacturer + + """ + + queryset = Manufacturer.objects.all() + serializer_class = ManufacturerSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class ManufacturerList(generics.ListCreateAPIView): + """ + + get: + Return a list of all Manufacturers + + post: + Create a new Manufacturer + + """ + + queryset = Manufacturer.objects.all() + serializer_class = ManufacturerSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class CustomerDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single Customer + + post: + Update a Customer + + delete: + Remove a Customer + + """ + + queryset = Customer.objects.all() + serializer_class = CustomerSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class CustomerList(generics.ListCreateAPIView): + """ + + get: + Return a list of all Cutstomers + + post: + Create a new Customer + + """ + + queryset = Customer.objects.all() + serializer_class = CustomerSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class SupplierDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single Supplier + + post: + Update a supplier + + delete: + Remove a supplier + + """ + + queryset = Supplier.objects.all() + serializer_class = SupplierSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class SupplierList(generics.ListCreateAPIView): + """ + + get: + Return a list of all Suppliers + + post: + Create a new Supplier + + """ + + queryset = Supplier.objects.all() + serializer_class = SupplierSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class SupplierPartDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single SupplierPart + + post: + Update a SupplierPart + + delete: + Remove a SupplierPart + + """ + + queryset = SupplierPart.objects.all() + serializer_class = SupplierPartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class SupplierPartFilter(FilterSet): + + class Meta: + model = SupplierPart + fields = ['supplier', 'part', 'manufacturer'] + + +class SupplierPartList(generics.ListCreateAPIView): + """ + + get: + List all SupplierParts + (with optional query filters) + + post: + Create a new SupplierPart + + """ + + queryset = SupplierPart.objects.all() + serializer_class = SupplierPartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + filter_backends = (DjangoFilterBackend,) + filter_class = SupplierPartFilter + + +class SupplierPriceBreakDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single SupplierPriceBreak + + post: + Update a SupplierPriceBreak + + delete: + Remove a SupplierPriceBreak + + """ + + queryset = SupplierPriceBreak.objects.all() + serializer_class = SupplierPriceBreakSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class PriceBreakFilter(FilterSet): + + class Meta: + model = SupplierPriceBreak + fields = ['part'] + + +class SupplierPriceBreakList(generics.ListCreateAPIView): + """ + + get: + Return a list of all SupplierPriceBreaks + (with optional query filters) + + post: + Create a new SupplierPriceBreak + + """ + + queryset = SupplierPriceBreak.objects.all() + serializer_class = SupplierPriceBreakSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + filter_backends = (DjangoFilterBackend,) + filter_class = PriceBreakFilter diff --git a/InvenTree/supplier/urls.py b/InvenTree/supplier/urls.py index f6491f5bba..2fa2be08dd 100644 --- a/InvenTree/supplier/urls.py +++ b/InvenTree/supplier/urls.py @@ -1,45 +1,46 @@ from django.conf.urls import url from . import views +from . import api cust_urls = [ # Customer detail - url(r'^(?P[0-9]+)/?$', views.CustomerDetail.as_view(), name='customer-detail'), + url(r'^(?P[0-9]+)/?$', api.CustomerDetail.as_view(), name='customer-detail'), # List customers - url(r'^\?.*/?$', views.CustomerList.as_view()), - url(r'^$', views.CustomerList.as_view()) + url(r'^\?.*/?$', api.CustomerList.as_view()), + url(r'^$', api.CustomerList.as_view()) ] manu_urls = [ # Manufacturer detail - url(r'^(?P[0-9]+)/?$', views.ManufacturerDetail.as_view(), name='manufacturer-detail'), + url(r'^(?P[0-9]+)/?$', api.ManufacturerDetail.as_view(), name='manufacturer-detail'), # List manufacturers - url(r'^\?.*/?$', views.ManufacturerList.as_view()), - url(r'^$', views.ManufacturerList.as_view()) + url(r'^\?.*/?$', api.ManufacturerList.as_view()), + url(r'^$', api.ManufacturerList.as_view()) ] supplier_part_urls = [ - url(r'^(?P[0-9]+)/?$', views.SupplierPartDetail.as_view(), name='supplierpart-detail'), + url(r'^(?P[0-9]+)/?$', api.SupplierPartDetail.as_view(), name='supplierpart-detail'), - url(r'^\?.*/?$', views.SupplierPartList.as_view()), - url(r'^$', views.SupplierPartList.as_view()) + url(r'^\?.*/?$', api.SupplierPartList.as_view()), + url(r'^$', api.SupplierPartList.as_view()) ] price_break_urls = [ - url(r'^(?P[0-9]+)/?$', views.SupplierPriceBreakDetail.as_view(), name='supplierpricebreak-detail'), + url(r'^(?P[0-9]+)/?$', api.SupplierPriceBreakDetail.as_view(), name='supplierpricebreak-detail'), - url(r'^\?.*/?$', views.SupplierPriceBreakList.as_view()), - url(r'^$', views.SupplierPriceBreakList.as_view()) + url(r'^\?.*/?$', api.SupplierPriceBreakList.as_view()), + url(r'^$', api.SupplierPriceBreakList.as_view()) ] supplier_urls = [ # Display details of a supplier - url(r'^(?P[0-9]+)/$', views.SupplierDetail.as_view(), name='supplier-detail'), + url(r'^(?P[0-9]+)/$', api.SupplierDetail.as_view(), name='supplier-detail'), # List suppliers - url(r'^\?.*/?$', views.SupplierList.as_view()), - url(r'^$', views.SupplierList.as_view()) + url(r'^\?.*/?$', api.SupplierList.as_view()), + url(r'^$', api.SupplierList.as_view()) ] diff --git a/InvenTree/supplier/views.py b/InvenTree/supplier/views.py index 8f9b43e03a..e69de29bb2 100644 --- a/InvenTree/supplier/views.py +++ b/InvenTree/supplier/views.py @@ -1,208 +0,0 @@ -from django_filters.rest_framework import FilterSet, DjangoFilterBackend - -from rest_framework import generics, permissions - -from .models import Supplier, SupplierPart, SupplierPriceBreak -from .models import Manufacturer, Customer -from .serializers import SupplierSerializer -from .serializers import SupplierPartSerializer -from .serializers import SupplierPriceBreakSerializer -from .serializers import ManufacturerSerializer -from .serializers import CustomerSerializer - - -class ManufacturerDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single Manufacturer - - post: - Update a Manufacturer - - delete: - Remove a Manufacturer - - """ - - queryset = Manufacturer.objects.all() - serializer_class = ManufacturerSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class ManufacturerList(generics.ListCreateAPIView): - """ - - get: - Return a list of all Manufacturers - - post: - Create a new Manufacturer - - """ - - queryset = Manufacturer.objects.all() - serializer_class = ManufacturerSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class CustomerDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single Customer - - post: - Update a Customer - - delete: - Remove a Customer - - """ - - queryset = Customer.objects.all() - serializer_class = CustomerSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class CustomerList(generics.ListCreateAPIView): - """ - - get: - Return a list of all Cutstomers - - post: - Create a new Customer - - """ - - queryset = Customer.objects.all() - serializer_class = CustomerSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class SupplierDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single Supplier - - post: - Update a supplier - - delete: - Remove a supplier - - """ - - queryset = Supplier.objects.all() - serializer_class = SupplierSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class SupplierList(generics.ListCreateAPIView): - """ - - get: - Return a list of all Suppliers - - post: - Create a new Supplier - - """ - - queryset = Supplier.objects.all() - serializer_class = SupplierSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class SupplierPartDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single SupplierPart - - post: - Update a SupplierPart - - delete: - Remove a SupplierPart - - """ - - queryset = SupplierPart.objects.all() - serializer_class = SupplierPartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class SupplierPartFilter(FilterSet): - - class Meta: - model = SupplierPart - fields = ['supplier', 'part', 'manufacturer'] - - -class SupplierPartList(generics.ListCreateAPIView): - """ - - get: - List all SupplierParts - (with optional query filters) - - post: - Create a new SupplierPart - - """ - - queryset = SupplierPart.objects.all() - serializer_class = SupplierPartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - filter_backends = (DjangoFilterBackend,) - filter_class = SupplierPartFilter - - -class SupplierPriceBreakDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single SupplierPriceBreak - - post: - Update a SupplierPriceBreak - - delete: - Remove a SupplierPriceBreak - - """ - - queryset = SupplierPriceBreak.objects.all() - serializer_class = SupplierPriceBreakSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class PriceBreakFilter(FilterSet): - - class Meta: - model = SupplierPriceBreak - fields = ['part'] - - -class SupplierPriceBreakList(generics.ListCreateAPIView): - """ - - get: - Return a list of all SupplierPriceBreaks - (with optional query filters) - - post: - Create a new SupplierPriceBreak - - """ - - queryset = SupplierPriceBreak.objects.all() - serializer_class = SupplierPriceBreakSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - filter_backends = (DjangoFilterBackend,) - filter_class = PriceBreakFilter diff --git a/InvenTree/track/api.py b/InvenTree/track/api.py new file mode 100644 index 0000000000..c36f710e0d --- /dev/null +++ b/InvenTree/track/api.py @@ -0,0 +1,97 @@ +from django_filters.rest_framework import FilterSet, DjangoFilterBackend +from django_filters import NumberFilter + +from rest_framework import generics, permissions + +from .models import UniquePart, PartTrackingInfo +from .serializers import UniquePartSerializer, PartTrackingInfoSerializer + + +class UniquePartDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single UniquePart + + post: + Update a UniquePart + + delete: + Remove a UniquePart + + """ + + queryset = UniquePart.objects.all() + serializer_class = UniquePartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class UniquePartFilter(FilterSet): + # Filter based on serial number + min_sn = NumberFilter(name='serial', lookup_expr='gte') + max_sn = NumberFilter(name='serial', lookup_expr='lte') + + class Meta: + model = UniquePart + fields = ['serial', 'part', 'customer'] + + +class UniquePartList(generics.ListCreateAPIView): + """ + + get: + Return a list of all UniqueParts + (with optional query filter) + + post: + Create a new UniquePart + """ + + queryset = UniquePart.objects.all() + serializer_class = UniquePartSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = UniquePartFilter + + +class PartTrackingDetail(generics.RetrieveUpdateDestroyAPIView): + """ + + get: + Return a single PartTrackingInfo object + + post: + Update a PartTrackingInfo object + + delete: + Remove a PartTrackingInfo object + """ + + queryset = PartTrackingInfo.objects.all() + serializer_class = PartTrackingInfoSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class PartTrackingFilter(FilterSet): + + class Meta: + model = PartTrackingInfo + fields = ['part'] + + +class PartTrackingList(generics.ListCreateAPIView): + """ + + get: + Return a list of all PartTrackingInfo objects + (with optional query filter) + + post: + Create a new PartTrackingInfo object + """ + + queryset = PartTrackingInfo.objects.all() + serializer_class = PartTrackingInfoSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + filter_backends = (DjangoFilterBackend,) + filter_class = PartTrackingFilter diff --git a/InvenTree/track/urls.py b/InvenTree/track/urls.py index cae9f9d5c2..37327b1ada 100644 --- a/InvenTree/track/urls.py +++ b/InvenTree/track/urls.py @@ -3,18 +3,18 @@ from django.conf.urls import url from . import views part_track_urls = [ - url(r'^(?P[0-9]+)/?$', views.PartTrackingDetail.as_view(), name='parttrackinginfo-detail'), + url(r'^(?P[0-9]+)/?$', api.PartTrackingDetail.as_view(), name='parttrackinginfo-detail'), - url(r'^\?.*/?$', views.PartTrackingList.as_view()), - url(r'^$', views.PartTrackingList.as_view()) + url(r'^\?.*/?$', api.PartTrackingList.as_view()), + url(r'^$', api.PartTrackingList.as_view()) ] unique_urls = [ # Detail for a single unique part - url(r'^(?P[0-9]+)/?$', views.UniquePartDetail.as_view(), name='uniquepart-detail'), + url(r'^(?P[0-9]+)/?$', api.UniquePartDetail.as_view(), name='uniquepart-detail'), # List all unique parts, with optional filters - url(r'^\?.*/?$', views.UniquePartList.as_view()), - url(r'^$', views.UniquePartList.as_view()), + url(r'^\?.*/?$', api.UniquePartList.as_view()), + url(r'^$', api.UniquePartList.as_view()), ] diff --git a/InvenTree/track/views.py b/InvenTree/track/views.py index c36f710e0d..e69de29bb2 100644 --- a/InvenTree/track/views.py +++ b/InvenTree/track/views.py @@ -1,97 +0,0 @@ -from django_filters.rest_framework import FilterSet, DjangoFilterBackend -from django_filters import NumberFilter - -from rest_framework import generics, permissions - -from .models import UniquePart, PartTrackingInfo -from .serializers import UniquePartSerializer, PartTrackingInfoSerializer - - -class UniquePartDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single UniquePart - - post: - Update a UniquePart - - delete: - Remove a UniquePart - - """ - - queryset = UniquePart.objects.all() - serializer_class = UniquePartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class UniquePartFilter(FilterSet): - # Filter based on serial number - min_sn = NumberFilter(name='serial', lookup_expr='gte') - max_sn = NumberFilter(name='serial', lookup_expr='lte') - - class Meta: - model = UniquePart - fields = ['serial', 'part', 'customer'] - - -class UniquePartList(generics.ListCreateAPIView): - """ - - get: - Return a list of all UniqueParts - (with optional query filter) - - post: - Create a new UniquePart - """ - - queryset = UniquePart.objects.all() - serializer_class = UniquePartSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = UniquePartFilter - - -class PartTrackingDetail(generics.RetrieveUpdateDestroyAPIView): - """ - - get: - Return a single PartTrackingInfo object - - post: - Update a PartTrackingInfo object - - delete: - Remove a PartTrackingInfo object - """ - - queryset = PartTrackingInfo.objects.all() - serializer_class = PartTrackingInfoSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - - -class PartTrackingFilter(FilterSet): - - class Meta: - model = PartTrackingInfo - fields = ['part'] - - -class PartTrackingList(generics.ListCreateAPIView): - """ - - get: - Return a list of all PartTrackingInfo objects - (with optional query filter) - - post: - Create a new PartTrackingInfo object - """ - - queryset = PartTrackingInfo.objects.all() - serializer_class = PartTrackingInfoSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) - filter_backends = (DjangoFilterBackend,) - filter_class = PartTrackingFilter