#1000: KostZuweisungDO.kt
projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt Tipo: Entidad JPA (DO) · Propósito: Asignación de costos que vincula facturas/salarios a Kost1/Kost2 · Fuente: projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt 266 líneas · 190 código · 55 comentarios · 21 en blanco
Representa una asignación de costos (KostZuweisung) — la distribución de montos de facturas o pagos de salarios de empleados a centros de costo específicos (Kost1 y Kost2). Cada asignación registra un monto neto y se vincula exactamente a uno de: una posición de factura emitida, una posición de factura recibida o una entrada de salario de empleado.
Diseño de la Entidad
| Campo | Tipo | Columna BD | Descripción |
index | Short | INT | Índice de matriz dentro de la lista de asignaciones de la posición |
netto | BigDecimal? | DECIMAL(12,2) | Monto neto asignado a este centro de costo |
kost1 | Kost1DO? | FK kost1_fk | Centro de costo nivel 1 (ManyToOne, lazy) |
kost2 | Kost2DO? | FK kost2_fk | Centro de costo nivel 2 (ManyToOne, lazy) |
rechnungsPosition | RechnungsPositionDO? | FK rechnungs_pos_fk | Posición de factura emitida (nullable) |
eingangsrechnungsPosition | EingangsrechnungsPositionDO? | FK eingangsrechnungs_pos_fk | Posición de factura recibida (nullable) |
employeeSalary | EmployeeSalaryDO? | FK employee_salary_fk | Entrada de salario de empleado (nullable) |
comment | String? | VARCHAR(4000) | Comentario opcional |
Propiedades Calculadas (Transitorias)
| Propiedad | Tipo | Descripción |
brutto | BigDecimal | Monto bruto calculado a partir del neto + IVA de la posición padre |
kost1Id | Long? | Acceso directo a kost1.id |
kost2Id | Long? | Acceso directo a kost2.id |
isEmpty | Boolean | Verdadero si netto es nulo o cero |
Restricción de Exclusión Mutua
Un KostZuweisung debe asignarse exactamente a un objeto financiero. El setter de cada una de las tres referencias aplica exclusividad mutua a nivel de Java: establecer rechnungsPosition lanza una excepción si eingangsrechnungsPosition o employeeSalary ya está establecido, y viceversa. El método hasErrors() valida que exactamente uno esté asignado (devuelve una clave de error i18n si se viola).
Detalles de Persistencia
- Mapeado a
T_FIBU_KOST_ZUWEISUNG
- Tres restricciones únicas, una para cada tipo de objeto financiero: (index, rechnungs_pos_fk, kost1_fk, kost2_fk), (index, eingangsrechnungs_pos_fk, kost1_fk, kost2_fk), (index, employee_salary_fk, kost1_fk, kost2_fk)
- Cinco índices para rendimiento de consultas basadas en FK
- Extiende
DefaultBaseDO, implementa DisplayNameCapable
@JsonBackReference en rechnungsPosition y eingangsrechnungsPosition previene recursión infinita durante la serialización JSON
@JsonSerialize(using = IdOnlySerializer) en todas las referencias ManyToOne para respuestas API compactas
Métodos Utilitarios
setAbstractRechnungsPosition(position) — setter polimórfico que despacha por tipo
newClone() — crea una copia profunda (sin IDs) para clonación de facturas
- Equals/hashCode basado en index + IDs de posición padre (clave de negocio entre los tres tipos padre)
Código Fuente (resumido)
@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.
}
Historial Git
868d6abb7 2025 -> 2026
63081666f Encabezados de archivos fuente: 2024-> 2025.
0237d5eba Json: IdOnlySerializer y IdsOnlySerializer.
db2599ab8 Historial en libro de órdenes, facturas y proyectos.
c8f8ed935 Todas las entidades FetchType.LAZY.
b04a74ffb DisplayHistoryEntry: nuevo concepto.
0b32a3f37 Cosas de migración...
4c04cfd65 ¡CAMBIO MAYOR! IDs Integer a IDs Long.
f984352a0 JsonBackReference/JsonManagedReference: KostZuweisungDO
ca27394ef Constantes refactorizadas.
b78b870bd ShortDisplayNameCapable -> DisplayNameCapable.
8675a1dbe Entidades JPA Kotlin declaradas open (corrección de carga diferida)
1cf12f943 Kostzuweisung: Bucle infinito en serialización json corregido.
812b5b751 Gran WIP: refactorización de (Eingangs)Rechnung* asesino de rendimiento
339e017b4 @PropertyInfo soportado para métodos getter.
3bd2b6e9d RechnungRest: Agregar lista de posiciones
100cc30f0 KostZuweisungDO.java -> KostZuweisungDO.kt