gchr_translate.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import logging
  2. from pathlib import Path
  3. import numpy as np
  4. import pandas as pd
  5. TRANSLATE = [
  6. "Konto_Nr_Händler",
  7. "Konto_Nr_SKR51",
  8. "Marke",
  9. "Standort",
  10. "Konto_Nr",
  11. "Kostenstelle",
  12. "Absatzkanal",
  13. "Kostenträger",
  14. "Kontoart",
  15. "Konto_1",
  16. "KRM",
  17. "IsNumeric",
  18. ]
  19. def load_translation(
  20. account_translation: str, debug_file: str, export_invalid_filename: str
  21. ) -> tuple[dict[str, str], dict[str, str], pd.DataFrame, pd.DataFrame]:
  22. account_translation_gchr = account_translation[:-4] + "_GCHR.csv"
  23. if (
  24. Path(account_translation_gchr).exists()
  25. and Path(account_translation_gchr).stat().st_mtime >= Path(account_translation).stat().st_mtime
  26. and False
  27. ):
  28. df_translate = pd.read_csv(
  29. account_translation_gchr,
  30. decimal=",",
  31. sep=";",
  32. encoding="latin-1",
  33. converters={i: str for i in range(0, 200)},
  34. )
  35. makes = get_makes_from_translation(df_translate)
  36. sites = get_sites_from_translation(df_translate)
  37. df_translate2 = (
  38. df_translate.copy().drop(columns=["Konto_Nr_Händler"]).drop_duplicates().set_index("Konto_Nr_SKR51")
  39. )
  40. return (makes, sites, df_translate, df_translate2)
  41. df_translate_import = pd.read_csv(
  42. account_translation,
  43. decimal=",",
  44. sep=";",
  45. encoding="latin-1",
  46. converters={i: str for i in range(0, 200)},
  47. usecols=["Konto_Nr_Händler", "Konto_Nr_SKR51", "Marke", "Standort", "Marke_HBV", "Standort_HBV"],
  48. ) # .reset_index()
  49. makes = get_makes_from_translation(df_translate_import)
  50. sites = get_sites_from_translation(df_translate_import)
  51. df_prepared = prepare_translation(df_translate_import)
  52. df_translate = special_translation(df_prepared, makes, sites, debug_file, export_invalid_filename)
  53. df_translate2 = df_translate.copy().drop(columns=["Konto_Nr_Händler"]).drop_duplicates().set_index("Konto_Nr_SKR51")
  54. df_translate3 = (
  55. df_translate[["Kontoart", "Konto_Nr_SKR51", "Konto_Nr_Händler"]]
  56. .copy()
  57. .sort_values(by=["Kontoart", "Konto_Nr_SKR51"])
  58. )
  59. df_translate3.to_csv(account_translation_gchr, decimal=",", sep=";", encoding="latin-1", index=False)
  60. return (makes, sites, df_translate, df_translate2)
  61. def get_makes_from_translation(df_translate_import: pd.DataFrame) -> dict[str, str]:
  62. df_makes = df_translate_import[["Marke", "Marke_HBV"]].copy().drop_duplicates()
  63. df_makes = df_makes[df_makes["Marke_HBV"] != "0000"]
  64. makes = dict([(e["Marke"], e["Marke_HBV"]) for e in df_makes.to_dict(orient="records")])
  65. makes["99"] = "0000"
  66. return makes
  67. def get_sites_from_translation(df_translate_import: pd.DataFrame) -> dict[str, str]:
  68. df_sites = df_translate_import[["Marke", "Standort", "Standort_HBV"]].copy().drop_duplicates()
  69. df_sites["Standort_HBV"] = np.where(df_sites["Standort_HBV"].str.len() < 4, "0000", df_sites["Standort_HBV"])
  70. sites = dict([(e["Marke"] + "-" + e["Standort"], e["Standort_HBV"]) for e in df_sites.to_dict(orient="records")])
  71. return sites
  72. def prepare_translation(df_translate_import: pd.DataFrame, dest_account: str = "01-01-0860-10-00-00") -> pd.DataFrame:
  73. df = df_translate_import[
  74. [
  75. "Konto_Nr_Händler",
  76. "Konto_Nr_SKR51",
  77. ]
  78. ].drop_duplicates()
  79. logging.info(df.shape)
  80. row = {
  81. "Konto_Nr_Händler": "01-01-0861-00-00-00",
  82. "Konto_Nr_SKR51": dest_account,
  83. }
  84. df = pd.concat([df, pd.DataFrame.from_records([row])])
  85. df.set_index("Konto_Nr_Händler")
  86. return df
  87. def special_translation(
  88. df: pd.DataFrame, makes: dict[str, str], sites: dict[str, str], debug_file: str, export_invalid_filename: str
  89. ) -> pd.DataFrame:
  90. df["Konto_Nr_Händler"] = df["Konto_Nr_Händler"].str.upper()
  91. df["Konto_Nr_SKR51"] = df["Konto_Nr_SKR51"].str.upper()
  92. df = extract_acct_info(df)
  93. df["Konto_Nr"] = df["Konto_Nr"].str.upper()
  94. logging.info(df.shape)
  95. logging.info(df.columns)
  96. logging.info(df.head())
  97. logging.info("df: " + str(df.shape))
  98. df["Bilanz"] = df["Konto_Nr"].str.match(r"^[013]")
  99. df["Kontoart"] = np.where(df["Bilanz"], "1", "2")
  100. df["Kontoart"] = np.where(df["Konto_Nr"].str.contains("_STK"), "3", df["Kontoart"])
  101. df["Kontoart"] = np.where(df["Konto_Nr"].str.match(r"^[9]"), "3", df["Kontoart"])
  102. df["Konto_1"] = df["Konto_Nr"].str.slice(0, 1)
  103. # fehlende Marken- und Standortzuordnung
  104. df["Marke"] = np.where(df["Marke"].isin(makes.keys()), df["Marke"], "99")
  105. df["Marke_Standort"] = df["Marke"] + "-" + df["Standort"]
  106. df["Standort"] = np.where(df["Marke_Standort"].isin(sites.keys()), df["Standort"], "01")
  107. if False:
  108. df_debug = df.drop(columns=["Bilanz"])
  109. logging.info(df_debug.groupby(["Kontoart"]).aggregate("sum"))
  110. logging.info(df_debug.groupby(["Kontoart", "Konto_1"]).aggregate("sum"))
  111. logging.info(df_debug.groupby(["Konto_Nr"]).aggregate("sum"))
  112. df_debug.groupby(["Konto_Nr"]).aggregate("sum").to_csv(debug_file, decimal=",", sep=";", encoding="latin-1")
  113. # Bereinigung GW-Kostenträger
  114. kst_nw_verkauf_1 = (df["Konto_Nr"].str.match(r"^[78]0")) & (df["Kostenstelle"].str.match(r"^[^1]\d"))
  115. df["Kostenstelle"] = np.where(kst_nw_verkauf_1 == True, "11", df["Kostenstelle"])
  116. kst_konto_7010 = df["Konto_Nr"].str.match(r"^[78]01[01]")
  117. df["Kostenstelle"] = np.where(kst_konto_7010 == True, "14", df["Kostenstelle"])
  118. kst_gw_verkauf_2 = (df["Konto_Nr"].str.match(r"^[78]1")) & (df["Kostenstelle"].str.match(r"^[^2]\d"))
  119. df["Kostenstelle"] = np.where(kst_gw_verkauf_2 == True, "21", df["Kostenstelle"])
  120. kst_gw_verkauf_3 = (df["Konto_Nr"].str.match(r"^[78]3")) & (df["Kostenstelle"].str.match(r"^[^3]\d"))
  121. df["Kostenstelle"] = np.where(kst_gw_verkauf_3 == True, "31", df["Kostenstelle"])
  122. kst_gw_verkauf_4 = (df["Konto_Nr"].str.match(r"^[78]4")) & (df["Kostenstelle"].str.match(r"^[^4]\d"))
  123. df["Kostenstelle"] = np.where(kst_gw_verkauf_4 == True, "41", df["Kostenstelle"])
  124. kst_gw_verkauf_x420 = df["Konto_Nr"].str.match(r"^[78]420")
  125. df["Kostenstelle"] = np.where(kst_gw_verkauf_x420 == True, "42", df["Kostenstelle"])
  126. kst_gw_verkauf_5 = (df["Konto_Nr"].str.match(r"^[78]50")) & (df["Kostenstelle"].str.match(r"^[^5]\d"))
  127. df["Kostenstelle"] = np.where(kst_gw_verkauf_5 == True, "51", df["Kostenstelle"])
  128. kst_gw_verkauf_50 = (df["Konto_Nr"].str.match(r"^[78]")) & (df["Kostenstelle"].str.match(r"^2"))
  129. df["Kostenträger"] = np.where(kst_gw_verkauf_50 == True, "52", df["Kostenträger"])
  130. df["Kostenträger"] = np.where(
  131. (kst_gw_verkauf_50 == True) & (df["Marke"] == "01"),
  132. "50",
  133. df["Kostenträger"],
  134. )
  135. ktr_nw_verkauf_00 = (
  136. (df["Konto_Nr"].str.match(r"^[78]2"))
  137. & (df["Kostenstelle"].str.match(r"^1"))
  138. & (df["Kostenträger"].str.match(r"^[^01234]"))
  139. )
  140. df["Kostenträger"] = np.where(ktr_nw_verkauf_00 == True, "00", df["Kostenträger"])
  141. ktr_gw_stk_50 = (df["Konto_Nr"].str.match(r"^9130")) & (df["Kostenstelle"].str.match(r"^2"))
  142. df["Kostenträger"] = np.where(ktr_gw_stk_50 == True, "52", df["Kostenträger"])
  143. df["Kostenträger"] = np.where((ktr_gw_stk_50 == True) & (df["Marke"] == "01"), "50", df["Kostenträger"])
  144. df["Kostenträger"] = np.where(df["Bilanz"] == True, "00", df["Kostenträger"])
  145. abs_konto_5 = (df["Konto_Nr"].str.match("^5")) | (df["Konto_Nr"].str.match("^9143"))
  146. df["Absatzkanal"] = np.where(abs_konto_5 == True, "99", df["Absatzkanal"])
  147. kst_ktr_konto_5005 = (df["Konto_Nr"].str.match("^5005")) & (df["Kostenstelle"].str.match(r"^[^12]"))
  148. df["Kostenstelle"] = np.where(kst_ktr_konto_5005 == True, "20", df["Kostenstelle"])
  149. df["Kostenträger"] = np.where(kst_ktr_konto_5005 == True, "50", df["Kostenträger"])
  150. kst_ktr_konto_5007 = (df["Konto_Nr"].str.match("^5007")) & (df["Kostenstelle"].str.match(r"^([^4]|42)"))
  151. df["Kostenstelle"] = np.where(kst_ktr_konto_5007 == True, "41", df["Kostenstelle"])
  152. df["Kostenträger"] = np.where(kst_ktr_konto_5007 == True, "70", df["Kostenträger"])
  153. ktr_konto_914x = (df["Konto_Nr"].str.match("^914[34]")) & (df["Kostenträger"].str.match(r"^[^7]"))
  154. df["Kostenträger"] = np.where(ktr_konto_914x == True, "70", df["Kostenträger"])
  155. ktr_teile_30_60 = (
  156. (df["Konto_Nr"].str.match(r"^[578]"))
  157. & (df["Kostenstelle"].str.match(r"^[3]"))
  158. & (df["Kostenträger"].str.match(r"^[^6]"))
  159. )
  160. df["Kostenträger"] = np.where(ktr_teile_30_60 == True, "60", df["Kostenträger"])
  161. ktr_service_40_70 = (
  162. (df["Konto_Nr"].str.match(r"^[578]"))
  163. & (df["Kostenstelle"].str.match(r"^[4]"))
  164. & (df["Kostenträger"].str.match(r"^[^7]"))
  165. )
  166. df["Kostenträger"] = np.where(ktr_service_40_70 == True, "70", df["Kostenträger"])
  167. ktr_mw_70 = (df["Konto_Nr"].str.match(r"^[78]50")) & (df["Kostenträger"].str.match(r"^70"))
  168. df["Kostenträger"] = np.where(ktr_mw_70 == True, "00", df["Kostenträger"])
  169. ktr_mw_70_vz = (
  170. (df["Konto_Nr"].str.match(r"^5"))
  171. & (df["Kostenstelle"].str.match(r"^5[156]"))
  172. & (df["Kostenträger"].str.match(r"^70"))
  173. )
  174. df["Kostenträger"] = np.where(ktr_mw_70_vz == True, "00", df["Kostenträger"])
  175. # Volkswagen Specials
  176. kto_1250 = (df["Konto_Nr"].str.match(r"^1250")) & ~(df["Kostenstelle"].str.match(r"^1"))
  177. df["Kostenstelle"] = np.where(kto_1250, "11", df["Kostenstelle"])
  178. kto_1729 = (df["Konto_Nr"].str.match(r"^1729")) & (df["Kostenstelle"].str.match(r"^9"))
  179. df["Kostenstelle"] = np.where(kto_1729, "11", df["Kostenstelle"])
  180. kto_1795 = (df["Konto_Nr"].str.match(r"^1795")) & ~(df["Kostenstelle"].str.match(r"^3"))
  181. df["Kostenstelle"] = np.where(kto_1795, "31", df["Kostenstelle"])
  182. kto_2 = (df["Konto_Nr"].str.match(r"^2")) & (df["Kostenträger"].str.match(r"^70"))
  183. df["Kostenträger"] = np.where(kto_2, "00", df["Kostenträger"])
  184. kto_4560 = (df["Konto_Nr"].isin(["4560", "4570", "5004"])) & (df["Kostenträger"].str.match(r"^70"))
  185. df["Kostenträger"] = np.where(kto_4560, "00", df["Kostenträger"])
  186. kto_8520 = (df["Konto_Nr"].isin(["8520", "8900"])) & (df["Kostenstelle"].str.match(r"^51"))
  187. df["Kostenträger"] = np.where(kto_8520, "00", df["Kostenträger"])
  188. kto_8999 = (df["Konto_Nr"].isin(["8999"])) & (df["Kostenstelle"].str.match(r"^30"))
  189. df["Kostenträger"] = np.where(kto_8999, "00", df["Kostenträger"])
  190. kto_8860 = df["Konto_Nr"].isin(["8860"])
  191. df["Kostenträger"] = np.where(kto_8860, "00", df["Kostenträger"])
  192. kto_3000 = (df["Konto_Nr"].isin(["3000", "3001"])) & ~(df["Kostenstelle"].isin(["10", "11", "13"]))
  193. df["Kostenstelle"] = np.where(kto_3000, "11", df["Kostenstelle"])
  194. kto_3010 = df["Konto_Nr"].isin(["3010", "3011"])
  195. df["Kostenstelle"] = np.where(kto_3010, "14", df["Kostenstelle"])
  196. kto_3110 = (df["Konto_Nr"].isin(["3110"])) & (df["Kostenstelle"].str.match(r"^1"))
  197. df["Kostenstelle"] = np.where(kto_3110, "20", df["Kostenstelle"])
  198. kto_3300 = (df["Konto_Nr"].isin(["3300"])) & ~(df["Kostenstelle"].str.match(r"^3"))
  199. df["Kostenstelle"] = np.where(kto_3300, "31", df["Kostenstelle"])
  200. kto_0200 = (df["Konto_Nr"].isin(["0200"])) & (df["Kostenstelle"].isin(["90"]))
  201. df["Kostenstelle"] = np.where(kto_0200, "40", df["Kostenstelle"])
  202. kto_3510 = (df["Konto_Nr"].isin(["3510"])) & (df["Kostenstelle"].isin(["00"]))
  203. df["Kostenstelle"] = np.where(kto_3510, "51", df["Kostenstelle"])
  204. df["Kostenträger"] = np.where(kto_3510, "01", df["Kostenträger"])
  205. df["KRM"] = df["Marke"] + df["Standort"] + df["Kostenstelle"] + df["Absatzkanal"] + df["Kostenträger"]
  206. df["Konto_Nr_SKR51"] = (
  207. (df["Marke"] + "-" + df["Standort"] + "-" + df["Konto_Nr"])
  208. + "-"
  209. + (df["Kostenstelle"] + "-" + df["Absatzkanal"] + "-" + df["Kostenträger"])
  210. )
  211. df["IsNumeric"] = (
  212. (df["KRM"].str.isdigit())
  213. & (df["Konto_Nr"].str.isdigit())
  214. & (df["Konto_Nr"].str.len() == 4)
  215. # & (df["Konto_Nr_SKR51"].str.len() == 19)
  216. )
  217. df_invalid = df[df["IsNumeric"] == False]
  218. df_invalid.to_csv(export_invalid_filename, decimal=",", sep=";", encoding="latin-1", index=False)
  219. return df[df["IsNumeric"] == True][TRANSLATE]
  220. def extract_acct_info(df: pd.DataFrame) -> pd.DataFrame:
  221. acct_info = [
  222. "Marke",
  223. "Standort",
  224. "Konto_Nr",
  225. "Kostenstelle",
  226. "Absatzkanal",
  227. "Kostenträger",
  228. ]
  229. df["HasFiveDashes"] = df["Konto_Nr_SKR51"].str.count("-") == 5
  230. df["Invalid"] = "XX-XX-XXXX-XX-XX-XX"
  231. df["Konto_Nr_SKR51"] = np.where(
  232. df["HasFiveDashes"],
  233. df["Konto_Nr_SKR51"],
  234. df["Invalid"],
  235. )
  236. df[acct_info] = df["Konto_Nr_SKR51"].str.split(pat="-", n=6, expand=True)
  237. return df