mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-20 01:55:01 +00:00
fix(regional): backport DATEV fix (#21281)
* fix: quote nonnumeric values * fix(DATEV Settings): restrict max length of IDs * fix: display Columns as Dynamic Link instead of as Data * fix: add column "Belegfeld 1" * fix: truncate column Buchungstext to 60 chars * fix: make header compatible to current DATEV Format 7.00 * fix: column names and descriptions
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Client ID",
|
||||
"length": 5,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -42,6 +43,7 @@
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Consultant ID",
|
||||
"length": 7,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -57,7 +59,7 @@
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"modified": "2019-08-14 00:03:26.616460",
|
||||
"modified": "2020-04-15 12:59:57.786506",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "DATEV Settings",
|
||||
|
||||
@@ -12,6 +12,7 @@ import datetime
|
||||
import json
|
||||
import six
|
||||
from six import string_types
|
||||
from csv import QUOTE_NONNUMERIC
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
@@ -57,8 +58,8 @@ def get_columns():
|
||||
"fieldtype": "Data",
|
||||
},
|
||||
{
|
||||
"label": "Kontonummer",
|
||||
"fieldname": "Kontonummer",
|
||||
"label": "Konto",
|
||||
"fieldname": "Konto",
|
||||
"fieldtype": "Data",
|
||||
},
|
||||
{
|
||||
@@ -71,6 +72,11 @@ def get_columns():
|
||||
"fieldname": "Belegdatum",
|
||||
"fieldtype": "Date",
|
||||
},
|
||||
{
|
||||
"label": "Belegfeld 1",
|
||||
"fieldname": "Belegfeld 1",
|
||||
"fieldtype": "Data",
|
||||
},
|
||||
{
|
||||
"label": "Buchungstext",
|
||||
"fieldname": "Buchungstext",
|
||||
@@ -79,22 +85,26 @@ def get_columns():
|
||||
{
|
||||
"label": "Beleginfo - Art 1",
|
||||
"fieldname": "Beleginfo - Art 1",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"options": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Beleginfo - Inhalt 1",
|
||||
"fieldname": "Beleginfo - Inhalt 1",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"options": "Beleginfo - Art 1"
|
||||
},
|
||||
{
|
||||
"label": "Beleginfo - Art 2",
|
||||
"fieldname": "Beleginfo - Art 2",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"options": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Beleginfo - Inhalt 2",
|
||||
"fieldname": "Beleginfo - Inhalt 2",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"options": "Beleginfo - Art 2"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -122,13 +132,14 @@ def get_gl_entries(filters, as_dict):
|
||||
case gl.debit when 0 then 'H' else 'S' end as 'Soll/Haben-Kennzeichen',
|
||||
|
||||
/* account number or, if empty, party account number */
|
||||
coalesce(acc.account_number, acc_pa.account_number) as 'Kontonummer',
|
||||
coalesce(acc.account_number, acc_pa.account_number) as 'Konto',
|
||||
|
||||
/* against number or, if empty, party against number */
|
||||
coalesce(acc_against.account_number, acc_against_pa.account_number) as 'Gegenkonto (ohne BU-Schlüssel)',
|
||||
|
||||
gl.posting_date as 'Belegdatum',
|
||||
gl.remarks as 'Buchungstext',
|
||||
gl.voucher_no as 'Belegfeld 1',
|
||||
LEFT(gl.remarks, 60) as 'Buchungstext',
|
||||
gl.voucher_type as 'Beleginfo - Art 1',
|
||||
gl.voucher_no as 'Beleginfo - Inhalt 1',
|
||||
gl.against_voucher_type as 'Beleginfo - Art 2',
|
||||
@@ -177,16 +188,19 @@ def get_datev_csv(data, filters):
|
||||
data -- array of dictionaries
|
||||
filters -- dict
|
||||
"""
|
||||
coa = frappe.get_value("Company", filters.get("company"), "chart_of_accounts")
|
||||
coa_used = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "")
|
||||
|
||||
header = [
|
||||
# A = DATEV format
|
||||
# A = DATEV-Format-KZ
|
||||
# DTVF = created by DATEV software,
|
||||
# EXTF = created by other software
|
||||
"EXTF",
|
||||
'"EXTF"',
|
||||
# B = version of the DATEV format
|
||||
# 141 = 1.41,
|
||||
# 510 = 5.10,
|
||||
# 720 = 7.20
|
||||
"510",
|
||||
"700",
|
||||
# C = Data category
|
||||
# 21 = Transaction batch (Buchungsstapel),
|
||||
# 67 = Buchungstextkonstanten,
|
||||
@@ -200,23 +214,22 @@ def get_datev_csv(data, filters):
|
||||
# Kontenbeschriftungen
|
||||
"Buchungsstapel",
|
||||
# E = Format version (regarding format name)
|
||||
"",
|
||||
"9",
|
||||
# F = Generated on
|
||||
datetime.datetime.now().strftime("%Y%m%d"),
|
||||
datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '000',
|
||||
# G = Imported on -- stays empty
|
||||
"",
|
||||
# H = Origin (SV = other (?), RE = KARE)
|
||||
"SV",
|
||||
# H = Herkunfts-Kennzeichen (Origin)
|
||||
# Any two letters
|
||||
'"EN"',
|
||||
# I = Exported by
|
||||
frappe.session.user,
|
||||
'"%s"' % frappe.session.user,
|
||||
# J = Imported by -- stays empty
|
||||
"",
|
||||
# K = Tax consultant number (Beraternummer)
|
||||
frappe.get_value("DATEV Settings", filters.get("company"), "consultant_number") or "",
|
||||
"",
|
||||
# L = Tax client number (Mandantennummer)
|
||||
frappe.get_value("DATEV Settings", filters.get("company"), "client_number") or "",
|
||||
"",
|
||||
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
||||
frappe.utils.formatdate(frappe.defaults.get_user_default("year_start_date"), "yyyyMMdd"),
|
||||
# N = Length of account numbers (Sachkontenlänge)
|
||||
@@ -226,10 +239,7 @@ def get_datev_csv(data, filters):
|
||||
# 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")
|
||||
),
|
||||
"Buchungsstapel",
|
||||
# R = Diktatkürzel
|
||||
"",
|
||||
# S = Buchungstyp
|
||||
@@ -237,11 +247,29 @@ def get_datev_csv(data, filters):
|
||||
# 2 = Annual financial statement (Jahresabschluss)
|
||||
"1",
|
||||
# T = Rechnungslegungszweck
|
||||
"",
|
||||
"0", # vom Rechnungslegungszweck unabhängig
|
||||
# U = Festschreibung
|
||||
"",
|
||||
"0", # keine Festschreibung
|
||||
# V = Kontoführungs-Währungskennzeichen des Geldkontos
|
||||
frappe.get_value("Company", filters.get("company"), "default_currency")
|
||||
frappe.get_value("Company", filters.get("company"), "default_currency"),
|
||||
# reserviert
|
||||
'',
|
||||
# Derivatskennzeichen
|
||||
'',
|
||||
# reserviert
|
||||
'',
|
||||
# reserviert
|
||||
'',
|
||||
# SKR
|
||||
'"%s"' % coa_used,
|
||||
# Branchen-Lösungs-ID
|
||||
'',
|
||||
# reserviert
|
||||
'',
|
||||
# reserviert
|
||||
'',
|
||||
# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
|
||||
''
|
||||
]
|
||||
columns = [
|
||||
# All possible columns must tbe listed here, because DATEV requires them to
|
||||
@@ -255,24 +283,27 @@ def get_datev_csv(data, filters):
|
||||
"Basis-Umsatz",
|
||||
"WKZ Basis-Umsatz",
|
||||
# Konto/Gegenkonto
|
||||
"Kontonummer",
|
||||
"Konto",
|
||||
"Gegenkonto (ohne BU-Schlüssel)",
|
||||
"BU-Schlüssel",
|
||||
# Datum
|
||||
"Belegdatum",
|
||||
# Belegfelder
|
||||
# Rechnungs- / Belegnummer
|
||||
"Belegfeld 1",
|
||||
# z.B. Fälligkeitsdatum Format: TTMMJJ
|
||||
"Belegfeld 2",
|
||||
# Weitere Felder
|
||||
# Skonto-Betrag / -Abzug (Der Wert 0 ist unzulässig)
|
||||
"Skonto",
|
||||
# Beschreibung des Buchungssatzes
|
||||
"Buchungstext",
|
||||
# OPOS-Informationen
|
||||
# Mahn- / Zahl-Sperre (1 = Postensperre)
|
||||
"Postensperre",
|
||||
"Diverse Adressnummer",
|
||||
"Geschäftspartnerbank",
|
||||
"Sachverhalt",
|
||||
# Keine Mahnzinsen
|
||||
"Zinssperre",
|
||||
# Digitaler Beleg
|
||||
# Link auf den Buchungsbeleg (Programmkürzel + GUID)
|
||||
"Beleglink",
|
||||
# Beleginfo
|
||||
"Beleginfo - Art 1",
|
||||
@@ -291,22 +322,30 @@ def get_datev_csv(data, filters):
|
||||
"Beleginfo - Inhalt 7",
|
||||
"Beleginfo - Art 8",
|
||||
"Beleginfo - Inhalt 8",
|
||||
# Kostenrechnung
|
||||
"Kost 1 - Kostenstelle",
|
||||
"Kost 2 - Kostenstelle",
|
||||
"Kost-Menge",
|
||||
# Steuerrechnung
|
||||
"EU-Land u. UStID",
|
||||
# Zuordnung des Geschäftsvorfalls für die Kostenrechnung
|
||||
"KOST1 - Kostenstelle",
|
||||
"KOST2 - Kostenstelle",
|
||||
"KOST-Menge",
|
||||
# USt-ID-Nummer (Beispiel: DE133546770)
|
||||
"EU-Mitgliedstaat u. USt-IdNr.",
|
||||
# Der im EU-Bestimmungsland gültige Steuersatz
|
||||
"EU-Steuersatz",
|
||||
# I = Ist-Versteuerung,
|
||||
# K = keine Umsatzsteuerrechnung
|
||||
# P = Pauschalierung (z. B. für Land- und Forstwirtschaft),
|
||||
# S = Soll-Versteuerung
|
||||
"Abw. Versteuerungsart",
|
||||
# L+L Sachverhalt
|
||||
# Sachverhalte gem. § 13b Abs. 1 Satz 1 Nrn. 1.-5. UStG
|
||||
"Sachverhalt L+L",
|
||||
# Steuersatz / Funktion zum L+L-Sachverhalt (Beispiel: Wert 190 für 19%)
|
||||
"Funktionsergänzung L+L",
|
||||
# Funktion Steuerschlüssel 49
|
||||
# Bei Verwendung des BU-Schlüssels 49 für „andere Steuersätze“ muss der
|
||||
# steuerliche Sachverhalt mitgegeben werden
|
||||
"BU 49 Hauptfunktionstyp",
|
||||
"BU 49 Hauptfunktionsnummer",
|
||||
"BU 49 Funktionsergänzung",
|
||||
# Zusatzinformationen
|
||||
# Zusatzinformationen, besitzen den Charakter eines Notizzettels und können
|
||||
# frei erfasst werden.
|
||||
"Zusatzinformation - Art 1",
|
||||
"Zusatzinformation - Inhalt 1",
|
||||
"Zusatzinformation - Art 2",
|
||||
@@ -347,54 +386,76 @@ def get_datev_csv(data, filters):
|
||||
"Zusatzinformation - Inhalt 19",
|
||||
"Zusatzinformation - Art 20",
|
||||
"Zusatzinformation - Inhalt 20",
|
||||
# Mengenfelder LuF
|
||||
# Wirkt sich nur bei Sachverhalt mit SKR 14 Land- und Forstwirtschaft aus,
|
||||
# für andere SKR werden die Felder beim Import / Export überlesen bzw.
|
||||
# leer exportiert.
|
||||
"Stück",
|
||||
"Gewicht",
|
||||
# Forderungsart
|
||||
# 1 = Lastschrift
|
||||
# 2 = Mahnung
|
||||
# 3 = Zahlung
|
||||
"Zahlweise",
|
||||
"Forderungsart",
|
||||
# JJJJ
|
||||
"Veranlagungsjahr",
|
||||
# TTMMJJJJ
|
||||
"Zugeordnete Fälligkeit",
|
||||
# Weitere Felder
|
||||
# 1 = Einkauf von Waren
|
||||
# 2 = Erwerb von Roh-Hilfs- und Betriebsstoffen
|
||||
"Skontotyp",
|
||||
# Anzahlungen
|
||||
# Allgemeine Bezeichnung, des Auftrags / Projekts.
|
||||
"Auftragsnummer",
|
||||
# AA = Angeforderte Anzahlung / Abschlagsrechnung
|
||||
# AG = Erhaltene Anzahlung (Geldeingang)
|
||||
# AV = Erhaltene Anzahlung (Verbindlichkeit)
|
||||
# SR = Schlussrechnung
|
||||
# SU = Schlussrechnung (Umbuchung)
|
||||
# SG = Schlussrechnung (Geldeingang)
|
||||
# SO = Sonstige
|
||||
"Buchungstyp",
|
||||
"USt-Schlüssel (Anzahlungen)",
|
||||
"EU-Land (Anzahlungen)",
|
||||
"EU-Mitgliedstaat (Anzahlungen)",
|
||||
"Sachverhalt L+L (Anzahlungen)",
|
||||
"EU-Steuersatz (Anzahlungen)",
|
||||
"Erlöskonto (Anzahlungen)",
|
||||
# Stapelinformationen
|
||||
# Wird beim Import durch SV (Stapelverarbeitung) ersetzt.
|
||||
"Herkunft-Kz",
|
||||
# Technische Identifikation
|
||||
"Buchungs GUID",
|
||||
# Kostenrechnung
|
||||
"Kost-Datum",
|
||||
# OPOS-Informationen
|
||||
# Wird von DATEV verwendet.
|
||||
"Leerfeld",
|
||||
# Format TTMMJJJJ
|
||||
"KOST-Datum",
|
||||
# Vom Zahlungsempfänger individuell vergebenes Kennzeichen eines Mandats
|
||||
# (z.B. Rechnungs- oder Kundennummer).
|
||||
"SEPA-Mandatsreferenz",
|
||||
# 1 = Skontosperre
|
||||
# 0 = Keine Skontosperre
|
||||
"Skontosperre",
|
||||
# Gesellschafter und Sonderbilanzsachverhalt
|
||||
"Gesellschaftername",
|
||||
# Amtliche Nummer aus der Feststellungserklärung
|
||||
"Beteiligtennummer",
|
||||
"Identifikationsnummer",
|
||||
"Zeichnernummer",
|
||||
# OPOS-Informationen
|
||||
# Format TTMMJJJJ
|
||||
"Postensperre bis",
|
||||
# Gesellschafter und Sonderbilanzsachverhalt
|
||||
"Bezeichnung SoBil-Sachverhalt",
|
||||
"Kennzeichen SoBil-Buchung",
|
||||
# Stapelinformationen
|
||||
# 0 = keine Festschreibung
|
||||
# 1 = Festschreibung
|
||||
"Festschreibung",
|
||||
# Datum
|
||||
# Format TTMMJJJJ
|
||||
"Leistungsdatum",
|
||||
# Format TTMMJJJJ
|
||||
"Datum Zuord. Steuerperiode",
|
||||
# OPOS-Informationen
|
||||
# OPOS-Informationen, Format TTMMJJJJ
|
||||
"Fälligkeit",
|
||||
# Konto/Gegenkonto
|
||||
# G oder 1 = Generalumkehr
|
||||
# 0 = keine Generalumkehr
|
||||
"Generalumkehr (GU)",
|
||||
# Steuersatz für Steuerschlüssel
|
||||
"Steuersatz",
|
||||
# Beispiel: DE für Deutschland
|
||||
"Land"
|
||||
]
|
||||
|
||||
@@ -419,7 +480,9 @@ def get_datev_csv(data, filters):
|
||||
# Do not number rows
|
||||
index=False,
|
||||
# Use all columns defined above
|
||||
columns=columns
|
||||
columns=columns,
|
||||
# Quote most fields, even currency values with "," separator
|
||||
quoting=QUOTE_NONNUMERIC
|
||||
)
|
||||
|
||||
if not six.PY2:
|
||||
|
||||
Reference in New Issue
Block a user