Rename the 'item' key to 'description' in all BOMEntry dicts

This way, both BOM and harness.additional_bom_items uses the same
set of keys in their dict entries. This was originally suggested
in a #115 review, but had too many issues to be implemented then.
This commit is contained in:
KV 2021-01-06 22:53:33 +01:00
parent 8e7c48d42e
commit 30dbd9573b

View File

@ -30,7 +30,7 @@ def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOM
bom_entries = [] bom_entries = []
for part in component.additional_components: for part in component.additional_components:
bom_entries.append({ bom_entries.append({
'item': part.description, 'description': part.description,
'qty': part.qty * component.get_qty_multiplier(part.qty_multiplier), 'qty': part.qty * component.get_qty_multiplier(part.qty_multiplier),
'unit': part.unit, 'unit': part.unit,
'manufacturer': part.manufacturer, 'manufacturer': part.manufacturer,
@ -42,7 +42,7 @@ def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOM
def bom_types_group(entry: BOMEntry) -> Tuple[str, ...]: def bom_types_group(entry: BOMEntry) -> Tuple[str, ...]:
"""Return a tuple of string values from the dict that must be equal to join BOM entries.""" """Return a tuple of string values from the dict that must be equal to join BOM entries."""
return tuple(make_str(entry.get(key)) for key in ('item', 'unit', 'manufacturer', 'mpn', 'pn')) return tuple(make_str(entry.get(key)) for key in ('description', 'unit', 'manufacturer', 'mpn', 'pn'))
def generate_bom(harness: "Harness") -> List[BOMEntry]: def generate_bom(harness: "Harness") -> List[BOMEntry]:
"""Return a list of BOM entries generated from the harness.""" """Return a list of BOM entries generated from the harness."""
@ -57,7 +57,7 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
+ (f', {connector.pincount} pins' if connector.show_pincount else '') + (f', {connector.pincount} pins' if connector.show_pincount else '')
+ (f', {connector.color}' if connector.color else '')) + (f', {connector.color}' if connector.color else ''))
bom_entries.append({ bom_entries.append({
'item': description, 'designators': connector.name if connector.show_name else None, 'description': description, 'designators': connector.name if connector.show_name else None,
'manufacturer': connector.manufacturer, 'mpn': connector.mpn, 'pn': connector.pn 'manufacturer': connector.manufacturer, 'mpn': connector.mpn, 'pn': connector.pn
}) })
@ -65,7 +65,7 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
bom_entries.extend(get_additional_component_bom(connector)) bom_entries.extend(get_additional_component_bom(connector))
# cables # cables
# TODO: If category can have other non-empty values than 'bundle', maybe it should be part of item name? # TODO: If category can have other non-empty values than 'bundle', maybe it should be part of description?
for cable in harness.cables.values(): for cable in harness.cables.values():
if not cable.ignore_in_bom: if not cable.ignore_in_bom:
if cable.category != 'bundle': if cable.category != 'bundle':
@ -76,7 +76,7 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
+ (f' x {cable.gauge} {cable.gauge_unit}' if cable.gauge else ' wires') + (f' x {cable.gauge} {cable.gauge_unit}' if cable.gauge else ' wires')
+ (' shielded' if cable.shield else '')) + (' shielded' if cable.shield else ''))
bom_entries.append({ bom_entries.append({
'item': description, 'qty': cable.length, 'unit': cable.length_unit, 'designators': cable.name if cable.show_name else None, 'description': description, 'qty': cable.length, 'unit': cable.length_unit, 'designators': cable.name if cable.show_name else None,
'manufacturer': cable.manufacturer, 'mpn': cable.mpn, 'pn': cable.pn 'manufacturer': cable.manufacturer, 'mpn': cable.mpn, 'pn': cable.pn
}) })
else: else:
@ -87,7 +87,7 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
+ (f', {cable.gauge} {cable.gauge_unit}' if cable.gauge else '') + (f', {cable.gauge} {cable.gauge_unit}' if cable.gauge else '')
+ (f', {color}' if color else '')) + (f', {color}' if color else ''))
bom_entries.append({ bom_entries.append({
'item': description, 'qty': cable.length, 'unit': cable.length_unit, 'designators': cable.name if cable.show_name else None, 'description': description, 'qty': cable.length, 'unit': cable.length_unit, 'designators': cable.name if cable.show_name else None,
'manufacturer': index_if_list(cable.manufacturer, index), 'manufacturer': index_if_list(cable.manufacturer, index),
'mpn': index_if_list(cable.mpn, index), 'pn': index_if_list(cable.pn, index) 'mpn': index_if_list(cable.mpn, index), 'pn': index_if_list(cable.pn, index)
}) })
@ -95,8 +95,8 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
# add cable/bundles aditional components to bom # add cable/bundles aditional components to bom
bom_entries.extend(get_additional_component_bom(cable)) bom_entries.extend(get_additional_component_bom(cable))
# TODO: Simplify this by renaming the 'item' key to 'description' in all BOMEntry dicts. # add harness aditional components to bom directly, as they both are List[BOMEntry]
bom_entries.extend([{k.replace('description', 'item'): v for k, v in entry.items()} for entry in harness.additional_bom_items]) bom_entries.extend(harness.additional_bom_items)
# remove line breaks if present and cleanup any resulting whitespace issues # remove line breaks if present and cleanup any resulting whitespace issues
bom_entries = [{k: clean_whitespace(v) for k, v in entry.items()} for entry in bom_entries] bom_entries = [{k: clean_whitespace(v) for k, v in entry.items()} for entry in bom_entries]
@ -109,23 +109,24 @@ def generate_bom(harness: "Harness") -> List[BOMEntry]:
total_qty = sum(entry.get('qty', 1) for entry in group_entries) total_qty = sum(entry.get('qty', 1) for entry in group_entries)
bom.append({**group_entries[0], 'qty': round(total_qty, 3), 'designators': sorted(set(designators))}) bom.append({**group_entries[0], 'qty': round(total_qty, 3), 'designators': sorted(set(designators))})
# add an incrementing id to each bom item # add an incrementing id to each bom entry
return [{**entry, 'id': index} for index, entry in enumerate(bom, 1)] return [{**entry, 'id': index} for index, entry in enumerate(bom, 1)]
def get_bom_index(bom: List[BOMEntry], part: AdditionalComponent) -> int: def get_bom_index(bom: List[BOMEntry], part: AdditionalComponent) -> int:
"""Return id of BOM entry or raise StopIteration if not found.""" """Return id of BOM entry or raise StopIteration if not found."""
# Remove linebreaks and clean whitespace of values in search # Remove linebreaks and clean whitespace of values in search
target = tuple(clean_whitespace(v) for v in bom_types_group({**asdict(part), 'item': part.description})) target = tuple(clean_whitespace(v) for v in bom_types_group({**asdict(part), 'description': part.description}))
return next(entry['id'] for entry in bom if bom_types_group(entry) == target) return next(entry['id'] for entry in bom if bom_types_group(entry) == target)
def bom_list(bom: List[BOMEntry]) -> List[List[str]]: def bom_list(bom: List[BOMEntry]) -> List[List[str]]:
"""Return list of BOM rows as lists of column strings with headings in top row.""" """Return list of BOM rows as lists of column strings with headings in top row."""
keys = ['id', 'item', 'qty', 'unit', 'designators'] # these BOM columns will always be included keys = ['id', 'description', 'qty', 'unit', 'designators'] # these BOM columns will always be included
for fieldname in ['pn', 'manufacturer', 'mpn']: # these optional BOM columns will only be included if at least one BOM item actually uses them for fieldname in ['pn', 'manufacturer', 'mpn']: # these optional BOM columns will only be included if at least one BOM entry actually uses them
if any(entry.get(fieldname) for entry in bom): if any(entry.get(fieldname) for entry in bom):
keys.append(fieldname) keys.append(fieldname)
# list of staic bom header names, headers not specified here are generated by capitilising the internal name # list of staic bom header names, headers not specified here are generated by capitilising the internal name
bom_headings = { bom_headings = {
"description": "Item", # TODO: Remove this line to use 'Description' in BOM heading.
"pn": "P/N", "pn": "P/N",
"mpn": "MPN" "mpn": "MPN"
} }