Eine Steuerzeile kann ohne Nutzungsdatensatz bleiben. Wer deshalb die gesamte Rechnungssumme mit exportierten Nutzungsdaten vergleicht, sieht eine Differenz, obwohl die Nutzungsbeträge übereinstimmen. FOCUS 1.4 ergänzt Cost and Usage um Invoice Detail und Billing Period. Ein Rechnungsabgleich vor dem Abschluss der Billing Period taugt nicht als Abschlusskontrolle, weil Nachbuchungen die Differenz noch verändern können.
Was FOCUS 1.4 für den Rechnungsabgleich ergänzt
Cost and Usage enthält Kosten- und Nutzungsdatensätze. Invoice Detail zeigt die Rechnungspositionen, Billing Period den Status des Abrechnungszeitraums. Für den Vergleich müssen die Beträge derselben Rechnung und Periode zugeordnet sein.
Was ist ein Rechnungsabgleich mit FOCUS 1.4?
FOCUS 1.4 ergänzt Cost and Usage um Invoice Detail für Rechnungszeilen und Billing Period für den Periodenstatus. Über die InvoiceId lassen sich Beträge einer Rechnung zusammenführen, sofern der Export den Schlüssel auf beiden Seiten liefert. Nach Periodenabschluss werden BilledCost-Summen verglichen; separat klassifizierte Steuerzeilen bleiben als eigene Spalte sichtbar.
Die Version der Spezifikation belegt noch nicht, dass ein Provider Invoice Detail und Billing Period im konkreten Export liefert. Bei Daten aus mehreren Cloud-Plattformen müssen die verfügbaren Datensätze und Felder deshalb für jeden Export geprüft werden. Fehlt einer der benötigten Datensätze, lässt sich die Abfrage mit Beispieldaten testen, aber keine echte Rechnung abstimmen. Für den ersten Test genügt eine abgeschlossene Beispielperiode.
Beispieldaten und Periodenstatus
Die Beträge sind in EUR angegeben. Das Beispiel umfasst eine Abrechnungsperiode und ein Abrechnungskonto; in der Tabelle billing_period_demo steht dafür genau ein Statusdatensatz mit PeriodKeyDemo = 'P1' und IsClosedDemo = 1. Beide Hilfsspalten sind lokal vergeben und keine behaupteten FOCUS-Feldnamen. Bei einem echten Export wird der Abschlussstatus aus dem gelieferten Billing-Period-Datensatz übernommen.
Die Tabellenzeilen sind Beispieldaten, keine Abbildung eines Provider-Schemas. LineKindDemo klassifiziert Rechnungspositionen im Beispiel als Nutzung, Steuer oder weitere Position. Die Spalte „Quelle“ trennt Invoice Detail von Cost and Usage.
| Quelle | InvoiceId | Position im Beispiel | BilledCost in EUR |
|---|---|---|---|
| Invoice Detail | INV-A | Nutzung | 150 |
| Invoice Detail | INV-A | Steuer | 10 |
| Cost and Usage | INV-A | Nutzung | 100 |
| Cost and Usage | INV-A | Nutzung | 50 |
| Invoice Detail | INV-B | Nutzung | 75 |
| Cost and Usage | INV-B | Nutzung | 70 |
| Invoice Detail | INV-C | Weitere Position | 12 |
INV-C hat in diesem Ausschnitt keine Cost-and-Usage-Zeile. Ob die zwölf Euro ein Entgelt ohne Nutzungszeile oder ein Hinweis auf einen unvollständigen Export sind, zeigt erst die zugehörige Rechnungsposition. Vor dieser Prüfung werden die Beträge je InvoiceId zusammengeführt.
Rechnungszeilen und Nutzungsdaten per InvoiceId verbinden
Einer Rechnungsposition über 150 EUR stehen bei INV-A zwei Nutzungszeilen über 100 und 50 EUR gegenüber. Zeilenweise lässt sich das nicht prüfen. Beide Seiten werden zunächst innerhalb derselben Abrechnungsperiode nach InvoiceId summiert; bei mehreren Konten oder Währungen müssen deren Kennungen ebenfalls in die Gruppierung eingehen.
Die Nutzungszeilen für INV-A ergeben zusammen 150 EUR. Invoice Detail enthält zusätzlich zehn Euro Steuer, sodass die Rechnung dort 160 EUR ausweist. Bei INV-B stehen 75 EUR auf der Rechnung nur 70 EUR in Cost and Usage gegenüber. INV-C darf trotz der fehlenden Nutzungszeile nicht aus dem Ergebnis verschwinden. Diese drei Fälle lassen sich mit einem Prüfsaldo je InvoiceId unterscheiden.
BilledCost-Differenzen mit SQL untersuchen
Die Abfrage arbeitet mit den vorbereiteten Beispieltabellen invoice_detail_demo, usage_demo und billing_period_demo. Der Parameter :period erhält für diesen Test den Wert 'P1'. Nur ein als abgeschlossen markierter Zeitraum gelangt in die Summen; vor dem Join werden beide Betragsseiten getrennt aggregiert.
WITH closed_period AS (
SELECT PeriodKeyDemo
FROM billing_period_demo
WHERE PeriodKeyDemo = :period
AND IsClosedDemo = 1
), invoice_totals AS (
SELECT d.InvoiceId,
SUM(CASE WHEN d.LineKindDemo = 'Tax'
THEN 0 ELSE d.BilledCost END) AS InvoiceWithoutTax,
SUM(CASE WHEN d.LineKindDemo = 'Tax'
THEN d.BilledCost ELSE 0 END) AS TaxAmount,
SUM(CASE WHEN d.LineKindDemo = 'Usage'
OR d.LineKindDemo = 'Tax'
THEN 0 ELSE d.BilledCost END) AS OtherAmount
FROM invoice_detail_demo d
JOIN closed_period p ON p.PeriodKeyDemo = d.PeriodKeyDemo
GROUP BY d.InvoiceId
), usage_totals AS (
SELECT u.InvoiceId, SUM(u.BilledCost) AS UsageCost
FROM usage_demo u
JOIN closed_period p ON p.PeriodKeyDemo = u.PeriodKeyDemo
GROUP BY u.InvoiceId
)
SELECT COALESCE(i.InvoiceId, u.InvoiceId) AS InvoiceId,
i.InvoiceWithoutTax,
u.UsageCost,
i.TaxAmount,
i.OtherAmount,
COALESCE(i.InvoiceWithoutTax, 0)
- COALESCE(u.UsageCost, 0) AS Difference
FROM invoice_totals i
FULL OUTER JOIN usage_totals u
ON i.InvoiceId = u.InvoiceId;
Für INV-A ergibt sich nach Abzug der separat ausgewiesenen Steuer eine Differenz von null Euro. INV-B weist fünf Euro auf; INV-C erscheint mit zwölf Euro Differenz und zwölf Euro unter „Weitere Position“. Der Betrag von INV-C ist damit ein Prüffall, noch kein belegter Nutzungsfehler. Der FULL OUTER JOIN zeigt auch Zeilen ohne Gegenstück; COALESCE ersetzt fehlende Werte nur für die Differenzberechnung durch null. Liefert die Statusabfrage keine abgeschlossene Periode, gibt dieses Beispiel keine Ergebniszeilen zurück. Damit aus dem Prüfsaldo ein wiederholbarer Abgleich wird, müssen die Voraussetzungen jedes Laufs festgehalten werden.
Den Abgleich für weitere Perioden dokumentieren
Ein Prüfprotokoll hält für jeden Lauf fest:
- die tatsächlich gelieferte FOCUS-Version und das Abrechnungskonto
- den Periodenschlüssel und den Abschlussstatus zum Auswertungszeitpunkt
- die Regeln für Steuern und weitere Rechnungspositionen
- die BilledCost-Summen je InvoiceId und die verwendete Währung
- offene Differenzen mit Rechnungsschlüssel und geprüften Beträgen
Bei weiteren Providern müssen Invoice Detail, Billing Period und die benötigten Felder jeweils im Export vorhanden sein. Die Demo-Abfrage setzt außerdem eine Datenbank mit Unterstützung für FULL OUTER JOIN voraus; ohne diese Join-Art braucht es eine andere Abfrageform. Fehlen die Datensätze, bestätigt das Beispiel nur die SQL-Logik und keinen realen Rechnungsabschluss. Diese Grenze gehört in den Bericht für das IT-Controlling.
Fazit
Die Null bei INV-A betrifft den Betrag ohne Steuer; die Rechnung enthält zusätzlich zehn Euro Steuer. INV-B und INV-C bleiben Prüffälle, bis die zugehörigen Rechnungspositionen geklärt sind. Übertrage die Abfrage auf eine abgeschlossene Periode deines Exports und prüfe die Zeilen hinter jeder offenen Differenz.