Merge branch 'develop' into datev_report_headers
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
index 50aed08..00c5177 100644
--- a/erpnext/regional/report/datev/datev.py
+++ b/erpnext/regional/report/datev/datev.py
@@ -8,6 +8,7 @@
all required columns. Used to import the data into the DATEV Software.
"""
from __future__ import unicode_literals
+import datetime
import json
from six import string_types
import frappe
@@ -158,13 +159,84 @@
return gl_entries
-def get_datev_csv(data):
+def get_datev_csv(data, filters):
"""
Fill in missing columns and return a CSV in DATEV Format.
+ For automatic processing, DATEV requires the first line of the CSV file to
+ hold meta data such as the length of account numbers oder the category of
+ the data.
+
Arguments:
data -- array of dictionaries
+ filters -- dict
"""
+ header = [
+ # A = DATEV format
+ # DTVF = created by DATEV software,
+ # EXTF = created by other software
+ "EXTF",
+ # B = version of the DATEV format
+ # 141 = 1.41,
+ # 510 = 5.10,
+ # 720 = 7.20
+ "510",
+ # C = Data category
+ # 21 = Transaction batch (Buchungsstapel),
+ # 67 = Buchungstextkonstanten,
+ # 16 = Debitors/Creditors,
+ # 20 = Account names (Kontenbeschriftungen)
+ "21",
+ # D = Format name
+ # Buchungsstapel,
+ # Buchungstextkonstanten,
+ # Debitoren/Kreditoren,
+ # Kontenbeschriftungen
+ "Buchungsstapel",
+ # E = Format version (regarding format name)
+ "",
+ # F = Generated on
+ datetime.datetime.now().strftime("%Y%m%d"),
+ # G = Imported on -- stays empty
+ "",
+ # H = Origin (SV = other (?), RE = KARE)
+ "SV",
+ # I = Exported by
+ frappe.session.user,
+ # J = Imported by -- stays empty
+ "",
+ # K = Tax consultant number (Beraternummer)
+ # TODO: frappe.get_value("Company", filters.get("company"), "tax_consultant_number"),
+ "",
+ # L = Tax client number (Mandantennummer)
+ # TODO: frappe.get_value("Company", filters.get("company"), "tax_client_number"),
+ "",
+ # M = Start of the fiscal year (Wirtschaftsjahresbeginn)
+ "",
+ # N = Length of account numbers (Sachkontenlänge)
+ "4",
+ # O = Transaction batch start date (YYYYMMDD)
+ frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd"),
+ # P = Transaction batch end date (YYYYMMDD)
+ frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd"),
+ # Q = Description (for example, "January - February 2019 Transactions")
+ "{} - {} Buchungsstapel".format(
+ frappe.utils.formatdate(filters.get('from_date'), "MMMM yyyy"),
+ frappe.utils.formatdate(filters.get('to_date'), "MMMM yyyy")
+ ),
+ # R = Diktatkürzel
+ "",
+ # S = Buchungstyp
+ # 1 = Transaction batch (Buchungsstapel),
+ # 2 = Annual financial statement (Jahresabschluss)
+ "1",
+ # T = Rechnungslegungszweck
+ "",
+ # U = Festschreibung
+ "",
+ # V = Kontoführungs-Währungskennzeichen des Geldkontos
+ frappe.get_value("Company", filters.get("company"), "default_currency")
+ ]
columns = [
# All possible columns must tbe listed here, because DATEV requires them to
# be present in the CSV.
@@ -324,9 +396,10 @@
data_df = pd.DataFrame.from_records(data)
result = empty_df.append(data_df)
- result["Belegdatum"] = pd.to_datetime(result["Belegdatum"])
+ result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
- return result.to_csv(
+ header = ';'.join(header).encode('latin_1')
+ data = result.to_csv(
sep=b';',
# European decimal seperator
decimal=',',
@@ -342,6 +415,7 @@
columns=columns
)
+ return header + b'\r\n' + data
@frappe.whitelist()
def download_datev_csv(filters=None):
@@ -362,12 +436,6 @@
validate_filters(filters)
data = get_gl_entries(filters, as_dict=1)
- filename = 'DATEV_Buchungsstapel_{}-{}_bis_{}'.format(
- filters.get('company'),
- filters.get('from_date'),
- filters.get('to_date')
- )
-
- frappe.response['result'] = get_datev_csv(data)
- frappe.response['doctype'] = filename
+ frappe.response['result'] = get_datev_csv(data, filters)
+ frappe.response['doctype'] = 'EXTF_Buchungsstapel'
frappe.response['type'] = 'csv'