mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 12:06:44 +00:00
Inherited BOM fix (#3579)
* Fix logic for get_used_in_bom_item_filter * Include scheduling information for inherited BOMs
This commit is contained in:
parent
c8de2efd9d
commit
89d5df4f1e
@ -574,16 +574,33 @@ class PartScheduling(RetrieveAPI):
|
|||||||
# Grab a list of BomItem objects that this part might be used in
|
# Grab a list of BomItem objects that this part might be used in
|
||||||
bom_items = BomItem.objects.filter(part.get_used_in_bom_item_filter())
|
bom_items = BomItem.objects.filter(part.get_used_in_bom_item_filter())
|
||||||
|
|
||||||
|
# Track all outstanding build orders
|
||||||
|
seen_builds = set()
|
||||||
|
|
||||||
for bom_item in bom_items:
|
for bom_item in bom_items:
|
||||||
# Find a list of active builds for this BomItem
|
# Find a list of active builds for this BomItem
|
||||||
|
|
||||||
builds = Build.objects.filter(
|
if bom_item.inherited:
|
||||||
status__in=BuildStatus.ACTIVE_CODES,
|
# An "inherited" BOM item filters down to variant parts also
|
||||||
part=bom_item.part,
|
childs = bom_item.part.get_descendants(include_self=True)
|
||||||
)
|
builds = Build.objects.filter(
|
||||||
|
status__in=BuildStatus.ACTIVE_CODES,
|
||||||
|
part__in=childs,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
builds = Build.objects.filter(
|
||||||
|
status__in=BuildStatus.ACTIVE_CODES,
|
||||||
|
part=bom_item.part,
|
||||||
|
)
|
||||||
|
|
||||||
for build in builds:
|
for build in builds:
|
||||||
|
|
||||||
|
# Ensure we don't double-count any builds
|
||||||
|
if build in seen_builds:
|
||||||
|
continue
|
||||||
|
|
||||||
|
seen_builds.add(build)
|
||||||
|
|
||||||
if bom_item.sub_part.trackable:
|
if bom_item.sub_part.trackable:
|
||||||
# Trackable parts are allocated against the outputs
|
# Trackable parts are allocated against the outputs
|
||||||
required_quantity = build.remaining * bom_item.quantity
|
required_quantity = build.remaining * bom_item.quantity
|
||||||
|
@ -1436,7 +1436,7 @@ class Part(MetadataMixin, MPTTModel):
|
|||||||
|
|
||||||
return parts
|
return parts
|
||||||
|
|
||||||
def get_used_in_bom_item_filter(self, include_inherited=True, include_variants=True, include_substitutes=True):
|
def get_used_in_bom_item_filter(self, include_variants=True, include_substitutes=True):
|
||||||
"""Return a BomItem queryset which returns all BomItem instances which refer to *this* part.
|
"""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:
|
As the BOM allocation logic is somewhat complicted, there are some considerations:
|
||||||
@ -1454,21 +1454,13 @@ class Part(MetadataMixin, MPTTModel):
|
|||||||
# Case A: This part is directly specified in a BomItem (we always use this case)
|
# Case A: This part is directly specified in a BomItem (we always use this case)
|
||||||
query = Q(
|
query = Q(
|
||||||
sub_part=self,
|
sub_part=self,
|
||||||
inherited=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if include_inherited:
|
|
||||||
query |= Q(
|
|
||||||
sub_part__in=parents,
|
|
||||||
inherited=True
|
|
||||||
)
|
|
||||||
|
|
||||||
if include_variants:
|
if include_variants:
|
||||||
# Case B: This part is a *variant* of a part which is specified in a BomItem which allows variants
|
# Case B: This part is a *variant* of a part which is specified in a BomItem which allows variants
|
||||||
query |= Q(
|
query |= Q(
|
||||||
allow_variants=True,
|
allow_variants=True,
|
||||||
sub_part__in=parents,
|
sub_part__in=parents,
|
||||||
inherited=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Case C: This part is a *substitute* of a part which is directly specified in a BomItem
|
# Case C: This part is a *substitute* of a part which is directly specified in a BomItem
|
||||||
|
Loading…
x
Reference in New Issue
Block a user