WireViz/src/wireviz/wv_bom.py
2021-10-21 22:07:30 +02:00

58 lines
1.7 KiB
Python

# -*- coding: utf-8 -*-
from collections import namedtuple
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional, Union
from wireviz.wv_helper import html_line_breaks
BOM_HASH_FIELDS = "description unit partnumbers"
BomHash = namedtuple("BomHash", BOM_HASH_FIELDS)
BomHashList = namedtuple("BomHashList", BOM_HASH_FIELDS)
BomCategory = Enum(
"BomEntry", "CONNECTOR CABLE WIRE ADDITIONAL_INSIDE ADDITIONAL_OUTSIDE"
)
PartNumberInfo = namedtuple("PartNumberInfo", "pn manufacturer mpn supplier spn")
PART_NUMBER_HEADERS = PartNumberInfo(
pn="P/N", manufacturer=None, mpn="MPN", supplier=None, spn="SPN"
)
@dataclass
class BomEntry:
hash: BomHash # includes description, part number info,
description: str
qty: Union[int, float]
unit: str
designators: List[str]
_category: BomCategory # for sorting
def partnumbers_to_list(partnumbers: PartNumberInfo) -> List[str]:
cell_contents = [
pn_info_string(PART_NUMBER_HEADERS.pn, None, partnumbers.pn),
pn_info_string(
PART_NUMBER_HEADERS.mpn, partnumbers.manufacturer, partnumbers.mpn
),
pn_info_string(PART_NUMBER_HEADERS.spn, partnumbers.supplier, partnumbers.spn),
]
if any(cell_contents):
return [html_line_breaks(cell) for cell in cell_contents]
else:
return None
def pn_info_string(
header: str, name: Optional[str], number: Optional[str]
) -> Optional[str]:
"""Return the company name and/or the part number in one single string or None otherwise."""
number = str(number).strip() if number is not None else ""
if name or number:
return f'{name if name else header}{": " + number if number else ""}'
else:
return None