From c47703c2e6ef59c46f903705c70d19fb143c067e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 21 Dec 2022 23:35:16 +1100 Subject: [PATCH] First pass at UI elements for performing stocktake --- InvenTree/part/templates/part/detail.html | 6 +- InvenTree/templates/js/translated/part.js | 128 +++++++++++++++++++++ InvenTree/templates/js/translated/stock.js | 14 +-- 3 files changed, 138 insertions(+), 10 deletions(-) diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index 5f9502d20e..fa3e35235e 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -63,7 +63,7 @@
{% if roles.part.add %} {% endif %} @@ -468,6 +468,10 @@ // Load the "stocktake" tab onPanelLoad('stocktake', function() { loadPartStocktakeTable({{ part.pk }}); + + $('#btn-stocktake').click(function() { + performStocktake({{ part.pk }}); + }); }); // Load the "suppliers" tab diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index d8c3f74478..eb8ddbaf73 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -37,7 +37,9 @@ loadPartVariantTable, loadRelatedPartsTable, loadSimplePartTable, + partDetail, partStockLabel, + performStocktake, toggleStar, validateBom, */ @@ -679,7 +681,133 @@ function makePartIcons(part) { } 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 ` + + ${part} + ${location} + ${quantity} + ${renderDate(updated)} + ${actions} + `; + } + + // 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 += ` + + + + + + + + + + + + `; + + response.forEach(function(item) { + html += buildStockItemRow(item); + }); + + html += `
{% trans "Stock Item" %}{% trans "Location" %}{% trans "Quantity" %}{% trans "Updated" %}
`; + + constructForm(`/api/part/stocktake/`, { + preFormContent: html, + method: 'POST', + title: '{% trans "Part Stocktake" %}', + confirm: true, + fields: { + part: { + value: partId, + hidden: true, + }, + quantity: {}, + note: {}, + } + }); + } + } + ); } diff --git a/InvenTree/templates/js/translated/stock.js b/InvenTree/templates/js/translated/stock.js index 76d6f3ec5f..62272e9487 100644 --- a/InvenTree/templates/js/translated/stock.js +++ b/InvenTree/templates/js/translated/stock.js @@ -1736,15 +1736,11 @@ function loadStockTable(table, options) { switchable: params['part_detail'], formatter: function(value, row) { - var url = `/part/${row.part}/`; - var thumb = row.part_detail.thumbnail; - var name = row.part_detail.full_name; - - var html = imageHoverIcon(thumb) + renderLink(shortenString(name), url); - - html += makePartIcons(row.part_detail); - - return html; + return partDetail(row.part_detail, { + thumb: true, + link: true, + icons: true, + }); } };