Add option for including supplier data for BOM export

This commit is contained in:
Oliver Walters 2020-08-19 14:05:16 +10:00
parent 965dba4739
commit d0b5550c86
3 changed files with 64 additions and 53 deletions

View File

@ -47,7 +47,7 @@ def MakeBomTemplate(fmt):
return DownloadFile(data, filename) return DownloadFile(data, filename)
def ExportBom(part, fmt='csv', cascade=False, max_levels=None): def ExportBom(part, fmt='csv', cascade=False, max_levels=None, supplier_data=False):
""" Export a BOM (Bill of Materials) for a given part. """ Export a BOM (Bill of Materials) for a given part.
Args: Args:
@ -92,67 +92,72 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None):
dataset = BomItemResource().export(queryset=bom_items, cascade=cascade) dataset = BomItemResource().export(queryset=bom_items, cascade=cascade)
# Expand dataset with manufacturer parts if supplier_data:
manufacturer_headers = [ """
_('Supplier'), If requested, add extra columns for each SupplierPart associated with the each line item
_('SKU'), """
_('Manufacturer'),
_('MPN'),
]
manufacturer_cols = {} # Expand dataset with manufacturer parts
manufacturer_headers = [
_('Supplier'),
_('SKU'),
_('Manufacturer'),
_('MPN'),
]
for b_idx, bom_item in enumerate(bom_items): manufacturer_cols = {}
# Get part instance
b_part = bom_item.sub_part
# Filter supplier parts for b_idx, bom_item in enumerate(bom_items):
supplier_parts = SupplierPart.objects.filter(part__pk=b_part.pk) # Get part instance
b_part = bom_item.sub_part
# Construct supplier-part data
supplier_part_list = []
for idx, supplier_part in enumerate(supplier_parts):
if supplier_part.supplier: # Filter supplier parts
supplier_name = supplier_part.supplier.name supplier_parts = SupplierPart.objects.filter(part__pk=b_part.pk)
else:
supplier_name = '' # Construct supplier-part data
supplier_part_list = []
for idx, supplier_part in enumerate(supplier_parts):
supplier_sku = supplier_part.SKU if supplier_part.supplier:
supplier_name = supplier_part.supplier.name
else:
supplier_name = ''
if supplier_part.manufacturer: supplier_sku = supplier_part.SKU
manufacturer_name = supplier_part.manufacturer.name
else:
manufacturer_name = ''
manufacturer_mpn = supplier_part.MPN if supplier_part.manufacturer:
manufacturer_name = supplier_part.manufacturer.name
else:
manufacturer_name = ''
# Add manufacturer data to the manufacturer columns manufacturer_mpn = supplier_part.MPN
# Generate column names for this supplier # Add manufacturer data to the manufacturer columns
k_sup = manufacturer_headers[0] + "_" + str(idx)
k_sku = manufacturer_headers[1] + "_" + str(idx)
k_man = manufacturer_headers[2] + "_" + str(idx)
k_mpn = manufacturer_headers[3] + "_" + str(idx)
try: # Generate column names for this supplier
manufacturer_cols[k_sup].update({b_idx: supplier_name}) k_sup = manufacturer_headers[0] + "_" + str(idx)
manufacturer_cols[k_sku].update({b_idx: supplier_sku}) k_sku = manufacturer_headers[1] + "_" + str(idx)
manufacturer_cols[k_man].update({b_idx: manufacturer_name}) k_man = manufacturer_headers[2] + "_" + str(idx)
manufacturer_cols[k_mpn].update({b_idx: manufacturer_mpn}) k_mpn = manufacturer_headers[3] + "_" + str(idx)
except KeyError:
manufacturer_cols[k_sup] = {b_idx: supplier_name}
manufacturer_cols[k_sku] = {b_idx: supplier_sku}
manufacturer_cols[k_man] = {b_idx: manufacturer_name}
manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn}
# Add manufacturer columns to dataset try:
for header, col_dict in manufacturer_cols.items(): manufacturer_cols[k_sup].update({b_idx: supplier_name})
# Construct column tuple manufacturer_cols[k_sku].update({b_idx: supplier_sku})
col = tuple(col_dict.get(c_idx, '') for c_idx in range(len(bom_items))) manufacturer_cols[k_man].update({b_idx: manufacturer_name})
# Add column to dataset manufacturer_cols[k_mpn].update({b_idx: manufacturer_mpn})
dataset.append_col(col, header=header) except KeyError:
manufacturer_cols[k_sup] = {b_idx: supplier_name}
manufacturer_cols[k_sku] = {b_idx: supplier_sku}
manufacturer_cols[k_man] = {b_idx: manufacturer_name}
manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn}
# Add manufacturer columns to dataset
for header, col_dict in manufacturer_cols.items():
# Construct column tuple
col = tuple(col_dict.get(c_idx, '') for c_idx in range(len(bom_items)))
# Add column to dataset
dataset.append_col(col, header=header)
data = dataset.export(fmt) data = dataset.export(fmt)

