mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
f00a7cb6ef
@ -489,7 +489,8 @@ class PartFilter(rest_filters.FilterSet):
|
|||||||
|
|
||||||
|
|
||||||
class PartList(generics.ListCreateAPIView):
|
class PartList(generics.ListCreateAPIView):
|
||||||
""" API endpoint for accessing a list of Part objects
|
"""
|
||||||
|
API endpoint for accessing a list of Part objects
|
||||||
|
|
||||||
- GET: Return list of objects
|
- GET: Return list of objects
|
||||||
- POST: Create a new Part object
|
- POST: Create a new Part object
|
||||||
@ -840,14 +841,54 @@ class PartParameterDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
serializer_class = part_serializers.PartParameterSerializer
|
serializer_class = part_serializers.PartParameterSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class BomFilter(rest_filters.FilterSet):
|
||||||
|
"""
|
||||||
|
Custom filters for the BOM list
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Boolean filters for BOM item
|
||||||
|
optional = rest_filters.BooleanFilter(label='BOM line is optional')
|
||||||
|
inherited = rest_filters.BooleanFilter(label='BOM line is inherited')
|
||||||
|
allow_variants = rest_filters.BooleanFilter(label='Variants are allowed')
|
||||||
|
|
||||||
|
validated = rest_filters.BooleanFilter(label='BOM line has been validated', method='filter_validated')
|
||||||
|
|
||||||
|
def filter_validated(self, queryset, name, value):
|
||||||
|
|
||||||
|
# Work out which lines have actually been validated
|
||||||
|
pks = []
|
||||||
|
|
||||||
|
for bom_item in queryset.all():
|
||||||
|
if bom_item.is_line_valid():
|
||||||
|
pks.append(bom_item.pk)
|
||||||
|
|
||||||
|
if str2bool(value):
|
||||||
|
queryset = queryset.filter(pk__in=pks)
|
||||||
|
else:
|
||||||
|
queryset = queryset.exclude(pk__in=pks)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
# Filters for linked 'part'
|
||||||
|
part_active = rest_filters.BooleanFilter(label='Master part is active', field_name='part__active')
|
||||||
|
part_trackable = rest_filters.BooleanFilter(label='Master part is trackable', field_name='part__trackable')
|
||||||
|
|
||||||
|
# Filters for linked 'sub_part'
|
||||||
|
sub_part_trackable = rest_filters.BooleanFilter(label='Sub part is trackable', field_name='sub_part__trackable')
|
||||||
|
sub_part_assembly = rest_filters.BooleanFilter(label='Sub part is an assembly', field_name='sub_part__assembly')
|
||||||
|
|
||||||
|
|
||||||
class BomList(generics.ListCreateAPIView):
|
class BomList(generics.ListCreateAPIView):
|
||||||
""" API endpoint for accessing a list of BomItem objects.
|
"""
|
||||||
|
API endpoint for accessing a list of BomItem objects.
|
||||||
|
|
||||||
- GET: Return list of BomItem objects
|
- GET: Return list of BomItem objects
|
||||||
- POST: Create a new BomItem object
|
- POST: Create a new BomItem object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = part_serializers.BomItemSerializer
|
serializer_class = part_serializers.BomItemSerializer
|
||||||
|
queryset = BomItem.objects.all()
|
||||||
|
filterset_class = BomFilter
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
|
|
||||||
@ -894,30 +935,6 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
params = self.request.query_params
|
params = self.request.query_params
|
||||||
|
|
||||||
# Filter by "optional" status?
|
|
||||||
optional = params.get('optional', None)
|
|
||||||
|
|
||||||
if optional is not None:
|
|
||||||
optional = str2bool(optional)
|
|
||||||
|
|
||||||
queryset = queryset.filter(optional=optional)
|
|
||||||
|
|
||||||
# Filter by "inherited" status
|
|
||||||
inherited = params.get('inherited', None)
|
|
||||||
|
|
||||||
if inherited is not None:
|
|
||||||
inherited = str2bool(inherited)
|
|
||||||
|
|
||||||
queryset = queryset.filter(inherited=inherited)
|
|
||||||
|
|
||||||
# Filter by "allow_variants"
|
|
||||||
variants = params.get("allow_variants", None)
|
|
||||||
|
|
||||||
if variants is not None:
|
|
||||||
variants = str2bool(variants)
|
|
||||||
|
|
||||||
queryset = queryset.filter(allow_variants=variants)
|
|
||||||
|
|
||||||
# Filter by part?
|
# Filter by part?
|
||||||
part = params.get('part', None)
|
part = params.get('part', None)
|
||||||
|
|
||||||
@ -940,45 +957,6 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
except (ValueError, Part.DoesNotExist):
|
except (ValueError, Part.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Filter by "active" status of the part
|
|
||||||
part_active = params.get('part_active', None)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
# Filter by whether the BOM line has been validated
|
|
||||||
validated = params.get('validated', None)
|
|
||||||
|
|
||||||
if validated is not None:
|
|
||||||
validated = str2bool(validated)
|
|
||||||
|
|
||||||
# Work out which lines have actually been validated
|
|
||||||
pks = []
|
|
||||||
|
|
||||||
for bom_item in queryset.all():
|
|
||||||
if bom_item.is_line_valid:
|
|
||||||
pks.append(bom_item.pk)
|
|
||||||
|
|
||||||
if validated:
|
|
||||||
queryset = queryset.filter(pk__in=pks)
|
|
||||||
else:
|
|
||||||
queryset = queryset.exclude(pk__in=pks)
|
|
||||||
|
|
||||||
# Annotate with purchase prices
|
# Annotate with purchase prices
|
||||||
queryset = queryset.annotate(
|
queryset = queryset.annotate(
|
||||||
purchase_price_min=Min('sub_part__stock_items__purchase_price'),
|
purchase_price_min=Min('sub_part__stock_items__purchase_price'),
|
||||||
|
@ -242,7 +242,7 @@ function loadBomTable(table, options) {
|
|||||||
return renderLink(text, url);
|
return renderLink(text, url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cols.push(
|
cols.push(
|
||||||
{
|
{
|
||||||
field: 'purchase_price_range',
|
field: 'purchase_price_range',
|
||||||
|
@ -314,7 +314,7 @@ function setupFilterList(tableKey, table, target) {
|
|||||||
// Only add the new filter if it is not empty!
|
// Only add the new filter if it is not empty!
|
||||||
if (tag && tag.length > 0) {
|
if (tag && tag.length > 0) {
|
||||||
var filters = addTableFilter(tableKey, tag, val);
|
var filters = addTableFilter(tableKey, tag, val);
|
||||||
reloadTable(table, filters);
|
reloadTableFilters(table, filters);
|
||||||
|
|
||||||
// Run this function again
|
// Run this function again
|
||||||
setupFilterList(tableKey, table, target);
|
setupFilterList(tableKey, table, target);
|
||||||
@ -333,7 +333,7 @@ function setupFilterList(tableKey, table, target) {
|
|||||||
element.find(`#${clear}`).click(function() {
|
element.find(`#${clear}`).click(function() {
|
||||||
var filters = clearTableFilters(tableKey);
|
var filters = clearTableFilters(tableKey);
|
||||||
|
|
||||||
reloadTable(table, filters);
|
reloadTableFilters(table, filters);
|
||||||
|
|
||||||
setupFilterList(tableKey, table, target);
|
setupFilterList(tableKey, table, target);
|
||||||
});
|
});
|
||||||
@ -346,7 +346,7 @@ function setupFilterList(tableKey, table, target) {
|
|||||||
|
|
||||||
var filters = removeTableFilter(tableKey, filter);
|
var filters = removeTableFilter(tableKey, filter);
|
||||||
|
|
||||||
reloadTable(table, filters);
|
reloadTableFilters(table, filters);
|
||||||
|
|
||||||
// Run this function again!
|
// Run this function again!
|
||||||
setupFilterList(tableKey, table, target);
|
setupFilterList(tableKey, table, target);
|
||||||
|
@ -42,6 +42,10 @@ function getAvailableTableFilters(tableKey) {
|
|||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Trackable Part" %}'
|
title: '{% trans "Trackable Part" %}'
|
||||||
},
|
},
|
||||||
|
sub_part_assembly: {
|
||||||
|
type: 'bool',
|
||||||
|
title: '{% trans "Assembled Part" %}',
|
||||||
|
},
|
||||||
validated: {
|
validated: {
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Validated" %}',
|
title: '{% trans "Validated" %}',
|
||||||
|
@ -68,7 +68,7 @@ function isNumeric(n) {
|
|||||||
* Reload a table which has already been made into a bootstrap table.
|
* Reload a table which has already been made into a bootstrap table.
|
||||||
* New filters can be optionally provided, to change the query params.
|
* New filters can be optionally provided, to change the query params.
|
||||||
*/
|
*/
|
||||||
function reloadTable(table, filters) {
|
function reloadTableFilters(table, filters) {
|
||||||
|
|
||||||
// Simply perform a refresh
|
// Simply perform a refresh
|
||||||
if (filters == null) {
|
if (filters == null) {
|
||||||
@ -94,16 +94,11 @@ function reloadTable(table, filters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
options.queryParams = function(tableParams) {
|
options.queryParams = function(tableParams) {
|
||||||
|
return convertQueryParameters(tableParams, params);
|
||||||
for (key in params) {
|
};
|
||||||
tableParams[key] = params[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
return tableParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.bootstrapTable('refreshOptions', options);
|
table.bootstrapTable('refreshOptions', options);
|
||||||
table.bootstrapTable('refresh');
|
table.bootstrapTable('refresh', filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,6 +117,55 @@ function visibleColumnString(columns) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert bootstrap-table style parameters to "InvenTree" style
|
||||||
|
*/
|
||||||
|
function convertQueryParameters(params, filters) {
|
||||||
|
|
||||||
|
// Override the way that we ask the server to sort results
|
||||||
|
// It seems bootstrap-table does not offer a "native" way to do this...
|
||||||
|
if ('sort' in params) {
|
||||||
|
var order = params['order'];
|
||||||
|
|
||||||
|
var ordering = params['sort'] || null;
|
||||||
|
|
||||||
|
if (ordering) {
|
||||||
|
|
||||||
|
if (order == 'desc') {
|
||||||
|
ordering = `-${ordering}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
params['ordering'] = ordering;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete params['sort'];
|
||||||
|
delete params['order'];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in filters) {
|
||||||
|
params[key] = filters[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add "order" back in (if it was originally specified by InvenTree)
|
||||||
|
// Annoyingly, "order" shadows some field names in InvenTree...
|
||||||
|
if ('order' in filters) {
|
||||||
|
params['order'] = filters['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove searchable[] array (generated by bootstrap-table)
|
||||||
|
if ('searchable' in params) {
|
||||||
|
delete params['searchable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('sortable' in params) {
|
||||||
|
delete params['sortable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper function for bootstrapTable.
|
/* Wrapper function for bootstrapTable.
|
||||||
* Sets some useful defaults, and manage persistent settings.
|
* Sets some useful defaults, and manage persistent settings.
|
||||||
*/
|
*/
|
||||||
@ -147,39 +191,8 @@ $.fn.inventreeTable = function(options) {
|
|||||||
var filters = options.queryParams || options.filters || {};
|
var filters = options.queryParams || options.filters || {};
|
||||||
|
|
||||||
options.queryParams = function(params) {
|
options.queryParams = function(params) {
|
||||||
|
return convertQueryParameters(params, filters);
|
||||||
// Override the way that we ask the server to sort results
|
};
|
||||||
// It seems bootstrap-table does not offer a "native" way to do this...
|
|
||||||
if ('sort' in params) {
|
|
||||||
var order = params['order'];
|
|
||||||
|
|
||||||
var ordering = params['sort'] || null;
|
|
||||||
|
|
||||||
if (ordering) {
|
|
||||||
|
|
||||||
if (order == 'desc') {
|
|
||||||
ordering = `-${ordering}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
params['ordering'] = ordering;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete params['sort'];
|
|
||||||
delete params['order'];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var key in filters) {
|
|
||||||
params[key] = filters[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add "order" back in (if it was originally specified by InvenTree)
|
|
||||||
// Annoyingly, "order" shadows some field names in InvenTree...
|
|
||||||
if ('order' in filters) {
|
|
||||||
params['order'] = filters['order'];
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
options.rememberOrder = true;
|
options.rememberOrder = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user