Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
/mvnw text eol=lf
*.cmd text eol=crlf
* text eol=lf
*.bat eol=crlf
*.htm text diff=html
*.html text diff=html
*.xhtml text diff=html
*.java text diff=java
*.css text diff=css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.capgemini.training.appointmentbooking.dataaccess.entity;

import java.time.Instant;
import java.util.Objects;

import com.capgemini.training.appointmentbooking.common.datatype.AppointmentStatus;

Expand Down Expand Up @@ -38,7 +39,30 @@ public class AppointmentEntity extends BaseEntity {
@Column(name = "DATE_TIME")
private Instant dateTime;

@Column(name = "END_DATE_TIME")
private Instant endsAt;

@Enumerated(EnumType.STRING)
private AppointmentStatus status;

@Override
public void prePersist() {
super.prePersist();
validateDates();
}

@Override
public void preUpdate() {
super.preUpdate();
validateDates();
}

private void validateDates() {
Objects.requireNonNull(this.dateTime);
Objects.requireNonNull(this.endsAt);
if (!this.endsAt.isAfter(this.dateTime)) {
throw new IllegalStateException(
String.format("Starting date: %s must be before end date: %s", this.dateTime, this.endsAt));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ SELECT CASE WHEN COUNT(a) > 0 THEN TRUE ELSE FALSE END
FROM AppointmentEntity a
JOIN a.treatment t
WHERE t.specialist.id = :specialistId
AND a.dateTime = :date
AND NOT ( a.endsAt <= :startDate OR a.dateTime >= :endDate)
AND a.status <> com.capgemini.training.appointmentbooking.common.datatype.AppointmentStatus.CANCELLED
""")
boolean hasConflictingAppointmentBySpecialistIdAndDateTime(@Param("specialistId") Long specialistId,
@Param("date") Instant date);
@Param("startDate") Instant startDate, @Param("endDate") Instant endDate);

}
4 changes: 4 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ management.endpoints.web.exposure.include=*
spring.flyway.locations=classpath:db/migration
spring.flyway.enabled=true
spring.flyway.clean-on-validation-error=true

spring.jpa.hibernate.ddl-auto=none

spring.banner.location=classpath:/banner/jbf_banner.txt
8 changes: 8 additions & 0 deletions src/main/resources/banner/jbf_banner.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
,--. ,-----. ,--. ,--. ,------. ,--. ,--. ,--.
| | ,--,--.,--. ,--.,--,--. | |) /_ ,--,--.,---.| |,-. ,---. ,--,--, ,-| | | .---',--.,--.,--,--, ,-| | ,--,--.,-' '-.`--' ,---. ,--,--,
,--. | |' ,-. | \ `' /' ,-. | | .-. \' ,-. | .--'| /| .-. :| \' .-. | | `--, | || || \' .-. |' ,-. |'-. .-',--.| .-. || \
| '-' /\ '-' | \ / \ '-' | | '--' /\ '-' \ `--.| \ \\ --.| || |\ `-' | | |` ' '' '| || |\ `-' |\ '-' | | | | |' '-' '| || |
`-----' `--`--' `--' `--`--' `------' `--`--'`---'`--'`--'`----'`--''--' `---' `--' `----' `--''--' `---' `--`--' `--' `--' `---' `--''--'

${application.title} ${application.version}
Powered by Spring Boot ${spring-boot.version}
5 changes: 3 additions & 2 deletions src/main/resources/db/migration/1.0/V0001__Create_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ CREATE TABLE APPOINTMENT (
ID NUMBER(19,0) NOT NULL,
VERSION INTEGER NOT NULL,
DATE_TIME TIMESTAMP NOT NULL,
END_DATE_TIME TIMESTAMP NOT NULL,
STATUS VARCHAR(128) NOT NULL DEFAULT 'SCHEDULED',
CLIENT_ID NUMBER(19,0) NOT NULL,
TREATMENT_ID NUMBER(19,0) NOT NULL,
Expand All @@ -69,6 +70,6 @@ CREATE SEQUENCE APPOINTMENT_SEQ START WITH 1 INCREMENT BY 100 NOCYCLE;
-- CREATING INDEX
CREATE INDEX IDX_CLIENT_USER ON CLIENT(USER_ID);
CREATE INDEX IDX_SPECIAL_USER ON SPECIALIST(USER_ID);
CREATE INDEX IDX_TREATM_SPECIAL ON TREATMENT(SPECIALIST_ID);
CREATE INDEX IDX_TREATM_SPECIAL ON TREATMENT(SPECIALIST_ID, ID);
CREATE INDEX IDX_APPOINT_CLIENT ON APPOINTMENT(CLIENT_ID);
CREATE INDEX IDX_APPOINT_TREATM ON APPOINTMENT(TREATMENT_ID);
CREATE INDEX IDX_APPOINT_TREATM ON APPOINTMENT(TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS);
40 changes: 20 additions & 20 deletions src/main/resources/db/migration/1.0/V0002__Create_mockdata.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,23 @@ INSERT INTO TREATMENT(ID, VERSION, NAME, DESCRIPTION, DURATION_MINUTES, SPECIALI
INSERT INTO TREATMENT(ID, VERSION, NAME, DESCRIPTION, DURATION_MINUTES, SPECIALIST_ID, CREATED, LAST_UPDATED) VALUES (-12, 0, 'Rekonstrukcja więzadła ACL', 'Rekonstrukcją więzadła krzyżowego przedniego (ACL) z zastąpieniem uszkodzonego więzadła nowym więzadłem ze ścięgien pacjenta.', 180, -4, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

-- APPOINTMENTS
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-1, 0, -1, -1, '2024-03-01 09:00:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-2, 0, -2, -3, '2024-03-02 10:30:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-3, 0, -3, -5, '2024-03-03 14:00:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-4, 0, -4, -10, '2024-03-04 08:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-5, 0, -1, -2, '2024-03-05 11:45:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-6, 0, -2, -4, '2024-03-06 16:30:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-7, 0, -3, -6, '2024-03-07 09:30:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-8, 0, -4, -11, '2024-03-08 13:45:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-9, 0, -1, -7, '2024-03-09 10:00:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-10, 0, -2, -8, '2024-03-10 12:30:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-11, 0, -3, -9, '2024-03-11 15:00:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-12, 0, -4, -12, '2024-03-12 17:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-13, 0, -1, -1, '2024-03-13 08:30:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-14, 0, -2, -3, '2024-03-14 11:00:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-15, 0, -3, -5, '2024-03-15 13:00:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-16, 0, -4, -10, '2024-03-16 09:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-17, 0, -1, -2, '2024-03-17 14:45:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-18, 0, -2, -4, '2024-03-18 16:00:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-19, 0, -3, -6, '2024-03-19 10:45:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-20, 0, -4, -11, '2024-03-20 12:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-1, 0, -1, -1, '2024-03-01 09:00:00', '2024-03-01 09:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-2, 0, -2, -3, '2024-03-02 10:30:00', '2024-03-02 10:45:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-3, 0, -3, -5, '2024-03-03 14:00:00', '2024-03-03 14:15:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-4, 0, -4, -10, '2024-03-04 08:15:00', '2024-03-04 08:30:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-5, 0, -1, -2, '2024-03-05 11:45:00', '2024-03-05 12:00:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-6, 0, -2, -4, '2024-03-06 16:30:00', '2024-03-06 16:45:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-7, 0, -3, -6, '2024-03-07 09:30:00', '2024-03-07 09:45:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-8, 0, -4, -11, '2024-03-08 13:45:00', '2024-03-08 14:00:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-9, 0, -1, -7, '2024-03-09 10:00:00', '2024-03-09 10:15:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-10, 0, -2, -8, '2024-03-10 12:30:00', '2024-03-10 12:45:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-11, 0, -3, -9, '2024-03-11 15:00:00', '2024-03-11 15:15:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-12, 0, -4, -12,'2024-03-12 17:15:00', '2024-03-12 17:30:00','SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-13, 0, -1, -1, '2024-03-13 08:30:00', '2024-03-13 08:45:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-14, 0, -2, -3, '2024-03-14 11:00:00', '2024-03-14 11:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-15, 0, -3, -5, '2024-03-15 13:00:00', '2024-03-15 13:15:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-16, 0, -4, -10,'2024-03-16 09:15:00', '2024-03-16 09:30:00','SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-17, 0, -1, -2, '2024-03-17 14:45:00', '2024-03-17 15:00:00', 'COMPLETED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-18, 0, -2, -4, '2024-03-18 16:00:00', '2024-03-18 16:15:00', 'SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-19, 0, -3, -6, '2024-03-19 10:45:00', '2024-03-19 11:00:00', 'CANCELLED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO APPOINTMENT(ID, VERSION, CLIENT_ID, TREATMENT_ID, DATE_TIME, END_DATE_TIME, STATUS, CREATED, LAST_UPDATED) VALUES (-20, 0, -4, -11,'2024-03-20 12:15:00', '2024-03-20 12:30:00','SCHEDULED', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,78 @@ void shouldFindAppointmentsBySpecialistIdBeforeDate() {
}

@Test
void shouldFindConflictedAppointment() {
void shouldNotFindConflictedAppointmentBefore() {
// given
Long specialistId = -1L;
Instant date = toInstant("2024-03-05 11:30:00");
Instant endDate = toInstant("2024-03-05 11:45:00");

// when
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date,
endDate);

// then
assertThat(conflict).isFalse();
}

@Test
void shouldNotFindConflictedAppointmentAfter() {
// given
Long specialistId = -1L;
Instant date = toInstant("2024-03-05 12:00:00");
Instant endDate = toInstant("2024-03-05 12:01:00");

// when
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date,
endDate);

// then
assertThat(conflict).isFalse();
}

@Test
void shouldFindConflictedAppointmentExact() {
// given
Long specialistId = -1L;
Instant date = toInstant("2024-03-05 11:45:00");
Instant endDate = toInstant("2024-03-05 12:00:00");

// when
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date);
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date,
endDate);

// then
assertThat(conflict).isTrue();
}

@Test
void shouldFindConflictedAppointmentBegin() {
// given
Long specialistId = -1L;
Instant date = toInstant("2024-03-05 11:40:00");
Instant endDate = toInstant("2024-03-05 11:45:01");

// when
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date,
endDate);

// then
assertThat(conflict).isTrue();
}

@Test
void shouldFindConflictedAppointmentEnd() {
// given
Long specialistId = -1L;
Instant date = toInstant("2024-03-05 11:59:59");
Instant endDate = toInstant("2024-03-05 12:05:00");

// when
boolean conflict = appointmentRepository.hasConflictingAppointmentBySpecialistIdAndDateTime(specialistId, date,
endDate);

// then
assertThat(conflict).isTrue();
}

}
Loading