Entwickler-Dokumentation für WooCommerce DATEV-Format Export Plugin
Hinweis: Diese Dokumentation ist für Entwickler gedacht. Sie ist nur dann relevant, wenn tiefgehende oder komplexe Änderungen an der Buchhaltungs-Logik vorgenommen werden sollen.
Allgemeiner Aufbau
In diesem Abschnitt wird zunächst der allgemeine Aufbau sowie die Grundkonzeption des Plugins beschrieben. Ein schematischer Ablauf ist in der Grafik unten enthalten.
Das Plugin umfasst zwei Kernfunktionen: 1) Die Erstellung von Buchungssätzen und das Speichern in der Datenbank sowie 2) der Export der jeweiligen Buchungssätze aus der Datenbank in die entsprechende CSV-/ZIP-Dateien.
Erstellung der Buchungssätze
Die Buchungssätze für eine Bestellung werden dann erstellt, wenn diese fertiggestellt ist. Denn dann stellt WordPress/WooCommerce sicher, dass keine Änderungen mehr vorgenommen werden können.
Für die Forderungs- bzw. Zahlungsbuchung müssen die jeweiligen Konten ermittelt werden. Das passiert pro Steuersatz, d.h. Produkte mit demselben Steuersatz werden zu einem Posten summiert. Anschließend werden für diesen Posten die jeweiligen Konten abgefragt. Mit den Filtern "wcdtvfe_revenue_account_data", "wcdtvfe_debtor_account_data", "wcdtvfe_payment_gateway_account_number" kann also programmatisch die Logik der Abfrage der FiBu-Konten verändert werden.
Anschließend wird der eigentliche Buchungssatz zusammengesetzt. Der gesamte Buchungssatz kann mittels des Filters wcdtvfe_create_receivables_record, wcdtvfe_create_receivables_record_manual_tax, wcdtvfe_create_payment_record verändert werden. Hier können jeweils Änderungen basierend auf den entsprechenden Buchungstypen vorgenommen werden.
Alle erstellten Buchungen werden immer durch den Filter wcdtvfe_create_raw_accounting_record_before_preprocessing bzw. _after_preprocessing gefiltert. Die Unterscheidung "before_preprocessing" und "after_preprocessing" ist notwendig, da z.B. Beträge gerundet werden müssen. Im before-Filter finden sich die Beträge, wie sie von WooCommerce übergeben werden. Im after-Filter sind die Beträge bereits korrekt gem. der DATEV-Spezifikation gerundet.
Anschließend werden die Buchungssätze in der Datenbank gespeichert.

