mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	Improve table for displaying what parts a particular part is "used in"
This commit is contained in:
		| @@ -761,12 +761,26 @@ class BomList(generics.ListCreateAPIView): | ||||
|         if sub_part is not None: | ||||
|             queryset = queryset.filter(sub_part=sub_part) | ||||
|  | ||||
|         # Filter by "trackable" status of the sub-part | ||||
|         trackable = params.get('trackable', None) | ||||
|         # Filter by "active" status of the part | ||||
|         part_active = params.get('part_active', None) | ||||
|  | ||||
|         if trackable is not None: | ||||
|             trackable = str2bool(trackable) | ||||
|             queryset = queryset.filter(sub_part__trackable=trackable) | ||||
|         if part_active is not None: | ||||
|             part_active = str2bool(part_active) | ||||
|             queryset = queryset.filter(part__active=part_active) | ||||
|  | ||||
|         # Filter by "trackable" status of the part | ||||
|         part_trackable = params.get('part_trackable', None) | ||||
|  | ||||
|         if part_trackable is not None: | ||||
|             part_trackable = str2bool(part_trackable) | ||||
|             queryset = queryset.filter(part__trackable=part_trackable) | ||||
|  | ||||
|         # Filter by "trackable" status of the sub-part | ||||
|         sub_part_trackable = params.get('sub_part_trackable', None) | ||||
|  | ||||
|         if sub_part_trackable is not None: | ||||
|             sub_part_trackable = str2bool(sub_part_trackable) | ||||
|             queryset = queryset.filter(sub_part__trackable=sub_part_trackable) | ||||
|  | ||||
|         return queryset | ||||
|  | ||||
|   | ||||
| @@ -32,21 +32,34 @@ | ||||
| </div> | ||||
| {% endif %} | ||||
|  | ||||
| <div id='button-toolbar' class="btn-group" role="group" aria-label="..."> | ||||
|     {% if editing_enabled %} | ||||
|     <button class='btn btn-default action-button' type='button' title='{% trans "Remove selected BOM items" %}' id='bom-item-delete'><span class='fas fa-trash-alt'></span></button> | ||||
|     <button class='btn btn-default action-button' type='button' title='{% trans "Import BOM data" %}' id='bom-upload'><span class='fas fa-file-upload'></span></button> | ||||
|     <button class='btn btn-default action-button' type='button' title='{% trans "New BOM Item" %}' id='bom-item-new'><span class='fas fa-plus-circle'></span></button> | ||||
|     <button class='btn btn-default action-button' type='button' title='{% trans "Finish Editing" %}' id='editing-finished'><span class='fas fa-check-circle'></span></button> | ||||
|     {% elif part.active %} | ||||
|     {% if roles.part.change %} | ||||
|     <button class='btn btn-default action-button' type='button' title='{% trans "Edit BOM" %}' id='edit-bom'><span class='fas fa-edit'></span></button> | ||||
|     {% if part.is_bom_valid == False %} | ||||
|     <button class='btn btn-default action-button' id='validate-bom' title='{% trans "Validate Bill of Materials" %}' type='button'><span class='fas fa-clipboard-check'></span></button> | ||||
|     {% endif %} | ||||
|     {% endif %} | ||||
|     <button title='{% trans "Export Bill of Materials" %}' class='btn btn-default action-button' id='download-bom' type='button'><span class='fas fa-file-download'></span></button> | ||||
|     {% endif %} | ||||
| <div id='button-toolbar'> | ||||
|     <div class="btn-group" role="group" aria-label="..."> | ||||
|         {% if editing_enabled %} | ||||
|         <button class='btn btn-default' type='button' title='{% trans "Remove selected BOM items" %}' id='bom-item-delete'> | ||||
|             <span class='fas fa-trash-alt'></span> | ||||
|         </button> | ||||
|         <button class='btn btn-primary' type='button' title='{% trans "Import BOM data" %}' id='bom-upload'> | ||||
|             <span class='fas fa-file-upload'></span> {% trans "Upload" %} | ||||
|         </button> | ||||
|         <button class='btn btn-default' type='button' title='{% trans "New BOM Item" %}' id='bom-item-new'> | ||||
|             <span class='fas fa-plus-circle'></span> {% trans "Add Item" %} | ||||
|         </button> | ||||
|         <button class='btn btn-success' type='button' title='{% trans "Finish Editing" %}' id='editing-finished'> | ||||
|             <span class='fas fa-check-circle'></span> {% trans "Finished" %} | ||||
|         </button> | ||||
|         {% elif part.active %} | ||||
|         {% if roles.part.change %} | ||||
|         <button class='btn btn-primary' type='button' title='{% trans "Edit BOM" %}' id='edit-bom'><span class='fas fa-edit'></span> {% trans "Edit" %}</button> | ||||
|         {% if part.is_bom_valid == False %} | ||||
|         <button class='btn btn-success' id='validate-bom' title='{% trans "Validate Bill of Materials" %}' type='button'><span class='fas fa-clipboard-check'></span> {% trans "Validate" %}</button> | ||||
|         {% endif %} | ||||
|         {% endif %} | ||||
|         <button title='{% trans "Export Bill of Materials" %}' class='btn btn-default' id='download-bom' type='button'><span class='fas fa-file-download'></span> {% trans "Export" %}</button> | ||||
|         {% endif %} | ||||
|     </div> | ||||
|     <div class='filter-list' id='filter-list-bom'> | ||||
|         <!-- Empty div (will be filled out with avilable BOM filters) --> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| <table class='table table-striped table-condensed' data-toolbar="#button-toolbar" id='bom-table'> | ||||
| @@ -184,4 +197,4 @@ | ||||
|  | ||||
|     {% endif %} | ||||
|  | ||||
| {% endblock %} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -8,7 +8,13 @@ | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <table class="table table-striped table-condensed" id='used-table'> | ||||
| <div id='button-toolbar'> | ||||
|     <div class='filter-list' id='filter-list-usedin'> | ||||
|         <!-- Empty div (will be filled out with avilable BOM filters) --> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| <table class="table table-striped table-condensed" id='used-table' data-toolbar='#button-toolbar'> | ||||
| </table> | ||||
|  | ||||
| {% endblock %} | ||||
| @@ -16,52 +22,10 @@ | ||||
| {% block js_ready %} | ||||
| {{ block.super }} | ||||
|  | ||||
|     $("#used-table").inventreeTable({ | ||||
|         formatNoMatches: function() { return "{{ part.full_name }} is not used to make any other parts"; }, | ||||
|         queryParams: function(p) { | ||||
|             return { | ||||
|                 sub_part: {{ part.id }}, | ||||
|                 part_detail: true, | ||||
|             } | ||||
|         }, | ||||
|         columns: [ | ||||
|             { | ||||
|                 field: 'pk', | ||||
|                 title: 'ID', | ||||
|                 visible: false, | ||||
|                 switchable: false, | ||||
|             }, | ||||
|             { | ||||
|                 field: 'part_detail', | ||||
|                 title: 'Part', | ||||
|                 sortable: true, | ||||
|                 formatter: function(value, row, index, field) { | ||||
|                     var link = `/part/${value.pk}/bom/`; | ||||
|                     var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value.full_name, link); | ||||
|     loadUsedInTable('#used-table', { | ||||
|         part_detail: true, | ||||
|         part_id: {{ part.pk }} | ||||
|     }); | ||||
|  | ||||
|                     if (!row.part_detail.active) { | ||||
|                         html += "<span class='label label-warning' style='float: right;'>{% trans "INACTIVE" %}</span>"; | ||||
|                     } | ||||
|  | ||||
|                     return html; | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 field: 'part_detail.description', | ||||
|                 title: 'Description', | ||||
|                 sortable: true, | ||||
|             }, | ||||
|             { | ||||
|                 sortable: true, | ||||
|                 field: 'quantity', | ||||
|                 title: 'Uses', | ||||
|                 formatter: function(value, row, index, field) { | ||||
|                     return parseFloat(value); | ||||
|                 }, | ||||
|             } | ||||
|  | ||||
|         ], | ||||
|         url: "{% url 'api-bom-list' %}" | ||||
|     }) | ||||
|  | ||||
| {% endblock %} | ||||
| @@ -427,4 +427,86 @@ function loadBomTable(table, options) { | ||||
|             ); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function loadUsedInTable(table, options) { | ||||
|     /* Load a table which displays all the parts that the given part is used in. | ||||
|      */ | ||||
|  | ||||
|     var params = { | ||||
|         sub_part: options.part_id, | ||||
|         ordering: 'name', | ||||
|     } | ||||
|  | ||||
|     if (options.part_detail) { | ||||
|         params.part_detail = true; | ||||
|     } | ||||
|  | ||||
|     if (options.sub_part_detail) { | ||||
|         params.sub_part_detail = true; | ||||
|     } | ||||
|  | ||||
|     var filters = {}; | ||||
|  | ||||
|     if (!options.disableFilters) { | ||||
|         filters = loadTableFilters("usedin"); | ||||
|     } | ||||
|  | ||||
|     for (var key in params) { | ||||
|         filters[key] = params[key]; | ||||
|     } | ||||
|  | ||||
|     setupFilterList("usedin", $(table)); | ||||
|  | ||||
|     // Columns to display in the table | ||||
|     var cols = [ | ||||
|         { | ||||
|             field: 'pk', | ||||
|             title: 'ID', | ||||
|             visible: false, | ||||
|             switchable: false, | ||||
|         }, | ||||
|         { | ||||
|             field: 'part_detail.full_name', | ||||
|             title: '{% trans "Part" %}', | ||||
|             sortable: true, | ||||
|             formatter: function(value, row, index, field) { | ||||
|                 var link = `/part/${row.part}/bom/`; | ||||
|                 var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, link); | ||||
|  | ||||
|                 if (!row.part_detail.active) { | ||||
|                     html += "<span class='label label-warning' style='float: right;'>{% trans 'INACTIVE' %}</span>"; | ||||
|                 } | ||||
|  | ||||
|                 return html; | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             field: 'part_detail.description', | ||||
|             title: '{% trans "Description" %}', | ||||
|             sortable: true, | ||||
|         }, | ||||
|         { | ||||
|             sortable: true, | ||||
|             field: 'quantity', | ||||
|             title: '{% trans "Uses" %}', | ||||
|             formatter: function(value, row, index, field) { | ||||
|                 return parseFloat(value); | ||||
|             }, | ||||
|         } | ||||
|     ]; | ||||
|  | ||||
|     // Load the table | ||||
|     $(table).inventreeTable({ | ||||
|         url: "{% url 'api-bom-list' %}", | ||||
|         formatNoMatches: function() { | ||||
|             return '{% trans "No matching parts found" %}'; | ||||
|         }, | ||||
|         columns: cols, | ||||
|         showColumns: true, | ||||
|         sortable: true, | ||||
|         serach: true, | ||||
|         queryParams: filters, | ||||
|         original: params, | ||||
|     }); | ||||
| } | ||||
| @@ -11,6 +11,30 @@ function getAvailableTableFilters(tableKey) { | ||||
|  | ||||
|     tableKey = tableKey.toLowerCase(); | ||||
|  | ||||
|     // Filters for Bill of Materials table | ||||
|     if (tableKey == "bom") { | ||||
|         return { | ||||
|             sub_part_trackable: { | ||||
|                 type: 'bool', | ||||
|                 title: '{% trans "Trackable Part" %}' | ||||
|             }, | ||||
|             validated: { | ||||
|                 type: 'bool', | ||||
|                 title: '{% trans "Validated" %}', | ||||
|             }, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     // Filters for the "used in" table | ||||
|     if (tableKey == 'usedin') { | ||||
|         return { | ||||
|             'part_active': { | ||||
|                 type: 'bool', | ||||
|                 title: '{% trans "Active" %}', | ||||
|             }, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     // Filters for the "customer stock" table (really a subset of "stock") | ||||
|     if (tableKey == "customerstock") { | ||||
|         return { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user