diff options
Diffstat (limited to 'src/ee/order')
-rw-r--r-- | src/ee/order/__init__.py | 115 | ||||
-rw-r--r-- | src/ee/order/templates/order.rst.j2 | 28 |
2 files changed, 74 insertions, 69 deletions
diff --git a/src/ee/order/__init__.py b/src/ee/order/__init__.py index a384cb7..83723ba 100644 --- a/src/ee/order/__init__.py +++ b/src/ee/order/__init__.py @@ -4,111 +4,104 @@ from typing import List, Tuple from ee import EeException from ee.db import ObjDb -from ee.part import PartDb, load_db, save_db -from ee.project import Project, report -from ee.xml import types, bom_file_utils +from ee.part import PartDb, load_db, save_db, Part +from ee.project import Project, report, SupplierDescriptor +from ee.xml import types __all__ = ["create_order"] class OrderPart(object): def __init__(self, part: types.Part): - self.part = part - self.ref = next((ref.referenceProp for ref in bom_file_utils.schematic_references(part)), None) + self.part = Part(part) + ref = self.part.get_only_schematic_reference() + self.ref = ref.referenceProp if ref else None self.available_from: List[Tuple[str, types.Part]] = [] - self.selected_supplier_and_part = None + self.selected_part = None - rl = part.referencesProp = part.referencesProp or types.ReferencesList() # type: types.ReferencesList - rl.schematic_referenceProp = rl.schematic_referenceProp or [] - rl.part_numberProp = rl.part_numberProp or [] - rl.supplier_part_numberProp = rl.supplier_part_numberProp or [] - - -def make_report(out_file, order_parts: ObjDb[OrderPart], has_unresolved_parts): - parts_by_supplier = {} - - for supplier, order_parts in order_parts.index("selected_part").items(): - parts = {} - for op in order_parts: - p = op.selected_supplier_and_part[1] - parts[p.uriProp] = p - parts_by_supplier[supplier] = parts.values() +def make_report(out_file, has_unresolved_parts, order_parts: ObjDb[OrderPart], supplier_parts: ObjDb[Path]): kwargs = { "order_parts": order_parts, - "parts_by_supplier": parts_by_supplier, + "supplier_parts": supplier_parts, "has_unresolved_parts": has_unresolved_parts, } report.save_report("ee.order", "order.rst.j2", out_file, **kwargs) -def create_order(project: Project, schematic_path: Path, out_path: Path, part_db_dirs: List[Path], +def create_order(project: Project, schematic_path: Path, out_path: Path, part_dbs: List[Path], fail_on_missing_parts: bool): - sch_db = load_db(schematic_path) - - dbs = [(path.parent.name, load_db(path)) for path in part_db_dirs] - - def supplier_index(op: OrderPart): - return [spn.supplierProp for spn in bom_file_utils.supplier_part_numbers(op.part)] - - def selected_part_index(op: OrderPart): - return [op.selected_supplier_and_part[0]] if op.selected_supplier_and_part else None - - def available_from_index(op: OrderPart): - return set([s for s, s_part in op.available_from]) - - def supplier_part_index(op: OrderPart): - return set([s_part.uriProp for s, s_part in op.available_from]) - - def pn_index(op: OrderPart): - return [pn.value for pn in bom_file_utils.part_numbers(op.part)] + supplier_parts = ObjDb[Part]() + supplier_parts.add_unique_index("uri", lambda p: p.uri) + supplier_parts.add_index("spn", lambda p: [ref.valueProp for ref in p.get_spns()], + multiple=True) + supplier_pn_idx = supplier_parts.add_multi_index("supplier,pn", lambda p: [ + (p.supplier, ref.valueProp) for ref in p.get_mpns()], multiple=True) + supplier_spn_idx = supplier_parts.add_multi_index("supplier,spn", lambda p: [ + (p.supplier, ref.valueProp) for ref in p.get_spns()], multiple=True) + + suppliers: List[SupplierDescriptor] = [project.get_supplier_by_key(path.parent.name) for path in part_dbs] + for path in part_dbs: + for xml in load_db(path).iterparts(): + if not xml.supplierProp: + continue + supplier_parts.add(Part(xml)) + sch_db = load_db(schematic_path) order_parts: ObjDb[OrderPart] = ObjDb[OrderPart]() + order_parts.add_multi_index("supplier,pn", lambda op: [ + (op.part.supplierProp, ref.valueProp) for ref in + op.part.get_mpns()] if op.part.supplier else None, multiple=True) + order_parts.add_multi_index("supplier,spn", lambda op: [ + (op.part.supplier, ref.valueProp) for ref in op.part.get_spns()], multiple=True) + for sch_part in sch_db.iterparts(): order_parts.add(OrderPart(sch_part)) for order_part in order_parts: - sch_part_numbers = order_part.part.referencesProp.part_number - sch_supplier_part_numbers: List[types.SupplierPartNumber] = order_part.part.referencesProp.supplier_part_number + sch_part_numbers = [pn.valueProp for pn in order_part.part.get_mpns()] + sch_supplier_part_numbers = [spn.valueProp for spn in order_part.part.get_spns()] - for supplier, db in dbs: - for supplier_part in db.iterparts(sort=True): - for sch_pn in sch_part_numbers: - for pn in bom_file_utils.part_numbers(supplier_part): - if sch_pn.valueProp == pn.valueProp: - order_part.available_from.append((supplier, supplier_part)) + for supplier in suppliers: + pns = supplier_pn_idx.get(supplier.uri) + spns = supplier_spn_idx.get(supplier.uri) - for sch_spn in sch_supplier_part_numbers: - for spn in bom_file_utils.supplier_part_numbers(supplier_part): - if sch_spn.valueProp == spn.valueProp and sch_spn.supplierProp == spn.supplierProp: - order_part.available_from.append((supplier, supplier_part)) + for sch_pn in sch_part_numbers: + for supplier_part in pns.get(sch_pn, []): + order_part.available_from.append((supplier.uri, supplier_part)) + for sch_spn in sch_supplier_part_numbers: + for supplier_part in spns.get(sch_spn, []): + order_part.available_from.append((supplier.uri, supplier_part)) has_unresolved_parts = False for order_part in order_parts: if len(order_part.available_from) == 0: has_unresolved_parts = True elif len(order_part.available_from) == 1: - order_part.selected_supplier_and_part = order_part.available_from[0] + order_part.selected_part = order_part.available_from[0] else: raise EeException("unimplemented: part available from multiple suppliers") + order_parts.add_index("partUri", lambda op: op.selected_part[1].uri if op.selected_part else None) + order_parts.add_multi_index("supplier,part", lambda op: ( + op.selected_part[0], op.selected_part[1].uri) if op.selected_part else None) + if has_unresolved_parts and fail_on_missing_parts: raise EeException("The order has parts that can't be found from any supplier") - order_parts.add_index("selected_part", selected_part_index) - out_file = project.report_dir / (os.path.splitext(out_path.name)[0] + ".rst") - make_report(out_file, order_parts, has_unresolved_parts) + make_report(out_file, has_unresolved_parts, order_parts, supplier_parts) out_parts = PartDb() for order_part in order_parts: - if not order_part.selected_supplier_and_part: + if not order_part.selected_part: continue - supplier, supplier_part = order_part.selected_supplier_and_part + supplier, supplier_part = order_part.selected_part - references = types.ReferencesList(schematic_reference=order_part.part.referencesProp.schematic_reference) - part = types.Part(uri=supplier_part.uri, references=references) + part = Part(types.Part(supplier=supplier_part.supplier)) + part.add_schematic_reference(order_part.part.get_exactly_one_schematic_reference().referenceProp) + part.add_part_reference(supplier_part.uri) out_parts.add_entry(part, True) diff --git a/src/ee/order/templates/order.rst.j2 b/src/ee/order/templates/order.rst.j2 index bc382a2..8dad217 100644 --- a/src/ee/order/templates/order.rst.j2 +++ b/src/ee/order/templates/order.rst.j2 @@ -1,3 +1,4 @@ +{% set order_part_uri_idx = order_parts.index("partUri") -%} Order ===== @@ -6,6 +7,8 @@ Has unresolved parts: {{ "yes" if has_unresolved_parts else "no" }}. Parts for Order =============== {% for op in order_parts %} +.. _ref-{{ op.ref }}: + {{ op.ref | subsection }} {% if op.available_from|length == 0 %} Part not resolved. @@ -23,30 +26,39 @@ MANY Part details ============ -{% for supplier, parts in parts_by_supplier.items() %} +{%- set part_by_uri=supplier_parts.index("uri") %} +{% for supplier, partUris in order_parts.index("supplier,part").items() %} {{ ("From " + supplier) | subsection }} -{% for part in parts %} +{% for partUri in partUris %} +{%- set part=part_by_uri.get_single(partUri) %} {%- set pn=part|first_pn %} {%- set spn=part|first_spn %} {%- set title=pn.valueProp if pn else (spn.valueProp if spn else "???") %} -{%- set links=part.linksProp.link %} .. _part-{{title}}: {{ title|subsubsection }} -{#- +=========== === +{%- if part.description %} +Description {{ part.description }} +{%- endif %} +MPN {{ pn.value }} +SPN {{ spn.value }} +Used by: {% for op in order_part_uri_idx.get(part.uriProp) %}`{{ op.ref }} <ref-{{ op.ref }}_>`_{{ ", " if not loop.last }}{% endfor %} +=========== === +{# Facts ..... {% for f in part.facts.fact %} f={{f}} {% endfor %} -#} -Media -..... +#} +Documentation +............. -{% for l in links %} +{% for l in part.get_links() %} {%- if l.relationProp == "http://purl.org/ee/link-relation#documentation" %} * `{{ l.title }} <{{ l.url }}>`__ {%- endif %} |