first version, for a small tool, creating files for accounting familyrooms
This commit is contained in:
218
main.py
Normal file
218
main.py
Normal file
@@ -0,0 +1,218 @@
|
||||
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:
|
||||
"""
|
||||
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())
|
||||
38
resources/debitoren.csv
Normal file
38
resources/debitoren.csv
Normal file
@@ -0,0 +1,38 @@
|
||||
"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"
|
||||
|
8
resources/preise_familienzimmer.csv
Normal file
8
resources/preise_familienzimmer.csv
Normal file
@@ -0,0 +1,8 @@
|
||||
Basis, 10
|
||||
proPerson, 5
|
||||
Familienzimmer 1.OG, 25
|
||||
1. OG, 20
|
||||
2. OG, 20
|
||||
3. OG, 20
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user