#1000: KostZuweisungDO.kt
projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt Тип: JPA-сущность (DO) · Назначение: распределение затрат, связывающее счета/зарплаты с Kost1/Kost2 · Исходник: projectforge-business/src/main/kotlin/org/projectforge/business/fibu/kost/KostZuweisungDO.kt 266 строк · 190 кода · 55 комментариев · 21 пустая
Представляет собой назначение затрат (KostZuweisung) — распределение сумм счетов или выплат заработной платы сотрудников по конкретным центрам затрат (Kost1 и Kost2). Каждое назначение фиксирует чистую сумму и ссылается ровно на один из следующих объектов: позиция исходящего счёта, позиция входящего счёта или запись о зарплате сотрудника.
Дизайн сущности
| Поле | Тип | Колонка БД | Описание |
index | Short | INT | Индекс в массиве назначений позиции |
netto | BigDecimal? | DECIMAL(12,2) | Чистая сумма, распределённая на этот центр затрат |
kost1 | Kost1DO? | FK kost1_fk | Центр затрат уровня 1 (ManyToOne, lazy) |
kost2 | Kost2DO? | FK kost2_fk | Центр затрат уровня 2 (ManyToOne, lazy) |
rechnungsPosition | RechnungsPositionDO? | FK rechnungs_pos_fk | Позиция исходящего счёта (nullable) |
eingangsrechnungsPosition | EingangsrechnungsPositionDO? | FK eingangsrechnungs_pos_fk | Позиция входящего счёта (nullable) |
employeeSalary | EmployeeSalaryDO? | FK employee_salary_fk | Запись о зарплате сотрудника (nullable) |
comment | String? | VARCHAR(4000) | Необязательный комментарий |
Вычисляемые (транзитные) свойства
| Свойство | Тип | Описание |
brutto | BigDecimal | Валовая сумма, рассчитанная из чистой суммы + НДС родительской позиции |
kost1Id | Long? | Сокращение для kost1.id |
kost2Id | Long? | Сокращение для kost2.id |
isEmpty | Boolean | True, если netto равно null или нулю |
Ограничение взаимного исключения
KostZuweisung должен быть назначен ровно одному финансовому объекту. Сеттер для каждой из трёх ссылок обеспечивает взаимное исключение на уровне Java: установка rechnungsPosition вызывает исключение, если eingangsrechnungsPosition или employeeSalary уже установлены, и наоборот. Метод hasErrors() проверяет, что назначен ровно один объект (возвращает ключ ошибки i18n в случае нарушения).
Детали персистентности
- Отображается на
T_FIBU_KOST_ZUWEISUNG
- Три уникальных ограничения, по одному для каждого типа финансового объекта: (index, rechnungs_pos_fk, kost1_fk, kost2_fk), (index, eingangsrechnungs_pos_fk, kost1_fk, kost2_fk), (index, employee_salary_fk, kost1_fk, kost2_fk)
- Пять индексов для производительности запросов по внешним ключам
- Расширяет
DefaultBaseDO, реализует DisplayNameCapable
@JsonBackReference на rechnungsPosition и eingangsrechnungsPosition предотвращает бесконечную рекурсию при JSON-сериализации
@JsonSerialize(using = IdOnlySerializer) на всех ссылках ManyToOne для компактных ответов API
Вспомогательные методы
setAbstractRechnungsPosition(position) — полиморфный сеттер, диспетчеризующий по типу
newClone() — создаёт глубокую копию (без ID) для клонирования счетов
- Equals/hashCode на основе index + ID родительской позиции (бизнес-ключ по всем трём типам родителей)
Исходный код (сокращён)
@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(), и т.д.
}
История Git
868d6abb7 2025 -> 2026
63081666f Заголовки исходных файлов: 2024-> 2025.
0237d5eba Json: IdOnlySerializer и IdsOnlySerializer.
db2599ab8 История в книге заказов, счетах и проектах.
c8f8ed935 Все сущности FetchType.LAZY.
b04a74ffb DisplayHistoryEntry: новая концепция.
0b32a3f37 Разное по миграции...
4c04cfd65 MAJOR-CHANGE! Integer id's to Long id's.
f984352a0 JsonBackReference/JsonManagedReference: KostZuweisungDO
ca27394ef Константы рефакторинг.
b78b870bd ShortDisplayNameCapable -> DisplayNameCapable.
8675a1dbe Kotlin JPA сущности объявлены open (исправление ленивой загрузки)
1cf12f943 Kostzuweisung: Исправлена бесконечная петля в json-сериализации.
812b5b751 Большой WIP: рефакторинг (Eingangs)Rechnung* убийца производительности
339e017b4 @PropertyInfo поддерживается для геттеров.
3bd2b6e9d RechnungRest: Добавить список позиций
100cc30f0 KostZuweisungDO.java -> KostZuweisungDO.kt