Files
Rieter-EKalk/Abfrage_Sivas.py
T

153 lines
7.1 KiB
Python

import pandas as pd
import configparser
import os.path
"""
Erstellung einer Excel-Datei mit aktuellen Preisen aus Sivas ist leicht möglich.
Diese soll in einer config-Datei für die Berechnung der rieter-eKalkulation verwendet werden.
Den Parametern der rieter_ekalk werden die entsprechenden Sivas-Nummern zugewiesen, und damit die aktuellen Preise.
Diese Zuordnung von Parametern und ihren aktuellen Preisen wird wieder in eine config-Datei geschrieben, die mit den Preisen der Sivas_Daten.cfg-Datei abzugleichen ist, auf die rieter_ekalk zugreift.
"""
faktoren_sivas_Nummern = {
"zuleitung_75_m_unterverteiler_4x4mm2_400vac":75,
"zuleitung_75_m_unterverteiler_12x4mm2_24_vdc":75,
"zuleitung_75_m_unterverteiler_12x2_5mm2_24_vdc":75,
"zuleitung_55_m_klemmkasten_rsm_mitte_14g1_5_mm":55,
"zuleitung_55_m_klemmkasten_rsm_mitte_14g1_0_mm":55,
"schnittstellen_8x1mm2_30m":30
}
class Kosten():
"""
Liest die Sivas-Excel-Liste ein und schreibt eine neue config Datei mit den aktuellen Preisen der in rieter-ekalk verwendeten Sivas-IDs.
"""
def __init__(self, pathNew="Zuordnung_Teilenummern.txt", pathOld="Sivas_Daten.cfg", sivasData="grid_export.xlsx"):
"""
:param pathNew: cfg-Datei, die den Bauteilen ihre Sivas-Nummern zuweist z.B. "schaltschrankgehaeuse_b2x800_zubehoer = 790821101"
:param pathOld: cfg-Datei, die in rieter_ekalk verwendet wird und den Bauteilen Preise zuweist z.B. "schaltschrankgehaeuse_b2x800_zubehoer = 4663.45"
:param sivasData: Excel-Datei mit Sivas-Nummern und entsprechenden Preisen, Überschrift: Teilenummer, Laufende Materialkosten
"""
df = pd.read_excel(sivasData, header=0, index_col=0, usecols=["Teilenummer", "Laufende Materialkosten" ])
self._kosten = df.to_dict()
self._given = True
if os.path.exists(pathNew):
self._zuordnung = configparser.ConfigParser(inline_comment_prefixes="#")
self._zuordnung.read_file(open(pathNew))
else:
self._given = False
self._zuordnung = None
self._default = configparser.ConfigParser(inline_comment_prefixes="#")
self._default.read_file(open(pathOld))
# wird verwendet, um die Werte der alten config zu speichern
self._HW_Einzelpreise = None
def exists(self):
return self._given
def getNewPricesAsDict(self, not_found_keys):
"""
Gibt die neuen Preise als Dict zurück.
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
"""
newDict = {}
for key, val in self.getZuordnungTeilenummernAsDict().items():
number = val.strip()
self.getPriceFromNumber(key, number, newDict, not_found_keys)
if "+" in number:
del not_found_keys[key]
split_sivas_ids = number.split('+')
self.getPriceFromAddedNumbers(key, split_sivas_ids, newDict, not_found_keys)
return newDict
def getPriceFromAddedNumbers(self, key, split_sivas_ids, newDict, not_found_keys):
"""
Trägt die Zuordnung Bauteil:Gesamtpreis in das newDict Dictionary ein, wenn das Bauteil mehrere Sivas-Nummern beinhaltet.
Ist die Nummer eines Summanden nicht in Sivas enthalten, wird er in das Dict "not_found_keys" eingetragen.
:param split_sivas_ids: Liste von Sivas IDs, die addiert werden z.B. [' 827072204', ' 721000041']
:param key: Name z.B. "anlagenrechner_ohne_bildschirm"
:param newDict: z.B. {'schaltschrankgehaeuse_b2x800_zubehoer':9490.23, ...}
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
"""
price = 0
for summand in split_sivas_ids:
summand = summand.strip()
# summand: einzelner Summand z.B. '827072204'
if summand in self._kosten["Laufende Materialkosten"]:
cost = self._kosten["Laufende Materialkosten"][summand]
# cost: Einzelpreis eines Summanden [€]
if type(cost) is type(int) or type(float):
price += cost
# price: Gesamtpreis
newDict.update({key: price})
else:
not_found_keys.update({key:summand})
def getPriceFromNumber(self, key, number, newDict, not_found_keys):
"""
Trägt die Zuordnung Bauteil:Gesamtpreis in das newDict Dictionary ein, wenn das Bauteil eine Sivas-Nummer beinhaltet.
In Sivas nicht existierende Nummern werden in das Dict "not_found_keys" zurückgegeben.
:param key: Name z.B. "anlagenrechner_ohne_bildschirm"
:param number: Sivas Nummer zum key z.B. '827072204'
:param newDict: z.B. {'schaltschrankgehaeuse_b2x800_zubehoer':9490.23, ...}
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
"""
if number in self._kosten["Laufende Materialkosten"]:
price = self._kosten["Laufende Materialkosten"][number]
if price is int or float:
newDict.update({key: price})
else:
not_found_keys.update({key:number})
def getDefaultDictAsFloat(self):
res = dict()
for key, val in self._default.items("HW_Einzelpreise"):
res[key] = float(val)
return res
def getZuordnungTeilenummernAsDict(self):
res = dict()
for key, val in self._zuordnung.items("HW_Einzelpreise"):
res[key] = val
return res
def writeNewConfig(self, name='Sivas_Abgleich.cfg'):
config = configparser.ConfigParser()
config["HW_Einzelpreise"] = latest_costs
config["Preise durch Sivas nicht ermittelbar"] = not_found_in_sivas
with open(name, 'w') as configfile:
config.write(configfile)
def writePriceIncrements(self, name='Preis_Increments.xlsx'):
not_found_in_sivas = dict()
latest_costs = self.getNewPricesAsDict(not_found_in_sivas)
sivas_numbers = list()
old_prices = list()
new_prices = list()
for sivas_number in latest_costs.keys():
sivas_numbers.append(sivas_number)
old_prices.append(self.getDefaultDictAsFloat().get(sivas_number))
new_prices.append(latest_costs.get(sivas_number))
data = {"Sivas-Nummern":sivas_numbers, "Alte Preise":old_prices, "Neue Preise":new_prices}
df = pd.DataFrame.from_dict(data)
df.to_excel(name, sheet_name="Preisänderungen", index_label="Sivas-Nummern")
# lies die alte config und die Excel-Liste mit den Sivas-Daten
costs = Kosten()
not_found_in_sivas = dict()
latest_costs = costs.getNewPricesAsDict(not_found_in_sivas)
# schreibe die neue config mit den aktuellen Preisen
costs.writeNewConfig('Sivas_Abgleich.cfg')
# schreibe die Preisänderungen in eine Excel-Datei
costs.writePriceIncrements('Preis_Increments.xlsx')