View Javadoc
1   package io.extact.rms.application.domain;
2   
3   import static java.time.temporal.ChronoUnit.*;
4   import static jakarta.persistence.AccessType.*;
5   
6   import java.time.LocalDateTime;
7   import java.time.chrono.ChronoLocalDateTime;
8   import java.util.Objects;
9   
10  import jakarta.persistence.Access;
11  import jakarta.persistence.Column;
12  import jakarta.persistence.Entity;
13  import jakarta.persistence.GeneratedValue;
14  import jakarta.persistence.GenerationType;
15  import jakarta.persistence.Id;
16  
17  import org.apache.commons.lang3.Range;
18  import org.apache.commons.lang3.builder.ToStringBuilder;
19  import org.apache.commons.lang3.builder.ToStringStyle;
20  
21  import lombok.Getter;
22  import lombok.Setter;
23  
24  import io.extact.rms.application.domain.constraint.BeforeAfterDateTime;
25  import io.extact.rms.application.domain.constraint.Note;
26  import io.extact.rms.application.domain.constraint.ReserveEndDateTime;
27  import io.extact.rms.application.domain.constraint.ReserveStartDateTime;
28  import io.extact.rms.application.domain.constraint.ReserveStartDateTimeFuture;
29  import io.extact.rms.application.domain.constraint.RmsId;
30  import io.extact.rms.application.domain.constraint.BeforeAfterDateTime.BeforeAfterDateTimeValidatable;
31  import io.extact.rms.application.domain.constraint.ValidationGroups.Add;
32  import io.extact.rms.application.domain.constraint.ValidationGroups.Update;
33  
34  @Access(FIELD)
35  @Entity
36  @BeforeAfterDateTime(from = "利用開始日時", to = "利用終了日時")
37  @Getter
38  @Setter
39  public class Reservation implements BeforeAfterDateTimeValidatable, Transformable, IdAccessable {
40  
41      /** id */
42      @Id
43      @GeneratedValue(strategy = GenerationType.IDENTITY)
44      @RmsId(groups = Update.class)
45      private Integer id;
46  
47      /** 利用開始日時 */
48      @ReserveStartDateTime
49      @ReserveStartDateTimeFuture(groups = Add.class)
50      @Column(columnDefinition = "TIMESTAMP")
51      private LocalDateTime startDateTime;
52  
53      /** 利用終了日時 */
54      @ReserveEndDateTime
55      @Column(columnDefinition = "TIMESTAMP")
56      private LocalDateTime endDateTime;
57  
58      /** メモ */
59      @Note
60      private String note;
61  
62      /** 予約したレンタル品ID */
63      @RmsId
64      private int rentalItemId;
65  
66      /** 予約したユーザのユーザアカウントID */
67      @RmsId
68      private int userAccountId;
69  
70      /** 予約したユーザ */
71      private transient UserAccount userAccount;
72  
73      /** 予約したレンタル品 */
74      private transient RentalItem rentalItem;
75  
76  
77      // ----------------------------------------------------- factory methods
78  
79      public static Reservation of(Integer reservationId, LocalDateTime startDateTime, LocalDateTime endDateTime, String note,
80              int rentalItemId, int userAccountId) {
81  
82          var entity = new Reservation();
83          entity.id = reservationId;
84          entity.startDateTime = startDateTime;
85          entity.endDateTime = endDateTime;
86          entity.note = note;
87          entity.rentalItemId = rentalItemId;
88          entity.userAccountId = userAccountId;
89          return entity;
90      }
91  
92      public static Reservation ofTransient(LocalDateTime startDateTime, LocalDateTime endDateTime, String note, int rentalItemId, int userAccountId) {
93          return of(null, startDateTime, endDateTime, note, rentalItemId, userAccountId);
94      }
95  
96      // ----------------------------------------------------- original setter methods
97  
98      public void setStartDateTime(LocalDateTime startDateTime) {
99          this.startDateTime = Objects.requireNonNull(startDateTime).truncatedTo(MINUTES);
100     }
101 
102     public void setEndDateTime(LocalDateTime endDateTime) {
103         this.endDateTime = Objects.requireNonNull(endDateTime).truncatedTo(MINUTES);
104     }
105 
106 
107     // ----------------------------------------------------- service methods
108 
109     public DateTimePeriod getReservePeriod() {
110         return new DateTimePeriod(startDateTime, endDateTime);
111     }
112 
113 
114     // ----------------------------------------------------- override methods
115 
116     @Override
117     public String toString() {
118         return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
119     }
120 
121 
122     // ----------------------------------------------------- inner classes
123 
124     public static class DateTimePeriod {
125 
126         private LocalDateTime startDateTime;
127         private LocalDateTime endDateTime;
128         private Range<ChronoLocalDateTime<?>> period;
129 
130         public DateTimePeriod(LocalDateTime startDateTime, LocalDateTime endDateTime) {
131             this.startDateTime = startDateTime;
132             this.endDateTime = endDateTime;
133             period = Range.between(startDateTime, endDateTime);        }
134 
135         public LocalDateTime getStartDateTime() {
136             return this.startDateTime;
137         }
138 
139         public LocalDateTime getEndDateTime() {
140             return this.endDateTime;
141         }
142 
143         public boolean isOverlappedBy(DateTimePeriod otherPeriod) {
144             return this.period.isOverlappedBy(otherPeriod.period);
145         }
146     }
147 }