Allow API filtering by "cascading" stock locations

This commit is contained in:
Oliver Walters 2021-04-20 20:00:15 +10:00
parent 6986709fb8
commit 412b05d76c
4 changed files with 64 additions and 12 deletions

View File

@ -289,20 +289,35 @@ class StockLocationList(generics.ListCreateAPIView):
queryset = super().get_queryset()
loc_id = self.request.query_params.get('parent', None)
params = self.request.query_params
if loc_id is not None:
cascade = str2bool(params.get('cascade', False))
# Look for top-level locations
if isNull(loc_id):
loc_id = params.get('parent', None)
# Look for top-level locations
if isNull(loc_id):
# If we allow "cascade" at the top-level, this essentially means *all* locations
if not cascade:
queryset = queryset.filter(parent=None)
else:
try:
loc_id = int(loc_id)
queryset = queryset.filter(parent=loc_id)
except ValueError:
pass
else:
try:
location = StockLocation.objects.get(pk=loc_id)
# All sub-locations to be returned too?
if cascade:
parents = location.get_descendants(include_self=True)
parent_ids = [p.id for p in parents]
queryset = queryset.filter(parent__in=parent_ids)
else:
queryset = queryset.filter(parent=location)
except (ValueError, StockLocation.DoesNotExist):
pass
return queryset

View File

@ -15,7 +15,16 @@
<div class='panel-heading'>
<h4>{% trans "Sublocations" %}</h4>
</div>
<table class='table table-striped table-condensed' id='sublocation-table'></table>
<div id='button-toolbar'>
<div class='button-toolbar container-fluid' style='float: right;'>
</div>
<div class='filter-list' id='filter-list-location'>
<!-- An empty div in which the filter list will be constructed -->
</div>
</div>
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='sublocation-table'></table>
</div>
{% endblock %}

View File

@ -957,6 +957,12 @@ function loadStockLocationTable(table, options) {
switchable: true,
sortable: false,
},
{
field: 'pathstring',
title: '{% trans "Path" %}',
switchable: true,
sortable: false,
},
{
field: 'items',
title: '{% trans "Stock Items" %}',

View File

@ -62,6 +62,28 @@ function getAvailableTableFilters(tableKey) {
};
}
// Filters for "stock location" table
if (tableKey == "location") {
return {
cascade: {
type: 'bool',
title: '{% trans "Include sublocations" %}',
description: '{% trans "Include locations" %}',
}
};
}
// Filters for "part category" table
if (tableKey == "category") {
return {
cascade: {
type: 'bool',
title: '{% trans "Include subcategories" %}',
description: '{% trans "Include subcategories" %}',
}
};
}
// Filters for the "customer stock" table (really a subset of "stock")
if (tableKey == "customerstock") {
return {