mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
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:
parent
61ac02a045
commit
05d7159882
@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
|
|
||||||
# InvenTree API version
|
# 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
|
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
|
v66 -> 2022-07-24 : https://github.com/inventree/InvenTree/pull/3393
|
||||||
- Part images can now be downloaded from a remote URL via the API
|
- 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
|
- Company images can now be downloaded from a remote URL via the API
|
||||||
|
@ -567,6 +567,40 @@ class PartScheduling(RetrieveAPI):
|
|||||||
return Response(schedule)
|
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):
|
class PartMetadata(RetrieveUpdateAPI):
|
||||||
"""API endpoint for viewing / updating Part metadata."""
|
"""API endpoint for viewing / updating Part metadata."""
|
||||||
|
|
||||||
@ -1997,6 +2031,8 @@ part_api_urls = [
|
|||||||
# Endpoint for future scheduling information
|
# Endpoint for future scheduling information
|
||||||
re_path(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'),
|
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
|
# Endpoint for duplicating a BOM for the specific Part
|
||||||
re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
|
re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
|
||||||
|
|
||||||
|
@ -817,7 +817,7 @@ function orderParts(parts_list, options={}) {
|
|||||||
|
|
||||||
var thumb = thumbnailImage(part.thumbnail || part.image);
|
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;
|
var quantity = part.quantity || 1;
|
||||||
|
|
||||||
if (quantity < 0) {
|
if (quantity < 0) {
|
||||||
@ -1017,6 +1017,29 @@ function orderParts(parts_list, options={}) {
|
|||||||
return '{% trans "No matching purchase orders" %}';
|
return '{% trans "No matching purchase orders" %}';
|
||||||
}
|
}
|
||||||
}, null, opts);
|
}, 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
|
// Add callback for "add to purchase order" button
|
||||||
|
Loading…
Reference in New Issue
Block a user