View File

@ -54,10 +54,12 @@ class BomExportForm(forms.Form):
file_format = forms.ChoiceField(label=_("File Format"), help_text=_("Select output file format")) file_format = forms.ChoiceField(label=_("File Format"), help_text=_("Select output file format"))
cascading = forms.BooleanField(label=_("Cascading"), required=False, initial=False, help_text=_("Download cascading / multi-level BOM")) cascading = forms.BooleanField(label=_("Cascading"), required=False, initial=True, help_text=_("Download cascading / multi-level BOM"))
levels = forms.IntegerField(label=_("Levels"), required=True, initial=0, help_text=_("Select maximum number of BOM levels to export (0 = all levels)")) levels = forms.IntegerField(label=_("Levels"), required=True, initial=0, help_text=_("Select maximum number of BOM levels to export (0 = all levels)"))
supplier_data = forms.BooleanField(label=_("Include Supplier Data"), required=False, initial=True, help_text=_("Include supplier part data in exported BOM"))
def get_choices(self): def get_choices(self):
""" BOM export format choices """ """ BOM export format choices """

View File

@ -1499,6 +1499,8 @@ class BomDownload(AjaxView):
cascade = str2bool(request.GET.get('cascade', False)) cascade = str2bool(request.GET.get('cascade', False))
supplier_data = str2bool(request.GET.get('supplier_data', False))
levels = request.GET.get('levels', None) levels = request.GET.get('levels', None)
if levels is not None: if levels is not None:
@ -1514,7 +1516,7 @@ class BomDownload(AjaxView):
if not IsValidBOMFormat(export_format): if not IsValidBOMFormat(export_format):
export_format = 'csv' export_format = 'csv'
return ExportBom(part, fmt=export_format, cascade=cascade, max_levels=levels) return ExportBom(part, fmt=export_format, cascade=cascade, max_levels=levels, supplier_data=supplier_data)
def get_data(self): def get_data(self):
return { return {
@ -1539,6 +1541,7 @@ class BomExport(AjaxView):
fmt = request.POST.get('file_format', 'csv').lower() fmt = request.POST.get('file_format', 'csv').lower()
cascade = str2bool(request.POST.get('cascading', False)) cascade = str2bool(request.POST.get('cascading', False))
levels = request.POST.get('levels', None) levels = request.POST.get('levels', None)
supplier_data = str2bool(request.POST.get('supplier_data', False))
try: try:
part = Part.objects.get(pk=self.kwargs['pk']) part = Part.objects.get(pk=self.kwargs['pk'])
@ -1553,6 +1556,7 @@ class BomExport(AjaxView):
url += '?file_format=' + fmt url += '?file_format=' + fmt
url += '&cascade=' + str(cascade) url += '&cascade=' + str(cascade)
url += '&supplier_data=' + str(supplier_data)
if levels: if levels:
url += '&levels=' + str(levels) url += '&levels=' + str(levels)