|
@@ -39,6 +39,15 @@ TRANSLATE = [
|
|
|
@dataclass
|
|
|
class GchrConfig:
|
|
|
first_month_of_financial_year: str
|
|
|
+ data_path: str
|
|
|
+ gcstruct_path: str
|
|
|
+ export_path: str
|
|
|
+
|
|
|
+
|
|
|
+@dataclass
|
|
|
+class GchrExportConfig:
|
|
|
+ current_year: str
|
|
|
+ current_month: str
|
|
|
|
|
|
|
|
|
class GCHR:
|
|
@@ -48,8 +57,10 @@ class GCHR:
|
|
|
df_translate2: pd.DataFrame = None
|
|
|
makes: dict[str, str] = None
|
|
|
sites: dict[str, str] = None
|
|
|
+ current_year: str
|
|
|
+ current_month: str
|
|
|
|
|
|
- def __init__(self, base_dir) -> None:
|
|
|
+ def __init__(self, base_dir: str) -> None:
|
|
|
self.base_dir = base_dir
|
|
|
|
|
|
self.account_translation = f"{self.base_dir}/data/Kontenrahmen_uebersetzt.csv"
|
|
@@ -59,7 +70,7 @@ class GCHR:
|
|
|
pd.set_option("display.max_rows", 500)
|
|
|
pd.set_option("display.float_format", lambda x: "%.2f" % x)
|
|
|
|
|
|
- def set_bookkeep_period(self, year, month):
|
|
|
+ def set_bookkeep_period(self, year: str, month: str) -> None:
|
|
|
self.current_year = year
|
|
|
self.current_month = month
|
|
|
period = f"{year}-{month}"
|
|
@@ -79,7 +90,7 @@ class GCHR:
|
|
|
self.last_year2 = str(int(self.current_year) - 2)
|
|
|
self.next_year = str(int(self.current_year) + 1)
|
|
|
|
|
|
- def header(self, makes_used, sites_used, main_site):
|
|
|
+ def header(self, makes_used: list[str], sites_used: list[str], main_site: str) -> dict[str, str]:
|
|
|
return {
|
|
|
"Country": "DE",
|
|
|
"MainBmCode": main_site,
|
|
@@ -94,7 +105,7 @@ class GCHR:
|
|
|
}
|
|
|
|
|
|
@property
|
|
|
- def bookkeep_filter(self):
|
|
|
+ def bookkeep_filter(self) -> dict[str, str]:
|
|
|
period = [self.current_year + str(i).zfill(2) for i in range(1, 13)]
|
|
|
if self.first_month_of_financial_year != "01":
|
|
|
if self.first_month_of_financial_year > self.current_month:
|
|
@@ -107,7 +118,7 @@ class GCHR:
|
|
|
rename_to = ["OpeningBalance"] + ["Period" + str(i).zfill(2) for i in range(1, 13)]
|
|
|
return dict(zip(period, rename_to))
|
|
|
|
|
|
- def extract_acct_info(self, df: pd.DataFrame):
|
|
|
+ def extract_acct_info(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
|
acct_info = [
|
|
|
"Marke",
|
|
|
"Standort",
|
|
@@ -126,7 +137,7 @@ class GCHR:
|
|
|
df[acct_info] = df["Konto_Nr_SKR51"].str.split(pat="-", n=6, expand=True)
|
|
|
return df
|
|
|
|
|
|
- def export_all_periods(self, overwrite=False, today=None):
|
|
|
+ def export_all_periods(self, overwrite=False, today=None) -> None:
|
|
|
dt = datetime.now()
|
|
|
if today is not None:
|
|
|
dt = datetime.fromisoformat(today)
|
|
@@ -140,7 +151,7 @@ class GCHR:
|
|
|
os.makedirs(Path(filename).parent.joinpath("info"), exist_ok=True)
|
|
|
self.export_period(year, month)
|
|
|
|
|
|
- def export_period(self, year, month):
|
|
|
+ def export_period(self, year: str, month: str) -> str:
|
|
|
self.set_bookkeep_period(year, month)
|
|
|
|
|
|
self.get_translation()
|
|
@@ -223,7 +234,7 @@ class GCHR:
|
|
|
df_ignored.to_csv(self.account_ignored, decimal=",", sep=";", encoding="latin-1")
|
|
|
return self.export_filename
|
|
|
|
|
|
- def get_translation(self):
|
|
|
+ def get_translation(self) -> pd.DataFrame:
|
|
|
if self.df_translate is None:
|
|
|
df_translate_import = pd.read_csv(
|
|
|
self.account_translation,
|
|
@@ -272,7 +283,7 @@ class GCHR:
|
|
|
df_translate.set_index("Konto_Nr_Händler")
|
|
|
return df_translate
|
|
|
|
|
|
- def special_translation(self, df: pd.DataFrame):
|
|
|
+ def special_translation(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
|
df["Konto_Nr_Händler"] = df["Konto_Nr_Händler"].str.upper()
|
|
|
df["Konto_Nr_SKR51"] = df["Konto_Nr_SKR51"].str.upper()
|
|
|
df = self.extract_acct_info(df)
|
|
@@ -388,7 +399,7 @@ class GCHR:
|
|
|
df_invalid.to_csv(self.export_invalid_filename, decimal=",", sep=";", encoding="latin-1", index=False)
|
|
|
return df[df["IsNumeric"] == True][TRANSLATE]
|
|
|
|
|
|
- def load_bookings_from_file(self):
|
|
|
+ def load_bookings_from_file(self) -> None:
|
|
|
df2 = []
|
|
|
timestamps = []
|
|
|
|
|
@@ -407,7 +418,7 @@ class GCHR:
|
|
|
self.df_bookings = pd.concat(df2)
|
|
|
self.df_bookings["amount"] = (self.df_bookings["Debit Amount"] + self.df_bookings["Credit Amount"]).round(2)
|
|
|
|
|
|
- def filter_bookings(self):
|
|
|
+ def filter_bookings(self) -> pd.DataFrame:
|
|
|
if self.df_bookings is None:
|
|
|
self.load_bookings_from_file()
|
|
|
|
|
@@ -468,21 +479,30 @@ class GCHR:
|
|
|
return df_combined[df_combined["amount"] != 0.00]
|
|
|
|
|
|
@property
|
|
|
- def export_filename(self):
|
|
|
+ def export_filename(self) -> str:
|
|
|
return self.export_filename_for_period(self.current_year, self.current_month)
|
|
|
|
|
|
@property
|
|
|
- def export_info_dir(self):
|
|
|
+ def export_info_dir(self) -> str:
|
|
|
return f"{self.base_dir}/Export/{self.current_year}/info/"
|
|
|
|
|
|
@property
|
|
|
- def export_invalid_filename(self):
|
|
|
+ def export_invalid_filename(self) -> str:
|
|
|
return f"{self.base_dir}/Export/ungueltig.csv"
|
|
|
|
|
|
- def export_filename_for_period(self, year, month):
|
|
|
+ def export_filename_for_period(self, year: str, month: str) -> str:
|
|
|
return f"{self.base_dir}/Export/{year}/export_{year}-{month}.xml"
|
|
|
|
|
|
- def export_skr51_xml(self, records, bk_filter, period_no, makes_used, sites_used, main_site, filename):
|
|
|
+ def export_skr51_xml(
|
|
|
+ self,
|
|
|
+ records: dict[str, list[str]],
|
|
|
+ bk_filter: dict[str, str],
|
|
|
+ period_no: str,
|
|
|
+ makes_used: list[str],
|
|
|
+ sites_used: list[str],
|
|
|
+ main_site: str,
|
|
|
+ filename: str,
|
|
|
+ ):
|
|
|
record_elements = ACCOUNT_INFO + ["Decimals"] + list(bk_filter.values())[:period_no] + ["CumulatedYear"]
|
|
|
root = ET.Element("HbvData")
|
|
|
h = ET.SubElement(root, "Header")
|
|
@@ -522,11 +542,12 @@ class GCHR:
|
|
|
with open(filename, "w", encoding="utf-8") as fwh:
|
|
|
fwh.write(minidom.parseString(ET.tostring(root)).toprettyxml(indent=" "))
|
|
|
|
|
|
- def convert_to_row(self, node):
|
|
|
+ def convert_to_row(self, node: list[ET.Element]) -> list[str]:
|
|
|
return [child.text for child in node]
|
|
|
|
|
|
- def convert_xml_to_csv(self, xmlfile, csvfile):
|
|
|
- record_list = ET.parse(xmlfile).getroot().find("RecordList")
|
|
|
+ def convert_xml_to_csv(self, xmlfile: str, csvfile: str) -> bool:
|
|
|
+ with open(xmlfile) as frh:
|
|
|
+ record_list = ET.parse(frh).getroot().find("RecordList")
|
|
|
header = [child.tag for child in record_list.find("Record")]
|
|
|
bookings = [self.convert_to_row(node) for node in record_list.findall("Record")]
|
|
|
with open(csvfile, "w") as fwh:
|
|
@@ -535,7 +556,7 @@ class GCHR:
|
|
|
cwh.writerows(bookings)
|
|
|
return True
|
|
|
|
|
|
- def convert_csv_to_xml(self, csvfile, xmlfile):
|
|
|
+ def convert_csv_to_xml(self, csvfile: str, xmlfile: str) -> None:
|
|
|
self.makes = {"01": "1844"}
|
|
|
self.sites = {"01-01": "1844"}
|
|
|
with open(csvfile, "r", encoding="latin-1") as frh:
|
|
@@ -543,7 +564,7 @@ class GCHR:
|
|
|
self.export_skr51_xml(csv_reader, self.bookkeep_filter(), 1, list(self.sites.values())[0], xmlfile)
|
|
|
|
|
|
|
|
|
-def gchr_local():
|
|
|
+def gchr_local() -> None:
|
|
|
base_dir = os.getcwd() + "/../GCHR2_Testdaten/Kunden"
|
|
|
for path in Path(base_dir).glob("*"):
|
|
|
if path.is_dir():
|
|
@@ -551,7 +572,7 @@ def gchr_local():
|
|
|
gchr_export(str(path))
|
|
|
|
|
|
|
|
|
-def gchr_export(base_dir):
|
|
|
+def gchr_export(base_dir: str) -> None:
|
|
|
gchr = GCHR(base_dir)
|
|
|
|
|
|
gchr.export_all_periods()
|