In 'manage_configs.py' Klasse 'SivasAssemblyData' in 'SivasBOM' und Klasse 'TeilestammMetadata' in 'SivasTeilestamm' umbenannt, da eindeutiger. In 'controller.py' Namen entsprechend aktualisiert. Zudem in 'manage_configs.py' Klasse 'SivasBOM' die Methode 'asm_data' in 'bom_data' umbenannt. Darüber hinaus gibt die Methode nun ein leeres Dict zurück, wenn keine JSON vorliegt oder keine generiert werden konnte. Dies wurde vorgesehen, um im Migrationsüberblick (Treeview) sowie dem Migrationstool (CreoMigrate) auch Teilenummern ohne Stückliste, d.h. ohne JSON abbilden zu können (genaue Funktionsweise siehe mehrzeiliger Kommentar in genannter Methode). Abgesehen davon Methode 'property_names' komplett entfernt, da diese fehlerhaft funktioniert hat, da jedes Mal durch alle Kinder der Assembly geloopt wurde und die Eigenschaften des aktuellen Kindes wie z.B. 'Bezeichnung', 'Parent', etc. ausgelesen wurden. Der Fehler liegt darin, dass die Eigenschaften der Nummer aus der vorherigen Iteration komplett überschrieben, aber nicht ergänzt wurden, falls in der aktuellen Iteration Eigenschaften vorliegen, die in der vorherigen noch nicht vorlagen. Um dieses Problem ganz zu umgehen, wurden die Methoden 'get_prop_val_for_all_ids' und 'all_bom_properties' umgeschrieben, sodass die Eigenschaften direkt innerhalb dieser Funktionen geholt werden
This commit is contained in:
+2
-2
@@ -2,7 +2,7 @@ import os
|
|||||||
from tkinter import messagebox
|
from tkinter import messagebox
|
||||||
import update_database
|
import update_database
|
||||||
|
|
||||||
from manage_configs import SivasAssemblyData, RuleDesignerDatabaseConfig, MigrationStatus
|
from manage_configs import SivasBOM, RuleDesignerDatabaseConfig, MigrationStatus
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Contains the logic for the MVC of CreoMigrate Gui
|
Contains the logic for the MVC of CreoMigrate Gui
|
||||||
@@ -120,7 +120,7 @@ class Controller(Observer):
|
|||||||
data_dir = self.get_env("data")
|
data_dir = self.get_env("data")
|
||||||
rd_dbase_filename = self.get_env("rd_dbase_filename")
|
rd_dbase_filename = self.get_env("rd_dbase_filename")
|
||||||
|
|
||||||
asm_data = SivasAssemblyData(data_dir, asm_id + '.json', load_local_asm_json)
|
asm_data = SivasBOM(data_dir, asm_id + '.json', load_local_asm_json)
|
||||||
rd_data = RuleDesignerDatabaseConfig(data_dir, rd_dbase_filename, load_local_rd_dbase)
|
rd_data = RuleDesignerDatabaseConfig(data_dir, rd_dbase_filename, load_local_rd_dbase)
|
||||||
migration_status = MigrationStatus(asm_data.child_ids, rd_data.ids)
|
migration_status = MigrationStatus(asm_data.child_ids, rd_data.ids)
|
||||||
|
|
||||||
|
|||||||
+72
-71
@@ -19,12 +19,9 @@ class JsonBasedConfig:
|
|||||||
|
|
||||||
def load_json_from_file(self):
|
def load_json_from_file(self):
|
||||||
"""lade das json file vom gegeben Pfad in ein json Objekt"""
|
"""lade das json file vom gegeben Pfad in ein json Objekt"""
|
||||||
try:
|
with open(self._config_path, 'r', encoding='utf-8') as fh:
|
||||||
with open(self._config_path, 'r', encoding='utf-8') as fh:
|
content = fh.read()
|
||||||
content = fh.read()
|
return json.loads(content)
|
||||||
return json.loads(content)
|
|
||||||
except FileNotFoundError:
|
|
||||||
raise ValueError("Bitte prüfen, ob korrekte Teilenummer, bzw. korrekter Dateiname angegeben wurde.")
|
|
||||||
|
|
||||||
def from_json(self, json_str):
|
def from_json(self, json_str):
|
||||||
"""nimm den Json String zur Initialisierung des Objektes"""
|
"""nimm den Json String zur Initialisierung des Objektes"""
|
||||||
@@ -99,45 +96,63 @@ class RuleDesignerSQLData(SQLBasedConfig):
|
|||||||
return self._rd_statuses
|
return self._rd_statuses
|
||||||
|
|
||||||
|
|
||||||
class SivasAssemblyData(JsonBasedConfig):
|
class SivasBOM(JsonBasedConfig):
|
||||||
"""Auslesen der Assembly-Informationen zu einer angegebenen Baugruppennummer"""
|
"""Auslesen der Assembly-Informationen zu einer angegebenen Baugruppennummer"""
|
||||||
|
|
||||||
def __init__(self, config_dir: str, config_file: str, load_local_json=False):
|
def __init__(self, config_dir: str, config_file: str, load_local_json=False):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
self._load_local_json = load_local_json
|
self._load_local_json = load_local_json
|
||||||
self._asm_data = None
|
self._bom_data = None
|
||||||
self._child_ids = None
|
self._child_ids = None
|
||||||
self._parent_children = None
|
self._parent_children = None
|
||||||
self._longest_child_id = None
|
self._longest_child_id = None
|
||||||
self._max_bom_depth = None
|
self._max_bom_depth = None
|
||||||
self._property_names = None
|
|
||||||
self._all_bom_properties = None
|
self._all_bom_properties = None
|
||||||
|
|
||||||
def create_asm_json(self):
|
def create_asm_json(self) -> bool:
|
||||||
"""Erstellt JSON mit den aktuellen Baugruppeninformationen"""
|
"""Erstellt JSON mit den aktuellen Baugruppeninformationen"""
|
||||||
try:
|
|
||||||
update_database.get_sivas_bom(self._config_file.removesuffix(".json"))
|
update_database.get_sivas_bom(self._config_file.removesuffix(".json"))
|
||||||
except:
|
|
||||||
raise ValueError("JSON-Datei mit Baugruppeninformationen konnte nicht erstellt werden!")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def asm_data(self) -> dict:
|
def bom_data(self) -> dict:
|
||||||
"""Liest die Baugruppen-JSON ein und gibt deren Informationen zurück"""
|
""" Liest die JSON-Datei der Baugruppenstückliste ein und speichert die Informationen als dict. """
|
||||||
if self._asm_data is None:
|
|
||||||
|
if self._bom_data is None:
|
||||||
|
|
||||||
|
"""
|
||||||
|
Falls die JSON nicht existiert oder nicht generiert werden kann, soll die Möglichkeit bestehen,
|
||||||
|
diese eigenständig zu erweitern, da in der JSON z.B. die Nummer der obersten Baugruppe standardmäßig
|
||||||
|
nicht vorliegt. Generierungs- und Einlese-Fehler werden daher bewusst ignoriert, um stattdessen ein leeres
|
||||||
|
dict zurückzugeben, das anschließend erweitert werden kann.
|
||||||
|
|
||||||
|
Die Möglichkeit zur Erweiterung der Stückliste ermöglicht es zudem, Teilenummern ohne Stückliste abzubilden.
|
||||||
|
Das funktioniert, indem man die Teilenummer ohne eigene Stückliste als Kind einer fiktiven Baugruppe "None"
|
||||||
|
ansieht / definiert. Dadurch ist keine separate Logik erforderlich, die sich nur mit Teilenummern
|
||||||
|
ohne Stückliste befasst.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._bom_data = {}
|
||||||
|
|
||||||
if not self._load_local_json:
|
if not self._load_local_json:
|
||||||
self.create_asm_json()
|
try:
|
||||||
|
self.create_asm_json()
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self._bom_data = self.load_json_from_file()
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
self._asm_data = self.load_json_from_file()
|
return self._bom_data
|
||||||
|
|
||||||
return self._asm_data
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def child_ids(self) -> set:
|
def child_ids(self) -> set:
|
||||||
"""Gibt alle Teilenummern der Stückliste zurück (auch Teilenummern aus tieferen Baugruppenebenen)"""
|
"""Gibt alle Teilenummern der Stückliste zurück (auch Teilenummern aus tieferen Baugruppenebenen)"""
|
||||||
|
|
||||||
if self._child_ids is None:
|
if self._child_ids is None:
|
||||||
self._child_ids = set(self.asm_data.keys())
|
self._child_ids = set(self.bom_data.keys())
|
||||||
return self._child_ids
|
return self._child_ids
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -147,7 +162,7 @@ class SivasAssemblyData(JsonBasedConfig):
|
|||||||
if self._parent_children is None:
|
if self._parent_children is None:
|
||||||
unordered_parent_children = {}
|
unordered_parent_children = {}
|
||||||
|
|
||||||
for child_id, parent_properties in self.asm_data.items():
|
for child_id, parent_properties in self.bom_data.items():
|
||||||
for parent_property in parent_properties:
|
for parent_property in parent_properties:
|
||||||
parent_id = parent_property["Parent"]
|
parent_id = parent_property["Parent"]
|
||||||
child_posnr_in_parent_bom = int(parent_property["Position"].lstrip(".").split("/")[0])
|
child_posnr_in_parent_bom = int(parent_property["Position"].lstrip(".").split("/")[0])
|
||||||
@@ -180,20 +195,11 @@ class SivasAssemblyData(JsonBasedConfig):
|
|||||||
]
|
]
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
|
if id not in self.bom_data:
|
||||||
|
self._bom_data[id] = []
|
||||||
|
|
||||||
property_names = self.property_names
|
self._bom_data[id].append(metadata)
|
||||||
|
return self._bom_data
|
||||||
asm_data = self.asm_data
|
|
||||||
|
|
||||||
if id not in asm_data:
|
|
||||||
self._asm_data[id] = []
|
|
||||||
|
|
||||||
for property_name in property_names:
|
|
||||||
if property_name not in metadata:
|
|
||||||
metadata[property_name] = None
|
|
||||||
|
|
||||||
self._asm_data[id].append(metadata)
|
|
||||||
return self._asm_data
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def longest_child_id(self) -> str:
|
def longest_child_id(self) -> str:
|
||||||
@@ -209,44 +215,32 @@ class SivasAssemblyData(JsonBasedConfig):
|
|||||||
|
|
||||||
if self._max_bom_depth is None:
|
if self._max_bom_depth is None:
|
||||||
bom_levels = []
|
bom_levels = []
|
||||||
for parents in self.asm_data.values():
|
for parents in self.bom_data.values():
|
||||||
for parent in parents:
|
for parent in parents:
|
||||||
current_bom_level = parent["Position"].count(".")
|
current_bom_level = parent["Position"].count(".")
|
||||||
bom_levels.append(current_bom_level)
|
bom_levels.append(current_bom_level)
|
||||||
self._max_bom_depth = max(bom_levels)
|
self._max_bom_depth = max(bom_levels)
|
||||||
return self._max_bom_depth
|
return self._max_bom_depth
|
||||||
|
|
||||||
@property
|
|
||||||
def property_names(self) -> list:
|
|
||||||
"""Gibt alle Eigenschaftsnamen zurück, die in der Assembly-json-Datei enthalten sind"""
|
|
||||||
|
|
||||||
if self._property_names is None:
|
|
||||||
for parent_data in self.asm_data.values():
|
|
||||||
self._property_names = list(parent_data[0])
|
|
||||||
return self._property_names
|
|
||||||
|
|
||||||
def get_prop_val_for_single_id(self, id:str, property_name:str) -> str:
|
def get_prop_val_for_single_id(self, id:str, property_name:str) -> str:
|
||||||
"""Gibt eine Eigenschaft von einer einzelnen Teilenummer aus der Stückliste zurück"""
|
"""Gibt eine Eigenschaft von einer einzelnen Teilenummer aus der Stückliste zurück"""
|
||||||
|
|
||||||
if id not in self._asm_data:
|
if id not in self._bom_data:
|
||||||
raise KeyError("Angegebene Teilenummer befindet sich nicht in der Baugruppe!")
|
raise ValueError("Teilenummer befindet sich nicht in der Baugruppe!")
|
||||||
|
|
||||||
if property_name not in self._asm_data[id][0]:
|
if property_name not in self._bom_data[id][0]:
|
||||||
raise ValueError(f"Teilenummer besitzt nicht die angegebene Eigenschaft '{property_name}'")
|
return
|
||||||
|
|
||||||
return self._asm_data[id][0][property_name]
|
return self._bom_data[id][0][property_name]
|
||||||
|
|
||||||
def get_prop_val_for_all_ids(self, property_name) -> dict:
|
def get_prop_val_for_all_ids(self, property_name) -> dict:
|
||||||
"""Gibt eine Eigenschaft zu allen Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
"""Gibt eine Eigenschaft zu allen Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
||||||
|
|
||||||
if property_name not in self.property_names:
|
|
||||||
raise ValueError("Angegebener Eigenschaftsname exisitert nicht!")
|
|
||||||
|
|
||||||
id_property_mapping = {}
|
id_property_mapping = {}
|
||||||
for child, parent_data in self.asm_data.items():
|
for child_id, asm_usages in self.bom_data.items():
|
||||||
for properties in parent_data:
|
child_properties = asm_usages[0]
|
||||||
if property_name in properties:
|
id_property_mapping[child_id] = None if property_name not in child_properties else child_properties[property_name]
|
||||||
id_property_mapping[child] = properties[property_name]
|
|
||||||
return id_property_mapping
|
return id_property_mapping
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -254,9 +248,16 @@ class SivasAssemblyData(JsonBasedConfig):
|
|||||||
"""Gibt alle Eigenschaften zu den Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
"""Gibt alle Eigenschaften zu den Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
||||||
|
|
||||||
if self._all_bom_properties is None:
|
if self._all_bom_properties is None:
|
||||||
|
|
||||||
self._all_bom_properties = {}
|
self._all_bom_properties = {}
|
||||||
for property_name in self.property_names:
|
|
||||||
self._all_bom_properties[property_name] = self.get_prop_val_for_all_ids(property_name)
|
for child_id, asm_usages in self.bom_data.items():
|
||||||
|
child_properties = asm_usages[0]
|
||||||
|
for property_name, property_val in child_properties.items():
|
||||||
|
if property_name not in self._all_bom_properties:
|
||||||
|
self._all_bom_properties[property_name] = {}
|
||||||
|
self._all_bom_properties[property_name][child_id] = property_val
|
||||||
|
|
||||||
return self._all_bom_properties
|
return self._all_bom_properties
|
||||||
|
|
||||||
|
|
||||||
@@ -338,34 +339,34 @@ class MigrationStatus:
|
|||||||
return self._ids_pending
|
return self._ids_pending
|
||||||
|
|
||||||
|
|
||||||
class TeilestammMetadata(CSVBasedConfig):
|
class SivasTeilestamm(CSVBasedConfig):
|
||||||
def __init__(self, config_dir, config_file, load_local_csv=False):
|
def __init__(self, config_dir, config_file, load_local_csv=False):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
self._load_local_csv = load_local_csv
|
self._load_local_csv = load_local_csv
|
||||||
self._csv_data = None
|
self._data = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_csvs(ids):
|
def create_csvs(ids):
|
||||||
"""Erstellt CSV-Datei(en) mit den Teilestamminformationen zu der / den angegebenen Teilenummer(n)"""
|
"""Erstellt CSV-Datei(en) mit den Teilestamminformationen zu der / den angegebenen Teilenummer(n)"""
|
||||||
try:
|
|
||||||
update_database.get_sivas_teilestamm(ids)
|
update_database.get_sivas_teilestamm(ids)
|
||||||
except:
|
|
||||||
raise ValueError("CSV(s) konnte nicht generiert werden!")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def csv_data(self):
|
def teilestamm_data(self):
|
||||||
"""Gibt CSV-Daten als Dataframe zurück"""
|
"""Gibt CSV-Daten als Dataframe zurück"""
|
||||||
if self._csv_data is None:
|
|
||||||
|
if self._data is None:
|
||||||
|
|
||||||
if not self._load_local_csv:
|
if not self._load_local_csv:
|
||||||
self.create_csvs(self._config_file.removesuffix(".csv"))
|
self.create_csvs(self._config_file.removesuffix(".csv"))
|
||||||
|
|
||||||
self._csv_data = self.load_csv_from_file()
|
self._data = self.load_csv_from_file()
|
||||||
return self._csv_data
|
|
||||||
|
return self._data
|
||||||
|
|
||||||
def get_property_values(self, property_name) -> str:
|
def get_property_values(self, property_name) -> str:
|
||||||
"""Gibt Wert aus der CSV für den angegebenen Spaltennamen zurück"""
|
"""Gibt Wert aus der CSV für den angegebenen Spaltennamen zurück"""
|
||||||
ret = self.csv_data[property_name][0]
|
ret = self.teilestamm_data[property_name][0]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user