gchr_translate.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import logging
  2. import numpy as np
  3. import pandas as pd
  4. TRANSLATE = [
  5. "Konto_Nr_Händler",
  6. "Konto_Nr_SKR51",
  7. "Marke",
  8. "Standort",
  9. "Konto_Nr",
  10. "Kostenstelle",
  11. "Absatzkanal",
  12. "Kostenträger",
  13. "Kontoart",
  14. "Konto_1",
  15. "KRM",
  16. "IsNumeric",
  17. ]
  18. def load_translation(
  19. account_translation: str, debug_file: str, export_invalid_filename: str
  20. ) -> tuple[dict[str, str], dict[str, str], pd.DataFrame, pd.DataFrame]:
  21. df_translate_import = pd.read_csv(
  22. account_translation,
  23. decimal=",",
  24. sep=";",
  25. encoding="latin-1",
  26. converters={i: str for i in range(0, 200)},
  27. ).reset_index()
  28. makes = get_makes_from_translation(df_translate_import)
  29. sites = get_sites_from_translation(df_translate_import)
  30. df_prepared = prepare_translation(df_translate_import)
  31. df_translate = special_translation(df_prepared, makes, sites, debug_file, export_invalid_filename)
  32. df_translate2 = df_translate.copy().drop(columns=["Konto_Nr_Händler"]).drop_duplicates().set_index("Konto_Nr_SKR51")
  33. df_translate3 = (
  34. df_translate[["Kontoart", "Konto_Nr_SKR51", "Konto_Nr_Händler"]]
  35. .copy()
  36. .sort_values(by=["Kontoart", "Konto_Nr_SKR51"])
  37. )
  38. df_translate3.to_csv(account_translation[:-4] + "_GCHR.csv", decimal=",", sep=";", encoding="latin-1", index=False)
  39. return (makes, sites, df_translate, df_translate2)
  40. def get_makes_from_translation(df_translate_import: pd.DataFrame) -> dict[str, str]:
  41. df_makes = df_translate_import[["Marke", "Marke_HBV"]].copy().drop_duplicates()
  42. df_makes = df_makes[df_makes["Marke_HBV"] != "0000"]
  43. makes = dict([(e["Marke"], e["Marke_HBV"]) for e in df_makes.to_dict(orient="records")])
  44. makes["99"] = "0000"
  45. return makes
  46. def get_sites_from_translation(df_translate_import: pd.DataFrame) -> dict[str, str]:
  47. df_sites = df_translate_import[["Marke", "Standort", "Standort_HBV"]].copy().drop_duplicates()
  48. df_sites["Standort_HBV"] = np.where(df_sites["Standort_HBV"].str.len() != 6, "0000", df_sites["Standort_HBV"])
  49. sites = dict([(e["Marke"] + "-" + e["Standort"], e["Standort_HBV"]) for e in df_sites.to_dict(orient="records")])
  50. return sites
  51. def prepare_translation(df_translate_import: pd.DataFrame) -> pd.DataFrame:
  52. df = df_translate_import[
  53. [
  54. "Konto_Nr_Händler",
  55. "Konto_Nr_SKR51",
  56. ]
  57. ].drop_duplicates()
  58. logging.info(df.shape)
  59. row = {
  60. "Konto_Nr_Händler": "01-01-0861-00-00-00",
  61. "Konto_Nr_SKR51": "01-01-0861-00-00-00",
  62. }
  63. df = pd.concat([df, pd.DataFrame.from_records([row])])
  64. df.set_index("Konto_Nr_Händler")
  65. return df
  66. def special_translation(
  67. df: pd.DataFrame, makes: dict[str, str], sites: dict[str, str], debug_file: str, export_invalid_filename: str
  68. ) -> pd.DataFrame:
  69. df["Konto_Nr_Händler"] = df["Konto_Nr_Händler"].str.upper()
  70. df["Konto_Nr_SKR51"] = df["Konto_Nr_SKR51"].str.upper()
  71. df = extract_acct_info(df)
  72. df["Konto_Nr"] = df["Konto_Nr"].str.upper()
  73. logging.info(df.shape)
  74. logging.info(df.columns)
  75. logging.info(df.head())
  76. logging.info("df: " + str(df.shape))
  77. df["Bilanz"] = df["Konto_Nr"].str.match(r"^[013]")
  78. df["Kontoart"] = np.where(df["Bilanz"], "1", "2")
  79. df["Kontoart"] = np.where(df["Konto_Nr"].str.contains("_STK"), "3", df["Kontoart"])
  80. df["Kontoart"] = np.where(df["Konto_Nr"].str.match(r"^[9]"), "3", df["Kontoart"])
  81. df["Konto_1"] = df["Konto_Nr"].str.slice(0, 1)
  82. # fehlende Marken- und Standortzuordnung
  83. df["Marke"] = np.where(df["Marke"].isin(makes.keys()), df["Marke"], "99")
  84. df["Marke_Standort"] = df["Marke"] + "-" + df["Standort"]
  85. df["Standort"] = np.where(df["Marke_Standort"].isin(sites.keys()), df["Standort"], "01")
  86. df_debug = df.drop(columns=["Bilanz"])
  87. logging.info(df_debug.groupby(["Kontoart"]).aggregate("sum"))
  88. logging.info(df_debug.groupby(["Kontoart", "Konto_1"]).aggregate("sum"))
  89. logging.info(df_debug.groupby(["Konto_Nr"]).aggregate("sum"))
  90. df_debug.groupby(["Konto_Nr"]).aggregate("sum").to_csv(debug_file, decimal=",", sep=";", encoding="latin-1")
  91. # Bereinigung GW-Kostenträger
  92. df["NW_Verkauf_1"] = (df["Konto_Nr"].str.match(r"^[78]0")) & (df["Kostenstelle"].str.match(r"^[^1]\d"))
  93. df["Kostenstelle"] = np.where(df["NW_Verkauf_1"] == True, "11", df["Kostenstelle"])
  94. df["Konto_7010"] = df["Konto_Nr"].str.match(r"^[78]01[01]")
  95. df["Kostenstelle"] = np.where(df["Konto_7010"] == True, "14", df["Kostenstelle"])
  96. df["GW_Verkauf_2"] = (df["Konto_Nr"].str.match(r"^[78]1")) & (df["Kostenstelle"].str.match(r"^[^2]\d"))
  97. df["Kostenstelle"] = np.where(df["GW_Verkauf_2"] == True, "21", df["Kostenstelle"])
  98. df["GW_Verkauf_3"] = (df["Konto_Nr"].str.match(r"^[78]3")) & (df["Kostenstelle"].str.match(r"^[^3]\d"))
  99. df["Kostenstelle"] = np.where(df["GW_Verkauf_3"] == True, "31", df["Kostenstelle"])
  100. df["GW_Verkauf_4"] = (df["Konto_Nr"].str.match(r"^[78]4")) & (df["Kostenstelle"].str.match(r"^[^4]\d"))
  101. df["Kostenstelle"] = np.where(df["GW_Verkauf_4"] == True, "41", df["Kostenstelle"])
  102. df["GW_Verkauf_x420"] = df["Konto_Nr"].str.match(r"^[78]420")
  103. df["Kostenstelle"] = np.where(df["GW_Verkauf_x420"] == True, "42", df["Kostenstelle"])
  104. df["GW_Verkauf_5"] = (df["Konto_Nr"].str.match(r"^[78]5")) & (df["Kostenstelle"].str.match(r"^[^5]\d"))
  105. df["Kostenstelle"] = np.where(df["GW_Verkauf_5"] == True, "51", df["Kostenstelle"])
  106. df["GW_Verkauf_50"] = (df["Konto_Nr"].str.match(r"^[78]")) & (df["Kostenstelle"].str.match(r"^2"))
  107. df["Kostenträger"] = np.where(df["GW_Verkauf_50"] == True, "52", df["Kostenträger"])
  108. df["Kostenträger"] = np.where(
  109. (df["GW_Verkauf_50"] == True) & (df["Marke"] == "01"),
  110. "50",
  111. df["Kostenträger"],
  112. )
  113. df["NW_Verkauf_00"] = (
  114. (df["Konto_Nr"].str.match(r"^[78]2"))
  115. & (df["Kostenstelle"].str.match(r"^1"))
  116. & (df["Kostenträger"].str.match(r"^[^01234]"))
  117. )
  118. df["Kostenträger"] = np.where(df["NW_Verkauf_00"] == True, "00", df["Kostenträger"])
  119. df["GW_Stk_50"] = (df["Konto_Nr"].str.match(r"^9130")) & (df["Kostenstelle"].str.match(r"^2"))
  120. df["Kostenträger"] = np.where(df["GW_Stk_50"] == True, "52", df["Kostenträger"])
  121. df["Kostenträger"] = np.where((df["GW_Stk_50"] == True) & (df["Marke"] == "01"), "50", df["Kostenträger"])
  122. df["Kostenträger"] = np.where(df["Bilanz"] == True, "00", df["Kostenträger"])
  123. df["Konto_5er"] = (df["Konto_Nr"].str.match("^5")) | (df["Konto_Nr"].str.match("^9143"))
  124. df["Absatzkanal"] = np.where(df["Konto_5er"] == True, "99", df["Absatzkanal"])
  125. df["Konto_5005"] = (df["Konto_Nr"].str.match("^5005")) & (df["Kostenstelle"].str.match(r"^[^12]"))
  126. df["Kostenstelle"] = np.where(df["Konto_5005"] == True, "20", df["Kostenstelle"])
  127. df["Kostenträger"] = np.where(df["Konto_5005"] == True, "50", df["Kostenträger"])
  128. df["Konto_5007"] = (df["Konto_Nr"].str.match("^5007")) & (df["Kostenstelle"].str.match(r"^([^4]|42)"))
  129. df["Kostenstelle"] = np.where(df["Konto_5007"] == True, "41", df["Kostenstelle"])
  130. df["Kostenträger"] = np.where(df["Konto_5007"] == True, "70", df["Kostenträger"])
  131. df["Konto_914er"] = (df["Konto_Nr"].str.match("^914[34]")) & (df["Kostenträger"].str.match(r"^[^7]"))
  132. df["Kostenträger"] = np.where(df["Konto_914er"] == True, "70", df["Kostenträger"])
  133. df["Teile_30_60"] = (
  134. (df["Konto_Nr"].str.match(r"^[578]"))
  135. & (df["Kostenstelle"].str.match(r"^[3]"))
  136. & (df["Kostenträger"].str.match(r"^[^6]"))
  137. )
  138. df["Kostenträger"] = np.where(df["Teile_30_60"] == True, "60", df["Kostenträger"])
  139. df["Service_40_70"] = (
  140. (df["Konto_Nr"].str.match(r"^[578]"))
  141. & (df["Kostenstelle"].str.match(r"^[4]"))
  142. & (df["Kostenträger"].str.match(r"^[^7]"))
  143. )
  144. df["Kostenträger"] = np.where(df["Service_40_70"] == True, "70", df["Kostenträger"])
  145. df["KRM"] = df["Marke"] + df["Standort"] + df["Kostenstelle"] + df["Absatzkanal"] + df["Kostenträger"]
  146. df["Konto_Nr_SKR51"] = (
  147. (df["Marke"] + "-" + df["Standort"] + "-" + df["Konto_Nr"])
  148. + "-"
  149. + (df["Kostenstelle"] + "-" + df["Absatzkanal"] + "-" + df["Kostenträger"])
  150. )
  151. df["IsNumeric"] = (
  152. (df["KRM"].str.isdigit())
  153. & (df["Konto_Nr"].str.isdigit())
  154. & (df["Konto_Nr"].str.len() == 4)
  155. # & (df["Konto_Nr_SKR51"].str.len() == 19)
  156. )
  157. df_invalid = df[df["IsNumeric"] == False]
  158. df_invalid.to_csv(export_invalid_filename, decimal=",", sep=";", encoding="latin-1", index=False)
  159. return df[df["IsNumeric"] == True][TRANSLATE]
  160. def extract_acct_info(df: pd.DataFrame) -> pd.DataFrame:
  161. acct_info = [
  162. "Marke",
  163. "Standort",
  164. "Konto_Nr",
  165. "Kostenstelle",
  166. "Absatzkanal",
  167. "Kostenträger",
  168. ]
  169. df["HasFiveDashes"] = df["Konto_Nr_SKR51"].str.count("-") == 5
  170. df["Invalid"] = "XX-XX-XXXX-XX-XX-XX"
  171. df["Konto_Nr_SKR51"] = np.where(
  172. df["HasFiveDashes"],
  173. df["Konto_Nr_SKR51"],
  174. df["Invalid"],
  175. )
  176. df[acct_info] = df["Konto_Nr_SKR51"].str.split(pat="-", n=6, expand=True)
  177. return df