mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Location barcode actions (#3887)
* Reorder action buttons for stock location * Tweak position of "New Location" button * Tweak loaction of "New Category" button for part category page * Working on skeleton for new barcode dialog * Scan location into location * Add configurable input delay for processing barcode scan data
This commit is contained in:
@ -13,6 +13,7 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="BARCODE_ENABLE" icon="fa-qrcode" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="BARCODE_INPUT_DELAY" icon="fa-hourglass-half" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="BARCODE_WEBCAM_SUPPORT" icon="fa-video" %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -14,7 +14,8 @@
|
||||
*/
|
||||
|
||||
/* exported
|
||||
barcodeCheckIn,
|
||||
barcodeCheckInStockItems,
|
||||
barcodeCheckInStockLocations,
|
||||
barcodeScanDialog,
|
||||
linkBarcodeDialog,
|
||||
scanItemsIntoLocation,
|
||||
@ -22,12 +23,14 @@
|
||||
onBarcodeScanClicked,
|
||||
*/
|
||||
|
||||
function makeBarcodeInput(placeholderText='', hintText='') {
|
||||
/*
|
||||
* Generate HTML for a barcode input
|
||||
*/
|
||||
var barcodeInputTimer = null;
|
||||
|
||||
placeholderText = placeholderText || '{% trans "Scan barcode data here using wedge scanner" %}';
|
||||
/*
|
||||
* Generate HTML for a barcode scan input
|
||||
*/
|
||||
function makeBarcodeInput(placeholderText='', hintText='') {
|
||||
|
||||
placeholderText = placeholderText || '{% trans "Scan barcode data here using barcode scanner" %}';
|
||||
|
||||
hintText = hintText || '{% trans "Enter barcode data" %}';
|
||||
|
||||
@ -43,7 +46,7 @@ function makeBarcodeInput(placeholderText='', hintText='') {
|
||||
<span class='fas fa-qrcode'></span>
|
||||
</span>
|
||||
<input id='barcode' class='textinput textInput form-control' type='text' name='barcode' placeholder='${placeholderText}'>
|
||||
<button id='barcode_scan_btn' type='button' class='btn btn-secondary' onclick='onBarcodeScanClicked()' style='display: none;'>
|
||||
<button title='{% trans "Scan barcode using connected webcam" %}' id='barcode_scan_btn' type='button' class='btn btn-secondary' onclick='onBarcodeScanClicked()' style='display: none;'>
|
||||
<span class='fas fa-camera'></span>
|
||||
</button>
|
||||
</div>
|
||||
@ -92,6 +95,9 @@ function onBarcodeScanCompleted(result, options) {
|
||||
postBarcodeData(result.data, options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a generic "notes" field for barcode scanning operations
|
||||
*/
|
||||
function makeNotesField(options={}) {
|
||||
|
||||
var tooltip = options.tooltip || '{% trans "Enter optional notes for stock transfer" %}';
|
||||
@ -199,6 +205,9 @@ function showBarcodeMessage(modal, message, style='danger') {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display an error message when the server indicates an error
|
||||
*/
|
||||
function showInvalidResponseError(modal, response, status) {
|
||||
showBarcodeMessage(
|
||||
modal,
|
||||
@ -207,6 +216,9 @@ function showInvalidResponseError(modal, response, status) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable (or disable) the barcode scanning input
|
||||
*/
|
||||
function enableBarcodeInput(modal, enabled=true) {
|
||||
|
||||
var barcode = $(modal + ' #barcode');
|
||||
@ -218,6 +230,10 @@ function enableBarcodeInput(modal, enabled=true) {
|
||||
barcode.focus();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Extract scanned data from the barcode input
|
||||
*/
|
||||
function getBarcodeData(modal) {
|
||||
|
||||
modal = modal || '#modal-form';
|
||||
@ -233,10 +249,10 @@ function getBarcodeData(modal) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle a barcode display dialog.
|
||||
*/
|
||||
function barcodeDialog(title, options={}) {
|
||||
/*
|
||||
* Handle a barcode display dialog.
|
||||
*/
|
||||
|
||||
var modal = '#modal-form';
|
||||
|
||||
@ -244,7 +260,6 @@ function barcodeDialog(title, options={}) {
|
||||
var barcode = getBarcodeData(modal);
|
||||
|
||||
if (barcode && barcode.length > 0) {
|
||||
|
||||
postBarcodeData(barcode, options);
|
||||
}
|
||||
}
|
||||
@ -264,7 +279,15 @@ function barcodeDialog(title, options={}) {
|
||||
event.preventDefault();
|
||||
|
||||
if (event.which == 10 || event.which == 13) {
|
||||
clearTimeout(barcodeInputTimer);
|
||||
sendBarcode();
|
||||
} else {
|
||||
// Start a timer to automatically send barcode after input is complete
|
||||
clearTimeout(barcodeInputTimer);
|
||||
|
||||
barcodeInputTimer = setTimeout(function() {
|
||||
sendBarcode();
|
||||
}, global_settings.BARCODE_INPUT_DELAY);
|
||||
}
|
||||
});
|
||||
|
||||
@ -305,9 +328,11 @@ function barcodeDialog(title, options={}) {
|
||||
modalShowSubmitButton(modal, false);
|
||||
}
|
||||
|
||||
var details = options.details || '{% trans "Scan barcode data" %}';
|
||||
|
||||
var content = '';
|
||||
|
||||
content += `<div class='alert alert-info alert-block'>{% trans "Scan barcode data below" %}</div>`;
|
||||
content += `<div class='alert alert-info alert-block'>${details}</div>`;
|
||||
|
||||
content += `<div id='barcode-error-message'></div>`;
|
||||
content += `<form class='js-modal-form' method='post'>`;
|
||||
@ -431,7 +456,7 @@ function unlinkBarcode(data, options={}) {
|
||||
/*
|
||||
* Display dialog to check multiple stock items in to a stock location.
|
||||
*/
|
||||
function barcodeCheckIn(location_id, options={}) {
|
||||
function barcodeCheckInStockItems(location_id, options={}) {
|
||||
|
||||
var modal = '#modal-form';
|
||||
|
||||
@ -486,6 +511,7 @@ function barcodeCheckIn(location_id, options={}) {
|
||||
|
||||
$(modal + ' #barcode').focus();
|
||||
|
||||
// Callback to remove the scanned item from the table
|
||||
$(modal + ' .button-item-remove').unbind('click').on('mouseup', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
@ -514,8 +540,9 @@ function barcodeCheckIn(location_id, options={}) {
|
||||
var extra = makeNotesField();
|
||||
|
||||
barcodeDialog(
|
||||
'{% trans "Check Stock Items into Location" %}',
|
||||
'{% trans "Scan Stock Items Into Location" %}',
|
||||
{
|
||||
details: '{% trans "Scan stock item barcode to check in to this location" %}',
|
||||
headerContent: table,
|
||||
preShow: function() {
|
||||
modalSetSubmitText(modal, '{% trans "Check In" %}');
|
||||
@ -609,7 +636,7 @@ function barcodeCheckIn(location_id, options={}) {
|
||||
);
|
||||
} else {
|
||||
// Barcode does not match a stock item
|
||||
showBarcodeMessage(modal, '{% trans "Barcode does not match Stock Item" %}', 'warning');
|
||||
showBarcodeMessage(modal, '{% trans "Barcode does not match valid stock item" %}', 'warning');
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -617,6 +644,59 @@ function barcodeCheckIn(location_id, options={}) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display dialog to scan stock locations into the current location
|
||||
*/
|
||||
function barcodeCheckInStockLocations(location_id, options={}) {
|
||||
|
||||
var modal = '#modal-form';
|
||||
var header = '';
|
||||
|
||||
barcodeDialog(
|
||||
'{% trans "Scan Stock Container Into Location" %}',
|
||||
{
|
||||
details: '{% trans "Scan stock container barcode to check in to this location" %}',
|
||||
headerContent: header,
|
||||
preShow: function() {
|
||||
modalEnable(modal, false);
|
||||
},
|
||||
onShow: function() {
|
||||
// TODO
|
||||
},
|
||||
onScan: function(response) {
|
||||
if ('stocklocation' in response) {
|
||||
var pk = response.stocklocation.pk;
|
||||
|
||||
var url = `/api/stock/location/${pk}/`;
|
||||
|
||||
// Move the scanned location into *this* location
|
||||
inventreePut(
|
||||
url,
|
||||
{
|
||||
parent: location_id,
|
||||
},
|
||||
{
|
||||
method: 'PATCH',
|
||||
success: function(response) {
|
||||
$(modal).modal('hide');
|
||||
handleFormSuccess(response, options);
|
||||
},
|
||||
error: function(xhr) {
|
||||
$(modal).modal('hide');
|
||||
showApiError(xhr, url);
|
||||
},
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// Barcode does not match a valid stock location
|
||||
showBarcodeMessage(modal, '{% trans "Barcode does not match valid stock location" %}', 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display dialog to check a single stock item into a stock location
|
||||
*/
|
||||
|
Reference in New Issue
Block a user