mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into matmair/issue2301
This commit is contained in:
@ -11,6 +11,7 @@
|
||||
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_BATCH_CODE_TEMPLATE" icon="fa-layer-group" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ENABLE_EXPIRY" icon="fa-stopwatch" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_STALE_DAYS" icon="fa-calendar" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}
|
||||
|
@ -691,8 +691,24 @@ function loadBomTable(table, options={}) {
|
||||
|
||||
setupFilterList('bom', $(table));
|
||||
|
||||
// Construct the table columns
|
||||
function availableQuantity(row) {
|
||||
|
||||
// Base stock
|
||||
var available = row.available_stock;
|
||||
|
||||
// Substitute stock
|
||||
available += (row.available_substitute_stock || 0);
|
||||
|
||||
// Variant stock
|
||||
if (row.allow_variants) {
|
||||
available += (row.available_variant_stock || 0);
|
||||
}
|
||||
|
||||
return available;
|
||||
|
||||
}
|
||||
|
||||
// Construct the table columns
|
||||
var cols = [];
|
||||
|
||||
if (options.editable) {
|
||||
@ -807,15 +823,27 @@ function loadBomTable(table, options={}) {
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var total = row.available_stock + row.available_substitute_stock;
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var text = `${total}`;
|
||||
var available_stock = availableQuantity(row);
|
||||
|
||||
var text = `${available_stock}`;
|
||||
|
||||
if (total <= 0) {
|
||||
if (available_stock <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
if (row.available_substitute_stock > 0) {
|
||||
text += `<span title='{% trans "Includes substitute stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,7 +938,7 @@ function loadBomTable(table, options={}) {
|
||||
formatter: function(value, row) {
|
||||
var can_build = 0;
|
||||
|
||||
var available = row.available_stock + row.available_substitute_stock;
|
||||
var available = availableQuantity(row);
|
||||
|
||||
if (row.quantity > 0) {
|
||||
can_build = available / row.quantity;
|
||||
@ -924,11 +952,11 @@ function loadBomTable(table, options={}) {
|
||||
var cb_b = 0;
|
||||
|
||||
if (rowA.quantity > 0) {
|
||||
cb_a = (rowA.available_stock + rowA.available_substitute_stock) / rowA.quantity;
|
||||
cb_a = availableQuantity(rowA) / rowA.quantity;
|
||||
}
|
||||
|
||||
if (rowB.quantity > 0) {
|
||||
cb_b = (rowB.available_stock + rowB.available_substitute_stock) / rowB.quantity;
|
||||
cb_b = availableQuantity(rowB) / rowB.quantity;
|
||||
}
|
||||
|
||||
return (cb_a > cb_b) ? 1 : -1;
|
||||
|
@ -1031,6 +1031,23 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
return row.required;
|
||||
}
|
||||
|
||||
function availableQuantity(row) {
|
||||
|
||||
// Base stock
|
||||
var available = row.available_stock;
|
||||
|
||||
// Substitute stock
|
||||
available += (row.available_substitute_stock || 0);
|
||||
|
||||
// Variant stock
|
||||
if (row.allow_variants) {
|
||||
available += (row.available_variant_stock || 0);
|
||||
}
|
||||
|
||||
return available;
|
||||
|
||||
}
|
||||
|
||||
function sumAllocations(row) {
|
||||
// Calculat total allocations for a given row
|
||||
if (!row.allocations) {
|
||||
@ -1425,20 +1442,52 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
title: '{% trans "Available" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
var total = row.available_stock + row.available_substitute_stock;
|
||||
|
||||
var text = `${total}`;
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
|
||||
if (total <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var available_stock = availableQuantity(row);
|
||||
|
||||
var required = requiredQuantity(row);
|
||||
|
||||
var text = '';
|
||||
|
||||
if (available_stock > 0) {
|
||||
text += `${available_stock}`;
|
||||
}
|
||||
|
||||
if (available_stock < required) {
|
||||
text += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`;
|
||||
} else {
|
||||
if (row.available_substitute_stock > 0) {
|
||||
text += `<span title='{% trans "Includes substitute stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
text += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
if (available_stock <= 0) {
|
||||
text += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
return renderLink(text, url);
|
||||
},
|
||||
sorter: function(valA, valB, rowA, rowB) {
|
||||
|
||||
return availableQuantity(rowA) > availableQuantity(rowB) ? 1 : -1;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'allocated',
|
||||
|
@ -672,7 +672,20 @@ function loadPartVariantTable(table, partId, options={}) {
|
||||
field: 'in_stock',
|
||||
title: '{% trans "Stock" %}',
|
||||
formatter: function(value, row) {
|
||||
return renderLink(value, `/part/${row.pk}/?display=part-stock`);
|
||||
|
||||
var base_stock = row.in_stock;
|
||||
var variant_stock = row.variant_stock || 0;
|
||||
|
||||
var total = base_stock + variant_stock;
|
||||
|
||||
var text = `${total}`;
|
||||
|
||||
if (variant_stock > 0) {
|
||||
text = `<em>${text}</em>`;
|
||||
text += `<span title='{% trans "Includes variant stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
|
||||
return renderLink(text, `/part/${row.pk}/?display=part-stock`);
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -1917,7 +1930,9 @@ function loadPriceBreakTable(table, options) {
|
||||
formatNoMatches: function() {
|
||||
return `{% trans "No ${human_name} information found" %}`;
|
||||
},
|
||||
queryParams: {part: options.part},
|
||||
queryParams: {
|
||||
part: options.part
|
||||
},
|
||||
url: options.url,
|
||||
onLoadSuccess: function(tableData) {
|
||||
if (linkedGraph) {
|
||||
@ -2023,36 +2038,45 @@ function initPriceBreakSet(table, options) {
|
||||
}
|
||||
|
||||
pb_new_btn.click(function() {
|
||||
launchModalForm(pb_new_url,
|
||||
{
|
||||
success: reloadPriceBreakTable,
|
||||
data: {
|
||||
part: part_id,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
constructForm(pb_new_url, {
|
||||
fields: {
|
||||
part: {
|
||||
hidden: true,
|
||||
value: part_id,
|
||||
},
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-delete`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/delete/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-edit`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/edit/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
fields: {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
title: '{% trans "Edit Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user