From c0691c3e9b55d3bd80ab94adc600e04315db1ee3 Mon Sep 17 00:00:00 2001 From: eeintech Date: Wed, 7 Apr 2021 11:43:05 -0400 Subject: [PATCH] Decoupled manufacturer and supplier data in BOM export, aggregate data needs more work --- InvenTree/part/bom.py | 120 +++++++++++++++++++++++++++++++++++----- InvenTree/part/forms.py | 4 +- InvenTree/part/views.py | 8 ++- 3 files changed, 115 insertions(+), 17 deletions(-) diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py index f3cf598225..c7de3b4905 100644 --- a/InvenTree/part/bom.py +++ b/InvenTree/part/bom.py @@ -16,7 +16,7 @@ from InvenTree.helpers import DownloadFile, GetExportFormats from .admin import BomItemResource from .models import BomItem -from company.models import SupplierPart +from company.models import ManufacturerPart, SupplierPart def IsValidBOMFormat(fmt): @@ -49,7 +49,7 @@ def MakeBomTemplate(fmt): return DownloadFile(data, filename) -def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=False, stock_data=False, supplier_data=False): +def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=False, stock_data=False, supplier_data=False, manufacturer_data=False): """ Export a BOM (Bill of Materials) for a given part. Args: @@ -160,17 +160,17 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa # Add stock columns to dataset add_columns_to_dataset(stock_cols, len(bom_items)) - if supplier_data: + if manufacturer_data and supplier_data: """ - If requested, add extra columns for each SupplierPart associated with each line item + If requested, add extra columns for each SupplierPart and ManufacturerPart associated with each line item """ # Expand dataset with manufacturer parts manufacturer_headers = [ - _('Supplier'), - _('SKU'), _('Manufacturer'), _('MPN'), + _('Supplier'), + _('SKU'), ] manufacturer_cols = {} @@ -191,31 +191,121 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa supplier_sku = supplier_part.SKU - if supplier_part.manufacturer: - manufacturer_name = supplier_part.manufacturer.name + if supplier_part.manufacturer_part.manufacturer: + manufacturer_name = supplier_part.manufacturer_part.manufacturer.name else: manufacturer_name = '' - manufacturer_mpn = supplier_part.MPN + manufacturer_mpn = supplier_part.manufacturer_part.MPN + + # Add manufacturer data to the manufacturer columns + + # Generate column names for this supplier + k_man = manufacturer_headers[0] + "_" + str(idx) + k_mpn = manufacturer_headers[1] + "_" + str(idx) + k_sup = manufacturer_headers[2] + "_" + str(idx) + k_sku = manufacturer_headers[3] + "_" + str(idx) + + try: + manufacturer_cols[k_man].update({b_idx: manufacturer_name}) + manufacturer_cols[k_mpn].update({b_idx: manufacturer_mpn}) + manufacturer_cols[k_sup].update({b_idx: supplier_name}) + manufacturer_cols[k_sku].update({b_idx: supplier_sku}) + except KeyError: + manufacturer_cols[k_man] = {b_idx: manufacturer_name} + manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn} + manufacturer_cols[k_sup] = {b_idx: supplier_name} + manufacturer_cols[k_sku] = {b_idx: supplier_sku} + + # Add manufacturer columns to dataset + add_columns_to_dataset(manufacturer_cols, len(bom_items)) + + elif manufacturer_data: + """ + If requested, add extra columns for each ManufacturerPart associated with each line item + """ + + # Expand dataset with manufacturer parts + manufacturer_headers = [ + _('Manufacturer'), + _('MPN'), + ] + + manufacturer_cols = {} + + for b_idx, bom_item in enumerate(bom_items): + # Get part instance + b_part = bom_item.sub_part + + # Filter supplier parts + manufacturer_parts = ManufacturerPart.objects.filter(part__pk=b_part.pk) + + for idx, manufacturer_part in enumerate(manufacturer_parts): + + if manufacturer_part: + manufacturer_name = manufacturer_part.manufacturer.name + else: + manufacturer_name = '' + + manufacturer_mpn = manufacturer_part.MPN + + # Add manufacturer data to the manufacturer columns + + # Generate column names for this supplier + k_man = manufacturer_headers[0] + "_" + str(idx) + k_mpn = manufacturer_headers[1] + "_" + str(idx) + + try: + manufacturer_cols[k_man].update({b_idx: manufacturer_name}) + manufacturer_cols[k_mpn].update({b_idx: manufacturer_mpn}) + except KeyError: + manufacturer_cols[k_man] = {b_idx: manufacturer_name} + manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn} + + # Add manufacturer columns to dataset + add_columns_to_dataset(manufacturer_cols, len(bom_items)) + + elif supplier_data: + """ + If requested, add extra columns for each SupplierPart associated with each line item + """ + + # Expand dataset with manufacturer parts + manufacturer_headers = [ + _('Supplier'), + _('SKU'), + ] + + manufacturer_cols = {} + + for b_idx, bom_item in enumerate(bom_items): + # Get part instance + b_part = bom_item.sub_part + + # Filter supplier parts + supplier_parts = SupplierPart.objects.filter(part__pk=b_part.pk) + + for idx, supplier_part in enumerate(supplier_parts): + + if supplier_part.supplier: + supplier_name = supplier_part.supplier.name + else: + supplier_name = '' + + supplier_sku = supplier_part.SKU # Add manufacturer data to the manufacturer columns # Generate column names for this supplier 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: manufacturer_cols[k_sup].update({b_idx: supplier_name}) manufacturer_cols[k_sku].update({b_idx: supplier_sku}) - manufacturer_cols[k_man].update({b_idx: manufacturer_name}) - manufacturer_cols[k_mpn].update({b_idx: manufacturer_mpn}) 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 add_columns_to_dataset(manufacturer_cols, len(bom_items)) diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 63cd7b4399..131c6aeac7 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -95,9 +95,11 @@ class BomExportForm(forms.Form): parameter_data = forms.BooleanField(label=_("Include Parameter Data"), required=False, initial=False, help_text=_("Include part parameters data in exported BOM")) stock_data = forms.BooleanField(label=_("Include Stock Data"), required=False, initial=False, help_text=_("Include part stock data in exported BOM")) + + manufacturer_data = forms.BooleanField(label=_("Include Manufacturer Data"), required=False, initial=True, help_text=_("Include part manufacturer data in exported BOM")) supplier_data = forms.BooleanField(label=_("Include Supplier Data"), required=False, initial=True, help_text=_("Include part supplier data in exported BOM")) - + def get_choices(self): """ BOM export format choices """ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 4efff3e9e3..229ae06109 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1845,6 +1845,8 @@ class BomDownload(AjaxView): supplier_data = str2bool(request.GET.get('supplier_data', False)) + manufacturer_data = str2bool(request.GET.get('manufacturer_data', False)) + levels = request.GET.get('levels', None) if levels is not None: @@ -1866,7 +1868,9 @@ class BomDownload(AjaxView): max_levels=levels, parameter_data=parameter_data, stock_data=stock_data, - supplier_data=supplier_data) + supplier_data=supplier_data, + manufacturer_data=manufacturer_data, + ) def get_data(self): return { @@ -1896,6 +1900,7 @@ class BomExport(AjaxView): parameter_data = str2bool(request.POST.get('parameter_data', False)) stock_data = str2bool(request.POST.get('stock_data', False)) supplier_data = str2bool(request.POST.get('supplier_data', False)) + manufacturer_data = str2bool(request.POST.get('manufacturer_data', False)) try: part = Part.objects.get(pk=self.kwargs['pk']) @@ -1913,6 +1918,7 @@ class BomExport(AjaxView): url += '¶meter_data=' + str(parameter_data) url += '&stock_data=' + str(stock_data) url += '&supplier_data=' + str(supplier_data) + url += '&manufacturer_data=' + str(manufacturer_data) if levels: url += '&levels=' + str(levels)