change structure, added readinging miete.csv
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
resources/
|
||||||
|
output/
|
||||||
|
*.csv
|
||||||
|
*.txt
|
||||||
11
README.md
11
README.md
@@ -1,2 +1,13 @@
|
|||||||
# Buchhaltung-Tools
|
# Buchhaltung-Tools
|
||||||
|
Dieses Tool soll in der Buchhaltung unterstützen Prozesse automatisiert ablaufen zu lassen
|
||||||
|
Es hat folgende Funktion:
|
||||||
|
Einlesen der Mietendatei und daraus ein .txt erstellen mit allen Mietforderungen (kaltmiete, Betriebskosten, Gesamt(als Split Buchung), CWS Miete und Familienzimmer Miete. für alle Debitoren
|
||||||
|
Berechnung der Mietforderungen für das Gästezimmer aus den Buchungsdaten
|
||||||
|
|
||||||
|
weiter Funktion in Zukunft:
|
||||||
|
Berechnung der Nebenkostenabrechnung und Erstellen der Übersichten für aller Mieterinnen
|
||||||
|
|
||||||
|
|
||||||
|
Im Mai sind alle Buchungen die im Mai beendet wurden, fängt der Buchungszeitraum schon im Vormonat an, wird trotzdem der gesamte Zeitraum Mai zugeschalgen.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
__pycache__/config.cpython-312.pyc
Normal file
BIN
__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/forderungen.cpython-312.pyc
Normal file
BIN
__pycache__/forderungen.cpython-312.pyc
Normal file
Binary file not shown.
6
config.py
Normal file
6
config.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
filename_debitoren = "resources/debitoren.csv"
|
||||||
|
encoding_debitoren = "ISO-8859-1"
|
||||||
|
filename_fz = "resources/Booking_System.csv"
|
||||||
|
filname_price_familyroom = "resources/preise_familienzimmer.csv"
|
||||||
|
seperator_price_familyroom = ","
|
||||||
|
filename_mieten = "resources/2025_05_miete.csv"
|
||||||
367
forderungen.py
Normal file
367
forderungen.py
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
|
KN_HABEN_MIETE_NK = "4106"
|
||||||
|
KN_HABEN_MIETE = "4105"
|
||||||
|
KN_HABEN_MIETE_CWS = "4107"
|
||||||
|
KOSTENSTELLE_CWS = "100"
|
||||||
|
KN_HABEN_MIETE_FZ = "4107"
|
||||||
|
KOSTENSTELLE_FZ = "200"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Forderung:
|
||||||
|
def __init__(self )->None:
|
||||||
|
self.name:list[str] = []
|
||||||
|
self.belegdatum:str = ""
|
||||||
|
self.amount:float = 0
|
||||||
|
self.text:str = ""
|
||||||
|
self.soll:int|None = None
|
||||||
|
self.haben:int|None = 0
|
||||||
|
self.kostenstelle:int = 0
|
||||||
|
self.kostentraeger:int = 0
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Name{self.name}, Haben {self.haben}, Soll {self.soll}, Amount {self.amount},Verwendung {self.text}"
|
||||||
|
|
||||||
|
|
||||||
|
def print_to_file_lexware(forderungen:dict):
|
||||||
|
"""
|
||||||
|
print Forderungen to a file, that can be read by lexware according the following format:
|
||||||
|
"Belegdatum";"Buchungsdatum";"Buchungstext"; "Buchungsbetrag"; "Sollkonto";"Habenkonto";"Kostenstelle"
|
||||||
|
01.03.2025; 19.02.2026;2; "Miete Familienzimmer"; 357,08; 12161; 4107; 200
|
||||||
|
"""
|
||||||
|
print('Start Drucken der Forderugen')
|
||||||
|
names = read_account_names(config.filename_debitoren)
|
||||||
|
for period, forderung in forderungen.items():
|
||||||
|
if forderung !={}:
|
||||||
|
filename = f"output/{period[0]}-{period[1]:02d}_Forderungen_Familienzimmer.csv"
|
||||||
|
print(f"\t ...{filename}")
|
||||||
|
with open(filename, "w",encoding="cp1252", newline="\r\c") as file:
|
||||||
|
file.write("\"Belegdatum\";\"Buchungstext\";\"Buchungsbetrag\";\"Sollkonto\";\"Habenkonto\";\"Kostenstelle\"\n")
|
||||||
|
for key in forderung:
|
||||||
|
f = forderung[key]
|
||||||
|
name = names[key]
|
||||||
|
file.write(f"01.{period[1]:02d}.{period[0]};\"{name} {f.text}\";{f.amount};{key};{f.haben};{f.kostenstelle}\n")
|
||||||
|
print("Fertig mit Drucken der Forderungen.")
|
||||||
|
|
||||||
|
def create_forderungen(forderungen:dict, period:tuple, id_subject:tuple, belegdatum:str, amount:float, soll:int|None, haben:str, kostenstelle:str)->dict:
|
||||||
|
"""
|
||||||
|
create the recievables in the dict and incerting the date.
|
||||||
|
if the amount is 0 this nothings added,
|
||||||
|
if tow recievables have the same period and subject, than the amounts will be added
|
||||||
|
"""
|
||||||
|
if amount == 0:
|
||||||
|
return forderungen
|
||||||
|
if period not in forderungen.keys():
|
||||||
|
forderungen[period] = {}
|
||||||
|
if id_subject not in forderungen[period]:
|
||||||
|
forderungen[period][id_subject] = Forderung()
|
||||||
|
forderungen[period][id_subject].amount = round(amount,2)
|
||||||
|
forderungen[period][id_subject].text = f"{id_subject[1]} {period[0]}-{period[1]:02d}"
|
||||||
|
forderungen[period][id_subject].kostenstelle = kostenstelle
|
||||||
|
forderungen[period][id_subject].haben = haben
|
||||||
|
forderungen[period][id_subject].soll = soll
|
||||||
|
forderungen[period][id_subject].belegdatum = belegdatum
|
||||||
|
else:
|
||||||
|
forderungen[period][id_subject].amount = round(amount+forderungen[period][id_subject].amount)
|
||||||
|
return forderungen
|
||||||
|
|
||||||
|
def create_forderungen_miete(filename:str, accounts:dict, forderungen:dict, month:int, year:int)->dict:
|
||||||
|
"""
|
||||||
|
Create all recievables for one Month from the "mieten.csv" file, warm (split to Nk and kalt+Parkplatz(+soli), cws, and familyrooms
|
||||||
|
"""
|
||||||
|
print(f"{year} {month} Start Einlesen der Mietendatei von {filename}")
|
||||||
|
try:
|
||||||
|
file = list(csv.DictReader(open(filename, 'r')))
|
||||||
|
period = (year,month)
|
||||||
|
for line in file:
|
||||||
|
kaltmiete = getFloat(line["Betrag Kaltmiete"])
|
||||||
|
if kaltmiete > 0:
|
||||||
|
name = getWords(line["Vorname, Name"])
|
||||||
|
id = getID(accounts, name)
|
||||||
|
if id > 0:
|
||||||
|
#calculate the Miete
|
||||||
|
betriebskosten = getFloat(line["Betrag Betriebskosten"])
|
||||||
|
stellplatz = getFloat(line["Betrag zusätzlicher Stellpl."])
|
||||||
|
zusatzVereinbarung = getFloat(line["Betrag Vereinbarung"])
|
||||||
|
mieteCWS = getFloat(line["Betrag Gemeinschaftsbuero"])
|
||||||
|
betragFz = getFloat(line["Betrag Gaestezimmer"])
|
||||||
|
|
||||||
|
miete = kaltmiete + zusatzVereinbarung + stellplatz
|
||||||
|
warmmiete = miete + betriebskosten
|
||||||
|
|
||||||
|
datum = f"01.{period[1]:02d}.{period[0]}"
|
||||||
|
create_forderungen(forderungen, period, (id, "Miete Gesamt"),datum,
|
||||||
|
warmmiete, id, "0", "")
|
||||||
|
create_forderungen(forderungen, period, (id, "Miete NK"), "",
|
||||||
|
betriebskosten, None, KN_HABEN_MIETE_NK,"")
|
||||||
|
create_forderungen(forderungen, period, (id, "Miete"),"",
|
||||||
|
miete, None, KN_HABEN_MIETE,"")
|
||||||
|
create_forderungen(forderungen, period, (id, "Miete CWS"),datum,
|
||||||
|
mieteCWS, id, KN_HABEN_MIETE_CWS, KOSTENSTELLE_CWS)
|
||||||
|
create_forderungen(forderungen, period, (id, "Miete Familienzimmer"), datum,
|
||||||
|
betragFz, id, KN_HABEN_MIETE_FZ, KOSTENSTELLE_FZ)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"Fehler: kein name gefunden!!!{name} {getID(accounts, name)} {line}")
|
||||||
|
print(f"Fertig, {year} {month} Erstellen von {len(forderungen[period])} Forderungen abgeschlossen.")
|
||||||
|
except IOError:
|
||||||
|
print(f"Fehler, Datei {filename} nicht gefunden.")
|
||||||
|
return forderungen
|
||||||
|
|
||||||
|
def create_forderungen_familienzimmer(filename:str, accounts:dict, forderungen:dict)->dict:
|
||||||
|
"""
|
||||||
|
Create the recievables from the familyrooms from the file from the inputfile,
|
||||||
|
assings it to the accouts, calculate the price, stores results in forderungen
|
||||||
|
"""
|
||||||
|
print(f"Start Einlesen der Buchungen des Familienźimmers von {filename}")
|
||||||
|
priceFamilyRooms = readPriceFamilyRooms(config.filname_price_familyroom)
|
||||||
|
counter = 0
|
||||||
|
try:
|
||||||
|
with open(filename, "r") as file:
|
||||||
|
reader = csv.DictReader(file)
|
||||||
|
for row in reader:
|
||||||
|
name = row["Created by"]
|
||||||
|
name = getWords(name)
|
||||||
|
id_subject = (getID(accounts, name[1:]), "Familienzimmer")
|
||||||
|
|
||||||
|
month = getMonth(row["End time"].split(" ")[2])
|
||||||
|
year = row["End time"].split(" ")[3]
|
||||||
|
period = (year, month)
|
||||||
|
if id_subject[0] > 0:
|
||||||
|
room = row["Room"].replace("\"","")
|
||||||
|
duration = getDuration(row["Duration"])
|
||||||
|
number_person = getNumberPerson(row["Number of guests"])
|
||||||
|
price = getPrice(room, priceFamilyRooms, duration, number_person)
|
||||||
|
#print(f"{name[1]} {id_subject} {room} dauer {duration} Tage, personen {number_person} preis {price}")
|
||||||
|
datum = f"01.{period[1]:02d}.{period[0]}"
|
||||||
|
|
||||||
|
create_forderungen(forderungen,period,id_subject,datum,
|
||||||
|
price,id_subject[0],KN_HABEN_MIETE_FZ,KOSTENSTELLE_FZ)
|
||||||
|
counter+=1
|
||||||
|
else:
|
||||||
|
print(f"Fehler, Name nicht gefunden\n\t{row}")
|
||||||
|
print(f"Fertig mit Erstellen von {counter} Forderungen")
|
||||||
|
except IOError:
|
||||||
|
print(f"Fehler, Datei {filename} nicht gefunden.")
|
||||||
|
return forderungen
|
||||||
|
|
||||||
|
def getFloat(field:str)->float:
|
||||||
|
"""
|
||||||
|
converts a number from not empty string (english format e.g. 1,946.44) to a float, rounding to 2, digits after the point
|
||||||
|
if the string is empty returns 0
|
||||||
|
"""
|
||||||
|
if field.isnumeric and len(field)>0:
|
||||||
|
return round(float(field.replace(",", "")),2)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def getWords(sentence:str)->list:
|
||||||
|
"""
|
||||||
|
Takes a sequence of chars (sentence), replaces special signs from the alphabet and returns a list of all words without special chars
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
word = ''
|
||||||
|
#sentence = sentence.lower()
|
||||||
|
sentence = sentence.replace("ä", "ae").replace("ö", "oe").replace("ü", "ue").replace("ß", "ss")
|
||||||
|
for c in sentence:
|
||||||
|
if ord("a")<= ord(c) <= ord("z") or ord("A")<= ord(c) <= ord("Z") or ord("0")<= ord(c) <= ord("9"):
|
||||||
|
word = word + c
|
||||||
|
elif len(word)>0:
|
||||||
|
result.append(word)
|
||||||
|
word = ""
|
||||||
|
if len(word)>0:
|
||||||
|
result.append(word)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def getPrice(room:str, prices:dict, duration:int, numberPerson:int)->int:
|
||||||
|
"""
|
||||||
|
calculate the price for one booking, 15 Euro per night, 5 Euro extra per extra person,
|
||||||
|
if there is no specific number take the max of person
|
||||||
|
"""
|
||||||
|
if numberPerson > 0:
|
||||||
|
return min(prices["proPerson"]*numberPerson+prices["Basis"],prices[room])*duration
|
||||||
|
else:
|
||||||
|
return prices[room]*duration#or 15*duratiion if it was before Okt 2025??
|
||||||
|
|
||||||
|
def getNumberPerson(field:str)->int:
|
||||||
|
if len(field) >0:
|
||||||
|
return int(field)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def getID(accounts:dict, names:list)->int:
|
||||||
|
for name in names:
|
||||||
|
if name in accounts:
|
||||||
|
return int(accounts[name])
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def getMonth(month:str)->int:
|
||||||
|
month = month.lower()
|
||||||
|
if month == "january" or month =="januar":
|
||||||
|
return 1
|
||||||
|
elif month == "february" or month =="februar":
|
||||||
|
return 2
|
||||||
|
elif month == "march" or month =="märz":
|
||||||
|
return 3
|
||||||
|
elif month == "april":
|
||||||
|
return 4
|
||||||
|
elif month == "may" or month =="mai":
|
||||||
|
return 5
|
||||||
|
elif month == "june" or month =="juni":
|
||||||
|
return 6
|
||||||
|
elif month == "july" or month =="juli":
|
||||||
|
return 7
|
||||||
|
elif month == "august":
|
||||||
|
return 8
|
||||||
|
elif month == "september":
|
||||||
|
return 9
|
||||||
|
elif month == "october" or month =="oktober":
|
||||||
|
return 10
|
||||||
|
elif month == "november":
|
||||||
|
return 11
|
||||||
|
elif month == "december" or month =="dezember":
|
||||||
|
return 12
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def getDuration(duration:str)->int:
|
||||||
|
duration = duration.split(" ")
|
||||||
|
if duration[1] == "weeks" or duration[1] == "Woche":
|
||||||
|
return int(duration[0]) * 7
|
||||||
|
elif duration[1] == "days" or duration[1] == "Tage":
|
||||||
|
return int(duration[0])
|
||||||
|
|
||||||
|
def read_account_ids(filename:str)->dict:
|
||||||
|
"""
|
||||||
|
Create a dictionary from name to account id for first and last name couples included,
|
||||||
|
names that are not unique will be removed
|
||||||
|
"""
|
||||||
|
print(f"Start Einlesen der Namen und Account IDs von {filename}.")
|
||||||
|
accounts = {}
|
||||||
|
number_accounts = 0
|
||||||
|
doubles = []
|
||||||
|
try:
|
||||||
|
with open(filename, "r",encoding=config.encoding_debitoren) as file:
|
||||||
|
for line in file:
|
||||||
|
line = getWords(line)
|
||||||
|
if len(line) >=2:
|
||||||
|
id = line[-1]
|
||||||
|
names = line[:-1]
|
||||||
|
number_accounts += 1
|
||||||
|
for name in names:
|
||||||
|
if name in accounts:
|
||||||
|
doubles.append(name)
|
||||||
|
else:
|
||||||
|
accounts[name] = int(id)
|
||||||
|
for twin in doubles:
|
||||||
|
if twin in accounts:
|
||||||
|
del accounts[twin]
|
||||||
|
print(f"Fertig mit Einlesen {number_accounts} found.")
|
||||||
|
except IOError:
|
||||||
|
print(f"Fehler, Datei {filename} nicht gefunden.")
|
||||||
|
return accounts
|
||||||
|
|
||||||
|
def read_account_names(filename:str)->dict:
|
||||||
|
"""
|
||||||
|
Create a dictionary from account id to name
|
||||||
|
"""
|
||||||
|
print(f"Start Einlesen der Kontonummern und Namen \"{filename}\" ")
|
||||||
|
try:
|
||||||
|
names = {}
|
||||||
|
with open(filename, "r",encoding=config.encoding_debitoren) as file:
|
||||||
|
for line in file:
|
||||||
|
line = getWords(line)
|
||||||
|
if len(line) >=2:
|
||||||
|
id = int(line[-1])
|
||||||
|
name = line[:-1]
|
||||||
|
names[id] = name
|
||||||
|
print(f"Fertig mit Einlesen, {len(names)} Kontonummer gefunden ")
|
||||||
|
except IOError:
|
||||||
|
print(f"Fehler, Datei {filename} nicht gefunden.")
|
||||||
|
return names
|
||||||
|
|
||||||
|
def readPriceFamilyRooms(filename:str)->dict:
|
||||||
|
"""
|
||||||
|
read the max price per night for each room from the file
|
||||||
|
"""
|
||||||
|
print(f"Start Einlesen der Preise für die Familienzimmer von {filename}")
|
||||||
|
prices = {}
|
||||||
|
try:
|
||||||
|
with open(filename, "r") as file:
|
||||||
|
for line in file:
|
||||||
|
line = line.strip().replace("\"","").split(config.seperator_price_familyroom)
|
||||||
|
if len(line) == 2:
|
||||||
|
prices[line[0]] = int(line[1])
|
||||||
|
print(f"Fertig mit Einlesen der Preise")
|
||||||
|
except IOError:
|
||||||
|
print(f"Fehler, Datei {filename} nicht gefunden.")
|
||||||
|
return prices
|
||||||
|
|
||||||
|
def parse_args() -> argparse.Namespace:
|
||||||
|
"""
|
||||||
|
Defines and parses command line arguments for this script.
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
return parser
|
||||||
|
parser.add_argument(
|
||||||
|
"bookings",
|
||||||
|
type=str,
|
||||||
|
help="the file from which the bookings come",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"miete",
|
||||||
|
type=str,
|
||||||
|
help="the file from which the bookings come",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"accounts",
|
||||||
|
type=str,
|
||||||
|
help="the file from which the account id are read",
|
||||||
|
)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def main(args: argparse.Namespace) -> None:
|
||||||
|
print(getWords("Hallo östereich-Ungarn !Achtung! ?ßchlange"))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(parse_args())
|
||||||
|
|
||||||
|
"""
|
||||||
|
Not used any more
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def create_forderungen_cws(filename:str, seperator:str, accounts:dict, forderungen:dict)->dict:
|
||||||
|
file = list(csv.DictReader(open(filename, 'r')))
|
||||||
|
year = file[14]["Raum"]
|
||||||
|
for line in file:
|
||||||
|
name = line["Name"].strip().replace("-", "").replace("ß", "ss").split(" ")
|
||||||
|
id = getID(accounts, name)
|
||||||
|
id_subject = (id,"CWS")
|
||||||
|
if id > 0:
|
||||||
|
for key, value in line.items():
|
||||||
|
if value !="X":
|
||||||
|
month = getMonth(key)
|
||||||
|
if month>0:
|
||||||
|
period = (year, month)
|
||||||
|
price = int(value)
|
||||||
|
if period not in forderungen.keys():
|
||||||
|
forderungen[period] = {}
|
||||||
|
if id_subject not in forderungen[period]:
|
||||||
|
forderungen[period][id_subject]= Forderung()
|
||||||
|
forderungen[period][id_subject].amount = price
|
||||||
|
forderungen[period][id_subject].text = f"Miete CWS {period[0]}-{period[1]:02d}"
|
||||||
|
forderungen[period][id_subject].kostenstelle = "100"
|
||||||
|
forderungen[period][id_subject].haben = "4107"
|
||||||
|
forderungen[period][id_subject].soll = id_subject[0]
|
||||||
|
else:
|
||||||
|
forderungen[period][id_subject].amount += price
|
||||||
|
else:
|
||||||
|
print(line)
|
||||||
|
return forderungen
|
||||||
|
|
||||||
|
"""
|
||||||
254
main.py
254
main.py
@@ -1,187 +1,6 @@
|
|||||||
|
import forderungen as f
|
||||||
|
import config
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
|
||||||
|
|
||||||
class Forderung:
|
|
||||||
def __init__(self )->None:
|
|
||||||
self.name:list[str] = []
|
|
||||||
self.buchungsdatum:str = ""
|
|
||||||
self.belegdatum:str = ""
|
|
||||||
#Buchungstext, Buchungsbetrag, Sollkonto, Habenkonto, Steuerschl<68>ssel,
|
|
||||||
# Kostenstelle,Kostentr<74>ger, Zusatzangaben
|
|
||||||
self.amount:int = 0
|
|
||||||
self.text:str = ""
|
|
||||||
self.soll:int = 0
|
|
||||||
self.haben:int = 0
|
|
||||||
self.steuerschluessel:int = 0
|
|
||||||
self.amount:int = 0
|
|
||||||
self.kostenstelle:int = 0
|
|
||||||
self.kostentraeger:int = 0
|
|
||||||
self.zusatzangaben:int = 0
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Haben {self.haben}, Soll {self.soll}, Amount {self.amount}, Verwendung {self.text}"
|
|
||||||
|
|
||||||
|
|
||||||
def print_to_file_lexware(forderungen:dict):
|
|
||||||
"""
|
|
||||||
print Forderungen to a file, that can be read by lexware according the following format:
|
|
||||||
"Belegdatum";"Buchungsdatum";"Buchungstext"; "Buchungsbetrag"; "Sollkonto";"Habenkonto";"Kostenstelle"
|
|
||||||
01.03.2025; 19.02.2026;2; "Miete Familienzimmer"; 357,08; 12161; 4107; 200
|
|
||||||
"""
|
|
||||||
names = read_account_names("resources/debitoren.csv",";")
|
|
||||||
for period, forderung in forderungen.items():
|
|
||||||
if forderung !={}:
|
|
||||||
filename = f"output/{period[0]}-{period[1]:02d}_Forderungen_Familienzimmer.csv"
|
|
||||||
with open(filename, "w") as file:
|
|
||||||
file.write("\"Belegdatum\";\"Buchungsdatum\";\"Buchungstext\";\"Buchungsbetrag\";\"Sollkonto\";\"Habenkonto\";\"Kostenstelle\"\n")
|
|
||||||
for key in forderung:
|
|
||||||
f= forderung[key]
|
|
||||||
name = names[key]
|
|
||||||
file.write(f"01.{period[1]:02d}.{period[0]};01.{period[1]:02d}.{period[0]};\"{name} {f.text}\";{f.amount};{key};{f.haben};{f.kostenstelle}\n")
|
|
||||||
|
|
||||||
def create_forderungen_familienzimmer(filename:str, seperator:str, accounts:dict)->list:
|
|
||||||
forderungen = {}
|
|
||||||
priceFamilyRooms = readPriceFamilyRooms("resources/preise_familienzimmer.csv", ",")
|
|
||||||
with open(filename, "r") as file:
|
|
||||||
reader = csv.DictReader(file)
|
|
||||||
for row in reader:
|
|
||||||
name = row["Created by"]
|
|
||||||
name = name.replace("(", "").replace(")","").replace("ß", "ss").split(" ")
|
|
||||||
id = getID(accounts, name[1:])
|
|
||||||
|
|
||||||
month = getMonth(row["End time"].split(" ")[2])
|
|
||||||
year = row["End time"].split(" ")[3]
|
|
||||||
period = (year,month)
|
|
||||||
if id > 0:
|
|
||||||
room = row["Room"].replace("\"","")
|
|
||||||
duration = getDuration(row["Duration"])
|
|
||||||
number_person = getNumberPerson(row["Number of guests"])
|
|
||||||
price = getPrice(room, priceFamilyRooms, duration, number_person)
|
|
||||||
print(f"{name[1]} {id} {room} dauer {duration} Tage, personen {number_person} preis {price}")
|
|
||||||
if period not in forderungen.keys():
|
|
||||||
forderungen[period] = {}
|
|
||||||
if id not in forderungen[period]:
|
|
||||||
forderungen[period][id]= Forderung()
|
|
||||||
forderungen[period][id].amount = price
|
|
||||||
forderungen[period][id].text = f"Miete Familienzimmer {period[0]}-{period[1]:02d}"
|
|
||||||
forderungen[period][id].kostenstelle = "200"
|
|
||||||
forderungen[period][id].haben = "4107"
|
|
||||||
forderungen[period][id].soll = id
|
|
||||||
else:
|
|
||||||
forderungen[period][id].amount += price
|
|
||||||
return forderungen
|
|
||||||
|
|
||||||
def getPrice(room:str, prices:dict, duration:int, numberPerson:int)->int:
|
|
||||||
"""
|
|
||||||
calculate the price for one booking, 15 Euro per night, 5 Euro extra per extra person,
|
|
||||||
if there is no specific number take the max of person
|
|
||||||
"""
|
|
||||||
if numberPerson > 0:
|
|
||||||
return min(prices["proPerson"]*numberPerson+prices["Basis"],prices[room])*duration
|
|
||||||
else:
|
|
||||||
return prices[room]*duration
|
|
||||||
|
|
||||||
def readPriceFamilyRooms(filename:str, seperator:str)->dict:
|
|
||||||
prices = {}
|
|
||||||
with open(filename, "r") as file:
|
|
||||||
for line in file:
|
|
||||||
line = line.strip().replace("\"","").split(seperator)
|
|
||||||
if len(line) == 2:
|
|
||||||
prices[line[0]] = int(line[1])
|
|
||||||
return prices
|
|
||||||
|
|
||||||
def getNumberPerson(field:str)->int:
|
|
||||||
if len(field) >0:
|
|
||||||
return int(field)
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def getID(accounts:dict, name:list)->int:
|
|
||||||
if name[0] in accounts:
|
|
||||||
return accounts[name[0]]
|
|
||||||
elif name[1] in accounts:
|
|
||||||
return accounts[name[1]]
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def getMonth(month:str)->int:
|
|
||||||
month = month.lower()
|
|
||||||
if month == "january" or month =="januar":
|
|
||||||
return 1
|
|
||||||
elif month == "february" or month =="febuar":
|
|
||||||
return 2
|
|
||||||
elif month == "march" or month =="märz":
|
|
||||||
return 3
|
|
||||||
elif month == "april":
|
|
||||||
return 4
|
|
||||||
elif month == "may" or month =="mai":
|
|
||||||
return 5
|
|
||||||
elif month == "june" or month =="juni":
|
|
||||||
return 6
|
|
||||||
elif month == "july" or month =="juli":
|
|
||||||
return 7
|
|
||||||
elif month == "august":
|
|
||||||
return 8
|
|
||||||
elif month == "september":
|
|
||||||
return 9
|
|
||||||
elif month == "october" or month =="oktober":
|
|
||||||
return 10
|
|
||||||
elif month == "november":
|
|
||||||
return 11
|
|
||||||
elif month == "december" or month =="dezember":
|
|
||||||
return 12
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def getDuration(duration:str)->int:
|
|
||||||
duration = duration.split(" ")
|
|
||||||
if duration[1] == "weeks" or duration[1] == "Woche":
|
|
||||||
return int(duration[0]) * 7
|
|
||||||
elif duration[1] == "days" or duration[1] == "Tage":
|
|
||||||
return int(duration[0])
|
|
||||||
|
|
||||||
def read_account_ids(file_name:str, seperator:str)->dict:
|
|
||||||
"""
|
|
||||||
Create a dictionary from name to account id for first and last name couples included,
|
|
||||||
names that are not uniquw will be removed
|
|
||||||
"""
|
|
||||||
accounts = {}
|
|
||||||
doubles = []
|
|
||||||
with open(file_name, "r",encoding="ISO-8859-1") as file:
|
|
||||||
for line in file:
|
|
||||||
line = line.strip().replace("\"", "").split(seperator)
|
|
||||||
if len(line) >=2:
|
|
||||||
id = line[1]
|
|
||||||
name = line[0].strip()
|
|
||||||
names = name.replace("-","").replace(";","").replace(",","").split(" ")
|
|
||||||
for name in names:
|
|
||||||
if name in accounts:
|
|
||||||
doubles.append(name)
|
|
||||||
elif name[0].isupper():
|
|
||||||
accounts[name] = int(id)
|
|
||||||
for twin in doubles:
|
|
||||||
if twin in accounts:
|
|
||||||
del accounts[twin]
|
|
||||||
return accounts
|
|
||||||
|
|
||||||
def read_account_names(file_name:str, seperator:str)->dict:
|
|
||||||
"""
|
|
||||||
Create a dictionary from account id to name
|
|
||||||
"""
|
|
||||||
names = {}
|
|
||||||
with open(file_name, "r",encoding="ISO-8859-1") as file:
|
|
||||||
for line in file:
|
|
||||||
line = line.strip().replace("\"", "").split(seperator)
|
|
||||||
if len(line) >=2:
|
|
||||||
id = int(line[1])
|
|
||||||
name = line[0].strip()
|
|
||||||
names[id] = name
|
|
||||||
return names
|
|
||||||
|
|
||||||
def list_to_line(data:list)->str:
|
|
||||||
line = ""
|
|
||||||
for element in data:
|
|
||||||
line +=element+","
|
|
||||||
return line[:-1]
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
def parse_args() -> argparse.Namespace:
|
||||||
"""
|
"""
|
||||||
@@ -189,30 +8,61 @@ def parse_args() -> argparse.Namespace:
|
|||||||
"""
|
"""
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"bookings",
|
"config",
|
||||||
type=str,
|
type=str,
|
||||||
help="the file from which the bookings come",
|
help="the file from which the config for the tool come",
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"accounts",
|
|
||||||
type=str,
|
|
||||||
help="the file from which the account id are read",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
def main(args: argparse.Namespace) -> None:
|
def main(args: argparse.Namespace) -> None:
|
||||||
accounts = read_account_ids(args.accounts, ";")
|
print("Willkommen zum Mieten Tool der Buchhaltung. Es könne folgende Aufgaben erledigt werden:\n\n" \
|
||||||
forderungen = create_forderungen_familienzimmer(args.bookings, ",", accounts)
|
"\t1\t aus der Mietendatai eine in lexware importierbare csv Datei erstellen\n" \
|
||||||
for f in forderungen.values():
|
"\t2\t alle ausgelesen Accounts mit Mame und Kontonummer anzeigen\n"\
|
||||||
for i in f.keys():
|
"\t3\t aus der Buchungsdatei der Familienzimmer die Forderungen berechnen und in eine csv datei schreiben\n"\
|
||||||
print(f"{i} {f[i]}")
|
"\t4\t Tool verlassen\n\n"
|
||||||
print_to_file_lexware(forderungen)
|
"Gib die Nummer welche Aufgabe gemacht werden soll.\n")
|
||||||
|
while True:
|
||||||
|
forderung = {}
|
||||||
# seperator = ';'
|
line = input()
|
||||||
#bookings = Booking()
|
if line == "4":
|
||||||
#bookings.read_from_file(args.bookings, seperator)
|
break
|
||||||
#bookings.print_to_file(f"2025-{args.month}_Forderungen_Familienzimmer.csv", bookings[1],bookings[1:])
|
else:
|
||||||
|
#accounts
|
||||||
|
filename_debitoren = config.filename_debitoren
|
||||||
|
newFilename = input(f"Aktuell werden die Debitoren aus der Datei {filename_debitoren} gelesen, wenn du eine andere Datei einlesen möchtest gib nun den neuen Pfad an:")
|
||||||
|
if len(newFilename)>=2:
|
||||||
|
filename_debitoren = newFilename
|
||||||
|
accounts = f.read_account_ids(filename_debitoren)
|
||||||
|
if line =="1":
|
||||||
|
#print accounts
|
||||||
|
#for name, id in accounts.items():
|
||||||
|
# print(f"{name} {id}")
|
||||||
|
names = f.read_account_names(filename_debitoren)
|
||||||
|
for id, name in names.items():
|
||||||
|
print(f"{id} {name}")
|
||||||
|
print("Bitte gib die Nummer einer weitern Aufgabe ein:\n")
|
||||||
|
elif line == "2":
|
||||||
|
#Miete
|
||||||
|
filename_miete = config.filename_mieten
|
||||||
|
newFilename = input(f"Aktuell werden die Mietforderungen aus der Datei {filename_miete} gelesen.\n Wenn du eine andere Datei einlesen möchtest gib nun den neuen Pfad an:")
|
||||||
|
if len(newFilename)>=2:
|
||||||
|
filename_miete = newFilename
|
||||||
|
forderung = f.create_forderungen_miete(filename_miete, accounts, forderung, 5, 2025)
|
||||||
|
f.print_to_file_lexware(forderung)
|
||||||
|
print("Bitte gib die Nummer einer Weitern Aufgabe ein:\n")
|
||||||
|
elif line == "3":
|
||||||
|
#familyrooms
|
||||||
|
filename_fz = config.filename_fz
|
||||||
|
newFilename = input(f"Aktuell werden die Mietforderungen aus der Datei {filename_fz} gelesen.\n Wenn du eine andere Datei einlesen möchtest gib nun den neuen Pfad an:")
|
||||||
|
if len(newFilename)>=2:
|
||||||
|
filename_fz = newFilename
|
||||||
|
forderung = f.create_forderungen_familienzimmer(filename_fz, accounts, forderung)
|
||||||
|
f.print_to_file_lexware(forderung)
|
||||||
|
print("Bitte gib die Nummer einer Weitern Aufgabe ein:\n")
|
||||||
|
else:
|
||||||
|
print("Ungültige Eingabe, bitte versuch es erneut!\n")
|
||||||
|
print("Auf Wiedersehen!")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(parse_args())
|
main(parse_args())
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
"Brühl, Clara";"12020"
|
|
||||||
"Braungardt Simon, Färber Verena";"12021"
|
|
||||||
"Classen, Jona";"12030"
|
|
||||||
"Eilers Maria und Karl-Heinz";"12050"
|
|
||||||
"Fokuhl, Esther";"12060"
|
|
||||||
"Fröschen- Ludwig, Brigitte";"12061"
|
|
||||||
"Hababi Hashim und Mayyadah";"12080"
|
|
||||||
"Hellgardt Maria";"12081"
|
|
||||||
"Cuervo Hellgardt, Frida ";"12082"
|
|
||||||
"Jahnel Svende, Lohmar Martin";"12100"
|
|
||||||
"Janetzky, Birgit";"12101"
|
|
||||||
"Kniep Martin und Jana";"12110"
|
|
||||||
"Khoroshenko Olena, Fomin Andrii";"12111"
|
|
||||||
"Kottmeier, Anna Paula";"12112"
|
|
||||||
"Kiser, Gabriele";"12113"
|
|
||||||
"Lüth, Kyra";"12120"
|
|
||||||
"Laurenz Eric, Wolf Jennyfer";"12121"
|
|
||||||
"Mohamed, Youssef";"12130"
|
|
||||||
"Meinzer Niklas, Deye Christin";"12131"
|
|
||||||
"Markus, Felix";"12132"
|
|
||||||
"Niemann Christa, Heitbrink Rolf";"12140"
|
|
||||||
"Orth Astrid und Stefan";"12150"
|
|
||||||
"Oelschlaegel Hauke, Nesswetter Hannah";"12151"
|
|
||||||
"Oberhoffner, Nicolai";"12152"
|
|
||||||
"Ponomarenko Ivan und Anna";"12160"
|
|
||||||
"Röder, Brigitte";"12180"
|
|
||||||
"Reiners Nils, Peter Nina";"12181"
|
|
||||||
"Schindler Jens, Weiss Rebecca";"12190"
|
|
||||||
"Scholz, Rotraut";"12191"
|
|
||||||
"Schultheiss Achim und Brigitte";"12192"
|
|
||||||
"Taxis, Susanne";"12200"
|
|
||||||
"Von Keutz, Pia";"12220"
|
|
||||||
"Vereskun Elena und Valerii";"12221"
|
|
||||||
"Vogelsang, Leona";"12222"
|
|
||||||
"Wulff, Svenja";"12230"
|
|
||||||
"Forderungen Bauleistungsversicherung BHV";"13000"
|
|
||||||
"Forderungen an Hausverein allmende e.V";"13100"
|
|
||||||
"Prymak, Valentyna";"10001"
|
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
Basis, 10
|
|
||||||
proPerson, 5
|
|
||||||
Familienzimmer 1.OG, 25
|
|
||||||
1. OG, 20
|
|
||||||
2. OG, 20
|
|
||||||
3. OG, 20
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user