diff --git a/lib/manage_configs.py b/lib/manage_configs.py index 06a7497..6c15c0b 100644 --- a/lib/manage_configs.py +++ b/lib/manage_configs.py @@ -1,6 +1,7 @@ import os import json from configparser import ConfigParser +import pandas as pd """ Diese Lib verwaltet alle Config dateien (als .cfg oder als .json) von CreoMigrate @@ -20,6 +21,132 @@ class JsonBasedConfig: """nimm den Json String zur Initialisierung des Objektes""" return json.loads(json_str) + +class CSVBasedConfig: + + def __init__(self, config_dir, config_file): + """merke dir den Pfad zu den Configdateien""" + self.config_path = os.path.join(config_dir, config_file) + + def load_csv_from_file(self): + """lade die csv aus dem angegebenen Dateipfad in ein Dataframe""" + return pd.read_csv(self.config_path, sep=";", dtype="object") + + +class SivasAssemblyData(JsonBasedConfig): + """Auslesen der Assembly-Informationen zu einer angegebenen Baugruppennummer""" + + def __init__(self, config_dir, config_file): + super().__init__(config_dir, config_file) + self.assembly_data = None + + def _lazy_init_assembly_data(func): + """Sorgt dafür, dass json-Datei der Baugruppe nur 1x geladen wird""" + + def wrapper(self, *args, **kwargs): + if self.assembly_data is None: + self.assembly_data = self.load_json_from_file() + return func(self, *args, **kwargs) + return wrapper + + @_lazy_init_assembly_data + def get_assembly_ids(self): + """Gibt alle Teilenummern der Stückliste zurück (auch Teilenummern aus tieferen Baugruppenebenen)""" + + assembly_ids = set() + for child_id, parent_properties in self.assembly_data.items(): + assembly_ids.add(child_id) + for parent_property in parent_properties: + parent_id = parent_property["Parent"] + assembly_ids.add(parent_id) + return assembly_ids + + @_lazy_init_assembly_data + def get_parent_children(self) -> dict: + """Ordnet Stücklistenpositionen (Kinder) den Baugruppennummern (Eltern) zu. Die Kinder sind entsprechend ihrer Positionsnummern in den Stücklisten sortiert.""" + + unordered_parent_children = {} + + for child_id, parent_properties in self.assembly_data.items(): + for parent_property in parent_properties: + parent_id = parent_property["Parent"] + child_posnr_in_parent_bom = int(parent_property["Position"].lstrip(".").split("/")[0]) + + if parent_id not in unordered_parent_children: + unordered_parent_children[parent_id] = {} + + unordered_parent_children[parent_id][child_posnr_in_parent_bom] = child_id + + ordered_parent_children = {} + for parent, children in unordered_parent_children.items(): + for pos_nr, child in sorted(children.items()): + if parent not in ordered_parent_children: + ordered_parent_children[parent] = [] + ordered_parent_children[parent].append(child) + return ordered_parent_children + + def get_longest_assembly_id(self) -> str: + """Gibt die längste Teilenummer von allen Stücklistenpositionen zurück""" + + return max(self.get_assembly_ids()) + + @_lazy_init_assembly_data + def get_max_bom_depth(self) -> int: + """Gibt die tiefste Stücklistenebene zurück (0 = höchste Ebene)""" + + bom_levels = [] + for parents in self.assembly_data.values(): + for parent in parents: + current_bom_level = parent["Position"].count(".") + bom_levels.append(current_bom_level) + return max(bom_levels) + + @_lazy_init_assembly_data + def get_property_names(self) -> list: + """Gibt alle Eigenschaftsnamen zurück, die in der Assembly-json-Datei enthalten sind""" + + for parent_data in self.assembly_data.values(): + return list(parent_data[0]) + + @_lazy_init_assembly_data + def get_property(self, property) -> dict: + """Gibt eine Eigenschaft zu den Teilenummern der Stückliste zurück (z.B. Bezeichnung)""" + + if property not in self.get_property_names(): + raise ValueError("Angegebener Eigenschaftsname exisitert nicht!") + + id_property_mapping = {} + for child, parent_data in self.assembly_data.items(): + for properties in parent_data: + id_property_mapping[child] = properties[property] + return id_property_mapping + + +class RuleDesignerDatabaseConfig(CSVBasedConfig): + """Auslesen der Angaben aus der RuleDesigner-Datenbank-CSV""" + def __init__(self, config_dir=".", config_file="RD_Teilenummern.csv"): + super().__init__(config_dir, config_file) + + def get_ruledesigner_ids(self): + return tuple(self.load_csv_from_file()['Teilenummern']) + + +class MigrationStatus: + def __init__(self, file_dir, assembly_json): + self.sivas_assembly_data = SivasAssemblyData(file_dir, assembly_json) + self.ruledesigner_data = RuleDesignerDatabaseConfig(file_dir) + + def get_migration_status(self): + """Gibt zurück, ob die Teilenummern der Baugruppe bereits migriert wurden, oder nicht""" + sivas_assembly_ids = self.sivas_assembly_data.get_assembly_ids() + ruledesigner_ids = self.ruledesigner_data.get_ruledesigner_ids() + + migration_status = {} + for sivas_assembly_id in sivas_assembly_ids: + migration_status[sivas_assembly_id] = True if sivas_assembly_id in ruledesigner_ids else False + return migration_status + + class TOSGroupsConfig(JsonBasedConfig): """Auslesen der Config Angaben zu den TOS Gruppen"""