mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2801 from rkalman/feat-use-unallocated-quantites
Use new unallocated_stock quantity in the part table and in the search results
This commit is contained in:
commit
d1a8b7ed48
@ -12,11 +12,14 @@ import common.models
|
|||||||
INVENTREE_SW_VERSION = "0.7.0 dev"
|
INVENTREE_SW_VERSION = "0.7.0 dev"
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 35
|
INVENTREE_API_VERSION = 36
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||||
|
|
||||||
|
v36 -> 2022-04-03
|
||||||
|
- Adds ability to filter part list endpoint by unallocated_stock argument
|
||||||
|
|
||||||
v35 -> 2022-04-01 : https://github.com/inventree/InvenTree/pull/2797
|
v35 -> 2022-04-01 : https://github.com/inventree/InvenTree/pull/2797
|
||||||
- Adds stock allocation information to the Part API
|
- Adds stock allocation information to the Part API
|
||||||
- Adds calculated field for "unallocated_quantity"
|
- Adds calculated field for "unallocated_quantity"
|
||||||
|
@ -798,6 +798,20 @@ class PartFilter(rest_filters.FilterSet):
|
|||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
# unallocated_stock filter
|
||||||
|
unallocated_stock = rest_filters.BooleanFilter(label='Unallocated stock', method='filter_unallocated_stock')
|
||||||
|
|
||||||
|
def filter_unallocated_stock(self, queryset, name, value):
|
||||||
|
|
||||||
|
value = str2bool(value)
|
||||||
|
|
||||||
|
if value:
|
||||||
|
queryset = queryset.filter(Q(unallocated_stock__gt=0))
|
||||||
|
else:
|
||||||
|
queryset = queryset.filter(Q(unallocated_stock__lte=0))
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
is_template = rest_filters.BooleanFilter()
|
is_template = rest_filters.BooleanFilter()
|
||||||
|
|
||||||
assembly = rest_filters.BooleanFilter()
|
assembly = rest_filters.BooleanFilter()
|
||||||
|
@ -494,10 +494,40 @@ function duplicateBom(part_id, options={}) {
|
|||||||
function partStockLabel(part, options={}) {
|
function partStockLabel(part, options={}) {
|
||||||
|
|
||||||
if (part.in_stock) {
|
if (part.in_stock) {
|
||||||
return `<span class='badge rounded-pill bg-success ${options.classes}'>{% trans "Stock" %}: ${part.in_stock}</span>`;
|
// There IS stock available for this part
|
||||||
|
|
||||||
|
// Is stock "low" (below the 'minimum_stock' quantity)?
|
||||||
|
if (part.minimum_stock && part.minimum_stock > part.in_stock) {
|
||||||
|
return `<span class='badge rounded-pill bg-warning ${options.classes}'>{% trans "Low stock" %}: ${part.in_stock}${part.units}</span>`;
|
||||||
|
} else if (part.unallocated_stock == 0) {
|
||||||
|
if (part.ordering) {
|
||||||
|
// There is no available stock, but stock is on order
|
||||||
|
return `<span class='badge rounded-pill bg-info ${options.classes}'>{% trans "On Order" %}: ${part.ordering}${part.units}</span>`;
|
||||||
|
} else if (part.building) {
|
||||||
|
// There is no available stock, but stock is being built
|
||||||
|
return `<span class='badge rounded-pill bg-info ${options.classes}'>{% trans "Building" %}: ${part.building}${part.units}</span>`;
|
||||||
|
} else {
|
||||||
|
// There is no available stock
|
||||||
|
return `<span class='badge rounded-pill bg-warning ${options.classes}'>{% trans "Available" %}: 0/${part.in_stock}${part.units}</span>`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return `<span class='badge rounded-pill bg-success ${options.classes}'>{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}${part.units}</span>`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return `<span class='badge rounded-pill bg-danger ${options.classes}'>{% trans "No Stock" %}</span>`;
|
// There IS NO stock available for this part
|
||||||
|
|
||||||
|
if (part.ordering) {
|
||||||
|
// There is no stock, but stock is on order
|
||||||
|
return `<span class='badge rounded-pill bg-info ${options.classes}'>{% trans "On Order" %}: ${part.ordering}${part.units}</span>`;
|
||||||
|
} else if (part.building) {
|
||||||
|
// There is no stock, but stock is being built
|
||||||
|
return `<span class='badge rounded-pill bg-info ${options.classes}'>{% trans "Building" %}: ${part.building}${part.units}</span>`;
|
||||||
|
} else {
|
||||||
|
// There is no stock
|
||||||
|
return `<span class='badge rounded-pill bg-danger ${options.classes}'>{% trans "No Stock" %}</span>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1160,12 +1190,14 @@ function partGridTile(part) {
|
|||||||
|
|
||||||
if (!part.in_stock) {
|
if (!part.in_stock) {
|
||||||
stock = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock" %}</span>`;
|
stock = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock" %}</span>`;
|
||||||
|
} else if (!part.unallocated_stock) {
|
||||||
|
stock = `<span class='badge rounded-pill bg-warning'>{% trans "Not available" %}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
rows += `<tr><td><b>{% trans "Stock" %}</b></td><td>${stock}</td></tr>`;
|
rows += `<tr><td><b>{% trans "Stock" %}</b></td><td>${stock}</td></tr>`;
|
||||||
|
|
||||||
if (part.on_order) {
|
if (part.ordering) {
|
||||||
rows += `<tr><td><b>{$ trans "On Order" %}</b></td><td>${part.on_order}</td></tr>`;
|
rows += `<tr><td><b>{% trans "On Order" %}</b></td><td>${part.ordering}</td></tr>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (part.building) {
|
if (part.building) {
|
||||||
@ -1322,31 +1354,47 @@ function loadPartTable(table, url, options={}) {
|
|||||||
columns.push(col);
|
columns.push(col);
|
||||||
|
|
||||||
col = {
|
col = {
|
||||||
field: 'in_stock',
|
field: 'unallocated_stock',
|
||||||
title: '{% trans "Stock" %}',
|
title: '{% trans "Available" %}',
|
||||||
searchable: false,
|
searchable: false,
|
||||||
formatter: function(value, row) {
|
formatter: function(value, row) {
|
||||||
var link = '?display=part-stock';
|
var link = '?display=part-stock';
|
||||||
|
|
||||||
if (value) {
|
if (row.in_stock) {
|
||||||
// There IS stock available for this part
|
// There IS stock available for this part
|
||||||
|
|
||||||
// Is stock "low" (below the 'minimum_stock' quantity)?
|
// Is stock "low" (below the 'minimum_stock' quantity)?
|
||||||
if (row.minimum_stock && row.minimum_stock > value) {
|
if (row.minimum_stock && row.minimum_stock > row.in_stock) {
|
||||||
value += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Low stock" %}</span>`;
|
value += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Low stock" %}</span>`;
|
||||||
|
} else if (value == 0) {
|
||||||
|
if (row.ordering) {
|
||||||
|
// There is no available stock, but stock is on order
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "On Order" %}: ${row.ordering}</span>`;
|
||||||
|
link = '?display=purchase-orders';
|
||||||
|
} else if (row.building) {
|
||||||
|
// There is no available stock, but stock is being built
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "Building" %}: ${row.building}</span>`;
|
||||||
|
link = '?display=build-orders';
|
||||||
|
} else {
|
||||||
|
// There is no available stock
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-warning'>{% trans "Not available" %}</span>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (row.on_order) {
|
|
||||||
// There is no stock available, but stock is on order
|
|
||||||
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "On Order" %}: ${row.on_order}</span>`;
|
|
||||||
link = '?display=purchase-orders';
|
|
||||||
} else if (row.building) {
|
|
||||||
// There is no stock available, but stock is being built
|
|
||||||
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "Building" %}: ${row.building}</span>`;
|
|
||||||
link = '?display=build-orders';
|
|
||||||
} else {
|
} else {
|
||||||
// There is no stock available
|
// There IS NO stock available for this part
|
||||||
value = `0<span class='badge badge-right rounded-pill bg-danger'>{% trans "No Stock" %}</span>`;
|
|
||||||
|
if (row.ordering) {
|
||||||
|
// There is no stock, but stock is on order
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "On Order" %}: ${row.ordering}</span>`;
|
||||||
|
link = '?display=purchase-orders';
|
||||||
|
} else if (row.building) {
|
||||||
|
// There is no stock, but stock is being built
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-info'>{% trans "Building" %}: ${row.building}</span>`;
|
||||||
|
link = '?display=build-orders';
|
||||||
|
} else {
|
||||||
|
// There is no stock
|
||||||
|
value = `0<span class='badge badge-right rounded-pill bg-danger'>{% trans "No Stock" %}</span>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderLink(value, `/part/${row.pk}/${link}`);
|
return renderLink(value, `/part/${row.pk}/${link}`);
|
||||||
|
@ -427,12 +427,16 @@ function getAvailableTableFilters(tableKey) {
|
|||||||
},
|
},
|
||||||
has_stock: {
|
has_stock: {
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Stock available" %}',
|
title: '{% trans "In stock" %}',
|
||||||
},
|
},
|
||||||
low_stock: {
|
low_stock: {
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Low stock" %}',
|
title: '{% trans "Low stock" %}',
|
||||||
},
|
},
|
||||||
|
unallocated_stock: {
|
||||||
|
type: 'bool',
|
||||||
|
title: '{% trans "Available stock" %}',
|
||||||
|
},
|
||||||
assembly: {
|
assembly: {
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Assembly" %}',
|
title: '{% trans "Assembly" %}',
|
||||||
|
Loading…
Reference in New Issue
Block a user