background
Previous Project

Domain Model

In this project we built the domain model, determining the way core business entities are structured and mapped to a PostgreSQL database for robust data integrity and scalable operations.

Next Project
Domain illustration

Implementation

Charity.kt – Defines the Charity entity, capturing vital details and establishing relationships for effective philanthropic management.
1@Entity
2@Table(name = "charity", schema = "data")
3class Charity(
4
5    @Id
6    @Column(name = "charity_id", nullable = false)
7    @NotNull
8    var id: UUID? = null,
9
10    @Embedded
11    var organisation: Organisation,
12
13    // --- RELATIONSHIPS ---
14    @JsonManagedReference
15    @OneToMany(mappedBy = "charity", cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = false)
16    var projects: MutableSet<Project> = mutableSetOf(),
17
18    @OneToMany
19    @JoinTable(
20        name = "charity_field_of_work",
21        joinColumns = [JoinColumn(name = "charity_id")],
22        inverseJoinColumns = [JoinColumn(name = "field_of_work_id")]
23    )
24    var fieldsOfWork: MutableSet<FieldOfWork> = mutableSetOf(), // Charity -> Fields of Work (One-directional)
25
26    @OneToMany(mappedBy = "charity", cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = false)
27    @JsonManagedReference
28    var certificateGrants: MutableSet<CertificateGrant> = mutableSetOf(),
29
30// --- GENERAL INFORMATION ---
31    @Column(name = "founded")
32    var founded: LocalDate? = null,
33
34    @Enumerated(EnumType.STRING)
35    @Column(name = "worldview")
36    var worldview: Worldview? = null,
37
38    @Enumerated(EnumType.STRING)
39    @Column(name = "governing_body")
40    var governingBody: GoverningBody? = null, // "Leitungsorgan"
41
42// --- FINANCIAL INFORMATION ---
43    @Column(name = "reporting_year")
44    var reportingYear: Year? = null, // Bezugsjahr
45
46    @Column(name = "total_income")
47    var totalIncome: BigDecimal? = null, // Gesamteinnahmen
48
49    @Column(name = "fundraising_income")
50    var fundraisingIncome: BigDecimal? = null, // Sammlungseinnahmen
51
52    @Column(name = "tax_deductible")
53    var taxDeductible: Boolean? = null, // Is the Charity tax-deductible?
54
55// --- HUMAN RESOURCES ---
56    @Column(name = "voting_members")
57    var votingMembers: Int? = null, // Stimmberechtigte Mitglieder
58
59    @Column(name = "employees")
60    var employees: Int? = null,  // "hauptamptlich"
61
62    @Column(name = "volunteers")
63    var volunteers: Int? = null,  // "ehrenamtlich"
64
65// --- GEOGRAPHIC REACH ---
66    @JdbcTypeCode(SqlTypes.JSON)
67    @Column(name = "focused_country_codes", columnDefinition = "json")
68    var focusedCountryCodes: List<String> = mutableListOf(),  // Countries where the charity operates
69
70    @Column(name = "created_at", nullable = false, updatable = false)
71    var createdAt: OffsetDateTime? = null,
72
73    @Column(name = "updated_at", nullable = false)
74    var updatedAt: OffsetDateTime? = null,
75
76    ) {
77
78    @PrePersist
79    fun prePersist() {
80        if (createdAt == null) {
81            createdAt = OffsetDateTime.now()
82        }
83        if (updatedAt == null) {
84            updatedAt = createdAt
85        }
86        if (id == null) {
87            id = UUID.randomUUID()
88        }
89    }
90
91    @PreUpdate
92    fun preUpdate() {
93        if (updatedAt == null) {
94            updatedAt = OffsetDateTime.now()
95        }
96    }
97
98    override fun equals(other: Any?): Boolean {
99        if (this === other) return true
100        if (javaClass != other?.javaClass) return false
101
102        other as Charity
103        return id == other.id
104    }
105
106    override fun hashCode(): Int {
107        return id.hashCode()
108    }
109
110    override fun toString(): String {
111        return "Charity(id=$id, organisation=$organisation, projects=$projects, fieldsOfWork=$fieldsOfWork, certificateGrants=$certificateGrants, founded=$founded, worldview=$worldview, governingBody=$governingBody, reportingYear=$reportingYear, totalIncome=$totalIncome, fundraisingIncome=$fundraisingIncome, taxDeductible=$taxDeductible, votingMembers=$votingMembers, employees=$employees, volunteers=$volunteers, focusedCountryCodes=$focusedCountryCodes, createdAt=$createdAt, updatedAt=$updatedAt)"
112    }
113
114
115}
116