Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement suppliers and supplier part numbers #241

Merged
merged 12 commits into from
Sep 14, 2021
18 changes: 14 additions & 4 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ additional_bom_items: # custom items to add to BOM
# product information (all optional)
ignore_in_bom: <bool> # if set to true the connector is not added to the BOM
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
additional_components: # additional components
- <additional-component> # additional component (see below)

Expand Down Expand Up @@ -173,8 +175,10 @@ Since the auto-incremented and auto-assigned designator is not known to the user
# product information (all optional)
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
additional_components: # additional components
- <additional-component> # additional component (see below)

Expand Down Expand Up @@ -309,8 +313,10 @@ Parts can be added to a connector or cable in the section `<additional-component
# total_length sum of lengths of each wire in the bundle
unit: <str>
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
```

Alternatively items can be added to just the BOM by putting them in the section `<bom-item>` above.
Expand All @@ -323,8 +329,10 @@ Alternatively items can be added to just the BOM by putting them in the section
unit: <str>
designators: <List>
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
```

## Colors
Expand Down Expand Up @@ -402,6 +410,8 @@ The following attributes accept multiline strings:
- `notes`
- `manufacturer`
- `mpn`
- `supplier`
- `spn`
- `image.caption`

### Method 1
Expand Down
8 changes: 7 additions & 1 deletion src/wireviz/DataClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class AdditionalComponent:
subtype: Optional[MultilineHypertext] = None
manufacturer: Optional[MultilineHypertext] = None
mpn: Optional[MultilineHypertext] = None
supplier: Optional[MultilineHypertext] = None
spn: Optional[MultilineHypertext] = None
pn: Optional[Hypertext] = None
qty: float = 1
unit: Optional[str] = None
Expand All @@ -116,6 +118,8 @@ class Connector:
name: Designator
manufacturer: Optional[MultilineHypertext] = None
mpn: Optional[MultilineHypertext] = None
supplier: Optional[MultilineHypertext] = None
spn: Optional[MultilineHypertext] = None
pn: Optional[Hypertext] = None
style: Optional[str] = None
category: Optional[str] = None
Expand Down Expand Up @@ -198,6 +202,8 @@ class Cable:
name: Designator
manufacturer: Union[MultilineHypertext, List[MultilineHypertext], None] = None
mpn: Union[MultilineHypertext, List[MultilineHypertext], None] = None
supplier: Union[MultilineHypertext, List[MultilineHypertext], None] = None
spn: Union[MultilineHypertext, List[MultilineHypertext], None] = None
pn: Union[Hypertext, List[Hypertext], None] = None
category: Optional[str] = None
type: Optional[MultilineHypertext] = None
Expand Down Expand Up @@ -288,7 +294,7 @@ def __post_init__(self) -> None:
raise Exception('"s" may not be used as a wire label for a shielded cable.')

# if lists of part numbers are provided check this is a bundle and that it matches the wirecount.
for idfield in [self.manufacturer, self.mpn, self.pn]:
for idfield in [self.manufacturer, self.mpn, self.supplier, self.spn, self.pn]:
if isinstance(idfield, list):
if self.category == "bundle":
# check the length
Expand Down
29 changes: 20 additions & 9 deletions src/wireviz/Harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
html_caption, remove_links, html_line_breaks
from wireviz.wv_bom import manufacturer_info_field, component_table_entry, \
get_additional_component_table, bom_list, generate_bom
from wireviz.wv_bom import pn_info_string, component_table_entry, \
get_additional_component_table, bom_list, generate_bom, \
HEADER_PN, HEADER_MPN, HEADER_SPN
from wireviz.wv_html import generate_html_output
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
open_file_read, open_file_write
Expand Down Expand Up @@ -124,8 +125,9 @@ def create_graph(self) -> Graph:
html = []

rows = [[remove_links(connector.name) if connector.show_name else None],
[f'P/N: {remove_links(connector.pn)}' if connector.pn else None,
html_line_breaks(manufacturer_info_field(connector.manufacturer, connector.mpn))],
[pn_info_string(HEADER_PN, None, remove_links(connector.pn)),
html_line_breaks(pn_info_string(HEADER_MPN, connector.manufacturer, connector.mpn)),
html_line_breaks(pn_info_string(HEADER_SPN, connector.supplier, connector.spn))],
[html_line_breaks(connector.type),
html_line_breaks(connector.subtype),
f'{connector.pincount}-pin' if connector.show_pincount else None,
Expand Down Expand Up @@ -207,10 +209,14 @@ def create_graph(self) -> Graph:
awg_fmt = f' ({mm2_equiv(cable.gauge)} mm\u00B2)'

rows = [[remove_links(cable.name) if cable.show_name else None],
[f'P/N: {remove_links(cable.pn)}' if (cable.pn and not isinstance(cable.pn, list)) else None,
html_line_breaks(manufacturer_info_field(
[pn_info_string(HEADER_PN, None,
remove_links(cable.pn)) if not isinstance(cable.pn, list) else None,
html_line_breaks(pn_info_string(HEADER_MPN,
cable.manufacturer if not isinstance(cable.manufacturer, list) else None,
cable.mpn if not isinstance(cable.mpn, list) else None))],
cable.mpn if not isinstance(cable.mpn, list) else None)),
html_line_breaks(pn_info_string(HEADER_SPN,
cable.supplier if not isinstance(cable.supplier, list) else None,
cable.spn if not isinstance(cable.spn, list) else None))],
[html_line_breaks(cable.type),
f'{cable.wirecount}x' if cable.show_wirecount else None,
f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else None,
Expand Down Expand Up @@ -262,12 +268,17 @@ def create_graph(self) -> Graph:
# create a list of wire parameters
wireidentification = []
if isinstance(cable.pn, list):
wireidentification.append(f'P/N: {remove_links(cable.pn[i - 1])}')
manufacturer_info = manufacturer_info_field(
wireidentification.append(pn_info_string(HEADER_PN, None, remove_links(cable.pn[i - 1])))
manufacturer_info = pn_info_string(HEADER_MPN,
cable.manufacturer[i - 1] if isinstance(cable.manufacturer, list) else None,
cable.mpn[i - 1] if isinstance(cable.mpn, list) else None)
supplier_info = pn_info_string(HEADER_SPN,
cable.supplier[i - 1] if isinstance(cable.supplier, list) else None,
cable.spn[i - 1] if isinstance(cable.spn, list) else None)
if manufacturer_info:
wireidentification.append(html_line_breaks(manufacturer_info))
if supplier_info:
wireidentification.append(html_line_breaks(supplier_info))
# print parameters into a table row under the wire
if len(wireidentification) > 0 :
wirehtml.append(' <tr><td colspan="3">')
Expand Down
34 changes: 22 additions & 12 deletions src/wireviz/wv_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
from wireviz.wv_helper import clean_whitespace

BOM_COLUMNS_ALWAYS = ('id', 'description', 'qty', 'unit', 'designators')
BOM_COLUMNS_OPTIONAL = ('pn', 'manufacturer', 'mpn')
BOM_COLUMNS_OPTIONAL = ('pn', 'manufacturer', 'mpn', 'supplier', 'spn')
BOM_COLUMNS_IN_KEY = ('description', 'unit') + BOM_COLUMNS_OPTIONAL

HEADER_PN = 'P/N'
HEADER_MPN = 'MPN'
HEADER_SPN = 'SPN'

BOMKey = Tuple[str, ...]
BOMColumn = str # = Literal[*BOM_COLUMNS_ALWAYS, *BOM_COLUMNS_OPTIONAL]
BOMEntry = Dict[BOMColumn, Union[str, int, float, List[str], None]]
Expand Down Expand Up @@ -143,8 +147,9 @@ def bom_list(bom: List[BOMEntry]) -> List[List[str]]:
# Custom mapping from internal name to BOM column headers.
# Headers not specified here are generated by capitilising the internal name.
bom_headings = {
"pn": "P/N",
"mpn": "MPN"
'pn': HEADER_PN,
'mpn': HEADER_MPN,
'spn': HEADER_SPN,
}
return ([[bom_headings.get(k, k.capitalize()) for k in keys]] + # Create header row with key names
[[make_str(entry.get(k)) for k in keys] for entry in bom]) # Create string list for each entry row
Expand All @@ -156,26 +161,31 @@ def component_table_entry(
pn: Optional[str] = None,
manufacturer: Optional[str] = None,
mpn: Optional[str] = None,
supplier: Optional[str] = None,
spn: Optional[str] = None,
) -> str:
"""Return a diagram node table row string with an additional component."""
manufacturer_str = manufacturer_info_field(manufacturer, mpn)
part_number_list = [
pn_info_string(HEADER_PN, None, pn),
pn_info_string(HEADER_MPN, manufacturer, mpn),
pn_info_string(HEADER_SPN, supplier, spn),
]
output = (f'{qty}'
+ (f' {unit}' if unit else '')
+ f' x {type}'
+ ('<br/>' if pn or manufacturer_str else '')
+ (f'P/N: {pn}' if pn else '')
formatc1702 marked this conversation as resolved.
Show resolved Hide resolved
+ (', ' if pn and manufacturer_str else '')
+ (manufacturer_str or ''))
+ ('<br/>' if any(part_number_list) else '')
+ (', '.join([pn for pn in part_number_list if pn])))
# format the above output as left aligned text in a single visible cell
# indent is set to two to match the indent in the generated html table
return f'''<table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
<td align="left" balign="left">{html_line_breaks(output)}</td>
</tr></table>'''

def manufacturer_info_field(manufacturer: Optional[str], mpn: Optional[str]) -> Optional[str]:
"""Return the manufacturer and/or the mpn in one single string or None otherwise."""
if manufacturer or mpn:
return f'{manufacturer if manufacturer else "MPN"}{": " + str(mpn) if mpn else ""}'
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

Expand Down
17 changes: 17 additions & 0 deletions tutorial/tutorial08.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
options:
mini_bom_mode: false

connectors:
X1: &template1 # define a template for later use
type: Molex KK 254
pincount: 4
subtype: female
manufacturer: '<a href="https://www.molex.com/">Molex</a>' # set manufacter name
mpn: '<a href="https://www.molex.com/molex/products/part-detail/crimp_housings/0022013047">22013047</a>' # set manufacturer part number
supplier: Digimouse
spn: 1234
# add a list of additional components to a part (shown in graph)
additional_components:
-
Expand All @@ -13,6 +18,14 @@ connectors:
qty_multiplier: populated # multipier for quantity (number of populated pins)
manufacturer: Molex # set manufacter name
mpn: 08500030 # set manufacturer part number
-
type: Test
qty: 1
pn: ABC
manufacturer: Molex
mpn: 45454
supplier: Mousikey
spn: 9999
X2:
<<: *template1 # reuse template
pn: CON4 # set an internal part number for just this connector
Expand All @@ -27,6 +40,8 @@ cables:
color_code: IEC
manufacturer: CablesCo
mpn: ABC123
supplier: Cables R Us
spn: 999-888-777
pn: CAB1
W2:
category: bundle
Expand All @@ -35,6 +50,8 @@ cables:
colors: [YE, BK, BK, RD]
manufacturer: [WiresCo,WiresCo,WiresCo,WiresCo] # set a manufacter per wire
mpn: [W1-YE,W1-BK,W1-BK,W1-RD]
supplier: [WireShack,WireShack,WireShack,WireShack]
kvid marked this conversation as resolved.
Show resolved Hide resolved
spn: [1001,1002,1002,1009]
pn: [WIRE1,WIRE2,WIRE2,WIRE3]
# add a list of additional components to a part (shown in graph)
additional_components:
Expand Down