diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
index b002484798..384e5d1d71 100644
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -244,17 +244,17 @@ class StockTransfer(StockAdjust):
def post(self, request, *args, **kwargs):
- self.get_items(request)
-
data = request.data
try:
location = StockLocation.objects.get(pk=data.get('location', None))
except (ValueError, StockLocation.DoesNotExist):
- raise ValidationError({'location': 'Valid location must be specified'})
+ raise ValidationError({'location': [_('Valid location must be specified')]})
n = 0
+ self.get_items(request)
+
for item in self.items:
# If quantity is not specified, move the entire stock
diff --git a/InvenTree/templates/js/api.js b/InvenTree/templates/js/api.js
index 5e8905a1dd..93fa5a41e4 100644
--- a/InvenTree/templates/js/api.js
+++ b/InvenTree/templates/js/api.js
@@ -1,3 +1,6 @@
+{% load i18n %}
+{% load inventree_extras %}
+
var jQuery = window.$;
// using jQuery
@@ -138,4 +141,49 @@ function inventreeDelete(url, options={}) {
inventreePut(url, {}, options);
+}
+
+
+function showApiError(xhr) {
+
+ var title = null;
+ var message = null;
+
+ switch (xhr.status) {
+ case 0: // No response
+ title = '{% trans "No Response" %}';
+ message = '{% trans "No response from the InvenTree server" %}';
+ break;
+ case 400: // Bad request
+ // Note: Normally error code 400 is handled separately,
+ // and should now be shown here!
+ title = '{% trans "Error 400: Bad request" %}';
+ message = '{% trans "API request returned error code 400" %}';
+ break;
+ case 401: // Not authenticated
+ title = '{% trans "Error 401: Not Authenticated" %}';
+ message = '{% trans "Authentication credentials not supplied" %}';
+ break;
+ case 403: // Permission denied
+ title = '{% trans "Error 403: Permission Denied" %}';
+ message = '{% trans "You do not have the required permissions to access this function" %}';
+ break;
+ case 404: // Resource not found
+ title = '{% trans "Error 404: Resource Not Found" %}';
+ message = '{% trans "The requested resource could not be located on the server" %}';
+ break;
+ case 408: // Timeout
+ title = '{% trans "Error 408: Timeout" %}';
+ message = '{% trans "Connection timeout while requesting data from server" %}';
+ break;
+ default:
+ title = '{% trans "Unhandled Error Code" %}';
+ message = `{% trans "Error code" %}: ${xhr.status}`;
+ break;
+ }
+
+ message += "
";
+ message += renderErrorMessage(xhr);
+
+ showAlertDialog(title, message);
}
\ No newline at end of file
diff --git a/InvenTree/templates/js/forms.js b/InvenTree/templates/js/forms.js
index 65c1a11b44..103ba26572 100644
--- a/InvenTree/templates/js/forms.js
+++ b/InvenTree/templates/js/forms.js
@@ -422,10 +422,8 @@ function constructFormBody(fields, options) {
default:
break;
}
-
- var f = constructField(name, field, options);
- html += f;
+ html += constructField(name, field, options);
}
// TODO: Dynamically create the modals,
@@ -599,47 +597,9 @@ function submitFormData(fields, options) {
case 400: // Bad request
handleFormErrors(xhr.responseJSON, fields, options);
break;
- case 0: // No response
- $(options.modal).modal('hide');
- showAlertDialog(
- '{% trans "No Response" %}',
- '{% trans "No response from the InvenTree server" %}',
- );
- break;
- case 401: // Not authenticated
- $(options.modal).modal('hide');
- showAlertDialog(
- '{% trans "Error 401: Not Authenticated" %}',
- '{% trans "Authentication credentials not supplied" %}',
- );
- break;
- case 403: // Permission denied
- $(options.modal).modal('hide');
- showAlertDialog(
- '{% trans "Error 403: Permission Denied" %}',
- '{% trans "You do not have the required permissions to access this function" %}',
- );
- break;
- case 404: // Resource not found
- $(options.modal).modal('hide');
- showAlertDialog(
- '{% trans "Error 404: Resource Not Found" %}',
- '{% trans "The requested resource could not be located on the server" %}',
- );
- break;
- case 408: // Timeout
- $(options.modal).modal('hide');
- showAlertDialog(
- '{% trans "Error 408: Timeout" %}',
- '{% trans "Connection timeout while requesting data from server" %}',
- );
- break;
default:
$(options.modal).modal('hide');
-
- showAlertDialog('{% trans "Error requesting form data" %}', renderErrorMessage(xhr));
-
- console.log(`WARNING: Unhandled response code - ${xhr.status}`);
+ showApiError(xhr);
break;
}
}
diff --git a/InvenTree/templates/js/modals.js b/InvenTree/templates/js/modals.js
index b613ed81f6..b49d7fadfc 100644
--- a/InvenTree/templates/js/modals.js
+++ b/InvenTree/templates/js/modals.js
@@ -39,12 +39,13 @@ function createNewModal(options={}) {
-
-
-
+
+
+
+
diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js
index 8612e2758a..c06ebf3fd0 100644
--- a/InvenTree/templates/js/stock.js
+++ b/InvenTree/templates/js/stock.js
@@ -255,6 +255,28 @@ function adjustStock(items, options={}) {
if (options.onSuccess) {
options.onSuccess();
}
+ },
+ error: function(xhr) {
+ switch (xhr.status) {
+ case 400:
+ console.log('400 bad request');
+ console.log(xhr.responseJSON);
+
+ // Handle errors for standard fields
+ handleFormErrors(
+ xhr.responseJSON,
+ extraFields,
+ {
+ modal: modal,
+ }
+ )
+
+ break;
+ default:
+ $(modal).modal('hide');
+ showApiError(xhr);
+ break;
+ }
}
}
);