Implement suppliers and supplier part numbers (#241)
Co-authored-by: kvid <kvid@users.noreply.github.com>
This commit is contained in:
parent
db05514469
commit
a3eefe6659
@ -102,8 +102,10 @@ tweak: # optional tweaking of .gv output
|
|||||||
# product information (all optional)
|
# product information (all optional)
|
||||||
ignore_in_bom: <bool> # if set to true the connector is not added to the BOM
|
ignore_in_bom: <bool> # if set to true the connector is not added to the BOM
|
||||||
pn: <str> # [internal] part number
|
pn: <str> # [internal] part number
|
||||||
mpn: <str> # manufacturer part number
|
|
||||||
manufacturer: <str> # manufacturer name
|
manufacturer: <str> # manufacturer name
|
||||||
|
mpn: <str> # manufacturer part number
|
||||||
|
supplier: <str> # supplier name
|
||||||
|
spn: <str> # supplier part number
|
||||||
additional_components: # additional components
|
additional_components: # additional components
|
||||||
- <additional-component> # additional component (see below)
|
- <additional-component> # additional component (see below)
|
||||||
|
|
||||||
@ -175,8 +177,10 @@ Since the auto-incremented and auto-assigned designator is not known to the user
|
|||||||
# product information (all optional)
|
# product information (all optional)
|
||||||
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
|
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
|
||||||
pn: <str> # [internal] part number
|
pn: <str> # [internal] part number
|
||||||
mpn: <str> # manufacturer part number
|
|
||||||
manufacturer: <str> # manufacturer name
|
manufacturer: <str> # manufacturer name
|
||||||
|
mpn: <str> # manufacturer part number
|
||||||
|
supplier: <str> # supplier name
|
||||||
|
spn: <str> # supplier part number
|
||||||
additional_components: # additional components
|
additional_components: # additional components
|
||||||
- <additional-component> # additional component (see below)
|
- <additional-component> # additional component (see below)
|
||||||
|
|
||||||
@ -311,8 +315,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
|
# total_length sum of lengths of each wire in the bundle
|
||||||
unit: <str>
|
unit: <str>
|
||||||
pn: <str> # [internal] part number
|
pn: <str> # [internal] part number
|
||||||
mpn: <str> # manufacturer part number
|
|
||||||
manufacturer: <str> # manufacturer name
|
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.
|
Alternatively items can be added to just the BOM by putting them in the section `<bom-item>` above.
|
||||||
@ -325,8 +331,10 @@ Alternatively items can be added to just the BOM by putting them in the section
|
|||||||
unit: <str>
|
unit: <str>
|
||||||
designators: <List>
|
designators: <List>
|
||||||
pn: <str> # [internal] part number
|
pn: <str> # [internal] part number
|
||||||
mpn: <str> # manufacturer part number
|
|
||||||
manufacturer: <str> # manufacturer name
|
manufacturer: <str> # manufacturer name
|
||||||
|
mpn: <str> # manufacturer part number
|
||||||
|
supplier: <str> # supplier name
|
||||||
|
spn: <str> # supplier part number
|
||||||
```
|
```
|
||||||
|
|
||||||
## GraphViz tweaking (experimental)
|
## GraphViz tweaking (experimental)
|
||||||
@ -429,6 +437,8 @@ The following attributes accept multiline strings:
|
|||||||
- `notes`
|
- `notes`
|
||||||
- `manufacturer`
|
- `manufacturer`
|
||||||
- `mpn`
|
- `mpn`
|
||||||
|
- `supplier`
|
||||||
|
- `spn`
|
||||||
- `image.caption`
|
- `image.caption`
|
||||||
- `tweak.append`
|
- `tweak.append`
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,8 @@ class AdditionalComponent:
|
|||||||
subtype: Optional[MultilineHypertext] = None
|
subtype: Optional[MultilineHypertext] = None
|
||||||
manufacturer: Optional[MultilineHypertext] = None
|
manufacturer: Optional[MultilineHypertext] = None
|
||||||
mpn: Optional[MultilineHypertext] = None
|
mpn: Optional[MultilineHypertext] = None
|
||||||
|
supplier: Optional[MultilineHypertext] = None
|
||||||
|
spn: Optional[MultilineHypertext] = None
|
||||||
pn: Optional[Hypertext] = None
|
pn: Optional[Hypertext] = None
|
||||||
qty: float = 1
|
qty: float = 1
|
||||||
unit: Optional[str] = None
|
unit: Optional[str] = None
|
||||||
@ -122,6 +124,8 @@ class Connector:
|
|||||||
name: Designator
|
name: Designator
|
||||||
manufacturer: Optional[MultilineHypertext] = None
|
manufacturer: Optional[MultilineHypertext] = None
|
||||||
mpn: Optional[MultilineHypertext] = None
|
mpn: Optional[MultilineHypertext] = None
|
||||||
|
supplier: Optional[MultilineHypertext] = None
|
||||||
|
spn: Optional[MultilineHypertext] = None
|
||||||
pn: Optional[Hypertext] = None
|
pn: Optional[Hypertext] = None
|
||||||
style: Optional[str] = None
|
style: Optional[str] = None
|
||||||
category: Optional[str] = None
|
category: Optional[str] = None
|
||||||
@ -204,6 +208,8 @@ class Cable:
|
|||||||
name: Designator
|
name: Designator
|
||||||
manufacturer: Union[MultilineHypertext, List[MultilineHypertext], None] = None
|
manufacturer: Union[MultilineHypertext, List[MultilineHypertext], None] = None
|
||||||
mpn: 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
|
pn: Union[Hypertext, List[Hypertext], None] = None
|
||||||
category: Optional[str] = None
|
category: Optional[str] = None
|
||||||
type: Optional[MultilineHypertext] = None
|
type: Optional[MultilineHypertext] = None
|
||||||
@ -294,7 +300,7 @@ class Cable:
|
|||||||
raise Exception('"s" may not be used as a wire label for a shielded cable.')
|
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.
|
# 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 isinstance(idfield, list):
|
||||||
if self.category == "bundle":
|
if self.category == "bundle":
|
||||||
# check the length
|
# check the length
|
||||||
|
|||||||
@ -14,8 +14,9 @@ from wireviz.DataClasses import Metadata, Options, Tweak, Connector, Cable
|
|||||||
from wireviz.wv_colors import get_color_hex, translate_color
|
from wireviz.wv_colors import get_color_hex, translate_color
|
||||||
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
|
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
|
||||||
html_caption, remove_links, html_line_breaks
|
html_caption, remove_links, html_line_breaks
|
||||||
from wireviz.wv_bom import manufacturer_info_field, component_table_entry, \
|
from wireviz.wv_bom import pn_info_string, component_table_entry, \
|
||||||
get_additional_component_table, bom_list, generate_bom
|
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_html import generate_html_output
|
||||||
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
|
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
|
||||||
open_file_read, open_file_write
|
open_file_read, open_file_write
|
||||||
@ -125,8 +126,9 @@ class Harness:
|
|||||||
html = []
|
html = []
|
||||||
|
|
||||||
rows = [[remove_links(connector.name) if connector.show_name else None],
|
rows = [[remove_links(connector.name) if connector.show_name else None],
|
||||||
[f'P/N: {remove_links(connector.pn)}' if connector.pn else None,
|
[pn_info_string(HEADER_PN, None, remove_links(connector.pn)),
|
||||||
html_line_breaks(manufacturer_info_field(connector.manufacturer, connector.mpn))],
|
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.type),
|
||||||
html_line_breaks(connector.subtype),
|
html_line_breaks(connector.subtype),
|
||||||
f'{connector.pincount}-pin' if connector.show_pincount else None,
|
f'{connector.pincount}-pin' if connector.show_pincount else None,
|
||||||
@ -208,10 +210,14 @@ class Harness:
|
|||||||
awg_fmt = f' ({mm2_equiv(cable.gauge)} mm\u00B2)'
|
awg_fmt = f' ({mm2_equiv(cable.gauge)} mm\u00B2)'
|
||||||
|
|
||||||
rows = [[remove_links(cable.name) if cable.show_name else None],
|
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,
|
[pn_info_string(HEADER_PN, None,
|
||||||
html_line_breaks(manufacturer_info_field(
|
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.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),
|
[html_line_breaks(cable.type),
|
||||||
f'{cable.wirecount}x' if cable.show_wirecount else None,
|
f'{cable.wirecount}x' if cable.show_wirecount else None,
|
||||||
f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else None,
|
f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else None,
|
||||||
@ -263,12 +269,17 @@ class Harness:
|
|||||||
# create a list of wire parameters
|
# create a list of wire parameters
|
||||||
wireidentification = []
|
wireidentification = []
|
||||||
if isinstance(cable.pn, list):
|
if isinstance(cable.pn, list):
|
||||||
wireidentification.append(f'P/N: {remove_links(cable.pn[i - 1])}')
|
wireidentification.append(pn_info_string(HEADER_PN, None, remove_links(cable.pn[i - 1])))
|
||||||
manufacturer_info = manufacturer_info_field(
|
manufacturer_info = pn_info_string(HEADER_MPN,
|
||||||
cable.manufacturer[i - 1] if isinstance(cable.manufacturer, list) else None,
|
cable.manufacturer[i - 1] if isinstance(cable.manufacturer, list) else None,
|
||||||
cable.mpn[i - 1] if isinstance(cable.mpn, 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:
|
if manufacturer_info:
|
||||||
wireidentification.append(html_line_breaks(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
|
# print parameters into a table row under the wire
|
||||||
if len(wireidentification) > 0 :
|
if len(wireidentification) > 0 :
|
||||||
wirehtml.append(' <tr><td colspan="3">')
|
wirehtml.append(' <tr><td colspan="3">')
|
||||||
|
|||||||
@ -11,9 +11,13 @@ from wireviz.wv_gv_html import html_line_breaks
|
|||||||
from wireviz.wv_helper import clean_whitespace
|
from wireviz.wv_helper import clean_whitespace
|
||||||
|
|
||||||
BOM_COLUMNS_ALWAYS = ('id', 'description', 'qty', 'unit', 'designators')
|
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
|
BOM_COLUMNS_IN_KEY = ('description', 'unit') + BOM_COLUMNS_OPTIONAL
|
||||||
|
|
||||||
|
HEADER_PN = 'P/N'
|
||||||
|
HEADER_MPN = 'MPN'
|
||||||
|
HEADER_SPN = 'SPN'
|
||||||
|
|
||||||
BOMKey = Tuple[str, ...]
|
BOMKey = Tuple[str, ...]
|
||||||
BOMColumn = str # = Literal[*BOM_COLUMNS_ALWAYS, *BOM_COLUMNS_OPTIONAL]
|
BOMColumn = str # = Literal[*BOM_COLUMNS_ALWAYS, *BOM_COLUMNS_OPTIONAL]
|
||||||
BOMEntry = Dict[BOMColumn, Union[str, int, float, List[str], None]]
|
BOMEntry = Dict[BOMColumn, Union[str, int, float, List[str], None]]
|
||||||
@ -143,8 +147,9 @@ def bom_list(bom: List[BOMEntry]) -> List[List[str]]:
|
|||||||
# Custom mapping from internal name to BOM column headers.
|
# Custom mapping from internal name to BOM column headers.
|
||||||
# Headers not specified here are generated by capitilising the internal name.
|
# Headers not specified here are generated by capitilising the internal name.
|
||||||
bom_headings = {
|
bom_headings = {
|
||||||
"pn": "P/N",
|
'pn': HEADER_PN,
|
||||||
"mpn": "MPN"
|
'mpn': HEADER_MPN,
|
||||||
|
'spn': HEADER_SPN,
|
||||||
}
|
}
|
||||||
return ([[bom_headings.get(k, k.capitalize()) for k in keys]] + # Create header row with key names
|
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
|
[[make_str(entry.get(k)) for k in keys] for entry in bom]) # Create string list for each entry row
|
||||||
@ -156,26 +161,31 @@ def component_table_entry(
|
|||||||
pn: Optional[str] = None,
|
pn: Optional[str] = None,
|
||||||
manufacturer: Optional[str] = None,
|
manufacturer: Optional[str] = None,
|
||||||
mpn: Optional[str] = None,
|
mpn: Optional[str] = None,
|
||||||
|
supplier: Optional[str] = None,
|
||||||
|
spn: Optional[str] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Return a diagram node table row string with an additional component."""
|
"""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}'
|
output = (f'{qty}'
|
||||||
+ (f' {unit}' if unit else '')
|
+ (f' {unit}' if unit else '')
|
||||||
+ f' x {type}'
|
+ f' x {type}'
|
||||||
+ ('<br/>' if pn or manufacturer_str else '')
|
+ ('<br/>' if any(part_number_list) else '')
|
||||||
+ (f'P/N: {pn}' if pn else '')
|
+ (', '.join([pn for pn in part_number_list if pn])))
|
||||||
+ (', ' if pn and manufacturer_str else '')
|
|
||||||
+ (manufacturer_str or ''))
|
|
||||||
# format the above output as left aligned text in a single visible cell
|
# 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
|
# 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>
|
return f'''<table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
|
||||||
<td align="left" balign="left">{html_line_breaks(output)}</td>
|
<td align="left" balign="left">{html_line_breaks(output)}</td>
|
||||||
</tr></table>'''
|
</tr></table>'''
|
||||||
|
|
||||||
def manufacturer_info_field(manufacturer: Optional[str], mpn: Optional[str]) -> Optional[str]:
|
def pn_info_string(header: str, name: Optional[str], number: Optional[str]) -> Optional[str]:
|
||||||
"""Return the manufacturer and/or the mpn in one single string or None otherwise."""
|
"""Return the company name and/or the part number in one single string or None otherwise."""
|
||||||
if manufacturer or mpn:
|
number = str(number).strip() if number is not None else ''
|
||||||
return f'{manufacturer if manufacturer else "MPN"}{": " + str(mpn) if mpn else ""}'
|
if name or number:
|
||||||
|
return f'{name if name else header}{": " + number if number else ""}'
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
options:
|
||||||
|
mini_bom_mode: false
|
||||||
|
|
||||||
connectors:
|
connectors:
|
||||||
X1: &template1 # define a template for later use
|
X1: &template1 # define a template for later use
|
||||||
type: Molex KK 254
|
type: Molex KK 254
|
||||||
@ -5,6 +8,8 @@ connectors:
|
|||||||
subtype: female
|
subtype: female
|
||||||
manufacturer: '<a href="https://www.molex.com/">Molex</a>' # set manufacter name
|
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
|
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)
|
# add a list of additional components to a part (shown in graph)
|
||||||
additional_components:
|
additional_components:
|
||||||
-
|
-
|
||||||
@ -13,6 +18,14 @@ connectors:
|
|||||||
qty_multiplier: populated # multipier for quantity (number of populated pins)
|
qty_multiplier: populated # multipier for quantity (number of populated pins)
|
||||||
manufacturer: Molex # set manufacter name
|
manufacturer: Molex # set manufacter name
|
||||||
mpn: 08500030 # set manufacturer part number
|
mpn: 08500030 # set manufacturer part number
|
||||||
|
-
|
||||||
|
type: Test
|
||||||
|
qty: 1
|
||||||
|
pn: ABC
|
||||||
|
manufacturer: Molex
|
||||||
|
mpn: 45454
|
||||||
|
supplier: Mousikey
|
||||||
|
spn: 9999
|
||||||
X2:
|
X2:
|
||||||
<<: *template1 # reuse template
|
<<: *template1 # reuse template
|
||||||
pn: CON4 # set an internal part number for just this connector
|
pn: CON4 # set an internal part number for just this connector
|
||||||
@ -27,6 +40,8 @@ cables:
|
|||||||
color_code: IEC
|
color_code: IEC
|
||||||
manufacturer: CablesCo
|
manufacturer: CablesCo
|
||||||
mpn: ABC123
|
mpn: ABC123
|
||||||
|
supplier: Cables R Us
|
||||||
|
spn: 999-888-777
|
||||||
pn: CAB1
|
pn: CAB1
|
||||||
W2:
|
W2:
|
||||||
category: bundle
|
category: bundle
|
||||||
@ -35,6 +50,8 @@ cables:
|
|||||||
colors: [YE, BK, BK, RD]
|
colors: [YE, BK, BK, RD]
|
||||||
manufacturer: [WiresCo,WiresCo,WiresCo,WiresCo] # set a manufacter per wire
|
manufacturer: [WiresCo,WiresCo,WiresCo,WiresCo] # set a manufacter per wire
|
||||||
mpn: [W1-YE,W1-BK,W1-BK,W1-RD]
|
mpn: [W1-YE,W1-BK,W1-BK,W1-RD]
|
||||||
|
supplier: [WireShack,WireShack,WireShack,WireShack]
|
||||||
|
spn: [1001,1002,1002,1009]
|
||||||
pn: [WIRE1,WIRE2,WIRE2,WIRE3]
|
pn: [WIRE1,WIRE2,WIRE2,WIRE3]
|
||||||
# add a list of additional components to a part (shown in graph)
|
# add a list of additional components to a part (shown in graph)
|
||||||
additional_components:
|
additional_components:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user