#1000: KostZuweisungDO.kt
projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt Typ: JPA-Entität (DO) · Zweck: Kostenverteilung, die Rechnungen/Gehälter mit Kost1/Kost2 verknüpft · Quelle: projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt 266 Zeilen · 190 Code · 55 Kommentare · 21 leer
Stellt eine Kostenverteilung (KostZuweisung) dar – die Zuordnung von Rechnungsbeträgen oder Mitarbeitergehaltszahlungen zu bestimmten Kostenstellen (Kost1 und Kost2). Jede Zuordnung erfasst einen Nettobetrag und verknüpft genau einen der folgenden Einträge: eine Ausgangsrechnungsposition, eine Eingangsrechnungsposition oder einen Mitarbeitergehaltseintrag.
Entwurf der Entität
| Feld | Typ | DB-Spalte | Beschreibung |
index | Short | INT | Array-Index innerhalb der Zuordnungsliste der Position |
netto | BigDecimal? | DECIMAL(12,2) | Dieser Kostenstelle zugewiesener Nettobetrag |
kost1 | Kost1DO? | FK kost1_fk | Kostenstelle Ebene 1 (ManyToOne, lazy) |
kost2 | Kost2DO? | FK kost2_fk | Kostenstelle Ebene 2 (ManyToOne, lazy) |
rechnungsPosition | RechnungsPositionDO? | FK rechnungs_pos_fk | Ausgangsrechnungsposition (nullable) |
eingangsrechnungsPosition | EingangsrechnungsPositionDO? | FK eingangsrechnungs_pos_fk | Eingangsrechnungsposition (nullable) |
employeeSalary | EmployeeSalaryDO? | FK employee_salary_fk | Mitarbeitergehaltseintrag (nullable) |
comment | String? | VARCHAR(4000) | Optionaler Kommentar |
Berechnete (transiente) Eigenschaften
| Eigenschaft | Typ | Beschreibung |
brutto | BigDecimal | Bruttobetrag, berechnet aus Netto + MwSt. der übergeordneten Position |
kost1Id | Long? | Abkürzung für kost1.id |
kost2Id | Long? | Abkürzung für kost2.id |
isEmpty | Boolean | True, wenn netto null oder null ist |
Bedingung des gegenseitigen Ausschlusses
Eine KostZuweisung muss genau einem Finanzobjekt zugeordnet sein. Der Setter für jede der drei Referenzen erzwingt den gegenseitigen Ausschluss auf Java-Ebene: Das Setzen von rechnungsPosition wirft einen Fehler, wenn eingangsrechnungsPosition oder employeeSalary bereits gesetzt ist, und umgekehrt. Die Methode hasErrors() validiert, dass genau eines zugewiesen ist (gibt einen i18n-Fehlerschlüssel zurück, falls verletzt).
Persistenzdetails
- Gemappt auf
T_FIBU_KOST_ZUWEISUNG
- Drei eindeutige Constraints, eines für jeden Finanzobjekttyp: (index, rechnungs_pos_fk, kost1_fk, kost2_fk), (index, eingangsrechnungs_pos_fk, kost1_fk, kost2_fk), (index, employee_salary_fk, kost1_fk, kost2_fk)
- Fünf Indizes für FK-basierte Abfrageleistung
- Erweitert
DefaultBaseDO, implementiert DisplayNameCapable
@JsonBackReference auf rechnungsPosition und eingangsrechnungsPosition verhindert unendliche Rekursion bei der JSON-Serialisierung
@JsonSerialize(using = IdOnlySerializer) auf allen ManyToOne-Referenzen für kompakte API-Antworten
Hilfsmethoden
setAbstractRechnungsPosition(position) — polymorpher Setter, der nach Typ dispatched
newClone() — erstellt eine tiefe Kopie (ohne IDs) zum Klonen von Rechnungen
- Equals/hashCode basierend auf Index + übergeordneten Positions-IDs (Geschäftsschlüssel über alle drei übergeordneten Typen hinweg)
Quellcode (gekürzt)
@Entity @Indexed @Table(name = "T_FIBU_KOST_ZUWEISUNG", ...)
open class KostZuweisungDO : DefaultBaseDO(), DisplayNameCapable {
open var index: Short = 0
open var netto: BigDecimal? = null
open var kost1: Kost1DO? = null
open var kost2: Kost2DO? = null
open var rechnungsPosition: RechnungsPositionDO? = null
set(value) { if (value != null && (eingangsrechnungsPosition != null
|| employeeSalary != null)) throw IllegalStateException(...) }
val brutto: BigDecimal
@Transient get() {
val vat = when {
rechnungsPosition != null -> rechnungsPosition!!.vat
eingangsrechnungsPosition != null -> eingangsrechnungsPosition!!.vat
else -> null
}
return CurrencyHelper.getGrossAmount(netto, vat)
}
// newClone(), hasErrors(), setAbstractRechnungsPosition(), etc.
}
Git-Verlauf
868d6abb7 2025 -> 2026
63081666f Quellcode-Dateiköpfe: 2024 -> 2025.
0237d5eba Json: IdOnlySerializer und IdsOnlySerializer.
db2599ab8 Verlauf in Auftragsbuch, Rechnungen und Projekten.
c8f8ed935 Alle Entitäten FetchType.LAZY.
b04a74ffb DisplayHistoryEntry: neues Konzept.
0b32a3f37 Migration usw...
4c04cfd65 MAJOR-CHANGE! Integer-IDs zu Long-IDs.
f984352a0 JsonBackReference/JsonManagedReference: KostZuweisungDO
ca27394ef Konstanten umgestaltet.
b78b870bd ShortDisplayNameCapable -> DisplayNameCapable.
8675a1dbe Kotlin-JPA-Entitäten als open deklariert (Lazy-Loading-Fix)
1cf12f943 Kostzuweisung: Endlosschleife in der JSON-Serialisierung behoben.
812b5b751 Schweres WIP: Refactoring (Eingangs)Rechnung* Leistungskiller
339e017b4 @PropertyInfo für Getter-Methoden unterstützt.
3bd2b6e9d RechnungRest: Positionsliste hinzugefügt
100cc30f0 KostZuweisungDO.java -> KostZuweisungDO.kt