mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 12:35:46 +00:00
First pass at UI elements for performing stocktake
This commit is contained in:
@ -63,7 +63,7 @@
|
|||||||
<div class='btn-group' role='group'>
|
<div class='btn-group' role='group'>
|
||||||
{% if roles.part.add %}
|
{% if roles.part.add %}
|
||||||
<button class='btn btn-success' type='button' id='btn-stocktake' title='{% trans "Add stocktake information" %}'>
|
<button class='btn btn-success' type='button' id='btn-stocktake' title='{% trans "Add stocktake information" %}'>
|
||||||
<span class='fas fa-plus-circle'></span> {% trans "Stocktake" %}
|
<span class='fas fa-clipboard-check'></span> {% trans "Stocktake" %}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!-- TODO: Buttons -->
|
<!-- TODO: Buttons -->
|
||||||
@ -468,6 +468,10 @@
|
|||||||
// Load the "stocktake" tab
|
// Load the "stocktake" tab
|
||||||
onPanelLoad('stocktake', function() {
|
onPanelLoad('stocktake', function() {
|
||||||
loadPartStocktakeTable({{ part.pk }});
|
loadPartStocktakeTable({{ part.pk }});
|
||||||
|
|
||||||
|
$('#btn-stocktake').click(function() {
|
||||||
|
performStocktake({{ part.pk }});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load the "suppliers" tab
|
// Load the "suppliers" tab
|
||||||
|
@ -37,7 +37,9 @@
|
|||||||
loadPartVariantTable,
|
loadPartVariantTable,
|
||||||
loadRelatedPartsTable,
|
loadRelatedPartsTable,
|
||||||
loadSimplePartTable,
|
loadSimplePartTable,
|
||||||
|
partDetail,
|
||||||
partStockLabel,
|
partStockLabel,
|
||||||
|
performStocktake,
|
||||||
toggleStar,
|
toggleStar,
|
||||||
validateBom,
|
validateBom,
|
||||||
*/
|
*/
|
||||||
@ -679,7 +681,133 @@ function makePartIcons(part) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Render part information for a table view
|
||||||
|
*
|
||||||
|
* part: JSON part object
|
||||||
|
* options:
|
||||||
|
* icons: Display part icons
|
||||||
|
* thumb: Display part thumbnail
|
||||||
|
* link: Display URL
|
||||||
|
*/
|
||||||
|
function partDetail(part, options={}) {
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
var name = part.full_name;
|
||||||
|
|
||||||
|
if (options.thumb) {
|
||||||
|
html += imageHoverIcon(part.thumbnail || part.image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.link) {
|
||||||
|
var url = `/part/${part.pk}/`;
|
||||||
|
html += renderLink(shortenString(name), url);
|
||||||
|
} else {
|
||||||
|
html += shortenString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.icons) {
|
||||||
|
html += makePartIcons(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guide user through "stocktake" process
|
||||||
|
*/
|
||||||
|
function performStocktake(partId, options={}) {
|
||||||
|
|
||||||
|
// Helper function for formatting a StockItem row
|
||||||
|
function buildStockItemRow(item) {
|
||||||
|
|
||||||
|
// Part detail
|
||||||
|
var part = partDetail(item.part_detail, {
|
||||||
|
thumb: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Location detail
|
||||||
|
var location = locationDetail(item);
|
||||||
|
|
||||||
|
// Quantity detail
|
||||||
|
var quantity = item.quantity;
|
||||||
|
|
||||||
|
if (item.serial && item.quantity == 1) {
|
||||||
|
quantity = `{% trans "Serial" %}: ${item.serial}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last update
|
||||||
|
var updated = item.updated || item.stocktake_date;
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
var actions = '';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<tr>
|
||||||
|
<td>${part}</td>
|
||||||
|
<td>${location}</td>
|
||||||
|
<td>${quantity}</td>
|
||||||
|
<td>${renderDate(updated)}</td>
|
||||||
|
<td>${actions}</td>
|
||||||
|
</tr>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, load stock information for the part
|
||||||
|
inventreeGet(
|
||||||
|
'{% url "api-stock-list" %}',
|
||||||
|
{
|
||||||
|
part: partId,
|
||||||
|
in_stock: true,
|
||||||
|
location_detail: true,
|
||||||
|
part_detail: true,
|
||||||
|
include_variants: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
success: function(response) {
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<table class='table table-striped table-condensed'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Stock Item" %}</th>
|
||||||
|
<th>{% trans "Location" %}</th>
|
||||||
|
<th>{% trans "Quantity" %}</th>
|
||||||
|
<th>{% trans "Updated" %}</th>
|
||||||
|
<th><!-- Actions --></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
`;
|
||||||
|
|
||||||
|
response.forEach(function(item) {
|
||||||
|
html += buildStockItemRow(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `</tbody></table>`;
|
||||||
|
|
||||||
|
constructForm(`/api/part/stocktake/`, {
|
||||||
|
preFormContent: html,
|
||||||
|
method: 'POST',
|
||||||
|
title: '{% trans "Part Stocktake" %}',
|
||||||
|
confirm: true,
|
||||||
|
fields: {
|
||||||
|
part: {
|
||||||
|
value: partId,
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
quantity: {},
|
||||||
|
note: {},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1736,15 +1736,11 @@ function loadStockTable(table, options) {
|
|||||||
switchable: params['part_detail'],
|
switchable: params['part_detail'],
|
||||||
formatter: function(value, row) {
|
formatter: function(value, row) {
|
||||||
|
|
||||||
var url = `/part/${row.part}/`;
|
return partDetail(row.part_detail, {
|
||||||
var thumb = row.part_detail.thumbnail;
|
thumb: true,
|
||||||
var name = row.part_detail.full_name;
|
link: true,
|
||||||
|
icons: true,
|
||||||
var html = imageHoverIcon(thumb) + renderLink(shortenString(name), url);
|
});
|
||||||
|
|
||||||
html += makePartIcons(row.part_detail);
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user