Pre-fill quantity on part ordering form (#3395)

* Pre-fill quantity on part ordering form

- Adds new API endpoint for requirement data
- Load data on the fly when launching ordering form

* Bump API version
This commit is contained in:
Oliver 2022-07-25 13:00:35 +10:00 committed by GitHub
parent 61ac02a045
commit 05d7159882
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 2 deletions

View File

@ -2,11 +2,15 @@
# InvenTree API version
INVENTREE_API_VERSION = 66
INVENTREE_API_VERSION = 67
"""
Increment this API version number whenever there is a significant change to the API that any clients need to know about
v67 -> 2022-07-25 : https://github.com/inventree/InvenTree/pull/3395
- Adds a 'requirements' endpoint for Part instance
- Provides information on outstanding order requirements for a given part
v66 -> 2022-07-24 : https://github.com/inventree/InvenTree/pull/3393
- Part images can now be downloaded from a remote URL via the API
- Company images can now be downloaded from a remote URL via the API

View File

@ -567,6 +567,40 @@ class PartScheduling(RetrieveAPI):
return Response(schedule)
class PartRequirements(RetrieveAPI):
"""API endpoint detailing 'requirements' information for aa particular part.
This endpoint returns information on upcoming requirements for:
- Sales Orders
- Build Orders
- Total requirements
As this data is somewhat complex to calculate, is it not included in the default API
"""
queryset = Part.objects.all()
def retrieve(self, request, *args, **kwargs):
"""Construct a response detailing Part requirements"""
part = self.get_object()
data = {
"available_stock": part.available_stock,
"on_order": part.on_order,
"required_build_order_quantity": part.required_build_order_quantity(),
"allocated_build_order_quantity": part.build_order_allocation_count(),
"required_sales_order_quantity": part.required_sales_order_quantity(),
"allocated_sales_order_quantity": part.sales_order_allocation_count(pending=True),
}
data["allocated"] = data["allocated_build_order_quantity"] + data["allocated_sales_order_quantity"]
data["required"] = data["required_build_order_quantity"] + data["required_sales_order_quantity"]
return Response(data)
class PartMetadata(RetrieveUpdateAPI):
"""API endpoint for viewing / updating Part metadata."""
@ -1997,6 +2031,8 @@ part_api_urls = [
# Endpoint for future scheduling information
re_path(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'),
re_path(r'^requirements/', PartRequirements.as_view(), name='api-part-requirements'),
# Endpoint for duplicating a BOM for the specific Part
re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),

View File

@ -817,7 +817,7 @@ function orderParts(parts_list, options={}) {
var thumb = thumbnailImage(part.thumbnail || part.image);
// The "quantity" field should have been provided for each part
// Default quantity value
var quantity = part.quantity || 1;
if (quantity < 0) {
@ -1017,6 +1017,29 @@ function orderParts(parts_list, options={}) {
return '{% trans "No matching purchase orders" %}';
}
}, null, opts);
// Request 'requirements' information for each part
inventreeGet(`/api/part/${part.pk}/requirements/`, {}, {
success: function(response) {
var required = response.required || 0;
var allocated = response.allocated || 0;
var available = response.available_stock || 0;
// Based on what we currently 'have' on hand, what do we need to order?
var deficit = Math.max(required - allocated, 0);
if (available < deficit) {
var q = deficit - available;
updateFieldValue(
`quantity_${part.pk}`,
q,
{},
opts
);
}
}
});
});
// Add callback for "add to purchase order" button