mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-06 13:40:56 +00:00
* Adds ReturnOrder and ReturnOrderAttachment models
* Adds new 'role' specific for return orders
* Refactor total_price into a mixin
- Required for PurchaseOrder and SalesOrder
- May not be required for ReturnOrder (remains to be seen)
* Adds API endpoints for ReturnOrder
- Add list endpoint
- Add detail endpoint
- Adds required serializer models
* Adds basic "index" page for Return Order model
* Update API version
* Update navbar text
* Add db migration for new "role"
* Add ContactList and ContactDetail API endpoints
* Adds template and JS code for manipulation of contacts
- Display a table
- Create / edit / delete
* Splits order.js into multiple files
- Javascript files was becoming extremely large
- Hard to debug and find code
- Split into purchase_order / return_order / sales_order
* Fix role name (change 'returns' to 'return_order')
- Similar to existing roles for purchase_order and sales_order
* Adds detail page for ReturnOrder
* URL cleanup
- Use <int:pk> instead of complex regex
* More URL cleanup
* Add "return orders" list to company detail page
* Break JS status codes into new javascript file
- Always difficult to track down where these are rendered
- Enough to warrant their own file now
* Add ability to edit return order from detail page
* Database migrations
- Add new ReturnOrder modeles
- Add new 'contact' field to external orders
* Adds "contact" to ReturnOrder
- Implement check to ensure that the selected "contact" matches the selected "company"
* Adjust filters to limit contact options
* Fix typo
* Expose 'contact' field for PurchaseOrder model
* Render contact information
* Add "contact" for SalesOrder
* Adds setting to enable / disable return order functionality
- Simply hides the navigation elements
- API is not disabled
* Support filtering ReturnOrder by 'status'
- Refactors existing filter into the OrderFilter class
* js linting
* More JS linting
* Adds ReturnOrderReport model
* Add serializer for the ReturnOrderReport model
- A little bit of refactoring along the way
* Admin integration for new report model
* Refactoring for report.api
- Adds generic mixins for filtering queryset (based on updates to label.api)
- Reduces repeated code a *lot*
* Exposes API endpoints for ReturnOrderReport
* Adds default example report file for ReturnOrder
- Requires some more work :)
* Refactor report printing javascript code
- Replace all existing functions with 'printReports'
* Improvements for default StockItem test report template
- Fix bug in template
- Handle potential errors in template tags
- Add more helpers to report tags
- Improve test result rendering
* Reduce logging verbosity from weasyprint
* Refactor javascript for label printing
- Consolidate into a single function
- Similar to refactor of report functions
* Add report print button to return order page
* Record user reference when creating via API
* Refactor order serializers
- Move common code into AbstractOrderSerializer class
* Adds extra line item model for the return order
- Adds serializer and API endpoints as appropriate
* Render extra line table for return order
- Refactor existing functions into a single generic function
- Reduces repeated JS code a lot
* Add ability to create a new extra line item
* Adds button for creating a new lien item
* JS linting
* Update test
* Typo fix
(cherry picked from commit 28ac2be35b
)
* Enable search for return order
* Don't do pricing (yet) for returnorder extra line table
- Fixes an uncaught error
* Error catching for api.js
* Updates for order models:
- Add 'target_date' field to abstract Order model
- Add IN_PROGRESS status code for return order
- Refactor 'overdue' and 'outstanding' API queries
- Refactor OVERDUE_FILTER on order models
- Refactor is_overdue on order models
- More table filters for return order model
* JS cleanup
* Create ReturnOrderLineItem model
- New type of status label
- Add TotalPriceMixin to ReturnOrder model
* Adds an API serializer for the ReturnOrderLineItem model
* Add API endpoints for ReturnOrderLineItem model
- Including some refactoring along the way
* javascript: refactor loadTableFilters function
- Pass enforced query through to the filters
- Call Object.assign() to construct a superset query
- Removes a lot of code duplication
* Refactor hard-coded URLS to use {% url %} lookup
- Forces error if the URL is wrong
- If we ever change the URL, will still work
* Implement creation of new return order line items
* Adds 'part_detail' annotation to ReturnOrderLineItem serializer
- Required for rendering part information
* javascript: refactor method for creating a group of buttons in a table
* javascript: refactor common buttons with helper functions
* Allow edit and delete of return order line items
* Add form option to automatically reload a table on success
- Pass table name to options.refreshTable
* JS linting
* Add common function for createExtraLineItem
* Refactor loading of attachment tables
- Setup drag-and-drop as part of core function
* CI fixes
* Refactoring out some more common API endpoint code
* Update migrations
* Fix permission typo
* Refactor for unit testing code
* Add unit tests for Contact model
* Tests for returnorder list API
* Annotate 'line_items' to ReturnOrder serializer
* Driving the refactor tractor
* More unit tests for the ReturnOrder API endpoints
* Refactor "print orders" button for various order tables
- Move into "setupFilterList" code (generic)
* add generic 'label printing' button to table actions buttons
* Refactor build output table
* Refactoring icon generation for js
* Refactoring for Part API
* Fix database model type for 'received_date'
* Add API endpoint to "issue" a ReturnOrder
* Improvements for stock tracking table
- Add new status codes
- Add rendering for SalesOrder
- Add rendering for ReturnOrder
- Fix status badges
* Adds functionality to receive line items against a return order
* Add endpoints for completing and cancelling orders
* Add option to allow / prevent editing of ReturnOrder after completed
* js linting
* Wrap "add extra line" button in setting check
* Updates to order/admin.py
* Remove inline admin for returnorderline model
* Updates to pass CI
* Serializer fix
* order template fixes
* Unit test fix
* Fixes for ReturnOrder.receive_line_item
* Unit testing for receiving line items against an RMA
* Improve example report for return order
* Extend unit tests for reporting
* Cleanup here and there
* Unit testing for order views
* Clear "sales_order" field when returning against ReturnOrder
* Add 'location' to deltas when returning from customer
* Bug fix for unit test
290 lines
7.3 KiB
JavaScript
290 lines
7.3 KiB
JavaScript
{% load i18n %}
|
|
{% load inventree_extras %}
|
|
|
|
/* globals
|
|
*/
|
|
|
|
/* exported
|
|
inventreeGet,
|
|
inventreeDelete,
|
|
inventreeFormDataUpload,
|
|
showApiError,
|
|
*/
|
|
|
|
$.urlParam = function(name) {
|
|
// eslint-disable-next-line no-useless-escape
|
|
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
|
|
|
|
if (results == null) {
|
|
return null;
|
|
}
|
|
|
|
return decodeURI(results[1]) || 0;
|
|
};
|
|
|
|
|
|
// using jQuery
|
|
function getCookie(name) {
|
|
var cookieValue = null;
|
|
if (document.cookie && document.cookie != '') {
|
|
var cookies = document.cookie.split(';');
|
|
for (var i = 0; i < cookies.length; i++) {
|
|
var cookie = jQuery.trim(cookies[i]);
|
|
// Does this cookie string begin with the name we want?
|
|
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return cookieValue;
|
|
}
|
|
|
|
|
|
/*
|
|
* Perform a GET request to the InvenTree server
|
|
*/
|
|
function inventreeGet(url, filters={}, options={}) {
|
|
|
|
if (!url) {
|
|
console.error('inventreeGet called without url');
|
|
return;
|
|
}
|
|
|
|
// Middleware token required for data update
|
|
var csrftoken = getCookie('csrftoken');
|
|
|
|
return $.ajax({
|
|
beforeSend: function(xhr) {
|
|
xhr.setRequestHeader('X-CSRFToken', csrftoken);
|
|
},
|
|
url: url,
|
|
type: 'GET',
|
|
data: filters,
|
|
dataType: 'json',
|
|
contentType: 'application/json',
|
|
async: (options.async == false) ? false : true,
|
|
success: function(response) {
|
|
if (options.success) {
|
|
options.success(response);
|
|
}
|
|
},
|
|
error: function(xhr, ajaxOptions, thrownError) {
|
|
console.error('Error on GET at ' + url);
|
|
|
|
if (thrownError) {
|
|
console.error('Error: ' + thrownError);
|
|
}
|
|
|
|
if (options.error) {
|
|
options.error({
|
|
error: thrownError
|
|
});
|
|
} else {
|
|
showApiError(xhr, url);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/* Upload via AJAX using the FormData approach.
|
|
*
|
|
* Note that the following AJAX parameters are required for FormData upload
|
|
*
|
|
* processData: false
|
|
* contentType: false
|
|
*/
|
|
function inventreeFormDataUpload(url, data, options={}) {
|
|
|
|
if (!url) {
|
|
console.error('inventreeFormDataUpload called without url');
|
|
return;
|
|
}
|
|
|
|
// CSRF cookie token
|
|
var csrftoken = getCookie('csrftoken');
|
|
|
|
return $.ajax({
|
|
beforeSend: function(xhr) {
|
|
xhr.setRequestHeader('X-CSRFToken', csrftoken);
|
|
},
|
|
url: url,
|
|
method: options.method || 'POST',
|
|
data: data,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(data, status, xhr) {
|
|
if (options.success) {
|
|
options.success(data, status, xhr);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('Form data upload failure: ' + status);
|
|
|
|
if (options.error) {
|
|
options.error(xhr, status, error);
|
|
} else {
|
|
showApiError(xhr, url);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/*
|
|
* Perform a PUT or PATCH request to the InvenTree server
|
|
*/
|
|
function inventreePut(url, data={}, options={}) {
|
|
|
|
if (!url) {
|
|
console.error('inventreePut called without url');
|
|
return;
|
|
}
|
|
|
|
var method = options.method || 'PUT';
|
|
|
|
// Middleware token required for data update
|
|
var csrftoken = getCookie('csrftoken');
|
|
|
|
return $.ajax({
|
|
beforeSend: function(xhr) {
|
|
xhr.setRequestHeader('X-CSRFToken', csrftoken);
|
|
},
|
|
url: url,
|
|
type: method,
|
|
data: JSON.stringify(data),
|
|
dataType: 'json',
|
|
contentType: 'application/json',
|
|
success: function(response, status) {
|
|
if (options.success) {
|
|
options.success(response, status);
|
|
}
|
|
if (options.reloadOnSuccess) {
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function(xhr, ajaxOptions, thrownError) {
|
|
if (options.error) {
|
|
options.error(xhr, ajaxOptions, thrownError);
|
|
} else {
|
|
console.error(`Error on ${method} to '${url}' - STATUS ${xhr.status}`);
|
|
console.error(thrownError);
|
|
|
|
showApiError(xhr, url);
|
|
}
|
|
},
|
|
complete: function(xhr, status) {
|
|
if (options.complete) {
|
|
options.complete(xhr, status);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/*
|
|
* Performs a DELETE API call to the server
|
|
*/
|
|
function inventreeDelete(url, options={}) {
|
|
|
|
if (!url) {
|
|
console.error('inventreeDelete called without url');
|
|
return;
|
|
}
|
|
|
|
options = options || {};
|
|
|
|
options.method = 'DELETE';
|
|
|
|
return inventreePut(
|
|
url,
|
|
options.data || {},
|
|
options
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* Display a notification with error information
|
|
*/
|
|
function showApiError(xhr, url) {
|
|
|
|
var title = null;
|
|
var message = null;
|
|
|
|
if (xhr.statusText == 'abort') {
|
|
// Don't show errors for requests which were intentionally aborted
|
|
return;
|
|
}
|
|
|
|
switch (xhr.status || 0) {
|
|
// No response
|
|
case 0:
|
|
title = '{% trans "No Response" %}';
|
|
message = '{% trans "No response from the InvenTree server" %}';
|
|
break;
|
|
// Bad request
|
|
case 400:
|
|
// 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;
|
|
// Not authenticated
|
|
case 401:
|
|
title = '{% trans "Error 401: Not Authenticated" %}';
|
|
message = '{% trans "Authentication credentials not supplied" %}';
|
|
break;
|
|
// Permission denied
|
|
case 403:
|
|
title = '{% trans "Error 403: Permission Denied" %}';
|
|
message = '{% trans "You do not have the required permissions to access this function" %}';
|
|
break;
|
|
// Resource not found
|
|
case 404:
|
|
title = '{% trans "Error 404: Resource Not Found" %}';
|
|
message = '{% trans "The requested resource could not be located on the server" %}';
|
|
break;
|
|
// Method not allowed
|
|
case 405:
|
|
title = '{% trans "Error 405: Method Not Allowed" %}';
|
|
message = '{% trans "HTTP method not allowed at URL" %}';
|
|
break;
|
|
// Timeout
|
|
case 408:
|
|
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}`;
|
|
|
|
var response = xhr.responseJSON;
|
|
|
|
// The server may have provided some extra information about this error
|
|
if (response) {
|
|
if (response.error) {
|
|
title = response.error;
|
|
}
|
|
|
|
if (response.detail) {
|
|
message = response.detail;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (url) {
|
|
message += '<hr>';
|
|
message += `URL: ${url}`;
|
|
}
|
|
|
|
showMessage(title, {
|
|
style: 'danger',
|
|
icon: 'fas fa-server icon-red',
|
|
details: message,
|
|
});
|
|
}
|