Klasse 'BOMConfig' sowie Methoden in Klasse 'SivasBOM' ergänzt, damit Teilenummern aus der Stücklistenstruktur herausgefiltert werden können. Aktuell ist es so festgelegt, dass wenn ein User ausgeschlossene Teilenummern an die Klasse 'SivasBOM' übergibt, diese dann auch automatisch aus der Stückliste ausgeschlossen werden, d.h. zum Ausschließen der der Nummern ist kein expliziter Aufruf der Methode '_remove_excluded_ids_from_bom' erforderlich. Hierbei gilt die Prämisse: Wenn Du ausgeschlossene Nummern angibst, möchtest Du sie auch nicht sehen. Weiso hättest Du sie sonst anggegeben?
This commit is contained in:
+109
-11
@@ -99,9 +99,19 @@ class RuleDesignerSQLData(SQLBasedConfig):
|
|||||||
class SivasBOM(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,
|
||||||
|
asm_id,
|
||||||
|
config_dir: str,
|
||||||
|
config_file: str,
|
||||||
|
load_local_json=False,
|
||||||
|
excluded_ids: list=None):
|
||||||
|
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
|
self.main_id = asm_id
|
||||||
self._load_local_json = load_local_json
|
self._load_local_json = load_local_json
|
||||||
|
self.excluded_ids_by_user = excluded_ids
|
||||||
|
self._excluded_ids_in_bom = None
|
||||||
self._bom_data = None
|
self._bom_data = None
|
||||||
self._child_ids = None
|
self._child_ids = None
|
||||||
self._parent_children = None
|
self._parent_children = None
|
||||||
@@ -112,6 +122,7 @@ class SivasBOM(JsonBasedConfig):
|
|||||||
def create_asm_json(self) -> bool:
|
def create_asm_json(self) -> bool:
|
||||||
"""Erstellt JSON mit den aktuellen Baugruppeninformationen"""
|
"""Erstellt JSON mit den aktuellen Baugruppeninformationen"""
|
||||||
|
|
||||||
|
if not self._load_local_json:
|
||||||
update_database.get_sivas_bom(self._config_file.removesuffix(".json"))
|
update_database.get_sivas_bom(self._config_file.removesuffix(".json"))
|
||||||
|
|
||||||
|
|
||||||
@@ -135,16 +146,19 @@ class SivasBOM(JsonBasedConfig):
|
|||||||
|
|
||||||
self._bom_data = {}
|
self._bom_data = {}
|
||||||
|
|
||||||
if not self._load_local_json:
|
|
||||||
try:
|
try:
|
||||||
self.create_asm_json()
|
self.create_asm_json()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._bom_data = self.load_json_from_file()
|
self._bom_data = self.load_json_from_file()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if self.excluded_ids_by_user is not None:
|
||||||
|
self._remove_excluded_ids_from_bom()
|
||||||
|
|
||||||
return self._bom_data
|
return self._bom_data
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -201,13 +215,81 @@ class SivasBOM(JsonBasedConfig):
|
|||||||
self._bom_data[id].append(metadata)
|
self._bom_data[id].append(metadata)
|
||||||
return self._bom_data
|
return self._bom_data
|
||||||
|
|
||||||
|
def _remove_excluded_ids_from_bom(self) -> None:
|
||||||
|
"""Entfernt ID's aus den Stücklistendaten, die nicht enthalten sein sollen"""
|
||||||
|
|
||||||
|
# Ausgeschlossene Teilenummern, die vom User angegeben wurden, können nicht einfach aus der Stückliste entfernt werden.
|
||||||
|
# Sie müssen zunächst aufbereiten werden, denn:
|
||||||
|
# - Ausgeschlossene Nummern, die kein Bestandteil der aktuellen Baugruppe sind, sind nicht von Interesse
|
||||||
|
# - Kinder von ausgeschlossenen Teilenummern, die vom User nicht angegeben wurden sind ggf. von Interesse, müssen aber zunächst
|
||||||
|
# ermittelt werden
|
||||||
|
|
||||||
|
ids_to_remove = self.excluded_ids_in_bom
|
||||||
|
|
||||||
|
if not ids_to_remove:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.main_id in ids_to_remove:
|
||||||
|
raise ValueError(f"Haupt-Teilenummer '{self.main_id}' darf nicht ausgeschlossen sein. Bitte $CREMIG_CFG/BOM-Settings.cfg -> Sektion 'ExcludedPartnumbersInBOM' prüfen, falls diese Datei zur Definition der ausgeschlossenen Teilenummern verwendet wurde")
|
||||||
|
|
||||||
|
filtered_bom_data = {}
|
||||||
|
for id, usages in self.bom_data.items():
|
||||||
|
|
||||||
|
if id in ids_to_remove:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for properties in usages:
|
||||||
|
|
||||||
|
if properties["Parent"] in ids_to_remove:
|
||||||
|
continue
|
||||||
|
if id not in filtered_bom_data:
|
||||||
|
filtered_bom_data[id] = []
|
||||||
|
|
||||||
|
filtered_bom_data[id].append(properties)
|
||||||
|
|
||||||
|
self._bom_data = filtered_bom_data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def excluded_ids_in_bom(self) -> list:
|
||||||
|
|
||||||
|
""" Gibt alle Teilenummern zurück, die in der SIVAS-Stückliste vorliegen, aber davon ausgeschlossen sein sollen. """
|
||||||
|
|
||||||
|
if self._excluded_ids_in_bom is None:
|
||||||
|
|
||||||
|
excluded_ids_by_user = self.excluded_ids_by_user
|
||||||
|
|
||||||
|
to_remove = {}
|
||||||
|
for id, usages in self.bom_data.items():
|
||||||
|
|
||||||
|
# Teilenummern zunächst als ausgeschlossen anzusehen und das später zu widerrufen erleichtert die Definition der Logik
|
||||||
|
to_remove[id] = True
|
||||||
|
|
||||||
|
# Teilenummern, die vom User ausgeschlossen wurden, aber kein Bestandteil dieser Baugruppe sind, interessieren uns nicht!
|
||||||
|
if id in excluded_ids_by_user:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Kinder von ausgeschlossenen Teilenummern werden ebenfalls als ausgeschlossen betrachtet, außer sie sind Kinder von
|
||||||
|
# weiteren Teilenummern, die nicht augeschlossen sein sollen
|
||||||
|
# Hinweis:
|
||||||
|
# Für die Prüfung, ob das Kind in weiteren Teilenummern verbaut ist, würde sich die Methode "parent_children" anbieten.
|
||||||
|
# Die ist aber Lazy, sprich, wenn wir die jetzt aufrufen, arbeitet sie mit den Stücklistendaten, vor dem die Teilenummern
|
||||||
|
# entfernt wurden. Die Laziness dafür zu entfernen macht aber auch keinen Sinn, weil diese Methode bei der Erstellung von
|
||||||
|
# baumförmigen Migrationsübersichten ständig aufgerufen wird, d.h. die Performance würde darunter stark leiden!
|
||||||
|
|
||||||
|
for properties in usages:
|
||||||
|
if properties["Parent"] not in excluded_ids_by_user:
|
||||||
|
to_remove[id] = False
|
||||||
|
|
||||||
|
self._excluded_ids_in_bom = list(filter(lambda id: to_remove[id] is True, to_remove))
|
||||||
|
return self._excluded_ids_in_bom
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def longest_child_id(self) -> str:
|
def longest_child_id(self) -> str:
|
||||||
"""Gibt die längste Teilenummer von allen Stücklistenpositionen zurück"""
|
"""Gibt die längste Teilenummer von allen Stücklistenpositionen zurück"""
|
||||||
|
|
||||||
if self._longest_child_id is None:
|
if self._longest_child_id is None:
|
||||||
self._longest_child_id = max(self.child_ids)
|
self._longest_child_id = max(self.child_ids)
|
||||||
return max(self.child_ids)
|
return self._longest_child_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max_bom_depth(self) -> int:
|
def max_bom_depth(self) -> int:
|
||||||
@@ -225,13 +307,13 @@ class SivasBOM(JsonBasedConfig):
|
|||||||
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._bom_data:
|
if id not in self.bom_data:
|
||||||
raise ValueError("Teilenummer befindet sich nicht in der Baugruppe!")
|
raise ValueError("Teilenummer befindet sich nicht in der Baugruppe!")
|
||||||
|
|
||||||
if property_name not in self._bom_data[id][0]:
|
if property_name not in self.bom_data[id][0]:
|
||||||
return
|
return
|
||||||
|
|
||||||
return self._bom_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)"""
|
||||||
@@ -345,10 +427,10 @@ class SivasTeilestamm(CSVBasedConfig):
|
|||||||
self._load_local_csv = load_local_csv
|
self._load_local_csv = load_local_csv
|
||||||
self._data = None
|
self._data = None
|
||||||
|
|
||||||
@staticmethod
|
def create_csvs(self, 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)"""
|
||||||
|
|
||||||
|
if not self._load_local_csv:
|
||||||
update_database.get_sivas_teilestamm(ids)
|
update_database.get_sivas_teilestamm(ids)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -356,10 +438,7 @@ class SivasTeilestamm(CSVBasedConfig):
|
|||||||
"""Gibt CSV-Daten als Dataframe zurück"""
|
"""Gibt CSV-Daten als Dataframe zurück"""
|
||||||
|
|
||||||
if self._data is None:
|
if self._data is None:
|
||||||
|
|
||||||
if not self._load_local_csv:
|
|
||||||
self.create_csvs(self._config_file.removesuffix(".csv"))
|
self.create_csvs(self._config_file.removesuffix(".csv"))
|
||||||
|
|
||||||
self._data = self.load_csv_from_file()
|
self._data = self.load_csv_from_file()
|
||||||
|
|
||||||
return self._data
|
return self._data
|
||||||
@@ -687,6 +766,24 @@ class GuiConfig(IniBasedConfig):
|
|||||||
config_file=spezific_file
|
config_file=spezific_file
|
||||||
super().__init__(config_dir, config_file=config_file)
|
super().__init__(config_dir, config_file=config_file)
|
||||||
|
|
||||||
|
class BOMConfig(IniBasedConfig):
|
||||||
|
def __init__(self, config_dir=os.environ.get("CREMIG_CFG"), config_file="BOM-Settings.cfg"):
|
||||||
|
self._config_dir = config_dir
|
||||||
|
self.config_file = config_file
|
||||||
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config_dir(self):
|
||||||
|
return self._config_dir
|
||||||
|
|
||||||
|
@config_dir.setter
|
||||||
|
def config_dir(self, directory):
|
||||||
|
if not os.path.isdir(directory):
|
||||||
|
raise ValueError("Verzeichnis existiert nicht!")
|
||||||
|
self._config_dir = directory
|
||||||
|
|
||||||
|
def get_excluded_ids(self, section_name:str="ExcludedPartnumbersInBOM") -> tuple:
|
||||||
|
return tuple(self.get_section_options(section_name))
|
||||||
|
|
||||||
class Configs:
|
class Configs:
|
||||||
"""Sammlung aller Configdateien """
|
"""Sammlung aller Configdateien """
|
||||||
@@ -707,6 +804,7 @@ class Configs:
|
|||||||
|
|
||||||
self.TOSGruppen = TOSGroupsConfig(cfg_dir)
|
self.TOSGruppen = TOSGroupsConfig(cfg_dir)
|
||||||
self.Materialien = MaterialTransConfig(cfg_dir)
|
self.Materialien = MaterialTransConfig(cfg_dir)
|
||||||
|
self.bom_config = BOMConfig(cfg_dir)
|
||||||
self._teilenummern = None
|
self._teilenummern = None
|
||||||
self._blacklist = None
|
self._blacklist = None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user