From 237a6faa8a23826e68bbc00bc107b2d6f97235d0 Mon Sep 17 00:00:00 2001
From: Trygve Laugstøl <trygvis@inamo.no>
Date: Fri, 15 Mar 2019 14:55:15 +0100
Subject: Refactoring: o Renaming part.id to part.uri. Changing to URIs and use
 that as an   identifier if the part is known. Schematic part does not have an
 URI. o Merging <schema-reference> and <part-numbers> into <references> o
 Creating <part-uri> as a possible <reference>. Used by order to point   to
 other parts.

---
 src/ee/order/__init__.py | 81 ++++++++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 34 deletions(-)

(limited to 'src/ee/order')

diff --git a/src/ee/order/__init__.py b/src/ee/order/__init__.py
index 5350667..56d233f 100644
--- a/src/ee/order/__init__.py
+++ b/src/ee/order/__init__.py
@@ -2,6 +2,7 @@ from functools import total_ordering
 from pathlib import Path
 from typing import List, Tuple
 
+from ee import EeException
 from ee.part import PartDb, load_db, save_db
 from ee.xml import types, bom_file_utils
 
@@ -12,12 +13,17 @@ __all__ = ["create_order"]
 class PartInfo(object):
     def __init__(self, part: types.Part):
         self.part = part
-        self.id = part.id
-        self.pn = bom_file_utils.find_pn(part)
+        self.ref = next((ref.referenceProp for ref in bom_file_utils.schematic_references(part)), None)
+        self.pn = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None)
         self.available_from: List[Tuple[str, types.Part]] = []
 
+        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 __lt__(self, other: "PartInfo"):
-        return self.part.idProp == other.part.idProp
+        return self.ref == other.ref
 
 
 def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path], fail_on_missing_parts: bool):
@@ -30,28 +36,41 @@ def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path],
     infos = [PartInfo(sch) for sch in sch_db.iterparts()]
 
     for info in infos:
-        print("Resolving {}".format(info.id))
-
-        for distributor, db in dbs:
-            for p in db.iterparts(sort=True):
-                if info.pn:
-                    p_pn: str = bom_file_utils.find_pn(p)
-
-                    if info.pn == p_pn:
-                        info.available_from.append((distributor, p))
-
-                for sch_pn_ in bom_file_utils.part_numbers(info.part):
-                    sch_pn: types.PartNumber = sch_pn_
-
-                    for p_pn_ in bom_file_utils.part_numbers(p):
-                        p_pn: types.PartNumber = p_pn_
-
-                        if sch_pn.distributorProp == p_pn.distributorProp and sch_pn.value == p_pn.value:
-                            if p.idProp not in info.available_from:
-                                info.available_from.append((distributor, p))
+        print("Resolving {}".format(info.ref))
+
+        sch_part_numbers = info.part.referencesProp.part_number
+        sch_supplier_part_numbers: List[types.SupplierPartNumber] = info.part.referencesProp.supplier_part_number
+
+        for supplier, db in dbs:
+            for supplier_part in db.iterparts(sort=True):
+                found = None
+                for sch_pn in sch_part_numbers:
+                    for pn in bom_file_utils.part_numbers(supplier_part):
+                        if sch_pn.valueProp == pn.valueProp:
+                            found = supplier_part
+                            break
+                    if found:
+                        break
+
+                if found:
+                    info.available_from.append((supplier, found))
+                    break
+
+                found = None
+                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:
+                            found = supplier_part
+                            break
+                    if found:
+                        break
+
+                if found:
+                    info.available_from.append((supplier, found))
+                    break
 
     for info in infos:
-        print("Resolved {} to {}".format(info.id, info.available_from))
+        print("Resolved {} to {}".format(info.ref, info.available_from))
 
     warnings = []
     has_missing_parts = False
@@ -59,28 +78,22 @@ def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path],
         if len(info.available_from) == 0:
             has_missing_parts = True
             warnings.append("Could not find {} in any database, part numbers: {}".
-                            format(info.id, ", ".join([p.value for p in bom_file_utils.part_numbers(info.part)])))
+                            format(info.ref, ", ".join([p.value for p in bom_file_utils.part_numbers(info.part)])))
 
     for w in sorted(warnings):
         print(w)
 
     if has_missing_parts and fail_on_missing_parts:
-        print("has missing parts")
-        return False
+        raise EeException("The order has parts that can't be found from any supplier")
 
     for info in infos:
-        part = types.Part(id=info.part.id,
-                            schema_reference=info.part.schema_reference,
-                            part_numbers=types.PartNumberList())
-
-        part_numbers = part.part_numbersProp.part_number
-
         if len(info.available_from) == 0:
             continue
 
-        distributor, distributor_part = info.available_from[0]
+        supplier, supplier_part = info.available_from[0]
 
-        part_numbers.append(types.PartNumber(value=distributor_part.id, distributor=distributor))
+        references = types.ReferencesList(schematic_reference=info.part.referencesProp.schematic_reference)
+        part = types.Part(uri=supplier_part.uri, references=references)
 
         out_parts.add_entry(part, True)
 
-- 
cgit v1.2.3