ReservationEntity.java
package cl.prgm.portaltrip.infrastructure.persistence;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import cl.prgm.portaltrip.domain.model.Quote;
import cl.prgm.portaltrip.domain.model.Reservation;
import cl.prgm.portaltrip.domain.model.ReservationStatus;
import cl.prgm.portaltrip.domain.model.RiskLevel;
import cl.prgm.portaltrip.domain.model.TripType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
@Entity
@Table(
name = "reservations",
uniqueConstraints = @UniqueConstraint(
name = "reservations_user_idempotency_key_uq",
columnNames = {"user_id", "idempotency_key"}))
public class ReservationEntity {
@Id
private UUID id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private UserEntity user;
@Column(name = "idempotency_key", nullable = false)
private UUID idempotencyKey;
@Column(nullable = false, unique = true)
private String number;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ReservationStatus status;
@Column(name = "passenger_name", nullable = false)
private String passengerName;
@Column(nullable = false)
private String email;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "destination_id", nullable = false)
private LocationEntity destination;
@Column(name = "travel_date", nullable = false)
private LocalDate travelDate;
@Column(nullable = false)
private int passengers;
@Column(name = "trip_type", nullable = false)
private String tripType;
@Column(nullable = false)
private boolean insurance;
@Column(nullable = false)
private String comments;
@Column(name = "base_price", nullable = false)
private BigDecimal basePrice;
@Column(name = "location_surcharge", nullable = false)
private BigDecimal locationSurcharge;
@Column(name = "passenger_surcharge", nullable = false)
private BigDecimal passengerSurcharge;
@Column(name = "trip_surcharge", nullable = false)
private BigDecimal tripSurcharge;
@Column(name = "insurance_cost", nullable = false)
private BigDecimal insuranceCost;
@Column(nullable = false)
private BigDecimal total;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private RiskLevel risk;
@Column(name = "created_at", nullable = false)
private OffsetDateTime createdAt;
@Column(name = "started_at")
private OffsetDateTime startedAt;
@Column(name = "completed_at")
private OffsetDateTime completedAt;
@ManyToMany
@JoinTable(
name = "reservation_companions",
joinColumns = @JoinColumn(name = "reservation_id"),
inverseJoinColumns = @JoinColumn(name = "character_id"))
private Set<CharacterEntity> companions = new LinkedHashSet<>();
protected ReservationEntity() {
}
public Reservation toDomain() {
List<Integer> companionIds = companions.stream()
.map(CharacterEntity::getId)
.sorted()
.toList();
Quote quote = new Quote(
basePrice,
locationSurcharge,
passengerSurcharge,
tripSurcharge,
insuranceCost,
total,
risk);
return new Reservation(
id,
user.getId(),
idempotencyKey,
number,
status,
passengerName,
email,
destination.getId(),
travelDate,
passengers,
companionIds,
TripType.fromCode(tripType),
insurance,
comments,
quote,
createdAt,
startedAt,
completedAt);
}
public static ReservationEntity fromDomain(
Reservation reservation,
UserEntity user,
LocationEntity destination,
Set<CharacterEntity> companions) {
ReservationEntity entity = new ReservationEntity();
entity.id = reservation.id();
entity.user = user;
entity.idempotencyKey = reservation.idempotencyKey();
entity.number = reservation.number();
entity.status = reservation.status();
entity.passengerName = reservation.passengerName();
entity.email = reservation.email();
entity.destination = destination;
entity.travelDate = reservation.travelDate();
entity.passengers = reservation.passengers();
entity.tripType = reservation.tripType().code();
entity.insurance = reservation.insurance();
entity.comments = reservation.comments();
entity.basePrice = reservation.quote().basePrice();
entity.locationSurcharge = reservation.quote().locationSurcharge();
entity.passengerSurcharge = reservation.quote().passengerSurcharge();
entity.tripSurcharge = reservation.quote().tripSurcharge();
entity.insuranceCost = reservation.quote().insuranceCost();
entity.total = reservation.quote().total();
entity.risk = reservation.quote().risk();
entity.createdAt = reservation.createdAt();
entity.startedAt = reservation.startedAt();
entity.completedAt = reservation.completedAt();
entity.companions = new LinkedHashSet<>(companions);
return entity;
}
}