aboutsummaryrefslogtreecommitdiff
path: root/src/ee/order
diff options
context:
space:
mode:
Diffstat (limited to 'src/ee/order')
-rw-r--r--src/ee/order/__init__.py115
-rw-r--r--src/ee/order/templates/order.rst.j228
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 %}