Offene Posten — Verarbeitung (OpenItems)
Zweck
Die Seite /open-items ist die zentrale Verarbeitungsoberflaeche für offene Posten — sowohl Forderungen (receivable) als auch Verbindlichkeiten (payable). Anders als die fokussierten Sichten /customer-open-items und /supplier-open-items zeigt diese Seite alle offenen Posten parallel und gruppiert sie nach Counterparty (Kunde oder Lieferant). Pro Counterparty werden alle zugehörigen offenen Posten aufgelistet, KPIs aggregiert und der Verarbeitungs-Workflow über das Transaction-Modal angeboten.
OpenItem ist polymorph: parentType ist SalesDocument oder PurchaseDocument, parentId der Beleg-Verweis. Jeder offene Posten gehört genau einem Beleg an.
Voraussetzungen
Berechtigungen (CASL)
| Action | Subject | Wirkung | Keycloak-Rolle |
|---|---|---|---|
view | FE_OpenItem, OpenItem | Liste/Detail aufrufbar | — |
update | OpenItem | Manuell Settlement-Status korrigieren | APP_SPEAMCORE_UPDATE_OPEN_ITEM |
view/create | Transaction | Zahlung erfassen | APP_SPEAMCORE_VIEW/CREATE_TRANSACTION |
view | TransactionAllocation | Allokationen anzeigen | APP_SPEAMCORE_VIEW_TRANSACTION_ALLOCATION |
view | SalesDocument, PurchaseDocument | Beleg-Daten in Liste/Detail | APP_SPEAMCORE_VIEW_SALES_DOCUMENT, PURCHASE_DOCUMENT |
view | Customer, Supplier | Counterparty-Spalte | APP_SPEAMCORE_VIEW_CUSTOMER, SUPPLIER |
Schritt-für-Schritt-Anleitung
Posten verarbeiten
- Offene Posten (
/open-items) öffnen. - KPI-Karte wählen — z. B. „Faellig" oder „Bezahlt (30 Tage)".
- Counterparty-Grid links wählen — listet Kunden und Lieferanten mit summierten offenen Betraegen.
- Detail-Panel rechts zeigt alle offenen Posten der gewählten Counterparty.
- Posten markieren → Zahlung erfassen →
OpenItemTransactionModalöffnet sich mit Vorbefuellung. - Transaktion erfassen — zugehörige
TransactionAllocationwird angelegt, Settlement-Status des Posten aktualisiert.
Settlement-Filter
Multi-Select für Status:
open— komplett offen.partial— teilweise bezahlt.settled— komplett ausgeglichen (standardmaessig ausgeblendet, für Historie sichtbar).overpaid— ueberzahlt (Erstattung erforderlich).
Storno-Modus
Modal kann zwischen payment und reversal geschaltet werden — ein Reversal storniert eine bestehende Allokation.
Brutto-/Netto-Toggle
showNet-Switch wechselt zwischen Brutto- und Netto-Anzeige (Steuer separat ausgewiesen).

