diff --git a/InvenTree/static/script/inventree/stock.js b/InvenTree/static/script/inventree/stock.js
index 84557535ba..65b0c55da5 100644
--- a/InvenTree/static/script/inventree/stock.js
+++ b/InvenTree/static/script/inventree/stock.js
@@ -28,377 +28,20 @@ function removeStockRow(e) {
$('#' + row).remove();
}
-
-/* Present user with a dialog to update multiple stock items
- * Possible actions:
- * - Stocktake
- * - Take stock
- * - Add stock
- */
-function updateStock(items, options={}) {
-
- if (!options.action) {
- alert('No action supplied to stock update');
- return false;
- }
-
- var modal = options.modal || '#modal-form';
-
- if (items.length == 0) {
- alert('No items selected');
- return;
- }
-
- var html = '';
-
- html += "
';
-
- html += "
";
- html += "Note field must be filled
";
-
- html += `
-
-
-
-
Confirm stock count
-
`;
-
-
- var title = '';
-
- if (options.action == 'stocktake') {
- title = 'Stocktake';
- }
- else if (options.action == 'remove') {
- title = 'Remove stock items';
- }
- else if (options.action == 'add') {
- title = 'Add stock items';
- }
-
- openModal({
- modal: modal,
- title: title,
- content: html
- });
-
- $(modal).find('#note-warning').hide();
- $(modal).find('#confirm-warning').hide();
-
- modalEnable(modal, true);
-
- modalSubmit(modal, function() {
-
- var stocktake = [];
- var notes = $(modal).find('#stocktake-notes').val();
- var confirm = $(modal).find('#stocktake-confirm').is(':checked');
-
- var valid = true;
-
- if (!notes) {
- $(modal).find('#note-warning').show();
- valid = false;
- }
-
- if (!confirm) {
- $(modal).find('#confirm-warning').show();
- valid = false;
- }
-
- if (!valid) {
- return false;
- }
-
- // Form stocktake data
- for (idx = 0; idx < items.length; idx++) {
- var item = items[idx];
-
- var q = $(modal).find("#q-update-" + item.pk).val();
-
- stocktake.push({
- pk: item.pk,
- quantity: q
- });
- };
-
- if (!valid) {
- alert('Invalid data');
- return false;
- }
-
- inventreePut("/api/stock/stocktake/",
- {
- 'action': options.action,
- 'items[]': stocktake,
- 'notes': $(modal).find('#stocktake-notes').val()
- },
- {
- method: 'post',
- }).then(function(response) {
- closeModal(modal);
- afterForm(response, options);
- }).fail(function(xhr, status, error) {
- alert(error);
- });
- });
-}
-
-
-function selectStockItems(options) {
- /* Return list of selections from stock table
- * If options.table not provided, assumed to be '#stock-table'
- */
-
- var table_name = options.table || '#stock-table';
-
- // Return list of selected items from the bootstrap table
- return $(table_name).bootstrapTable('getSelections');
-}
-
-
-function adjustStock(options) {
- if (options.items) {
- updateStock(options.items, options);
- }
- else {
- // Lookup of individual item
- if (options.query.pk) {
- getStockDetail(options.query.pk).then(function(response) {
- updateStock([response], options);
- });
- }
- else {
- getStockList(options.query).then(function(response) {
- updateStock(response, options);
- });
- }
- }
-}
-
-
-function updateStockItems(options) {
- /* Update one or more stock items selected from a stock-table
- * Options available:
- * 'action' - Action to perform - 'add' / 'remove' / 'stocktake'
- * 'table' - ID of the stock table (default = '#stock-table'
- */
-
- var table = options.table || '#stock-table';
-
- var items = selectStockItems({
- table: table,
- });
-
- // Pass items through
- options.items = items;
- options.table = table;
-
- // On success, reload the table
- options.success = function() {
- $(table).bootstrapTable('refresh');
- };
-
- adjustStock(options);
-}
-
-function moveStockItems(items, options) {
-
- var modal = options.modal || '#modal-form';
-
- if (items.length == 0) {
- alert('No stock items selected');
- return;
- }
-
- function doMove(location, parts, notes) {
- inventreePut("/api/stock/move/",
- {
- location: location,
- 'stock': parts,
- 'notes': notes,
- },
- {
- method: 'post',
- }).then(function(response) {
- closeModal(modal);
- afterForm(response, options);
- }).fail(function(xhr, status, error) {
- alert(error);
- });
- }
-
-
- getStockLocations({},
- {
- success: function(response) {
-
- // Extact part row info
- var parts = [];
-
- var html = "Select new location:
\n";
-
- html += "
";
-
- html += "
";
-
- html += "Note field must be filled
";
-
- html += "
The following stock items will be moved:
";
-
- html += `
- ";
-
- openModal({
- modal: modal,
- title: "Move " + items.length + " stock items",
- submit_text: "Move",
- content: html
- });
-
- //modalSetContent(modal, html);
- attachSelect(modal);
-
- modalEnable(modal, true);
-
- $(modal).find('#note-warning').hide();
-
- modalSubmit(modal, function() {
- var locId = $(modal).find("#stock-location").val();
-
- var notes = $(modal).find('#notes').val();
-
- if (!notes) {
- $(modal).find('#note-warning').show();
- return false;
- }
-
- // Update the quantity for each item
- for (var ii = 0; ii < parts.length; ii++) {
- var pk = parts[ii].pk;
-
- var q = $(modal).find('#q-move-' + pk).val();
-
- parts[ii].quantity = q;
- }
-
- doMove(locId, parts, notes);
- });
- },
- error: function(error) {
- alert('Error getting stock locations:\n' + error.error);
- }
- });
-}
-
function loadStockTable(table, options) {
-
+ /* Load data into a stock table with adjustable options.
+ * Fetches data (via AJAX) and loads into a bootstrap table.
+ * Also links in default button callbacks.
+ *
+ * Options:
+ * url - URL for the stock query
+ * params - query params for augmenting stock data request
+ * groupByField - Column for grouping stock items
+ * buttons - Which buttons to link to stock selection callbacks
+ */
+
var params = options.params || {};
- // Aggregate stock items
- //params.aggregate = true;
-
table.bootstrapTable({
sortable: true,
search: true,