mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge branch 'inventree:master' into load-minified-fa
This commit is contained in:
		| @@ -781,6 +781,7 @@ input[type="submit"] { | ||||
| .btn-small { | ||||
|     padding: 3px; | ||||
|     padding-left: 5px; | ||||
|     padding-right: 5px; | ||||
| } | ||||
|  | ||||
| .btn-remove { | ||||
|   | ||||
| @@ -12,11 +12,15 @@ import common.models | ||||
| INVENTREE_SW_VERSION = "0.6.0 dev" | ||||
|  | ||||
| # InvenTree API version | ||||
| INVENTREE_API_VERSION = 18 | ||||
| INVENTREE_API_VERSION = 19 | ||||
|  | ||||
| """ | ||||
| Increment this API version number whenever there is a significant change to the API that any clients need to know about | ||||
|  | ||||
| v19 -> 2021-12-02 | ||||
|     - Adds the ability to filter the StockItem API by "part_tree" | ||||
|     - Returns only stock items which match a particular part.tree_id field | ||||
|  | ||||
| v18 -> 2021-11-15 | ||||
|     - Adds the ability to filter BomItem API by "uses" field | ||||
|     - This returns a list of all BomItems which "use" the specified part | ||||
|   | ||||
| @@ -1075,6 +1075,7 @@ class PartList(generics.ListCreateAPIView): | ||||
|         'revision', | ||||
|         'keywords', | ||||
|         'category__name', | ||||
|         'manufacturer_parts__MPN', | ||||
|     ] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -322,7 +322,14 @@ | ||||
|                 <tr> | ||||
|                     <td><span class='fas fa-hashtag'></span></td> | ||||
|                     <td>{% trans "Latest Serial Number" %}</td> | ||||
|                     <td>{{ part.getLatestSerialNumber }}{% include "clip.html"%}</td> | ||||
|                     <td> | ||||
|                         {{ part.getLatestSerialNumber }} | ||||
|                         <div class='btn-group float-right' role='group'> | ||||
|                             <a class='btn btn-small btn-outline-secondary text-sm' href='#' id='serial-number-search' title='{% trans "Search for serial number" %}'> | ||||
|                                 <span class='fas fa-search'></span> | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                 {% endif %} | ||||
|                 {% if part.default_location %} | ||||
| @@ -577,4 +584,8 @@ | ||||
|         $('#collapse-part-details').collapse('show'); | ||||
|     } | ||||
|  | ||||
|     $('#serial-number-search').click(function() { | ||||
|         findStockItemBySerialNumber({{ part.pk }}); | ||||
|     });     | ||||
|  | ||||
| {% endblock %} | ||||
| @@ -313,7 +313,7 @@ class StockFilter(rest_filters.FilterSet): | ||||
|     # Serial number filtering | ||||
|     serial_gte = rest_filters.NumberFilter(label='Serial number GTE', field_name='serial', lookup_expr='gte') | ||||
|     serial_lte = rest_filters.NumberFilter(label='Serial number LTE', field_name='serial', lookup_expr='lte') | ||||
|     serial = rest_filters.NumberFilter(label='Serial number', field_name='serial', lookup_expr='exact') | ||||
|     serial = rest_filters.CharFilter(label='Serial number', field_name='serial', lookup_expr='exact') | ||||
|  | ||||
|     serialized = rest_filters.BooleanFilter(label='Has serial number', method='filter_serialized') | ||||
|  | ||||
| @@ -703,6 +703,18 @@ class StockList(generics.ListCreateAPIView): | ||||
|             except (ValueError, StockItem.DoesNotExist): | ||||
|                 pass | ||||
|  | ||||
|         # Filter by "part tree" - only allow parts within a given variant tree | ||||
|         part_tree = params.get('part_tree', None) | ||||
|  | ||||
|         if part_tree is not None: | ||||
|             try: | ||||
|                 part = Part.objects.get(pk=part_tree) | ||||
|  | ||||
|                 if part.tree_id is not None: | ||||
|                     queryset = queryset.filter(part__tree_id=part.tree_id) | ||||
|             except: | ||||
|                 pass | ||||
|  | ||||
|         # Filter by 'allocated' parts? | ||||
|         allocated = params.get('allocated', None) | ||||
|  | ||||
|   | ||||
| @@ -148,17 +148,24 @@ | ||||
|         <td><span class='fas fa-hashtag'></span></td> | ||||
|         <td>{% trans "Serial Number" %}</td> | ||||
|         <td> | ||||
|         {% if previous %} | ||||
|             <a class="btn btn-outline-secondary" aria-label="{% trans 'previous page' %}" href="{% url request.resolver_match.url_name previous.id %}"> | ||||
|                 <small>{{ previous.serial }}</small>  ‹ | ||||
|             </a> | ||||
|         {% endif %} | ||||
|         {{ item.serial }} | ||||
|         {% if next %} | ||||
|             <a class="btn btn-outline-secondary text-sm" aria-label="{% trans 'next page' %}" href="{% url request.resolver_match.url_name next.id %}"> | ||||
|                 ›  <small>{{ next.serial }}</small> | ||||
|             </a> | ||||
|         {% endif %} | ||||
|             {{ item.serial }} | ||||
|             <div class='btn-group float-right' role='group'> | ||||
|                 {% if previous %} | ||||
|                 <a class="btn btn-small btn-outline-secondary" aria-label="{% trans 'previous page' %}" href="{% url request.resolver_match.url_name previous.id %}" title='{% trans "Navigate to previous serial number" %}'> | ||||
|                     <span class='fas fa-angle-left'></span> | ||||
|                     <small>{{ previous.serial }}</small> | ||||
|                 </a> | ||||
|                 {% endif %} | ||||
|                 <a class='btn btn-small btn-outline-secondary text-sm' href='#' id='serial-number-search' title='{% trans "Search for serial number" %}'> | ||||
|                     <span class='fas fa-search'></span> | ||||
|                 </a> | ||||
|                 {% if next %} | ||||
|                 <a class="btn btn-small btn-outline-secondary text-sm" aria-label="{% trans 'next page' %}" href="{% url request.resolver_match.url_name next.id %}" title='{% trans "Navigate to next serial number" %}'> | ||||
|                     <small>{{ next.serial }}</small> | ||||
|                     <span class='fas fa-angle-right'></span> | ||||
|                 </a> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         </td> | ||||
|     </tr> | ||||
|     {% else %} | ||||
| @@ -592,4 +599,8 @@ $("#stock-return-from-customer").click(function() { | ||||
|  | ||||
| {% endif %} | ||||
|  | ||||
| $('#serial-number-search').click(function() { | ||||
|     findStockItemBySerialNumber({{ item.part.pk }}); | ||||
| }); | ||||
|  | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -44,6 +44,7 @@ | ||||
|     editStockItem, | ||||
|     editStockLocation, | ||||
|     exportStock, | ||||
|     findStockItemBySerialNumber, | ||||
|     loadInstalledInTable, | ||||
|     loadStockLocationTable, | ||||
|     loadStockTable, | ||||
| @@ -394,6 +395,87 @@ function createNewStockItem(options={}) { | ||||
|     constructForm(url, options); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Launch a modal form to find a particular stock item by serial number. | ||||
|  * Arguments: | ||||
|  * - part: ID (PK) of the part in question | ||||
|  */ | ||||
|  | ||||
| function findStockItemBySerialNumber(part_id) { | ||||
|  | ||||
|     constructFormBody({}, { | ||||
|         title: '{% trans "Find Serial Number" %}', | ||||
|         fields: { | ||||
|             serial: { | ||||
|                 label: '{% trans "Serial Number" %}', | ||||
|                 help_text: '{% trans "Enter serial number" %}', | ||||
|                 placeholder: '{% trans "Enter serial number" %}', | ||||
|                 required: true, | ||||
|                 type: 'string', | ||||
|                 value: '', | ||||
|             } | ||||
|         }, | ||||
|         onSubmit: function(fields, opts) { | ||||
|  | ||||
|             var serial = getFormFieldValue('serial', fields['serial'], opts); | ||||
|          | ||||
|             serial = serial.toString().trim(); | ||||
|  | ||||
|             if (!serial) { | ||||
|                 handleFormErrors( | ||||
|                     { | ||||
|                         'serial': [ | ||||
|                             '{% trans "Enter a serial number" %}', | ||||
|                         ] | ||||
|                     }, fields, opts | ||||
|                 ); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             inventreeGet( | ||||
|                 '{% url "api-stock-list" %}', | ||||
|                 { | ||||
|                     part_tree: part_id, | ||||
|                     serial: serial, | ||||
|                 }, | ||||
|                 { | ||||
|                     success: function(response) { | ||||
|                         if (response.length == 0) { | ||||
|                             // No results! | ||||
|                             handleFormErrors( | ||||
|                                 { | ||||
|                                     'serial': [ | ||||
|                                         '{% trans "No matching serial number" %}', | ||||
|                                     ] | ||||
|                                 }, fields, opts | ||||
|                             ); | ||||
|                         } else if (response.length > 1) { | ||||
|                             // Too many results! | ||||
|                             handleFormErrors( | ||||
|                                 { | ||||
|                                     'serial': [ | ||||
|                                         '{% trans "More than one matching result found" %}', | ||||
|                                     ] | ||||
|                                 }, fields, opts | ||||
|                             ); | ||||
|                         } else { | ||||
|                             $(opts.modal).modal('hide'); | ||||
|  | ||||
|                             // Redirect | ||||
|                             var pk = response[0].pk; | ||||
|                             location.href = `/stock/item/${pk}/`; | ||||
|                         } | ||||
|                     }, | ||||
|                     error: function(xhr) { | ||||
|                         showApiError(xhr, opts.url); | ||||
|                         $(opts.modal).modal('hide'); | ||||
|                     } | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Stock API functions | ||||
|  * Requires api.js to be loaded first | ||||
|   | ||||
		Reference in New Issue
	
	Block a user