gchr_export.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import xml.etree.ElementTree as ET
  2. from collections.abc import Callable
  3. from dataclasses import dataclass
  4. from datetime import datetime
  5. from enum import StrEnum, auto
  6. from xml.dom import minidom
  7. ACCOUNT_INFO = [
  8. "Account",
  9. "Make",
  10. "Site",
  11. "Origin",
  12. "SalesChannel",
  13. "CostCarrier",
  14. "CostAccountingString",
  15. ]
  16. class GchrExportFormat(StrEnum):
  17. SKR51 = auto()
  18. Volkswagen = auto()
  19. Opel = auto()
  20. @dataclass
  21. class GchrExportConfig:
  22. main_site: str
  23. current_year: str
  24. current_month: str
  25. makes_used: dict[str, str]
  26. sites_used: dict[str, str]
  27. first_month: str
  28. period_no: str
  29. bookkeep_filter: dict[str, str]
  30. extraction_date: datetime
  31. export_file: str
  32. bookkeep_records = dict[str, list[str]]
  33. def export_skr51_xml(export_cfg: GchrExportConfig):
  34. record_elements = (
  35. ACCOUNT_INFO
  36. + ["Decimals"]
  37. + list(export_cfg.bookkeep_filter.values())[: export_cfg.period_no]
  38. + ["CumulatedYear"]
  39. )
  40. root = ET.Element("HbvData")
  41. h = ET.SubElement(root, "Header")
  42. for k, v in export_skr51_header(export_cfg).items():
  43. ET.SubElement(h, k).text = str(v)
  44. make_list = ET.SubElement(root, "MakeList")
  45. for make, make_code in export_cfg.makes_used.items():
  46. e = ET.SubElement(make_list, "MakeListEntry")
  47. ET.SubElement(e, "Make").text = make
  48. ET.SubElement(e, "MakeCode").text = make_code
  49. bm_code_list = ET.SubElement(root, "BmCodeList")
  50. for s, bmcode in export_cfg.sites_used.items():
  51. make, site = s.split("-")
  52. e = ET.SubElement(bm_code_list, "BmCodeEntry")
  53. ET.SubElement(e, "Make").text = make
  54. ET.SubElement(e, "Site").text = site
  55. ET.SubElement(e, "BmCode").text = bmcode
  56. record_list = ET.SubElement(root, "RecordList")
  57. for row in export_cfg.bookkeep_records:
  58. record = ET.SubElement(record_list, "Record")
  59. for e in record_elements:
  60. child = ET.SubElement(record, e)
  61. field = row.get(e, 0.0)
  62. if str(field) == "nan":
  63. field = "0"
  64. elif type(field) is float:
  65. field = "{:.0f}".format(field * 100)
  66. child.text = str(field)
  67. with open(export_cfg.export_file, "w", encoding="utf-8") as fwh:
  68. fwh.write(minidom.parseString(ET.tostring(root)).toprettyxml(indent=" "))
  69. def export_skr51_header(export_cfg: GchrExportConfig) -> dict[str, str]:
  70. return {
  71. "Country": "DE",
  72. "MainBmCode": export_cfg.main_site,
  73. "Month": export_cfg.current_month,
  74. "Year": export_cfg.current_year,
  75. "Currency": "EUR",
  76. "NumberOfMakes": len(export_cfg.makes_used),
  77. "NumberOfSites": len(export_cfg.sites_used),
  78. "ExtractionDate": export_cfg.extraction_date.strftime("%d.%m.%Y"),
  79. "ExtractionTime": export_cfg.extraction_date.strftime("%H:%M:%S"),
  80. "BeginFiscalYear": export_cfg.first_month,
  81. }
  82. GchrExportFn = Callable[[GchrExportConfig], None]
  83. EXPORT_FN: dict[GchrExportFormat, GchrExportFn] = {
  84. GchrExportFormat.SKR51: export_skr51_xml,
  85. }
  86. def export_dummy(export_cfg: GchrExportConfig) -> None:
  87. pass
  88. def get_export_fn(export_format: GchrExportFormat) -> GchrExportFn:
  89. return EXPORT_FN.get(export_format, export_dummy)