diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 496153a6d0..62bfae7261 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -21,6 +21,7 @@ from .models import Part, PartCategory, BomItem, PartStar from .models import PartParameter, PartParameterTemplate from .models import PartAttachment, PartTestTemplate from .models import PartSellPriceBreak +from .models import PartCategoryParameterTemplate from build.models import Build @@ -111,6 +112,36 @@ class CategoryDetail(generics.RetrieveUpdateDestroyAPIView): queryset = PartCategory.objects.all() +class CategoryParameters(generics.ListAPIView): + """ API endpoint for accessing a list of PartCategory objects. + + - GET: Return a list of PartCategory objects + """ + + queryset = PartCategoryParameterTemplate.objects.all() + serializer_class = part_serializers.CategoryParameterTemplateSerializer + + def get_queryset(self): + """ + Custom filtering: + - Allow filtering by "null" parent to retrieve top-level part categories + """ + + cat_id = self.kwargs.get('pk', None) + + queryset = super().get_queryset() + + if cat_id is not None: + + try: + cat_id = int(cat_id) + queryset = queryset.filter(category=cat_id) + except ValueError: + pass + + return queryset + + class PartSalePriceList(generics.ListCreateAPIView): """ API endpoint for list view of PartSalePriceBreak model @@ -853,6 +884,7 @@ part_api_urls = [ # Base URL for PartCategory API endpoints url(r'^category/', include([ + url(r'^(?P\d+)/parameters/?', CategoryParameters.as_view(), name='api-part-category-parameters'), url(r'^(?P\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'), url(r'^$', CategoryList.as_view(), name='api-part-category-list'), ])), diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index f6eb8dc95b..faa6c9973a 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -15,7 +15,7 @@ from stock.models import StockItem from .models import (BomItem, Part, PartAttachment, PartCategory, PartParameter, PartParameterTemplate, PartSellPriceBreak, - PartStar, PartTestTemplate) + PartStar, PartTestTemplate, PartCategoryParameterTemplate) class CategorySerializer(InvenTreeModelSerializer): @@ -425,3 +425,21 @@ class PartParameterTemplateSerializer(InvenTreeModelSerializer): 'name', 'units', ] + + +class CategoryParameterTemplateSerializer(InvenTreeModelSerializer): + """ Serializer for PartCategoryParameterTemplate """ + + parameter_template_detail = PartParameterTemplateSerializer(source='parameter_template', + many=False, + read_only=True) + + class Meta: + model = PartCategoryParameterTemplate + fields = [ + 'pk', + 'category', + 'parameter_template', + 'parameter_template_detail', + 'default_value', + ] diff --git a/InvenTree/templates/InvenTree/settings/category.html b/InvenTree/templates/InvenTree/settings/category.html index 3dc702adc1..c91058e02b 100644 --- a/InvenTree/templates/InvenTree/settings/category.html +++ b/InvenTree/templates/InvenTree/settings/category.html @@ -37,6 +37,33 @@ {{ block.super }} {% if category %} + $("#param-table").inventreeTable({ + url: "{% url 'api-part-category-parameters' category %}", + queryParams: { + ordering: 'name', + }, + formatNoMatches: function() { return '{% trans "No category parameter templates found" %}'; }, + columns: [ + { + field: 'pk', + title: 'ID', + visible: false, + switchable: false, + }, + { + field: 'parameter_template_detail.name', + title: 'Parameter Template', + sortable: 'true', + }, + { + field: 'default_value', + title: 'Default Value', + sortable: 'true', + }, + ] + }); + + $("#new-param").click(function() { launchModalForm("{% url 'category-param-template-create' category %}", { success: function() { @@ -44,6 +71,6 @@ }, }); }); - + {% endif %} {% endblock %}