Fundraiser.java
package org.petify.funding.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "fundraisers")
public class Fundraiser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "shelter_id", nullable = false)
private Long shelterId;
@Column(name = "title", nullable = false, length = 200)
private String title;
@Column(name = "description", length = 2000)
private String description;
@Column(name = "goal_amount", nullable = false, precision = 15, scale = 2)
private BigDecimal goalAmount;
@Enumerated(EnumType.STRING)
@Column(name = "currency", length = 3, nullable = false)
private Currency currency = Currency.PLN;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
@Builder.Default
private FundraiserStatus status = FundraiserStatus.ACTIVE;
@Enumerated(EnumType.STRING)
@Column(name = "type", nullable = false, length = 20)
private FundraiserType type = FundraiserType.GENERAL;
@Column(name = "start_date", nullable = false)
private Instant startDate;
@Column(name = "end_date")
private Instant endDate;
@Column(name = "is_main", nullable = false)
private Boolean isMain = false;
@Column(name = "needs", length = 1000)
private String needs;
@Column(name = "created_by", nullable = false)
private String createdBy;
@Column(name = "created_at")
private Instant createdAt;
@Column(name = "updated_at")
private Instant updatedAt;
@Column(name = "completed_at")
private Instant completedAt;
@Column(name = "cancelled_at")
private Instant cancelledAt;
@PrePersist
protected void onCreate() {
createdAt = Instant.now();
updatedAt = Instant.now();
if (status == null) {
status = FundraiserStatus.ACTIVE;
}
if (startDate == null) {
startDate = Instant.now();
}
}
@PreUpdate
protected void onUpdate() {
updatedAt = Instant.now();
if (status == FundraiserStatus.COMPLETED && completedAt == null) {
completedAt = Instant.now();
}
if (status == FundraiserStatus.CANCELLED && cancelledAt == null) {
cancelledAt = Instant.now();
}
}
public boolean isActive() {
return status == FundraiserStatus.ACTIVE
&& (endDate == null || Instant.now().isBefore(endDate));
}
public boolean isCompleted() {
return status == FundraiserStatus.COMPLETED;
}
public boolean isCancelled() {
return status == FundraiserStatus.CANCELLED;
}
public boolean canAcceptDonations() {
return isActive() && !isCompleted() && !isCancelled();
}
public double calculateProgress(BigDecimal currentAmount) {
if (goalAmount == null || goalAmount.compareTo(BigDecimal.ZERO) == 0) {
return 0.0;
}
return currentAmount.divide(goalAmount, 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100))
.doubleValue();
}
}