mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #919 from eeintech/bom_export_parameter_stock
BoM export: added option to export part parameters (#126) and stocks (#793)
This commit is contained in:
commit
60c6d6d33e
@ -7,6 +7,8 @@ from rapidfuzz import fuzz
|
|||||||
import tablib
|
import tablib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ def MakeBomTemplate(fmt):
|
|||||||
return DownloadFile(data, filename)
|
return DownloadFile(data, filename)
|
||||||
|
|
||||||
|
|
||||||
def ExportBom(part, fmt='csv', cascade=False, max_levels=None, supplier_data=False):
|
def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=False, stock_data=False, 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,9 +94,75 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, supplier_data=Fal
|
|||||||
|
|
||||||
dataset = BomItemResource().export(queryset=bom_items, cascade=cascade)
|
dataset = BomItemResource().export(queryset=bom_items, cascade=cascade)
|
||||||
|
|
||||||
|
def add_columns_to_dataset(columns, column_size):
|
||||||
|
try:
|
||||||
|
for header, column_dict in columns.items():
|
||||||
|
# Construct column tuple
|
||||||
|
col = tuple(column_dict.get(c_idx, '') for c_idx in range(column_size))
|
||||||
|
# Add column to dataset
|
||||||
|
dataset.append_col(col, header=header)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if parameter_data:
|
||||||
|
"""
|
||||||
|
If requested, add extra columns for each PartParameter associated with each line item
|
||||||
|
"""
|
||||||
|
|
||||||
|
parameter_cols = {}
|
||||||
|
|
||||||
|
for b_idx, bom_item in enumerate(bom_items):
|
||||||
|
# Get part parameters
|
||||||
|
parameters = bom_item.sub_part.get_parameters()
|
||||||
|
# Add parameters to columns
|
||||||
|
if parameters:
|
||||||
|
for parameter in parameters:
|
||||||
|
name = parameter.template.name
|
||||||
|
value = parameter.data
|
||||||
|
|
||||||
|
try:
|
||||||
|
parameter_cols[name].update({b_idx: value})
|
||||||
|
except KeyError:
|
||||||
|
parameter_cols[name] = {b_idx: value}
|
||||||
|
|
||||||
|
# Add parameter columns to dataset
|
||||||
|
parameter_cols_ordered = OrderedDict(sorted(parameter_cols.items(), key=lambda x: x[0]))
|
||||||
|
add_columns_to_dataset(parameter_cols_ordered, len(bom_items))
|
||||||
|
|
||||||
|
if stock_data:
|
||||||
|
"""
|
||||||
|
If requested, add extra columns for stock data associated with each line item
|
||||||
|
"""
|
||||||
|
|
||||||
|
stock_headers = [
|
||||||
|
_('Default Location'),
|
||||||
|
_('Available Stock'),
|
||||||
|
]
|
||||||
|
|
||||||
|
stock_cols = {}
|
||||||
|
|
||||||
|
for b_idx, bom_item in enumerate(bom_items):
|
||||||
|
stock_data = []
|
||||||
|
# Get part default location
|
||||||
|
try:
|
||||||
|
stock_data.append(bom_item.sub_part.get_default_location().name)
|
||||||
|
except AttributeError:
|
||||||
|
stock_data.append('')
|
||||||
|
# Get part current stock
|
||||||
|
stock_data.append(bom_item.sub_part.available_stock)
|
||||||
|
|
||||||
|
for s_idx, header in enumerate(stock_headers):
|
||||||
|
try:
|
||||||
|
stock_cols[header].update({b_idx: stock_data[s_idx]})
|
||||||
|
except KeyError:
|
||||||
|
stock_cols[header] = {b_idx: stock_data[s_idx]}
|
||||||
|
|
||||||
|
# Add stock columns to dataset
|
||||||
|
add_columns_to_dataset(stock_cols, len(bom_items))
|
||||||
|
|
||||||
if supplier_data:
|
if supplier_data:
|
||||||
"""
|
"""
|
||||||
If requested, add extra columns for each SupplierPart associated with the each line item
|
If requested, add extra columns for each SupplierPart associated with each line item
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Expand dataset with manufacturer parts
|
# Expand dataset with manufacturer parts
|
||||||
@ -150,11 +218,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, supplier_data=Fal
|
|||||||
manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn}
|
manufacturer_cols[k_mpn] = {b_idx: manufacturer_mpn}
|
||||||
|
|
||||||
# Add manufacturer columns to dataset
|
# Add manufacturer columns to dataset
|
||||||
for header, col_dict in manufacturer_cols.items():
|
add_columns_to_dataset(manufacturer_cols, len(bom_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)
|
||||||
|
|
||||||
|
@ -58,7 +58,11 @@ class BomExportForm(forms.Form):
|
|||||||
|
|
||||||
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"))
|
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"))
|
||||||
|
|
||||||
|
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):
|
def get_choices(self):
|
||||||
""" BOM export format choices """
|
""" BOM export format choices """
|
||||||
|
@ -1499,6 +1499,10 @@ class BomDownload(AjaxView):
|
|||||||
|
|
||||||
cascade = str2bool(request.GET.get('cascade', False))
|
cascade = str2bool(request.GET.get('cascade', False))
|
||||||
|
|
||||||
|
parameter_data = str2bool(request.GET.get('parameter_data', False))
|
||||||
|
|
||||||
|
stock_data = str2bool(request.GET.get('stock_data', False))
|
||||||
|
|
||||||
supplier_data = str2bool(request.GET.get('supplier_data', False))
|
supplier_data = str2bool(request.GET.get('supplier_data', False))
|
||||||
|
|
||||||
levels = request.GET.get('levels', None)
|
levels = request.GET.get('levels', None)
|
||||||
@ -1516,7 +1520,13 @@ 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, supplier_data=supplier_data)
|
return ExportBom(part,
|
||||||
|
fmt=export_format,
|
||||||
|
cascade=cascade,
|
||||||
|
max_levels=levels,
|
||||||
|
parameter_data=parameter_data,
|
||||||
|
stock_data=stock_data,
|
||||||
|
supplier_data=supplier_data)
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {
|
return {
|
||||||
@ -1541,6 +1551,8 @@ 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)
|
||||||
|
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))
|
supplier_data = str2bool(request.POST.get('supplier_data', False))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1556,6 +1568,8 @@ class BomExport(AjaxView):
|
|||||||
|
|
||||||
url += '?file_format=' + fmt
|
url += '?file_format=' + fmt
|
||||||
url += '&cascade=' + str(cascade)
|
url += '&cascade=' + str(cascade)
|
||||||
|
url += '¶meter_data=' + str(parameter_data)
|
||||||
|
url += '&stock_data=' + str(stock_data)
|
||||||
url += '&supplier_data=' + str(supplier_data)
|
url += '&supplier_data=' + str(supplier_data)
|
||||||
|
|
||||||
if levels:
|
if levels:
|
||||||
|
Loading…
Reference in New Issue
Block a user