Erstellung der DATEV-Exportdatei
Bei der Anforderung einer DATEV-Exportdatei werden die Buchungen gem. der Filter-Einstellungen des Benutzer abgefragt. Diese Buchungen werden dann in einer Exportdatei gemeinsam exportiert. Bei Erstellung werden Formatierungen (z.B. von Tausender-Trennzeichen und Dezimaltrennern) gemäß der DATEV-Spezifikationen vorgenommen. Außerdem werden für jeden Buchungssatz die jeweiligen Belegdateien abgefragt und entsprechend als ZIP-Datei mit gesammelt/exportiert.
Filter-Übersicht
Abfrage von Buchhaltungs-Kontonummern
Abfrage der Erlöskonten (wcdtvfe_revenue_account_data)
add_filter( 'wcdtvfe_revenue_account_data', function( $tax_rate_data, $order, $tax_rate_id ) {
// Do something
return $tax_rate_data
}, 10, 3);
Achtung: $tax_rate_data ist ein Objekt, in dem revenue_account_number, ggfs. Bu-Schlüssel, Backup-Konto gesetzt sein müssen.
Abfrage der Debitorkonten (wcdtvfe_revenue_account_data)
add_filter( 'wcdtvfe_debtor_account_number', function( $debtor_account, $order ) {
// Do something
return $debtor_account
}, 10, 2);
Abfrage der Zahlungsart-Konten (wcdtvfe_payment_gateway_account_number)
add_filter( 'wcdtvfe_payment_gateway_account_number', function( $payment_account, $order ) {
// Do something
return $payment_account
}, 10, 2);
Erstellung von Buchungssätzen
Bearbeitung von Erlös-/Forderungsbuchungen
In der Regel kommt nur der Filter "wcdtvfe_create_receivables_record" zum Einsatz, da ein Buchungssatz pro Steuerklasse erstellt wird. Dieser Buchungssatz enthält dann Bruttobeträge.
Der Filter "wcdtvfe_create_receivables_record_manual_tax" wird nur verwendet, wenn ein "manuelles Steuerkonto" gesetzt ist. In diesem Fall wird über "wcdtvfe_create_receivables_record" der Buchungssatz für die Nettobeträge gefiltert, und über "wcdtvfe_create_receivables_record_manual_tax" der Buchungssatz für die jeweiligen Steuerbeträge.
add_filter( 'wcdtvfe_create_receivables_record', function( $accounting_record_data, $order_id, $tax_rate_id ) {
// Do something
return $accounting_record_data
}, 10, 3);
add_filter( 'wcdtvfe_create_receivables_record_manual_tax', function( $accounting_record_data, $order_id, $tax_rate_id ) {
// Do something
return $accounting_record_data
}, 10, 3);
Bearbeitung von Zahlungsbuchungssätzen
add_filter( 'wcdtvfe_create_payment_record', function( $payment_record_data, $order_id) {
// Do something
return $payment_record_data
}, 10, 2);
Einfügen der Buchungssätze in die Datenbank
add_filter( 'wcdtvfe_create_raw_accounting_record_before_preprocessing', function( $record_data ) {
// Do something
return $payment_record_data
}, 10, 1);
add_filter( 'wcdtvfe_create_raw_accounting_record_after_preprocessing', function( $record_data ) {
// Do something
return $payment_record_data
}, 10, 1);
Erstellung der eigentlichen CSV-Datei
add_filter( 'wcdtvfe_create_export_file_before_preprocessing', function( $accounting_record ) {
// Do something
return $accounting_record
}, 10, 1);
add_filter( 'wcdtvfe_create_export_file_after_preprocessing', function( $accounting_record ) {
// Do something
return $accounting_record
}, 10, 1);
Abruf von Belegdateien
Ein Filter, um z.B. Belegdateien von selbst entwickelten Rechnungs-Plugins einzubinden, folgt in einer zukünftigen Version. Im Zweifel nehmen Sie bitte mit mir Kontakt auf.
Beispiele
Germanized-Rechnungsnummer in Belegfeld 1 übergeben
Wie kann ich die Rechnungsnummer im Belegfeld 1 mit exportieren?
add_filter ( 'wcdtvfe_create_raw_accounting_record_after_preprocessing',
function( $record_data, $order_id, $type ) {
$record_data[ '011_note1' ] = "%%invoice_number%%";
return $record_data;
}, 10, 3
);
add_filter ( 'wcdtvfe_create_export_file_after_preprocessing',
function( $accounting_record ) {
$invoice_number = wcdtvfe_get_invoice_number_on_export_file_creation( $accounting_record );
if (!$invoice_number) {
$invoice_number = "";
}
$accounting_record[ '011_note1' ] = str_replace( "%%invoice_number%%", $invoice_number, $accounting_record['011_note1'] );
return $accounting_record;
}, 10, 1
);
Eigene Debitor-Nummern (z.B. die WC-Kundennummer) für ausgewählte Kunden verwenden
Achtung: Dieser Code wurde explizit für die Verwendung mit einem Dritt-Plugin geschrieben. Sie müssen den Code auf Ihre Situation anpassen.
Hier wird die User-ID verwendet, wenn es sich um einen Händler handelt. Ansonsten werden die normalen Sammeldebitor-Konten verwendet.
add_filter( 'wcdtvfe_debtor_account_number',
function( $debtor_account, $order ) {
$customer_id = $order->get_user_id();
if ( $customer_id == 0 ) {
return $debtor_account;
}
$user = get_user_by( 'id', $customer_id );
if ( in_array( 'haendler', (array) $user->roles ) ) {
$user_debtor_account_id = get_user_meta( $customer_id, 'wscn', true );
if ( $user_debtor_account_id && $user_debtor_account_id != 00 && $user_debtor_account_id != "" ) {
$debtor_account = $user_debtor_account_id;
}
}
return $debtor_account;
}, 10, 2
);
Bei PayPal-Bestellung soll Belegfeld 1 die Bestellungs-ID enthalten, sonst die Rechnungsnummer
add_filter ( 'wcdtvfe_create_raw_accounting_record_after_preprocessing',
function( $record_data, $order_id, $type ) {
$order = wc_get_order( $order_id );
$payment_method = $order->get_payment_method_title();
if ( $payment_method === "PayPal" ) {
$record_data[ '011_note1' ] = $order_id;
}
else {
$record_data[ '011_note1' ] = "%%invoice_number%%";
}
return $record_data;
}, 10, 3
);
Dokumentation Datenbank-Spalten und $accounting_record_data-Array
Bezeichnung gem. DATEV-Formatbeschreibung | Array/DB-Spalten-Schlüssel | Hinweise/Beschreibung |
---|---|---|
/ | 'actual_date' | Datum von "010: Belegdatum" im Format Y-m-d. Wird als DB-Typ "year" abgespeichert. Notwendig, da das Belegdatum alleine nur das Format "TTMM" nutzt. Dadurch geht die Information über das Jahr verloren. |
Umsatz | '001_revenue' | |
Soll-/Haben-Kennzeichen | '002_soll_haben' | |
WKZ Umsatz | '003_revenue_currency' | |
Kurs | '004_exchange_rate' | |
Basisumsatz | '005_base_revenue' | |
WKZ Basisumsatz | '006_base_revenue_currency' | |
Konto | '007_debit' | |
... | '008_credit' | |
'009_tax_code' | ||
'010_transaction_date' | ||
'011_note1' | ||
'012_note2' | ||
'013_cashback' | ||
'014_posting_text' | ||
'015_post_lock' | ||
'016_various_address_number' | ||
'017_business_partner_bank' | ||
'018_circumstance' | ||
'019_interest_lock' | ||
'020_receipt_link' | ||
'021_receipt_info_type_1' | ||
'022_receipt_info_content_1' | ||
'023_receipt_info_type_2' | ||
'024_receipt_info_content_2' | ||
'025_receipt_info_type_3' | ||
'026_receipt_info_content_3' | ||
'027_receipt_info_type_4' | ||
'028_receipt_info_content_4' | ||
'029_receipt_info_type_5' | ||
'030_receipt_info_content_5' | ||
'031_receipt_info_type_6' | ||
'032_receipt_info_content_6' | ||
'033_receipt_info_type_7' | ||
'034_receipt_info_content_7' | ||
'035_receipt_info_type_8' | ||
'036_receipt_info_content_8' | ||
'037_cost_centre_1' | ||
'038_cost_centre_2' | ||
'039_cost_centre_reference' | ||
'040_vat_no_destination' | ||
'041_eu_tax_destination' | ||
'042_alternating_taxation' | ||
'043_p13b_record' | ||
'044_p13b_value' | ||
'045_bu_49_main_function_type' | ||
'046_bu_49_main_function_number' | ||
'047_bu_49_function_addition' | ||
'048_additional_information_type_1' | ||
'049_additional_information_content_1' | ||
'050_additional_information_type_2' | ||
'051_additional_information_content_2' | ||
'050_additional_information_type_2' | ||
'051_additional_information_content_2' | ||
'052_additional_information_type_3' | ||
'053_additional_information_content_3' | ||
'054_additional_information_type_4' | ||
'055_additional_information_content_4' | ||
'056_additional_information_type_5' | ||
'057_additional_information_content_5' | ||
'058_additional_information_type_6' | ||
'059_additional_information_content_6' | ||
'060_additional_information_type_7' | ||
'061_additional_information_content_7' | ||
'062_additional_information_type_8' | ||
'063_additional_information_content_8' | ||
'064_additional_information_type_9' | ||
'065_additional_information_content_9' | ||
'066_additional_information_type_10' | ||
'067_additional_information_content_10' | ||
'068_additional_information_type_11' | ||
'069_additional_information_content_11' | ||
'070_additional_information_type_12' | ||
'071_additional_information_content_12' | ||
'072_additional_information_type_13' | ||
'073_additional_information_content_13' | ||
'074_additional_information_type_14' | ||
'075_additional_information_content_14' | ||
'076_additional_information_type_15' | ||
'077_additional_information_content_15' | ||
'078_additional_information_type_16' | ||
'079_additional_information_content_16' | ||
'080_additional_information_type_17' | ||
'081_additional_information_content_17' | ||
'082_additional_information_type_18' | ||
'083_additional_information_content_18' | ||
'084_additional_information_type_19' | ||
'085_additional_information_content_19' | ||
'086_additional_information_type_20' | ||
'087_additional_information_content_20' | ||
'088_piece' | ||
'089_weight' | ||
'090_payment_method' | ||
'091_claim_type' | ||
'092_assessment_year' | ||
'093_assigned_due_date' | ||
'094_skonto_type' | ||
'095_job_number' | ||
'096_booking_type' | ||
'097_tax_key_deposits' | ||
'098_eu_member_state_deposits' | ||
'099_p13b_record_deposits' | ||
'100_eu_tax_deposits' | ||
'101_receivables_account_deposit' | ||
'102_origin_tag' | ||
'103_empty_field' | ||
'104_kost_date' | ||
'105_sepa_mandate_reference' | ||
'106_skonto_lock' | ||
'107_partner_name' | ||
'108_participant_number' | ||
'109_id_number' | ||
'110_signee_number' | ||
'111_post_lock_until' | ||
'112_designation_special_balance_circumstance' | ||
'113_designator_special_balance_booking' | ||
'114_fixation' | ||
'115_delivery_date' | ||
'116_date_assignment_tax_period' | ||
'117_due_date' | ||
'118_general_reverse' | ||
'120_country' | ||
'121_settlement_reference' | ||
'122_bvv_position' | ||
'123_vat_no_origin' | ||
'124_eu_tax_origin' |