Dialog for checking multiple items into a stock location

This commit is contained in:
Oliver Walters 2021-01-28 21:36:57 +11:00
parent 7e8def15ed
commit d61ae8532a
4 changed files with 163 additions and 24 deletions

View File

@ -90,7 +90,7 @@ class BarcodeScan(APIView):
if loc is not None:
response['stocklocation'] = plugin.renderStockLocation(loc)
response['url'] = reverse('location-detail', kwargs={'pk': loc.id})
response['url'] = reverse('stock-location-detail', kwargs={'pk': loc.id})
match_found = True
# Try to associate with a part

View File

@ -160,7 +160,8 @@ class StockAdjust(APIView):
try:
quantity = Decimal(str(entry.get('quantity', None)))
except (ValueError, TypeError, InvalidOperation):
raise ValidationError({'quantity': 'Each entry must contain a valid quantity field'})
# Default to the quantity of the item
quantity = item.quantity
if quantity < 0:
raise ValidationError({'quantity': 'Quantity field must not be less than zero'})

View File

@ -460,7 +460,7 @@ $("#barcode-unlink").click(function() {
});
$("#barcode-scan-into-location").click(function() {
scanItemIntoLocation({{ item.id }});
scanItemsIntoLocation([{{ item.id }}]);
});
{% if item.in_stock %}

View File

@ -25,6 +25,25 @@ function makeBarcodeInput(placeholderText='') {
return html;
}
function makeNotesField(options={}) {
var tooltip = options.tooltip || '{% trans "Enter optional notes for stock transfer" %}';
return `
<div class='form-group'>
<label class='control-label' for='notes'>{% trans "Notes" %}</label>
<div class='controls'>
<div class='input-group'>
<span class='input-group-addon'>
<span class='fas fa-sticky-note'></span>
</span>
<input id='notes' class='textinput textInput form-control' type='text' name='notes' placeholder='{% trans "Enter notes" %}'>
</div>
<div id='hint_notes' class='help_block'>${tooltip}</div>
</div>
</div>`;
}
function showBarcodeMessage(modal, message, style='danger') {
@ -386,22 +405,10 @@ function barcodeCheckIn(location_id, options={}) {
var table = `<div class='container' id='items-table-div' style='width: 80%; float: left;'></div>`;
// Extra form fields
var extra = `
<div class='form-group'>
<label class='control-label' for='notes'>{% trans "Notes" %}</label>
<div class='controls'>
<div class='input-group'>
<span class='input-group-addon'>
<span class='fas fa-sticky-note'></span>
</span>
<input id='notes' class='textinput textInput form-control' type='text' name='notes' placeholder='{% trans "Enter notes" %}'>
</div>
<div id='hint_notes' class='help_block'>{% trans "Enter optional notes for stock transfer" %}</div>
</div>
</div>`;
var extra = makeNotesField();
barcodeDialog(
"{% trans "Check Stock Items into Location" %}",
'{% trans "Check Stock Items into Location" %}',
{
headerContent: table,
preShow: function() {
@ -414,7 +421,6 @@ function barcodeCheckIn(location_id, options={}) {
extraFields: extra,
onSubmit: function() {
// Called when the 'check-in' button is pressed
var data = {location: location_id};
@ -434,7 +440,7 @@ function barcodeCheckIn(location_id, options={}) {
data.items = entries;
inventreePut(
'{% url 'api-stock-transfer' %}',
"{% url 'api-stock-transfer' %}",
data,
{
method: 'POST',
@ -446,7 +452,7 @@ function barcodeCheckIn(location_id, options={}) {
showAlertOrCache('alert-success', response.success, true);
location.reload();
} else {
showAlertOrCache('alert-success', 'Error transferring stock', false);
showAlertOrCache('alert-success', '{% trans "Error transferring stock" %}', false);
}
}
}
@ -482,25 +488,25 @@ function barcodeCheckIn(location_id, options={}) {
});
if (duplicate) {
showBarcodeMessage(modal, "{% trans "Stock Item already scanned" %}", "warning");
showBarcodeMessage(modal, '{% trans "Stock Item already scanned" %}', "warning");
} else {
if (stockitem.location == location_id) {
showBarcodeMessage(modal, "{% trans "Stock Item already in this location" %}");
showBarcodeMessage(modal, '{% trans "Stock Item already in this location" %}');
return;
}
// Add this stock item to the list
items.push(stockitem);
showBarcodeMessage(modal, "{% trans "Added stock item" %}", "success");
showBarcodeMessage(modal, '{% trans "Added stock item" %}', "success");
reloadTable();
}
} 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 Stock Item" %}', "warning");
}
} else {
showInvalidResponseError(modal, response, status);
@ -512,3 +518,135 @@ function barcodeCheckIn(location_id, options={}) {
}
);
}
/*
* Display dialog to check a single stock item into a stock location
*/
function scanItemsIntoLocation(item_id_list, options={}) {
var modal = options.modal || '#modal-form';
var stock_location = null;
// Extra form fields
var extra = makeNotesField();
// Header contentfor
var header = `
<div id='header-div'>
</div>
`;
function updateLocationInfo(location) {
var div = $(modal + ' #header-div');
if (stock_location && stock_location.pk) {
div.html(`
<div class='alert alert-block alert-info'>
<b>{% trans "Location" %}</b></br>
${stock_location.name}<br>
<i>${stock_location.description}</i>
</div>
`);
} else {
div.html('');
}
}
barcodeDialog(
'{% trans "Check Into Location" %}',
{
headerContent: header,
extraFields: extra,
preShow: function() {
modalSetSubmitText(modal, '{% trans "Check In" %}');
modalEnable(modal, false);
},
onShow: function() {
},
onSubmit: function() {
// Called when the 'check-in' button is pressed
if (!stock_location) {
return;
}
var items = [];
item_id_list.forEach(function(pk) {
items.push({
pk: pk,
});
})
var data = {
location: stock_location.pk,
notes: $(modal + ' #notes').val(),
items: items,
};
// Send API request
inventreePut(
'{% url "api-stock-transfer" %}',
data,
{
method: 'POST',
success: function(response, status) {
// First hide the modal
$(modal).modal('hide');
if (status == 'success' && 'success' in response) {
showAlertOrCache('alert-success', response.success, true);
location.reload();
} else {
showAlertOrCache('alert-danger', '{% trans "Error transferring stock" %}', false);
}
}
}
)
},
onScan: function(barcode) {
updateLocationInfo(null);
enableBarcodeInput(modal, false);
inventreePut(
'/api/barcode/',
{
barcode: barcode,
},
{
method: 'POST',
error: function() {
enableBarcodeInput(modal, true);
showBarcodeMessage(modal, '{% trans "Server error" %}');
},
success: function(response, status) {
modalEnable(modal, false);
enableBarcodeInput(modal, true);
if (status == 'success') {
if ('stocklocation' in response) {
// Barcode corresponds to a StockLocation
stock_location = response.stocklocation;
updateLocationInfo(stock_location);
modalEnable(modal, true);
} else {
// Barcode does *NOT* correspond to a StockLocation
showBarcodeMessage(
modal,
'{% trans "Barcode does not match a valid location" %}',
"warning",
);
}
} else {
// Invalid response returned from server
showInvalidResponseError(modal, response, status);
}
}
}
)
}
}
)
}