mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	Merge pull request #984 from SchrodingersGat/index_page_fixes
Tweaks for new index page
This commit is contained in:
		| @@ -12,6 +12,7 @@ from rest_framework import generics, permissions | ||||
| from django.conf.urls import url, include | ||||
|  | ||||
| from InvenTree.helpers import str2bool | ||||
| from InvenTree.status_codes import BuildStatus | ||||
|  | ||||
| from .models import Build, BuildItem | ||||
| from .serializers import BuildSerializer, BuildItemSerializer | ||||
| @@ -59,10 +60,18 @@ class BuildList(generics.ListCreateAPIView): | ||||
|         status = self.request.query_params.get('status', None) | ||||
|  | ||||
|         if status is not None: | ||||
|             # Get status codes | ||||
|             codes = status.split('-') | ||||
|             # Filter by codes | ||||
|             queryset = queryset.filter(status__in=codes) | ||||
|             queryset = queryset.filter(status=status) | ||||
|  | ||||
|         # Filter by "active" status | ||||
|         active = self.request.query_params.get('active', None) | ||||
|  | ||||
|         if active is not None: | ||||
|             active = str2bool(active) | ||||
|  | ||||
|             if active: | ||||
|                 queryset = queryset.filter(status__in=BuildStatus.ACTIVE_CODES) | ||||
|             else: | ||||
|                 queryset = queryset.exclude(status__in=BuildStatus.ACTIVE_CODES) | ||||
|  | ||||
|         # Filter by associated part? | ||||
|         part = self.request.query_params.get('part', None) | ||||
|   | ||||
| @@ -405,26 +405,27 @@ class PartList(generics.ListCreateAPIView): | ||||
|             except (ValueError, Part.DoesNotExist): | ||||
|                 pass | ||||
|  | ||||
|         # Filter by latest part creation date | ||||
|         latest_parts = params.get('latest_parts', None) | ||||
|         # Filter by whether the BOM has been validated (or not) | ||||
|         bom_valid = params.get('bom_valid', None) | ||||
|  | ||||
|         if latest_parts is not None: | ||||
|             # Get the last 5 created parts | ||||
|             queryset = queryset.order_by('-creation_date')[:5] | ||||
|         # TODO: Querying bom_valid status may be quite expensive | ||||
|         # TODO: (It needs to be profiled!) | ||||
|         # TODO: It might be worth caching the bom_valid status to a database column | ||||
|  | ||||
|         # Filter invalid BOMs | ||||
|         bom_invalid = params.get('bom_invalid', None) | ||||
|         if bom_valid is not None: | ||||
|  | ||||
|         if bom_invalid is not None: | ||||
|             # Get assemblies with invalid BOMs | ||||
|             assemblies = queryset.filter(active=True).filter(assembly=True) | ||||
|             valid_boms = [] | ||||
|             bom_valid = str2bool(bom_valid) | ||||
|  | ||||
|             for part in assemblies: | ||||
|                 if part.is_bom_valid: | ||||
|                     valid_boms.append(part.pk) | ||||
|             # Limit queryset to active assemblies | ||||
|             queryset = queryset.filter(active=True, assembly=True) | ||||
|  | ||||
|             queryset = assemblies.exclude(pk__in=valid_boms) | ||||
|             pks = [] | ||||
|  | ||||
|             for part in queryset: | ||||
|                 if part.is_bom_valid() == bom_valid: | ||||
|                     pks.append(part.pk) | ||||
|  | ||||
|             queryset = queryset.filter(pk__in=pks) | ||||
|  | ||||
|         # Filter by 'starred' parts? | ||||
|         starred = params.get('starred', None) | ||||
| @@ -475,6 +476,7 @@ class PartList(generics.ListCreateAPIView): | ||||
|  | ||||
|         # Filter by whether the part has stock | ||||
|         has_stock = params.get("has_stock", None) | ||||
|  | ||||
|         if has_stock is not None: | ||||
|             has_stock = str2bool(has_stock) | ||||
|  | ||||
| @@ -501,6 +503,9 @@ class PartList(generics.ListCreateAPIView): | ||||
|         # Filter by "parts which need stock to complete build" | ||||
|         stock_to_build = params.get('stock_to_build', None) | ||||
|  | ||||
|         # TODO: This is super expensive, database query wise... | ||||
|         # TODO: Need to figure out a cheaper way of making this filter query | ||||
|  | ||||
|         if stock_to_build is not None: | ||||
|             # Filter only active parts | ||||
|             queryset = queryset.filter(active=True) | ||||
| @@ -514,6 +519,17 @@ class PartList(generics.ListCreateAPIView): | ||||
|  | ||||
|             queryset = queryset.filter(pk__in=parts_need_stock) | ||||
|  | ||||
|         # Limit choices | ||||
|         limit = params.get('limit', None) | ||||
|  | ||||
|         if limit is not None: | ||||
|             try: | ||||
|                 limit = int(limit) | ||||
|                 if limit > 0: | ||||
|                     queryset = queryset[:limit] | ||||
|             except ValueError: | ||||
|                 pass | ||||
|  | ||||
|         return queryset | ||||
|  | ||||
|     permission_classes = [ | ||||
| @@ -539,6 +555,7 @@ class PartList(generics.ListCreateAPIView): | ||||
|  | ||||
|     ordering_fields = [ | ||||
|         'name', | ||||
|         'creation_date', | ||||
|     ] | ||||
|  | ||||
|     # Default ordering | ||||
|   | ||||
| @@ -845,7 +845,6 @@ class Part(MPTTModel): | ||||
|  | ||||
|         return str(hash.digest()) | ||||
|  | ||||
|     @property | ||||
|     def is_bom_valid(self): | ||||
|         """ Check if the BOM is 'valid' - if the calculated checksum matches the stored value | ||||
|         """ | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-times-circle icon-header'></span> | ||||
| {% trans "BOM Waiting Validation" %}<span class='badge' id='bom-invalid-count'>0</span> | ||||
| {% trans "BOM Waiting Validation" %}<span class='badge' id='bom-invalid-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-cogs icon-header'></span> | ||||
| {% trans "Pending Builds" %}<span class='badge' id='build-pending-count'>0</span> | ||||
| {% trans "Pending Builds" %}<span class='badge' id='build-pending-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -55,58 +55,65 @@ InvenTree | Index | ||||
|  | ||||
| {{ block.super }} | ||||
|  | ||||
| loadPartTable("#latest-parts-table", "{% url 'api-part-list' %}", { | ||||
| loadSimplePartTable("#latest-parts-table", "{% url 'api-part-list' %}", { | ||||
|     params: { | ||||
|         "latest_parts": true, | ||||
|     } | ||||
|         ordering: "-creation_date", | ||||
|         limit: 10, | ||||
|     }, | ||||
|     name: 'latest_parts', | ||||
| }); | ||||
|  | ||||
| loadPartTable("#starred-parts-table", "{% url 'api-part-list' %}", { | ||||
| loadSimplePartTable("#starred-parts-table", "{% url 'api-part-list' %}", { | ||||
|     params: { | ||||
|         "starred": true, | ||||
|     } | ||||
|     }, | ||||
|     name: 'starred_parts', | ||||
| }); | ||||
|  | ||||
| loadPartTable("#bom-invalid-table", "{% url 'api-part-list' %}", { | ||||
| loadSimplePartTable("#bom-invalid-table", "{% url 'api-part-list' %}", { | ||||
|     params: { | ||||
|         "bom_invalid": true, | ||||
|     } | ||||
|         "bom_valid": false, | ||||
|     }, | ||||
|     name: 'bom_invalid_parts', | ||||
| }); | ||||
|  | ||||
| loadBuildTable("#build-pending-table", { | ||||
|     url: "{% url 'api-build-list' %}", | ||||
|     params: { | ||||
|         "part_detail": true, | ||||
|         "status": "10-20", | ||||
|     } | ||||
|         part_detail: true, | ||||
|         active: true, | ||||
|     }, | ||||
|     disableFilters: true, | ||||
| }); | ||||
|  | ||||
| loadPartTable("#low-stock-table", "{% url 'api-part-list' %}", { | ||||
| loadSimplePartTable("#low-stock-table", "{% url 'api-part-list' %}", { | ||||
|     params: { | ||||
|         "low_stock": true, | ||||
|     } | ||||
|         low_stock: true, | ||||
|     }, | ||||
|     name: "low_stock_parts", | ||||
| }); | ||||
|  | ||||
| loadPartTable("#stock-to-build-table", "{% url 'api-part-list' %}", { | ||||
| loadSimplePartTable("#stock-to-build-table", "{% url 'api-part-list' %}", { | ||||
|     params: { | ||||
|         "stock_to_build": true, | ||||
|     } | ||||
|         stock_to_build: true, | ||||
|     }, | ||||
|     name: "to_build_parts", | ||||
| }); | ||||
|  | ||||
| loadPurchaseOrderTable("#po-outstanding-table", { | ||||
|     url: "{% url 'api-po-list' %}", | ||||
|     params: { | ||||
|         "supplier_detail": true, | ||||
|         "oustanding": true, | ||||
|         supplier_detail: true, | ||||
|         outstanding: true, | ||||
|     } | ||||
| }); | ||||
|  | ||||
| loadSalesOrderTable("#so-outstanding-table", { | ||||
|     url: "{% url 'api-so-list' %}", | ||||
|     params: { | ||||
|         "customer_detail": true, | ||||
|         "oustanding": true, | ||||
|     } | ||||
|         customer_detail: true, | ||||
|         outstanding: true, | ||||
|     }, | ||||
| }); | ||||
|  | ||||
| $("#latest-parts-table").on('load-success.bs.table', function() { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-newspaper icon-header'></span> | ||||
| {% trans "Latest Parts" %}<span class='badge' id='latest-parts-count'>0</span> | ||||
| {% trans "Latest Parts" %}<span class='badge' id='latest-parts-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-shopping-cart icon-header'></span> | ||||
| {% trans "Low Stock" %}<span class='badge' id='low-stock-count'>0</span> | ||||
| {% trans "Low Stock" %}<span class='badge' id='low-stock-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| {% extends "collapse.html" %} | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-tools icon-header'></span> | ||||
| Parts to Build<span class='badge'>{{ to_build | length }}</span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_heading %} | ||||
| There are {{ to_build | length }} parts which need building. | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|  | ||||
| {% include "required_part_table.html" with parts=to_build table_id="to-build-table" %} | ||||
|  | ||||
| {% endblock %} | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-sign-in-alt icon-header'></span> | ||||
| {% trans "Outstanding Purchase Orders" %}<span class='badge' id='po-outstanding-count'>0</span> | ||||
| {% trans "Outstanding Purchase Orders" %}<span class='badge' id='po-outstanding-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-bullhorn icon-header'></span> | ||||
| {% trans "Require Stock To Complete Build" %}<span class='badge' id='stock-to-build-count'>0</span> | ||||
| {% trans "Require Stock To Complete Build" %}<span class='badge' id='stock-to-build-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-sign-out-alt icon-header'></span> | ||||
| {% trans "Outstanding Sales Orders" %}<span class='badge' id='so-outstanding-count'>0</span> | ||||
| {% trans "Outstanding Sales Orders" %}<span class='badge' id='so-outstanding-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| {% block collapse_title %} | ||||
| <span class='fas fa-star icon-header'></span> | ||||
| {% trans "Starred Parts" %}<span class='badge' id='starred-parts-count'>0</span> | ||||
| {% trans "Starred Parts" %}<span class='badge' id='starred-parts-count'><span class='fas fa-spin fa-hourglass-half'></span></span> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block collapse_content %} | ||||
|   | ||||
| @@ -5,7 +5,11 @@ function loadBuildTable(table, options) { | ||||
|  | ||||
|     var params = options.params || {}; | ||||
|  | ||||
|     var filters = loadTableFilters("build"); | ||||
|     var filters = {}; | ||||
|      | ||||
|     if (!options.disableFilters) { | ||||
|         loadTableFilters("build"); | ||||
|     } | ||||
|  | ||||
|     for (var key in params) { | ||||
|         filters[key] = params[key]; | ||||
|   | ||||
| @@ -155,6 +155,14 @@ function loadPartVariantTable(table, partId, options) { | ||||
| } | ||||
|  | ||||
|  | ||||
| function loadSimplePartTable(table, url, options={}) { | ||||
|  | ||||
|     options.disableFilters = true; | ||||
|  | ||||
|     loadPartTable(table, url, options); | ||||
| } | ||||
|  | ||||
|  | ||||
| function loadPartTable(table, url, options={}) { | ||||
|     /* Load part listing data into specified table. | ||||
|      *  | ||||
| @@ -332,7 +340,7 @@ function loadPartTable(table, url, options={}) { | ||||
|         method: 'get', | ||||
|         queryParams: filters, | ||||
|         groupBy: false, | ||||
|         name: 'part', | ||||
|         name: options.name || 'part', | ||||
|         original: params, | ||||
|         formatNoMatches: function() { return "{% trans "No parts found" %}"; }, | ||||
|         columns: columns, | ||||
|   | ||||
| @@ -109,7 +109,10 @@ function getAvailableTableFilters(tableKey) { | ||||
|                 title: '{% trans "Build status" %}', | ||||
|                 options: buildCodes, | ||||
|             }, | ||||
|  | ||||
|             pending: { | ||||
|                 type: 'bool', | ||||
|                 title: '{% trans "Pending" %}', | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user