mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Implement cascading export of BOM
This commit is contained in:
parent
434d084371
commit
f865573e48
@ -129,15 +129,17 @@ class PartStarAdmin(admin.ModelAdmin):
|
|||||||
class BomItemResource(ModelResource):
|
class BomItemResource(ModelResource):
|
||||||
""" Class for managing BomItem data import/export """
|
""" Class for managing BomItem data import/export """
|
||||||
|
|
||||||
|
level = Field(attribute='level', readonly=True)
|
||||||
|
|
||||||
part = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
|
part = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
|
||||||
|
|
||||||
part_name = Field(attribute='part__full_name', readonly=True)
|
parent_part_name = Field(attribute='part__full_name', readonly=True)
|
||||||
|
|
||||||
sub_part = Field(attribute='sub_part', widget=widgets.ForeignKeyWidget(Part))
|
id = Field(attribute='sub_part', widget=widgets.ForeignKeyWidget(Part))
|
||||||
|
|
||||||
sub_part_name = Field(attribute='sub_part__full_name', readonly=True)
|
sub_part_name = Field(attribute='sub_part__full_name', readonly=True)
|
||||||
|
|
||||||
stock = Field(attribute='sub_part__total_stock', readonly=True)
|
sub_assembly = Field(attribute='sub_part__assembly', readonly=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = BomItem
|
model = BomItem
|
||||||
@ -145,7 +147,7 @@ class BomItemResource(ModelResource):
|
|||||||
report_skipped = False
|
report_skipped = False
|
||||||
clean_model_instances = True
|
clean_model_instances = True
|
||||||
|
|
||||||
exclude = ('checksum')
|
exclude = ['checksum', ]
|
||||||
|
|
||||||
|
|
||||||
class BomItemAdmin(ImportExportModelAdmin):
|
class BomItemAdmin(ImportExportModelAdmin):
|
||||||
|
@ -40,16 +40,43 @@ def MakeBomTemplate(fmt):
|
|||||||
return DownloadFile(data, filename)
|
return DownloadFile(data, filename)
|
||||||
|
|
||||||
|
|
||||||
def ExportBom(part, fmt='csv'):
|
def ExportBom(part, fmt='csv', cascade=False):
|
||||||
""" Export a BOM (Bill of Materials) for a given part.
|
""" Export a BOM (Bill of Materials) for a given part.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fmt: File format (default = 'csv')
|
||||||
|
cascade: If True, multi-level BOM output is supported. Otherwise, a flat top-level-only BOM is exported.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not IsValidBOMFormat(fmt):
|
if not IsValidBOMFormat(fmt):
|
||||||
fmt = 'csv'
|
fmt = 'csv'
|
||||||
|
|
||||||
bom_items = part.bom_items.all().order_by('id')
|
bom_items = []
|
||||||
|
|
||||||
dataset = BomItemResource().export(queryset=bom_items)
|
def add_items(items, level):
|
||||||
|
# Add items at a given layer
|
||||||
|
for item in items:
|
||||||
|
|
||||||
|
item.level = '-' * level
|
||||||
|
|
||||||
|
bom_items.append(item)
|
||||||
|
|
||||||
|
if item.sub_part.assembly:
|
||||||
|
add_items(item.sub_part.bom_items.all().order_by('id'), level + 1)
|
||||||
|
|
||||||
|
if cascade:
|
||||||
|
# Cascading (multi-level) BOM
|
||||||
|
|
||||||
|
# Start with the top level
|
||||||
|
items_to_process = part.bom_items.all().order_by('id')
|
||||||
|
|
||||||
|
add_items(items_to_process, 1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# No cascading needed - just the top-level items
|
||||||
|
bom_items = [item for item in part.bom_items.all().order_by('id')]
|
||||||
|
|
||||||
|
dataset = BomItemResource().export(queryset=bom_items, cascade=cascade)
|
||||||
data = dataset.export(fmt)
|
data = dataset.export(fmt)
|
||||||
|
|
||||||
filename = '{n}_BOM.{fmt}'.format(n=part.full_name, fmt=fmt)
|
filename = '{n}_BOM.{fmt}'.format(n=part.full_name, fmt=fmt)
|
||||||
|
@ -1334,10 +1334,12 @@ class BomDownload(AjaxView):
|
|||||||
|
|
||||||
export_format = request.GET.get('file_format', 'csv')
|
export_format = request.GET.get('file_format', 'csv')
|
||||||
|
|
||||||
|
cascade = str2bool(request.GET.get('cascade', False))
|
||||||
|
|
||||||
if not IsValidBOMFormat(export_format):
|
if not IsValidBOMFormat(export_format):
|
||||||
export_format = 'csv'
|
export_format = 'csv'
|
||||||
|
|
||||||
return ExportBom(part, fmt=export_format)
|
return ExportBom(part, fmt=export_format, cascade=cascade)
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {
|
return {
|
||||||
|
Loading…
Reference in New Issue
Block a user