mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-05 13:10:57 +00:00
Scheduling improvements (#3564)
* Handle case where initial API call fails * Error if scheduling fails to retrieve * Visual improvements for scheduling graph: - Fixes for vertical scales - Add "minimum stock level" line * Refactor / improve query for list of BOM items a part can exist in * Remove stock column from "substitute part" dialog - Stock quantity no longer available in this serailizer * Add a button to reload part scheduling information * Add extra information to part scheduling API - Include "speculative" quantity drawdown for build orders * Add table of scheduling data * Improved chart display - Adds "minimum" and "maximum" expected values - Adds table of scheduling information * Bump API version * Improve table rendering * Improve axis scaling * Add ability to dynamically refresh schedling data * JS linting * JS fix
This commit is contained in:
@ -1436,6 +1436,53 @@ class Part(MetadataMixin, MPTTModel):
|
||||
|
||||
return parts
|
||||
|
||||
def get_used_in_bom_item_filter(self, include_inherited=True, include_variants=True, include_substitutes=True):
|
||||
"""Return a BomItem queryset which returns all BomItem instances which refer to *this* part.
|
||||
|
||||
As the BOM allocation logic is somewhat complicted, there are some considerations:
|
||||
|
||||
A) This part may be directly specified in a BomItem instance
|
||||
B) This part may be a *variant* of a part which is directly specified in a BomItem instance
|
||||
C) This part may be a *substitute* for a part which is directly specifed in a BomItem instance
|
||||
|
||||
So we construct a query for each case, and combine them...
|
||||
"""
|
||||
|
||||
# Cache all *parent* parts
|
||||
parents = self.get_ancestors(include_self=False)
|
||||
|
||||
# Case A: This part is directly specified in a BomItem (we always use this case)
|
||||
query = Q(
|
||||
sub_part=self,
|
||||
inherited=False,
|
||||
)
|
||||
|
||||
if include_inherited:
|
||||
query |= Q(
|
||||
sub_part__in=parents,
|
||||
inherited=True
|
||||
)
|
||||
|
||||
if include_variants:
|
||||
# Case B: This part is a *variant* of a part which is specified in a BomItem which allows variants
|
||||
query |= Q(
|
||||
allow_variants=True,
|
||||
sub_part__in=parents,
|
||||
inherited=False,
|
||||
)
|
||||
|
||||
# Case C: This part is a *substitute* of a part which is directly specified in a BomItem
|
||||
if include_substitutes:
|
||||
|
||||
# Grab a list of BomItem substitutes which reference this part
|
||||
substitutes = self.substitute_items.all()
|
||||
|
||||
query |= Q(
|
||||
pk__in=[substitute.bom_item.pk for substitute in substitutes],
|
||||
)
|
||||
|
||||
return query
|
||||
|
||||
def get_used_in_filter(self, include_inherited=True):
|
||||
"""Return a query filter for all parts that this part is used in.
|
||||
|
||||
|
Reference in New Issue
Block a user