From 2f695ace2ebd2c5ebeb421a93e07695ba460cf70 Mon Sep 17 00:00:00 2001
From: Trygve Laugstøl <trygvis@inamo.no>
Date: Thu, 28 Mar 2019 19:10:29 +0100
Subject: create-order: o Showing all unresolved parts first in the report. o
 Showing all MPNs and SPNs for unresolved parts.

---
 src/ee/order/__init__.py            | 38 ++++++++++++++++++-------------------
 src/ee/order/templates/order.rst.j2 | 34 +++++++++++++++++++++++++++------
 2 files changed, 47 insertions(+), 25 deletions(-)

(limited to 'src/ee/order')

diff --git a/src/ee/order/__init__.py b/src/ee/order/__init__.py
index 83723ba..fc112d1 100644
--- a/src/ee/order/__init__.py
+++ b/src/ee/order/__init__.py
@@ -1,6 +1,6 @@
 import os.path
 from pathlib import Path
-from typing import List, Tuple
+from typing import List, MutableMapping
 
 from ee import EeException
 from ee.db import ObjDb
@@ -16,15 +16,15 @@ class OrderPart(object):
         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.available_from: MutableMapping[str, Part] = {}
         self.selected_part = None
 
 
-def make_report(out_file, has_unresolved_parts, order_parts: ObjDb[OrderPart], supplier_parts: ObjDb[Path]):
+def make_report(out_file, unresolved_parts, order_parts: ObjDb[OrderPart], supplier_parts: ObjDb[Path]):
     kwargs = {
         "order_parts": order_parts,
         "supplier_parts": supplier_parts,
-        "has_unresolved_parts": has_unresolved_parts,
+        "unresolved_parts": unresolved_parts,
     }
     report.save_report("ee.order", "order.rst.j2", out_file, **kwargs)
 
@@ -52,8 +52,6 @@ def create_order(project: Project, schematic_path: Path, out_path: Path, part_db
     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))
@@ -68,36 +66,38 @@ def create_order(project: Project, schematic_path: Path, out_path: Path, part_db
 
             for sch_pn in sch_part_numbers:
                 for supplier_part in pns.get(sch_pn, []):
-                    order_part.available_from.append((supplier.uri, supplier_part))
+                    order_part.available_from[supplier_part.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))
+                    order_part.available_from[supplier_part.uri] = supplier_part
 
-    has_unresolved_parts = False
+    unresolved_parts = []
     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_part = order_part.available_from[0]
+        af = order_part.available_from
+        if len(af) == 0:
+            unresolved_parts.append(order_part)
+        elif len(af) == 1:
+            order_part.selected_part = next(iter(af.values()))
         else:
-            raise EeException("unimplemented: part available from multiple suppliers")
+            raise EeException("unimplemented: part ({}) available from multiple suppliers: {}".
+                              format(order_part.ref, ",".join(af.keys())))
 
-    order_parts.add_index("partUri", lambda op: op.selected_part[1].uri if op.selected_part else None)
+    order_parts.add_index("uri", lambda op: op.selected_part.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)
+        op.selected_part.supplier, op.selected_part.uri) if op.selected_part else None)
 
-    if has_unresolved_parts and fail_on_missing_parts:
+    if len(unresolved_parts) and fail_on_missing_parts:
         raise EeException("The order has parts that can't be found from any supplier")
 
     out_file = project.report_dir / (os.path.splitext(out_path.name)[0] + ".rst")
-    make_report(out_file, has_unresolved_parts, order_parts, supplier_parts)
+    make_report(out_file, unresolved_parts, order_parts, supplier_parts)
 
     out_parts = PartDb()
     for order_part in order_parts:
         if not order_part.selected_part:
             continue
 
-        supplier, supplier_part = order_part.selected_part
+        supplier_part = order_part.selected_part
 
         part = Part(types.Part(supplier=supplier_part.supplier))
         part.add_schematic_reference(order_part.part.get_exactly_one_schematic_reference().referenceProp)
diff --git a/src/ee/order/templates/order.rst.j2 b/src/ee/order/templates/order.rst.j2
index 8dad217..b46600c 100644
--- a/src/ee/order/templates/order.rst.j2
+++ b/src/ee/order/templates/order.rst.j2
@@ -1,8 +1,13 @@
-{% set order_part_uri_idx = order_parts.index("partUri") -%}
+{% set order_part_uri_idx = order_parts.index("uri") -%}
 Order
 =====
 
-Has unresolved parts: {{ "yes" if has_unresolved_parts else "no" }}.
+{% if unresolved_parts %}
+Unresolved parts:
+{% for op in unresolved_parts %}
+* `{{ op.ref }} <ref-{{ op.ref }}_>`_
+{%- endfor %}
+{%- endif %}
 
 Parts for Order
 ===============
@@ -11,13 +16,30 @@ Parts for Order
 
 {{ op.ref | subsection }}
 {% if op.available_from|length == 0 %}
-Part not resolved.
+Could not find part.
+
+{% if op.part.get_mpns()|length == 1 -%}
+MPN: {{ op.part.get_mpns()[0].valueProp }}
+{% elif op.part.get_mpns()|length > 1 -%}
+{%- for mpn in op.part.get_mpns() %}
+MPNs:
+* {{ mpn.valueProp }}
+{%- endfor %}
+{%- endif -%}
+{% if op.part.get_spns()|length == 1 -%}
+SPN: {{ op.part.get_spns()[0].valueProp }}
+{% elif op.part.get_spns()|length > 1 -%}
+{%- for spn in op.part.get_spns() %}
+SPNs:
+* {{ spn.valueProp }}
+{%- endfor %}
+{%- endif -%}
+
 {% elif op.available_from|length == 1 %}
-{%- set from=op.available_from[0] %}
-{%- set part=from[1] %}
+{%- set part=op.available_from.values()|first %}
 {%- set pn=part|first_pn %}
 {%- set spn=part|first_spn %}
-Selected supplier: {{ from[0] }}{{ (", pn: " + pn.valueProp) if pn else "" }}{{ (", spn: " + spn.valueProp) if spn else "" }}.
+Selected supplier: {{ part.supplier }}{{ (", pn: " + pn.valueProp) if pn else "" }}{{ (", spn: " + spn.valueProp) if spn else "" }}.
 Part: `{{pn.valueProp}} <part-{{pn.valueProp}}_>`_
 {% else %}
 MANY
-- 
cgit v1.2.3