mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-16 01:36:29 +00:00
Table custom buttons (#5075)
* Add generic implementation for barcode actions - Commonize code against tables - Cleaner UI - Better code - Will make future react refactor easier * Add permissions.js - Separate .js file for dynamically checking permissions * Update stock table to use client-side actions * API endpoint for bulk category adjustment * Bug fix for purchase_order.js - Prevent some really strange API calls * Refactor actions for part table - Now done dynamically * Refactor actions for the attachment tables * Refactor actions for build output table * Increment API version * Cleanup janky button * Refactor supplier part table * Refactor manufacturer part table * Remove linkButtonsToSelection - no longer needed - Cleanup, yay! * Cleanup purchase order line table * Refactor BOM table buttons * JS linting * Further cleanup * Template cleanup - remove extra div elements * js linting * js fix
This commit is contained in:
@@ -30,7 +30,6 @@
|
||||
inventreePut,
|
||||
inventreeSave,
|
||||
launchModalForm,
|
||||
linkButtonsToSelection,
|
||||
loadTableFilters,
|
||||
makeDeleteButton,
|
||||
makeEditButton,
|
||||
@@ -1707,6 +1706,121 @@ function locationDetail(row, showLink=true) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Construct a set of custom actions for the stock table
|
||||
*/
|
||||
function makeStockActions(table) {
|
||||
let actions = [
|
||||
{
|
||||
label: 'add',
|
||||
icon: 'fa-plus-circle icon-green',
|
||||
title: '{% trans "Add stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
stockAdjustment('add', data, table);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'remove',
|
||||
icon: 'fa-minus-circle icon-red',
|
||||
title: '{% trans "Remove stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
stockAdjustment('take', data, table);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'stocktake',
|
||||
icon: 'fa-check-circle icon-blue',
|
||||
title: '{% trans "Count stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
stockAdjustment('count', data, table);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'move',
|
||||
icon: 'fa-exchange-alt icon-blue',
|
||||
title: '{% trans "Transfer stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
stockAdjustment('move', data, table);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'status',
|
||||
icon: 'fa-info-circle icon-blue',
|
||||
title: '{% trans "Change stock status" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
setStockStatus(data, {table: table});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'merge',
|
||||
icon: 'fa-object-group',
|
||||
title: '{% trans "Merge stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
mergeStockItems(data, {
|
||||
success: function(response) {
|
||||
$(table).bootstrapTable('refresh');
|
||||
|
||||
showMessage('{% trans "Merged stock items" %}', {
|
||||
style: 'success',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'order',
|
||||
icon: 'fa-shopping-cart',
|
||||
title: '{% trans "Order stock" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
let parts = [];
|
||||
|
||||
data.forEach(function(item) {
|
||||
var part = item.part_detail;
|
||||
|
||||
if (part) {
|
||||
parts.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
orderParts(parts, {});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'assign',
|
||||
icon: 'fa-user-tie',
|
||||
title: '{% trans "Assign to customer" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(data) {
|
||||
assignStockToCustomer(data, {
|
||||
success: function() {
|
||||
$(table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'delete',
|
||||
icon: 'fa-trash-alt icon-red',
|
||||
title: '{% trans "Delete stock" %}',
|
||||
permission: 'stock.delete',
|
||||
callback: function(data) {
|
||||
stockAdjustment('delete', data, table);
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
return actions;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
@@ -1746,7 +1860,26 @@ function loadStockTable(table, options) {
|
||||
key: 'item',
|
||||
},
|
||||
singular_name: '{% trans "stock item" %}',
|
||||
plural_name: '{% trans "stock items" %}'
|
||||
plural_name: '{% trans "stock items" %}',
|
||||
barcode_actions: [
|
||||
{
|
||||
icon: 'fa-sitemap',
|
||||
label: 'scantolocation',
|
||||
title: '{% trans "Scan to location" %}',
|
||||
permission: 'stock.change',
|
||||
callback: function(items) {
|
||||
scanItemsIntoLocation(items);
|
||||
}
|
||||
}
|
||||
],
|
||||
custom_actions: [
|
||||
{
|
||||
actions: makeStockActions(table),
|
||||
icon: 'fa-boxes',
|
||||
title: '{% trans "Stock Actions" %}',
|
||||
label: 'stock',
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Override the default values, or add new ones
|
||||
@@ -2267,114 +2400,6 @@ function loadStockTable(table, options) {
|
||||
buttons.push('#stock-barcode-options');
|
||||
}
|
||||
|
||||
linkButtonsToSelection(
|
||||
table,
|
||||
buttons,
|
||||
);
|
||||
|
||||
function stockAdjustment(action) {
|
||||
var items = getTableData(table);
|
||||
|
||||
adjustStock(action, items, {
|
||||
success: function() {
|
||||
$(table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Automatically link button callbacks
|
||||
if (global_settings.BARCODE_ENABLE) {
|
||||
$('#multi-item-barcode-scan-into-location').click(function() {
|
||||
var selections = getTableData(table);
|
||||
|
||||
var items = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
items.push(item);
|
||||
});
|
||||
|
||||
scanItemsIntoLocation(items);
|
||||
});
|
||||
}
|
||||
|
||||
// Callback for 'stocktake' button
|
||||
$('#multi-item-stocktake').click(function() {
|
||||
stockAdjustment('count');
|
||||
});
|
||||
|
||||
// Callback for 'remove stock' button
|
||||
$('#multi-item-remove').click(function() {
|
||||
stockAdjustment('take');
|
||||
});
|
||||
|
||||
// Callback for 'add stock' button
|
||||
$('#multi-item-add').click(function() {
|
||||
stockAdjustment('add');
|
||||
});
|
||||
|
||||
// Callback for 'move stock' button
|
||||
$('#multi-item-move').click(function() {
|
||||
stockAdjustment('move');
|
||||
});
|
||||
|
||||
// Callback for 'merge stock' button
|
||||
$('#multi-item-merge').click(function() {
|
||||
var items = getTableData(table);
|
||||
|
||||
mergeStockItems(items, {
|
||||
success: function(response) {
|
||||
$(table).bootstrapTable('refresh');
|
||||
|
||||
showMessage('{% trans "Merged stock items" %}', {
|
||||
style: 'success',
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for 'assign stock' button
|
||||
$('#multi-item-assign').click(function() {
|
||||
|
||||
var items = getTableData(table);
|
||||
|
||||
assignStockToCustomer(items, {
|
||||
success: function() {
|
||||
$(table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for 'un-assign stock' button
|
||||
$('#multi-item-order').click(function() {
|
||||
|
||||
var selections = getTableData(table);
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
var part = item.part_detail;
|
||||
|
||||
if (part) {
|
||||
parts.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
orderParts(parts, {});
|
||||
});
|
||||
|
||||
// Callback for 'delete stock' button
|
||||
$('#multi-item-delete').click(function() {
|
||||
var selections = getTableData(table);
|
||||
|
||||
var stock = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
stock.push(item.pk);
|
||||
});
|
||||
|
||||
stockAdjustment('delete');
|
||||
});
|
||||
|
||||
// Callback for 'change status' button
|
||||
$('#multi-item-status').click(function() {
|
||||
let selections = getTableData(table);
|
||||
@@ -2384,35 +2409,9 @@ function loadStockTable(table, options) {
|
||||
items.push(item.pk);
|
||||
});
|
||||
|
||||
if (items.length == 0) {
|
||||
showAlertDialog(
|
||||
'{% trans "Select Stock Items" %}',
|
||||
'{% trans "Select one or more stock items" %}'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<div class='alert alert-info alert-block>
|
||||
{% trans "Selected stock items" %}: ${items.length}
|
||||
</div>`;
|
||||
|
||||
constructForm('{% url "api-stock-change-status" %}', {
|
||||
title: '{% trans "Change Stock Status" %}',
|
||||
method: 'POST',
|
||||
preFormContent: html,
|
||||
fields: {
|
||||
status: {},
|
||||
note: {},
|
||||
},
|
||||
processBeforeUpload: function(data) {
|
||||
data.items = items;
|
||||
return data;
|
||||
},
|
||||
onSuccess: function() {
|
||||
$(table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2917,10 +2916,6 @@ function loadStockTrackingTable(table, options) {
|
||||
url: options.url,
|
||||
});
|
||||
|
||||
if (options.buttons) {
|
||||
linkButtonsToSelection(table, options.buttons);
|
||||
}
|
||||
|
||||
table.on('click', '.btn-entry-edit', function() {
|
||||
var button = $(this);
|
||||
|
||||
@@ -3131,3 +3126,55 @@ function installStockItem(stock_item_id, part_id, options={}) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Perform the specified stock adjustment action against the selected items
|
||||
function stockAdjustment(action, items, table) {
|
||||
adjustStock(action, items, {
|
||||
success: function() {
|
||||
$(table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the status of the selected stock items
|
||||
*/
|
||||
function setStockStatus(items, options={}) {
|
||||
|
||||
if (items.length == 0) {
|
||||
showAlertDialog(
|
||||
'{% trans "Select Stock Items" %}',
|
||||
'{% trans "Select one or more stock items" %}'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let id_values = [];
|
||||
|
||||
items.forEach(function(item) {
|
||||
id_values.push(item.pk)
|
||||
});
|
||||
|
||||
let html = `
|
||||
<div class='alert alert-info alert-block>
|
||||
{% trans "Selected stock items" %}: ${items.length}
|
||||
</div>`;
|
||||
|
||||
constructForm('{% url "api-stock-change-status" %}', {
|
||||
title: '{% trans "Change Stock Status" %}',
|
||||
method: 'POST',
|
||||
preFormContent: html,
|
||||
fields: {
|
||||
status: {},
|
||||
note: {},
|
||||
},
|
||||
processBeforeUpload: function(data) {
|
||||
data.items = items;
|
||||
return data;
|
||||
},
|
||||
onSuccess: function() {
|
||||
$(options.table).bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user