RFC: Revenue Recognition by Delivery Date (Erlösrealisation nach Versanddatum)
Status: Draft Author: CONA Engineering Created: 2026-04-02 Updated: 2026-04-08 Strategy: B — DATEV-gestützte Anzahlungsautomatik Related: HGB § 252 Abs. 1 Nr. 4 (Realisationsprinzip), § 13 Abs. 1 Nr. 1a UStG, GoBD1. Motivation
A customer wants to recognize revenue not at order/invoice time, but at shipment date (Versanddatum / Fulfillment date). This is the correct approach under HGB’s Realisationsprinzip, which requires revenue recognition at the point of Gefahrenübergang (transfer of risk). For B2C e-commerce (Verbrauchsgüterkauf), § 475 Abs. 2 BGB places the Gefahrenübergang at delivery to the consumer. We use the fulfillment date as a pragmatic proxy accepted by most Steuerberater.Current Model
Target Model
Design Decision: Strategie B (DATEV-Automatik)
CONA is not the leading accounting system — it delivers booking entries to DATEV, which is the system of record. Therefore:- CONA’s internal GL keeps its current structure (Bank ↔ Sammeldebitor ↔ Erlöse)
- CONA does NOT book to “Erhaltene Anzahlungen” (1718) or generate Auflösungsbuchungen
- The DATEV export enriches bookings with Anzahlungsfelder (
Buchungstyp,Auftragsnummer,USt-Schlüssel (Anzahlungen),Erlöskonto (Anzahlungen)) - DATEV Kanzlei-Rechnungswesen uses its built-in Anzahlungsfunktion to handle USt-Korrektur, 1718-Umbuchung, and Auflösung automatically
2. Legal Basis
| Aspect | Regulation | Implication |
|---|---|---|
| Revenue recognition | HGB § 252 Abs. 1 Nr. 4 | Revenue at Gefahrenübergang (delivery) |
| B2C risk transfer | BGB § 475 Abs. 2 | At delivery to consumer (not shipment to carrier) |
| VAT on prepayments | UStG § 13 Abs. 1 Nr. 1a S. 4 | VAT due when prepayment is received |
| Timely booking | GoBD Tz. 50-52 | Record within 10 days, period-correct |
| Service date on invoices | UStDV § 31 Abs. 4 | Leistungsdatum mandatory on invoices |
3. Vorher / Nachher — EXTF-Export am konkreten Beispiel
Szenario: Bestellung #1042, bezahlt am 28.03.2026, versendet am 02.04.2026. Brutto 1.190,00 € (netto 1.000 €, 19% USt). Shopify-Transaktions-ID: 98765.3.1 VORHER — Feature AUS (Umsatzrealisierung nach Bestelldatum)
Beide Buchungssätze landen im März-Stapel mit Belegdatum 28.03.: Buchung 1 — Zahlung (März-Stapel):- März-UStVA: 190 € USt (aus Erlösbuchung)
- Sammeldebitor: OPOS ausgeziffert über Belegfeld 1
- Erlös: im März verbucht
3.2 NACHHER — Feature AN (Umsatzrealisierung nach Versanddatum)
Die Zahlung bleibt im März-Stapel, der Erlös wandert in den April-Stapel. Zusätzlich werden die Anzahlungsfelder und das Leistungsdatum gesetzt: Buchung 1 — Zahlung (März-Stapel):3.3 Was DATEV daraus macht
| Feature AUS | Feature AN | |
|---|---|---|
| USt März-UStVA | 190 € (aus Erlösbuchung) | 190 € (DATEV extrahiert USt aus AG-Buchung automatisch) |
| USt April-UStVA | — | 190 € Erlös-USt abzgl. 190 € Anzahlungs-USt-Korrektur = 0 € Netto-Änderung |
| Erlös März | 1.000 € | — |
| Erlös April | — | 1.000 € |
| Sammeldebitor OPOS | Ausgeziffert (Belegfeld 1) | Ausgeziffert (Belegfeld 1) |
| Erh. Anzahlungen (1718) | — | DATEV bucht intern um + löst automatisch auf |
3.4 Wann werden die Anzahlungsfelder NICHT gesetzt?
| Situation | Buchungstyp AG/SR? | Leistungsdatum? |
|---|---|---|
| Zahlung + Versand im selben Monat | Nein (nicht nötig, USt stimmt ohnehin) | Ja |
| Zahlung + Versand am selben Tag | Nein | Ja |
| Zahlung nach Versand (Kauf auf Rechnung) | Nein (keine Anzahlung) | Ja |
| Zahlung vor Versand, unterschiedliche Monate | Ja (USt-relevant) | Ja |
4. Booking Model in CONA
4.1 Principle: Minimal Changes
CONA’s internal GL structure stays identical to today. The only change is the timing of when the revenue entry is created:4.2 CONA GL Entries
Entry #1 — Payment Received (Day 1, e.g. March 28)
Entry #2 — Revenue at Fulfillment (Day 2, e.g. April 2)
Reconciliation on Sammeldebitor (1400)
4.3 Same-Day Scenario (Payment + Fulfillment am selben Tag)
Wenn Zahlung und Versand am selben Tag, ist es exakt wie das heutige Modell. Kein Buchungstyp AG/SR nötig im DATEV-Export — nurLeistungsdatum wird zusätzlich gesetzt.
4.4 Was sich in CONA ändert / nicht ändert
| Bereich | Änderung? | Begründung |
|---|---|---|
| Kontenrahmen / Chart of Accounts | Nein | Kein 1718 Konto in CONA nötig |
| Posting Matrix (Debit/Credit) | Nein | Gleiche Kontenkombinationen |
| Posting Matrix (BU) | Ja — Vereinfachung | BU-Matrix wird durch einfache Mapping-Tabelle ersetzt (s. Section 6) |
general_ledger-Schema | Ja | Neue Spalte bu_schluessel + service_date |
| Reconciliation Engine | Nein | GID-basiert auf Sammeldebitor wie bisher |
getReferenceDocumentNumber() | Nein | Kein Cross-Account-Lookup nötig |
createAccountingImpact / createJournalEntry | Minimal | BU automatisch setzen + service_date hinzufügen |
| Auflösungsbuchungen | Nein | DATEV erzeugt diese automatisch |
5. DATEV Export — Die Anzahlungsfelder
5.1 Relevante DATEV-Felder
Die DATEV EXTF-Spezifikation enthält einen Anzahlungsblock (Felder #95-#101), den wir bisher nicht befüllen:| # | DATEV-Feld | Format | Beschreibung |
|---|---|---|---|
| 95 | Auftragsnummer | 0-30 Zeichen | Verknüpft alle Buchungen eines Vorgangs |
| 96 | Buchungstyp | 2 Buchstaben | Steuert die Anzahlungsautomatik |
| 97 | USt-Schlüssel (Anzahlungen) | 0-2 Ziffern | USt-Schlüssel der späteren Schlussrechnung |
| 98 | EU-Mitgliedstaat (Anzahlungen) | 2 Buchstaben | EU-Land der Schlussrechnung |
| 99 | Sachverhalt L+L (Anzahlungen) | 0-3 Ziffern | L+L-Sachverhalt der Schlussrechnung |
| 100 | EU-Steuersatz (Anzahlungen) | Ziffern | EU-Steuersatz der Schlussrechnung |
| 101 | Erlöskonto (Anzahlungen) | 4-8 Ziffern | Erlöskonto der Schlussrechnung |
| 115 | Leistungsdatum | TTMMJJJJ | Lieferdatum / Leistungsdatum |
| 116 | Datum Zuord. Steuerperiode | TTMMJJJJ | Zuordnung zur USt-Periode |
5.2 Buchungstyp-Werte
| Code | Bedeutung | Wann wir ihn setzen |
|---|---|---|
| AG | Erhaltene Anzahlung (Geldeingang) | Payment-Buchung, wenn Zahlung VOR Fulfillment |
| SR | Schlussrechnung | Revenue-Buchung bei Fulfillment |
| SG | Schlussrechnung (Geldeingang) | Payment-Buchung, wenn Zahlung NACH Fulfillment |
| — | (leer) | Zahlung und Fulfillment am selben Tag |
5.3 DATEV-Export je Buchung
Payment-Buchung (Buchungstyp “AG”)
Wird gesetzt wennpaymentDate < fulfillmentDate:
| DATEV-Feld | Wert | Bemerkung |
|---|---|---|
| Umsatz | 1190,00 | Bruttobetrag |
| Soll/Haben | S | |
| Konto | 1200 | Bank |
| Gegenkonto | 1400 | Sammeldebitor |
| Belegdatum | 2803 | Zahlungsdatum |
| Belegfeld 1 | "SHP-98765" | GID für OPOS-Ausgleich |
| Buchungstext | "Shopify Payment #1042" | |
| Auftragsnummer | "1042" | NEU — Shopify Order-Nr. |
| Buchungstyp | "AG" | NEU — Erhaltene Anzahlung |
| USt-Schlüssel (Anz.) | 9 | NEU — BU 9 = 19% Verkauf (aus SR-Buchung, s. 5.4) |
| Erlöskonto (Anz.) | 8400 | NEU — Erlöse 19% (aus SR-Buchung, s. 5.4) |
Was DATEV damit macht: Beim Import erkennt DATEV den Buchungstyp “AG” und speichert den Vorgang als offene Anzahlung. Die USt auf die Anzahlung wird automatisch in die korrekte UStVA-Periode gebucht (§ 13 Abs. 1 Nr. 1a S. 4 UStG).
Revenue-Buchung (Buchungstyp “SR”)
| DATEV-Feld | Wert | Bemerkung |
|---|---|---|
| Umsatz | 1190,00 | Bruttobetrag |
| Soll/Haben | S | |
| Konto | 1400 | Sammeldebitor |
| Gegenkonto | 8400 | Erlöse 19% USt (Automatikkonto) |
| BU-Schlüssel | 9 | BU 9 = 19% Verkauf |
| Belegdatum | 0204 | Fulfillment-Datum |
| Belegfeld 1 | "SHP-98765" | Gleiche GID |
| Buchungstext | "Sales Invoice INV-1042" | |
| Auftragsnummer | "1042" | NEU — Gleiche Order-Nr. |
| Buchungstyp | "SR" | NEU — Schlussrechnung |
| Leistungsdatum | 02042026 | NEU — Versanddatum |
| Datum Zuord. Steuerperiode | 02042026 | NEU — USt-Periodenzuordnung |
Was DATEV damit macht: Beim Import erkennt DATEV anhand der gleichen Auftragsnummer die Zugehörigkeit zur Anzahlung “AG”. DATEV erzeugt automatisch die Auflösungsbuchung (Erh. Anz. an Sammeldebitor), korrigiert die Anzahlungs-USt und bucht die endgültige USt der Schlussrechnung.
5.4 Herkunft von USt-Schlüssel und Erlöskonto auf der AG-Buchung
Problem: Die Payment-Buchung (Bank → Sammeldebitor) hat keinen BU-Schlüssel und kein Erlöskonto — das sind Eigenschaften der noch nicht existierenden Revenue-Buchung. DATEV braucht die Werte aber beim Import der AG-Buchung. Lösung: Durch die BU-Schlüssel-Vereinfachung (s. Section 6) ist der BU direkt als DB-Spalte auf dem GL-Entry verfügbar:- Der DATEV-Export wird typischerweise nach Periodenabschluss ausgelöst (z.B. März-Export Anfang April)
- Zu diesem Zeitpunkt existiert die Revenue-Buchung (02.04.) bereits in CONAs GL
sr_entry.bu_schluesselenthält den korrekten BU direkt als Spalte — kein JSON-Parsing, kein Dimension-Mapping- Fallback:
deriveBuSchluessel()(gleiche Funktion wie bei Journal-Entry-Erstellung, s. 6.4)
- CONA ruft
deriveBuSchluessel()mit dem Order-Steuersatz auf (Shopify liefert taxRate bei Bestellung) - Erlöskonto wird analog aus der BU-Config aufgelöst
- Werte sind in 99% identisch zur späteren SR (gleiche Ware, gleicher Steuersatz)
| Steuersatz | BU-Schlüssel | Erlöskonto | Kontobezeichnung |
|---|---|---|---|
| 19% | 9 | 8400 | Erlöse 19% USt (AM → bucht automatisch auf 1776) |
| 7% | 14 | 8300 | Erlöse 7% USt (AM → bucht automatisch auf 1771) |
| 0% (steuerfrei) | 2 | 8120 | Steuerfreie Umsätze §4 |
| 0% (ig. Lieferung) | 3 | 8125 | Steuerfreie ig. Lieferungen §4 Nr.1b |
Hinweis zu Automatikkonten: 8400 und 8300 sind Automatikkonten (AM) in DATEV. Wenn das Gegenkonto ein Automatikkonto ist, berechnet DATEV die USt automatisch. Der BU-Schlüssel 9 bzw. 14 dient als zusätzliche Absicherung.
5.5 Automatische DATEV-Buchungen (transparent für CONA)
DATEV erzeugt intern bei Import der SR-Buchung mit passender Auftragsnummer:5.6 DATEV-Einrichtung durch Steuerberater (einmalig)
In DATEV Kanzlei-Rechnungswesen → Buchungsstapel → Eigenschaften → Anzahlungen:- Anzahlungskonto festlegen: z.B. 1718 (Erhaltene Anzahlungen)
- Buchungsfall einstellen: “Erhaltene Anzahlungen ohne Abschlagsrechnung”
- Buchungstext für Auflösung konfigurieren
5.7 Hinweis zu Feld #115 Leistungsdatum
Aus der DATEV-Spezifikation:
“Beim Import des Leistungsdatums muss das Feld Datum Zuord. Steuerperiode (#116) gefüllt sein. Der Einsatz des Leistungsdatums muss in Absprache mit dem Steuerberater erfolgen.”
Beide Felder (#115 + #116) werden daher immer zusammen gesetzt. Datum Zuord. Steuerperiode steuert, in welche UStVA-Periode die Buchung fällt.
6. BU-Schlüssel — Vereinfachung des Steuerschlüssel-Systems
6.1 Motivation
Aktuell wird der BU-Schlüssel über eine vollständige Posting-Matrix (Tax Code (BU) Matrix) mit Rules bestimmt, als gl_dimensions-Wert im dimensions-JSON des GL-Eintrags gespeichert, und beim DATEV-Export über ein Dimension-Mapping aufgelöst. Diese Architektur ist für den BU-Schlüssel overengineered:
- Der BU-Schlüssel ist deterministisch aus Steuersatz + Lieferland ableitbar
- 95%+ der Nutzer haben identische BU-Rules (19% → 9, 7% → 14, ig. Lieferung → 3)
- Die Posting-Matrix-Konfiguration für BU ist unnötig komplex
- Für die AG-Buchungen im Revenue-Recognition-Feature brauchen wir den BU direkt als DB-Spalte, nicht versteckt im JSON
6.2 Architektur-Entscheidung
6.3 Neue DB-Spalte
dimensions-JSON-Spalte bleibt bestehen für KOST1, KOST2 und Kost-Menge — nur der BU-Schlüssel wird herausgezogen.
6.4 Automatische BU-Ableitung
Neue FunktionderiveBuSchluessel() in @cona/core:
isEUCountry()-Logik aus @cona/utils.
6.5 BU-Konfiguration in DATEV-Settings
Statt Posting-Matrix-Rules: einfache Mapping-Tabelle in den DATEV Export Settings:6.6 Auswirkungen auf bestehende Systeme
| Bereich | Änderung |
|---|---|
createJournalEntry() | BU automatisch setzen via deriveBuSchluessel() |
process-dimensions.ts | BU-Dimension überspringen (nicht mehr als GL-Dimension evaluieren) |
generateDimensionKey() | bu_schluessel-Spalte statt dimensions-JSON für BU |
| DATEV Entry-Transformer | entry.bu_schluessel direkt lesen statt Dimension-Mapping |
| DATEV Consolidated-Transformer | Gleiche Vereinfachung |
| Posting-Matrix-Seed | ”Tax Code (BU)” Matrix nicht mehr erstellen |
datevDimensionType | "BU" entfernen (KOST1/KOST2/Kost-Menge bleiben) |
| DATEV-Settings-UI | Neuer “BU-Schlüssel” Tab mit Mapping-Tabelle statt Dimension-Mapping |
| Migration | Bestehende BU-Werte aus dimensions-JSON in bu_schluessel-Spalte backfillen |
6.7 Vorteil für Revenue Recognition
Mitbu_schluessel als eigene Spalte wird die AG/SR-Logik im DATEV-Export deutlich einfacher:
- USt-Schlüssel (Anzahlungen) auf der AG-Buchung =
sr_entry.bu_schluessel(direkt lesbar) - Fallback wenn noch kein SR existiert =
deriveBuSchluessel(order.taxRate, ...)(gleiche Funktion) - Kein Dimension-Mapping-Lookup mehr nötig, keine UUID-Auflösung, kein JSON-Parsing
7. GID / Auszifferung
7.1 Keine Änderung an der Reconciliation-Logik
Die bestehende GID-basierte Auszifferung auf dem Sammeldebitor bleibt identisch:7.2 GID-Quelle (wie bisher)
7.3 Split Payments
Für Bestellungen mit mehreren Zahlungsmethoden erzeugt die bestehende Multi-GID-Allocation proportionale GL-Einträge. Das funktioniert unverändert:8. Edge Cases
8.1 Same-Day (Zahlung + Versand am selben Tag)
Kein Buchungstyp AG/SR nötig. Standard-Buchung wie bisher, nurLeistungsdatum wird gesetzt. Optional können wir trotzdem die Auftragsnummer setzen — schadet nicht, löst aber keine Anzahlungsautomatik aus wenn kein AG vorhanden ist.
8.2 Partial Fulfillment (Teillieferung)
Shopify unterstützt mehrere Fulfillments pro Order. Jedes Fulfillment enthält eine Teilmenge der Line Items.Auftragsnummer. DATEV löst die Anzahlung bei der ersten Schlussrechnung anteilig auf und den Rest bei der zweiten.
Auszifferung in CONA: Auf dem Sammeldebitor stehen Payment (-80 €) und zwei Revenue-Buchungen (+50 €, +30 €). Der Reconciliation Engine erkennt über den autoDifferenceThreshold die Teilzahlungen.
8.3 Cancelled Order (Stornierung ohne Versand)
8.4 Payment After Fulfillment (Kauf auf Rechnung)
Zahlung kommt NACH Fulfillment. Kein Anzahlungssachverhalt:8.5 Fulfillment in geschlossener Buchungsperiode
- Warnung loggen: “Revenue für Fulfillment vom 31.03. wird in April gebucht (März geschlossen)”
- CONA bucht in die nächste offene Periode
Leistungsdatumwird trotzdem auf das tatsächliche Fulfillment-Datum gesetzt (31.03.)Datum Zuord. Steuerperiode= tatsächliches Fulfillment-Datum → DATEV ordnet die USt korrekt zu
8.6 Refund After Revenue Recognition
Standard-Refund-Handling. Die Gutschrift referenziert die Original-Rechnung:9. Implementation Plan
Each phase is independently shippable and delivers value on its own. Later phases build on earlier ones but are not blocked by them unless noted.Phase 1: BU-Schlüssel Foundation (mittel, s. Section 6)
Refactor the BU-Schlüssel from a dimension-JSON value into a first-class DB column. No user-facing behaviour change — purely internal simplification that unblocks everything else. Data Model:- Add
bu_schluessel String?column togeneral_ledgertable - Migration: Backfill existing entries from
dimensions-JSON →bu_schluesselcolumn - Migration: Remove BU key from
dimensions-JSON (cleanup)
- Create
packages/core/src/general_ledger/derive-bu-schluessel.ts— zentrale Ableitungsfunktion -
createJournalEntry(): BU automatisch setzen viaderiveBuSchluessel(taxRate, country, buConfig) -
process-dimensions.ts: BU-Dimension aus Rule-Verarbeitung ausnehmen -
consolidate-entries.ts:generateDimensionKey()umbu_schluessel-Spalte erweitern (statt aus dimensions-JSON)
- Add
buSchluesselConfigtodatevExportSettingsSchemain@cona/types - Remove
"BU"fromdatevDimensionTypeenum (KOST1/KOST2/Kost-Menge bleiben) - Default
buSchluesselConfiginposting-matrix-seed.tssetzen statt BU-Dimension + Matrix
-
entry-transformer.ts(Temporal + Webapp):entry.bu_schluesseldirekt lesen -
consolidated-transformer.ts(Temporal + Webapp): gleiche Vereinfachung
- DATEV-Settings-Dialog: “BU-Schlüssel” Tab mit einfacher Mapping-Tabelle
-
"BU"aus Dimension-Mapping-Optionen entfernen - Posting-Matrix: “Tax Code (BU)” Matrix nicht mehr für neue Gruppen erstellen
Phase 2: Leistungsdatum — always set service date (klein)
SetLeistungsdatum (#115) and Datum Zuord. Steuerperiode (#116) on every revenue booking in the DATEV export. This is legally required (UStDV § 31 Abs. 4) and valuable independent of any revenue-timing change. No toggle needed — this is unconditionally correct.
Data Model:
- Add
service_datefield togeneral_ledger(nullableDateTime) - Add
fulfillment_datefield todocumentstable (nullableDateTime)
- Extend Shopify Orders GraphQL query to include fulfillment data (
fulfillments.createdAt) - Set
service_dateon revenue GL entries: usefulfillment.createdAtwhen available, fall back toorder.processedAt - Set
fulfillment_dateon the document when a fulfillment exists
-
Leistungsdatum(#115): emitentry.service_datein TTMMJJJJ format when present -
Datum Zuord. Steuerperiode(#116): always set together with Leistungsdatum
- Show
Leistungsdatumin the GL detail view
service_date export exactly as before (fields left empty).
Phase 3: Revenue Recognition by Fulfillment Date (mittel)
Shift revenue booking from order date to fulfillment date. Opt-in per Shopify integration. Depends on: Phase 2 (service_date column + fulfillment data from Shopify) Settings:- Add
revenue_recognition_modeto Shopify integration settings ("order_date"|"fulfillment_date") - Toggle in Shopify-Integration-Settings UI: “Umsatzrealisierung: Bestelldatum / Versanddatum”
- When
revenue_recognition_mode = "fulfillment_date":- Payment booking: weiterhin bei Zahlungseingang (wie bisher)
- Sales Invoice: erst bei Fulfillment erzeugen, mit
date = fulfillment.createdAt service_date=fulfillment.createdAt(already wired from Phase 2)
- Handle partial fulfillments: proportionale Revenue-Buchungen je Fulfillment
Phase 4: DATEV Anzahlungsfelder — AG/SR for cross-month bookings (klein)
Enrich the DATEV export with Buchungstyp AG/SR and Anzahlungsfelder so DATEV can automatically handle prepayment reclassification and VAT correction across periods. Depends on: Phase 1 (bu_schluessel column) + Phase 3 (revenue timing shift) DATEV Export — Änderungen inentry-transformer.ts:
-
Auftragsnummer(#95) mit Shopify Order-Nr. befüllen -
Buchungstyp(#96) setzen — nur wenn Zahlung vor Fulfillment UND unterschiedliche Kalendermonate:"AG"für Payment-Buchungen (Erhaltene Anzahlung)"SR"für Revenue-Buchungen (Schlussrechnung)
-
USt-Schlüssel (Anzahlungen)(#97) auf AG-Buchungen:- Primär:
sr_entry.bu_schluessel(direkt aus DB-Spalte, dank Phase 1) - Fallback:
deriveBuSchluessel(order.taxRate, country, buConfig)
- Primär:
-
Erlöskonto (Anzahlungen)(#101) auf AG-Buchungen:- Primär:
sr_entry.credit_account.account_nr(Gegenkonto der SR) - Fallback: Erlöskonto aus
buConfig.taxRateMappings
- Primär:
- Hinweis-Banner: “Steuerberater muss Anzahlungsfunktion in DATEV einmalig konfigurieren”
10. Was sich NICHT ändert (Abgrenzung)
| Bereich | Status |
|---|---|
| Kontenrahmen / Chart of Accounts | Keine neuen Konten nötig |
| Posting Matrix (Debit/Credit) | Unverändert — Kontenfindung weiterhin über Rules |
| KOST1/KOST2/Kost-Menge Dimensions | Unverändert — bleiben im dimensions-JSON |
| Reconciliation Engine | Unverändert (GID-basiert auf Sammeldebitor) |
getReferenceDocumentNumber() | Unverändert |
| Auflösungsbuchungen in CONA | Nicht nötig (DATEV übernimmt) |
| Konto 1718 in CONA | Nicht nötig (DATEV bucht intern um) |
11. Risks & Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Steuerberater konfiguriert Anzahlungsfunktion nicht in DATEV | Buchungstyp AG/SR wird ignoriert, USt stimmt nicht | Doku + Onboarding-Checkliste, Hinweis in UI |
| Shopify liefert kein Fulfillment | Revenue bleibt als offene Forderung auf Sammeldebitor | Alert nach X Tagen ohne Fulfillment |
| Fulfillment-Datum in geschlossener Periode | Falsche Periodenzuordnung | Buchung in nächste offene Periode + Warnung |
| Split Payments + Partial Fulfillments | Komplexe proportionale Berechnung | Umfangreiche Tests |
| CONA-Bilanz zeigt keine “Erhaltenen Anzahlungen” | Interne Reports nicht 100% bilanzkonform | Akzeptiert — DATEV ist führend |
| Breaking Change für bestehende Kunden | Falsche historische Daten | Feature-Flag, opt-in, keine rückwirkende Änderung |
12. Resolved Questions
-
Fulfillment-Datum:
fulfillment.createdAt(Versanddatum) wird verwendet. NichtdeliveryStatus === "delivered", da die meisten Shops kein Carrier-Tracking haben. - Multi-Currency: Es wird der FX-Kurs vom jeweiligen Buchungstag genommen. Für die Payment-Buchung der Kurs vom Zahlungstag, für die Revenue-Buchung der Kurs vom Fulfillment-Tag. Daraus entstehende Währungsdifferenzen werden wie gewohnt ausgebucht.
- Accounting Period Auto-Creation: Ja, Buchungsperioden werden automatisch erstellt wie bei allen anderen Vorgängen auch.
-
Consolidated Entries + AG/SR: Bereits gelöst durch die bestehende Konsolidierungslogik. In
consolidate-entries.tswerden Reconciliation Groups, die mehrere Perioden umspannen, automatisch als “problematic” markiert und von der Konsolidierung ausgeschlossen. Da bei monatsübergreifenden Vorgängen Payment (März) und Revenue (April) über den gleichen GID verknüpft sind, erkennt die Engine die periodenübergreifende Recon Group und exportiert die Einträge einzeln — genau das Verhalten, das wir für AG/SR brauchen. Keine Code-Änderung nötig. - DATEV Anzahlungs-Verhalten bei Konsolidierung: Siehe #4 — monatsübergreifende Buchungen werden bereits nicht konsolidiert. Bei Same-Month-Vorgängen (kein AG/SR nötig) können Buchungen weiterhin konsolidiert werden, da dort kein Buchungstyp gesetzt wird.