1 package io.extact.rms.application.persistence.jpa;
2
3 import java.time.LocalDate;
4 import java.time.LocalDateTime;
5 import java.util.List;
6
7 import io.extact.rms.application.domain.Reservation;
8 import io.extact.rms.application.persistence.GenericRepository.ApiType;
9 import io.extact.rms.application.persistence.ReservationRepository;
10 import io.extact.rms.platform.extension.EnabledIfRuntimeConfig;
11 import jakarta.enterprise.context.ApplicationScoped;
12 import jakarta.persistence.EntityManager;
13 import jakarta.persistence.PersistenceContext;
14
15 @ApplicationScoped
16 @EnabledIfRuntimeConfig(propertyName = ApiType.PROP_NAME, value = ApiType.JPA)
17 public class ReservationJpaRepository extends JpaCrudRepository<Reservation> implements ReservationRepository {
18
19 private static final String JPQL_SELECT_BY_RENTAL_ID = "select r from Reservation r where r.rentalItemId = ?1 order by r.id";
20
21 @PersistenceContext
22 private EntityManager em;
23
24 @Override
25 public List<Reservation> findByRentalItemAndStartDate(int rentalItemId, LocalDate startDate) {
26 return em.createQuery(JPQL_SELECT_BY_RENTAL_ID, Reservation.class)
27 .setParameter(1, rentalItemId)
28 .getResultList().stream()
29 .filter(reservation -> reservation.getStartDateTime().toLocalDate().equals(startDate))
30 .toList();
31 }
32
33 @Override
34 public List<Reservation> findByReserverId(int reserverId) {
35 var jpql = "select r from Reservation r where r.userAccountId = ?1 order by r.id";
36 return em.createQuery(jpql, Reservation.class)
37 .setParameter(1, reserverId)
38 .getResultList();
39 }
40
41 @Override
42 public List<Reservation> findByRentalItemId(int rentalItemId) {
43 return em.createQuery(JPQL_SELECT_BY_RENTAL_ID, Reservation.class)
44 .setParameter(1, rentalItemId)
45 .getResultList();
46 }
47
48
49 public List<Reservation> findOverlappedReservations(int rentalItemId, LocalDateTime startDateTime, LocalDateTime endDateTime) {
50 var period = new Reservation.DateTimePeriod(startDateTime, endDateTime);
51 return em.createQuery(JPQL_SELECT_BY_RENTAL_ID, Reservation.class)
52 .setParameter(1, rentalItemId)
53 .getResultList().stream()
54 .filter(reservation -> reservation.getReservePeriod().isOverlappedBy(period))
55 .toList();
56 }
57
58 @Override
59 public Reservation findOverlappedReservation(int rentalItemId, LocalDateTime startDateTime, LocalDateTime endDateTime) {
60 return this.findOverlappedReservations(rentalItemId, startDateTime, endDateTime).stream()
61 .findFirst()
62 .orElse(null);
63 }
64
65 @Override
66 public List<Reservation> findOverlappedReservations(LocalDateTime from, LocalDateTime to) {
67 var period = new Reservation.DateTimePeriod(from, to);
68 return findAll().stream()
69 .filter(reservation -> reservation.getReservePeriod().isOverlappedBy(period))
70 .toList();
71 }
72
73 @Override
74 public EntityManager getEntityManage() {
75 return this.em;
76 }
77
78 @Override
79 public Class<Reservation> getTargetClass() {
80 return Reservation.class;
81 }
82 }