UI-Elemente
Komponente: KpiSummaryCards
Karten mit aggregierten Counts/Summen pro KPI-Filter (all, open, due, paid30, overpaid).
Komponente: CounterpartyGrid
Liste der Kunden + Lieferanten mit aggregiertem offenem Betrag. Klick selektiert Counterparty und filtert das Detail-Panel.
Komponente: OpenItemDetailPanel
Posten-Liste der gewählten Counterparty. DataGridPremium mit Spalten: Beleg-Nummer, Datum, Brutto/Netto, Offen, Faellig-Datum, Status.
Komponente: OpenItemTransactionModal
Modal zum Erfassen einer Zahlung oder Stornierung. Vorbefuellt mit Posten-Daten und Restbetrag.
Felder und Eingaben (lesend pro OpenItem)
| Feldname | Datentyp | Bedeutung |
|---|---|---|
parentType | ENUM (SalesDocument, PurchaseDocument) | Beleg-Typ. |
parentId | UUID | Verweis auf Beleg. |
direction | ENUM (receivable, payable) | Forderung oder Verbindlichkeit. |
amount | Decimal | Brutto-Originalbetrag des Postens. |
outstandingAmount | Decimal (berechnet) | Noch offener Betrag = amount − Summe aller Allokationen. |
dueDate | Date | Faelligkeit. Wird aus Beleg-paymentTarget abgeleitet. |
settlementStatus | ENUM (open, partial, settled, overpaid, partiallyPaid) | Berechneter Status. |
Welche Belege einen offenen Posten erzeugen
Ein offener Posten entsteht nur für buchhalterisch relevante Belege. Angebote, Auftragsbestätigungen und Lieferscheine bekommen keinen offenen Posten — ein etwaiger Altlast-Eintrag wird beim Sperren automatisch entfernt.
| Quelle | Belegtypen mit offenem Posten |
|---|---|
Verkauf (SalesDocument) | invoice, interimInvoice, finalInvoice, creditNote, correctionInvoice, depositInvoice |
Einkauf (PurchaseDocument) | incomingInvoice |
Dieser Billable-Guard (isBillableDocument) greift beim Anlegen (createOpenItemForDocument). Da der Eindeutigkeits-Index auch soft-gelöschte Zeilen abdeckt, wird beim erneuten Sperren ein zuvor soft-gelöschter Posten wiederbelebt statt doppelt angelegt (siehe Hinweis weiter unten).
Beleg-gegen-Beleg-Ausgleich (OpenItemSettlement)
Zwei offene Posten können sich ohne Bankzahlung gegeneinander ausgleichen — typischerweise eine Storno-Gutschrift gegen die Original-Rechnung beim Korrigieren. Dafür gibt es das Modell OpenItemSettlement:
| Feld | Bedeutung |
|---|---|
invoiceDocumentId / invoiceDocumentType | Rechnungsseite — der positive offene Posten, der abgebaut wird |
creditDocumentId / creditDocumentType | Gutschrift-/Storno-Seite — der negative offene Posten, der verbraucht wird |
amount | verrechneter Betrag |
reason | Grund (Default correction) |
createdByEmployeeId | auslösender Mitarbeiter |
computeOpenItemState rechnet diese Verrechnungen in den bezahlten Betrag (paidAmount) ein. Beispiel: Original-Rechnung 100 € und Storno-Gutschrift −100 € gleichen sich aus → beide offenen Posten gehen auf settled, ohne dass sich am Hauptbuch (GL) etwas bewegt.
Wiederverwendbare Konzepte
- Buchhaltungskonten — Querschnitts-Konzept.
- Polymorpher Parent-Pattern —
parentType/parentIdzu Sales-/PurchaseDocument. - Berechtigungen verstehen (CASL)
Verknuepfungen zu anderen Modulen
- Forderungen Kunden — fokussierte Sicht nur Receivables.
- Verbindlichkeiten Lieferanten — fokussierte Sicht nur Payables.
- Verkaufsbelege — erzeugen Receivables über den Buchungs-Service.
- Bestellbelege — erzeugen Payables.
- Transaktionen — Zahlung wird als Transaction angelegt.
- Match-Vorschlaege — Auto-Match-Engine schlaegt OpenItems für Transaktionen vor.
- Mahnwesen — überfällige Forderungen (
receivable) sind die Datenbasis für Mahnläufe.
Häufige Fehler und Lösungen
| Fehler | Lösung |
|---|---|
| Counterparty fehlt im Grid | Kein offener Posten oder alle bereits settled und Filter blendet sie aus. |
outstandingAmount weicht vom Erwarteten ab | Allokation prüfen — z. B. fehlerhafte Doppel-Zahlung. |
| Modal vorbefuellt mit falschem Konto | transactionPrefill haelt Voreinstellungen — bei wiederholter Nutzung Cache leeren oder neue Auswahl treffen. |
| Settlement-Status stimmt nicht | Allokationen laufen über Transaction-Service. Status wird beim Speichern neu berechnet. |
API/Schnittstellen
| Methode | Endpoint | Zweck | CASL |
|---|---|---|---|
GET | /api/open-items | Liste (mit include=salesDocument,purchaseDocument,...) | view OpenItem |
GET | /api/open-items/:id | Detail | view OpenItem |
PATCH | /api/open-items/:id | Settlement-Status manuell korrigieren | update OpenItem |
POST | /api/open-items/regenerate | Offene(n) Posten zu einem Beleg neu erzeugen | view OpenItem |
POST | /api/open-items/reconcile-tivapp | OP-Export aus TIVApp (Excel) gegen SpeamCore abgleichen | view OpenItem |
POST | /api/transactions | Zahlung erfassen (loest Allokation aus) | create Transaction |
GET | /api/transaction-allocations?filter[openItemId] | Allokationen pro Posten | view TransactionAllocation |
Versionshinweise
- 2026-06-22: Billable-Guard dokumentiert (offene Posten nur für Rechnungs-/Gutschrift- bzw. Eingangsrechnungs-Typen; Altlasten werden bereinigt) und Beleg-gegen-Beleg-Ausgleich (
OpenItemSettlement) — Storno-Gutschrift gegen Original ohne GL-Bewegung. Verifiziert anopenItem.service.ts(BILLABLE_SALES_TYPES,isBillableDocument,computeOpenItemState) undopenItemSettlement.model.ts. - 2026-06-09: Endpoint
POST /open-items/regenerate(offenen Posten pro Beleg neu erzeugen) ergänzt; Hinweis zu Wiederbelebung soft-gelöschter OpenItems beim Relock + Backfill. Verifiziert anopenItem.router.ts(regenerateOpenItem). - 2026-06-09 (Nachmittag): TIVApp-OP-Abgleich (
POST /open-items/reconcile-tivapp, Excel-Upload,view:OpenItem) — gleicht einen offenen-Posten-Export aus dem Drittsystem TIVApp gegen SpeamCore ab. Verifiziert antivAppReconciliation.service.ts. - 2026-04-30: Initiale Veroeffentlichung.