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�ssel, # Kostenstelle,Kostentr�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: """ Defines and parses command line arguments for this script. """ parser = argparse.ArgumentParser() parser.add_argument( "bookings", 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: accounts = read_account_ids(args.accounts, ";") forderungen = create_forderungen_familienzimmer(args.bookings, ",", accounts) for f in forderungen.values(): for i in f.keys(): print(f"{i} {f[i]}") print_to_file_lexware(forderungen) # seperator = ';' #bookings = Booking() #bookings.read_from_file(args.bookings, seperator) #bookings.print_to_file(f"2025-{args.month}_Forderungen_Familienzimmer.csv", bookings[1],bookings[1:]) if __name__ == "__main__": main(parse_args())