truncate seconds

This commit is contained in:
2021-11-26 07:26:23 +01:00
parent 430d1c731d
commit 9ad604d012
4 changed files with 164 additions and 140 deletions
@@ -6,6 +6,7 @@ package de.bstly.we.borrow.controller.validation;
import java.time.Duration; import java.time.Duration;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -21,6 +22,7 @@ import de.bstly.we.borrow.model.BorrowRequest;
import de.bstly.we.borrow.model.BorrowRequestStatus; import de.bstly.we.borrow.model.BorrowRequestStatus;
import de.bstly.we.borrow.model.QBorrowRequest; import de.bstly.we.borrow.model.QBorrowRequest;
import de.bstly.we.borrow.repository.BorrowRequestRepository; import de.bstly.we.borrow.repository.BorrowRequestRepository;
import de.bstly.we.businesslogic.support.InstantHelper;
/** /**
* The Class BorrowRequestValidator. * The Class BorrowRequestValidator.
@@ -61,112 +63,114 @@ public class BorrowRequestValidator implements Validator {
return; return;
} }
validateTime(borrowRequest, borrowItem, errors);
}
public void validateTime(BorrowRequest borrowRequest, BorrowItem borrowItem, Errors errors) {
if (borrowRequest.getStarts() == null) { if (borrowRequest.getStarts() == null) {
errors.rejectValue("starts", "REQUIRED"); errors.rejectValue("starts", "REQUIRED");
return;
} }
if (borrowRequest.getEnds() == null) { if (borrowRequest.getEnds() == null) {
errors.rejectValue("ends", "REQUIRED"); errors.rejectValue("ends", "REQUIRED");
return;
} }
borrowRequest
.setStarts(InstantHelper.truncate(borrowRequest.getStarts(), ChronoUnit.SECONDS));
borrowRequest.setEnds(InstantHelper.truncate(borrowRequest.getEnds(), ChronoUnit.SECONDS));
// expiry + start // expiry + start
if (borrowRequest.getEnds() != null && borrowRequest.getStarts() != null) { if (borrowRequest.getStarts().isAfter(borrowRequest.getEnds())
if (borrowRequest.getStarts().isAfter(borrowRequest.getEnds()) || borrowRequestRepository.exists(qBorrowRequest.item.eq(borrowRequest.getItem())
|| borrowRequestRepository.exists(qBorrowRequest.item // exlude self
.eq(borrowRequest.getItem()) .and(qBorrowRequest.id
// exlude self .ne(borrowRequest.getId() == null ? -1L : borrowRequest.getId()))
.and(qBorrowRequest.id.ne( // accepted
borrowRequest.getId() == null ? -1L : borrowRequest.getId())) .and(qBorrowRequest.status.eq(BorrowRequestStatus.ACCEPTED))
// accepted // expires after start
.and(qBorrowRequest.status.eq(BorrowRequestStatus.ACCEPTED)) .and(qBorrowRequest.ends.after(borrowRequest.getStarts()))
// expires after start // start before expires
.and(qBorrowRequest.ends.after(borrowRequest.getStarts())) .and(qBorrowRequest.starts.before(borrowRequest.getEnds())))) {
// start before expires errors.rejectValue("starts", "ALREADY_USED");
.and(qBorrowRequest.starts.before(borrowRequest.getEnds())))) { errors.rejectValue("ends", "ALREADY_USED");
errors.rejectValue("starts", "ALREADY_USED"); } else {
errors.rejectValue("ends", "ALREADY_USED"); if (borrowItem.getMinDuration() != null && borrowItem.getMinDuration().compareTo(
Duration.between(borrowRequest.getEnds(), borrowRequest.getStarts())) > 0) {
errors.rejectValue("starts", "TOO_SHORT");
errors.rejectValue("ends", "TOO_SHORT");
} else if (borrowItem.getMaxDuration() != null
&& Duration.between(borrowRequest.getEnds(), borrowRequest.getStarts())
.compareTo(borrowItem.getMaxDuration()) > 0) {
errors.rejectValue("starts", "TOO_LONG");
errors.rejectValue("ends", "TOO_LONG");
} else { } else {
if (borrowItem.getMinDuration() != null && borrowItem.getMinDuration().compareTo( boolean validSlot = false;
Duration.between(borrowRequest.getEnds(), borrowRequest.getStarts())) > 0) { boolean validStart = false;
errors.rejectValue("starts", "TOO_SHORT"); boolean validEnd = false;
errors.rejectValue("ends", "TOO_SHORT"); borrowItemManager.applySlots(borrowItem);
} else if (borrowItem.getMaxDuration() != null
&& Duration.between(borrowRequest.getEnds(), borrowRequest.getStarts())
.compareTo(borrowItem.getMaxDuration()) > 0) {
errors.rejectValue("starts", "TOO_LONG");
errors.rejectValue("ends", "TOO_LONG");
} else {
boolean validSlot = false;
boolean validStart = false;
boolean validEnd = false;
borrowItemManager.applySlots(borrowItem);
switch (borrowItem.getAvailability()) { switch (borrowItem.getAvailability()) {
case ALWAYS: case ALWAYS:
validSlot = true; validSlot = true;
break; break;
case MANUAL: case MANUAL:
for (BorrowItemSlot borrowItemSlot : borrowItem.getSlots()) { for (BorrowItemSlot borrowItemSlot : borrowItem.getSlots()) {
if (borrowItemSlot instanceof BorrowItemManualSlot) { if (borrowItemSlot instanceof BorrowItemManualSlot) {
BorrowItemManualSlot borrowItemManualSlot = (BorrowItemManualSlot) borrowItemSlot; BorrowItemManualSlot borrowItemManualSlot = (BorrowItemManualSlot) borrowItemSlot;
if (borrowRequest.getStarts() if (borrowRequest.getStarts()
.compareTo(borrowItemManualSlot.getStart()) >= 0) { .compareTo(borrowItemManualSlot.getStart()) >= 0) {
validStart = true; validStart = true;
} }
if (borrowRequest.getEnds() if (borrowRequest.getEnds()
.compareTo(borrowItemManualSlot.getEnd()) <= 0) { .compareTo(borrowItemManualSlot.getEnd()) <= 0) {
validEnd = true; validEnd = true;
} }
if (validStart && validEnd) { if (validStart && validEnd) {
validSlot = true; validSlot = true;
break; break;
}
} }
} }
break;
case PERIOD:
for (BorrowItemSlot borrowItemSlot : borrowItem.getSlots()) {
if (borrowItemSlot instanceof BorrowItemPeriodSlot) {
BorrowItemPeriodSlot borrowItemPeriodSlot = (BorrowItemPeriodSlot) borrowItemSlot;
if (borrowRequest.getStarts().atZone(ZoneOffset.UTC).getDayOfWeek()
.compareTo(borrowItemPeriodSlot.getStartDay()) >= 0
&& LocalTime
.ofInstant(borrowRequest.getStarts(),
ZoneOffset.UTC)
.compareTo(
borrowItemPeriodSlot.getStartTime()) >= 0) {
validStart = true;
}
if (borrowRequest.getEnds().atZone(ZoneOffset.UTC).getDayOfWeek()
.compareTo(borrowItemPeriodSlot.getEndDay()) <= 0
&& LocalTime
.ofInstant(borrowRequest.getEnds(), ZoneOffset.UTC)
.compareTo(
borrowItemPeriodSlot.getEndTime()) <= 0) {
validEnd = true;
}
if (validStart && validEnd) {
validSlot = true;
break;
}
}
}
break;
default:
break;
} }
break;
case PERIOD:
for (BorrowItemSlot borrowItemSlot : borrowItem.getSlots()) {
if (borrowItemSlot instanceof BorrowItemPeriodSlot) {
BorrowItemPeriodSlot borrowItemPeriodSlot = (BorrowItemPeriodSlot) borrowItemSlot;
if (borrowRequest.getStarts().atZone(ZoneOffset.UTC).getDayOfWeek()
.compareTo(borrowItemPeriodSlot.getStartDay()) >= 0
&& LocalTime
.ofInstant(borrowRequest.getStarts(), ZoneOffset.UTC)
.compareTo(borrowItemPeriodSlot.getStartTime()) >= 0) {
validStart = true;
}
if (borrowRequest.getEnds().atZone(ZoneOffset.UTC).getDayOfWeek()
.compareTo(borrowItemPeriodSlot.getEndDay()) <= 0
&& LocalTime.ofInstant(borrowRequest.getEnds(), ZoneOffset.UTC)
.compareTo(borrowItemPeriodSlot.getEndTime()) <= 0) {
validEnd = true;
}
if (validStart && validEnd) {
validSlot = true;
break;
}
}
}
break;
default:
break;
}
if (!validSlot) { if (!validSlot) {
if (!validStart) { if (!validStart) {
errors.rejectValue("starts", "INVALID"); errors.rejectValue("starts", "INVALID");
} }
if (!validEnd) { if (!validEnd) {
errors.rejectValue("ends", "INVALID"); errors.rejectValue("ends", "INVALID");
}
} }
} }
} }
} }
} }
} }
@@ -4,6 +4,7 @@
package de.bstly.we.jitsi.controller.validation; package de.bstly.we.jitsi.controller.validation;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -13,6 +14,7 @@ import org.springframework.validation.Validator;
import de.bstly.we.businesslogic.SystemPropertyManager; import de.bstly.we.businesslogic.SystemPropertyManager;
import de.bstly.we.businesslogic.UserManager; import de.bstly.we.businesslogic.UserManager;
import de.bstly.we.businesslogic.support.InstantHelper;
import de.bstly.we.jitsi.model.JitsiRoom; import de.bstly.we.jitsi.model.JitsiRoom;
import de.bstly.we.jitsi.model.QJitsiRoom; import de.bstly.we.jitsi.model.QJitsiRoom;
import de.bstly.we.jitsi.repository.JitsiRoomRepository; import de.bstly.we.jitsi.repository.JitsiRoomRepository;
@@ -65,9 +67,9 @@ public class JitsiRoomValidator implements Validator {
/** /**
* Validate. * Validate.
* *
* @param owner the owner * @param owner the owner
* @param roomName the room name * @param roomName the room name
* @param errors the errors * @param errors the errors
*/ */
public void validate(Long owner, String roomName, Errors errors) { public void validate(Long owner, String roomName, Errors errors) {
if (owner == null) { if (owner == null) {
@@ -95,7 +97,7 @@ public class JitsiRoomValidator implements Validator {
* Validate room. * Validate room.
* *
* @param roomName the room name * @param roomName the room name
* @param errors the errors * @param errors the errors
*/ */
public void validateRoom(String roomName, Errors errors) { public void validateRoom(String roomName, Errors errors) {
for (String systemRoomName : systemPropertyManager.get(RESERVED_JITSI_ROOMS, "") for (String systemRoomName : systemPropertyManager.get(RESERVED_JITSI_ROOMS, "")
@@ -113,10 +115,24 @@ public class JitsiRoomValidator implements Validator {
* Validate expiry. * Validate expiry.
* *
* @param jitsiRoom the jitsi room * @param jitsiRoom the jitsi room
* @param errors the errors * @param errors the errors
*/ */
public void validateExpiry(JitsiRoom jitsiRoom, Errors errors) { public void validateExpiry(JitsiRoom jitsiRoom, Errors errors) {
if (jitsiRoom.getStarts() != null) {
jitsiRoom.setStarts(InstantHelper.truncate(jitsiRoom.getStarts(), ChronoUnit.SECONDS));
}
if (jitsiRoom.getModerationStarts() != null) {
jitsiRoom.setModerationStarts(
InstantHelper.truncate(jitsiRoom.getModerationStarts(), ChronoUnit.SECONDS));
}
if (jitsiRoom.getExpires() != null) {
jitsiRoom
.setExpires(InstantHelper.truncate(jitsiRoom.getExpires(), ChronoUnit.SECONDS));
}
// no moderation start without start // no moderation start without start
if (jitsiRoom.getStarts() == null && jitsiRoom.getModerationStarts() != null) { if (jitsiRoom.getStarts() == null && jitsiRoom.getModerationStarts() != null) {
errors.rejectValue("moderationStarts", "NOT_VALID"); errors.rejectValue("moderationStarts", "NOT_VALID");
@@ -16,6 +16,7 @@ import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import de.bstly.we.businesslogic.SystemPropertyManager; import de.bstly.we.businesslogic.SystemPropertyManager;
import de.bstly.we.businesslogic.support.InstantHelper;
import de.bstly.we.partey.timeslot.businesslogic.TimeslotManager; import de.bstly.we.partey.timeslot.businesslogic.TimeslotManager;
import de.bstly.we.partey.timeslot.model.QTimeslot; import de.bstly.we.partey.timeslot.model.QTimeslot;
import de.bstly.we.partey.timeslot.model.Timeslot; import de.bstly.we.partey.timeslot.model.Timeslot;
@@ -65,65 +66,68 @@ public class TimeslotValidator implements Validator {
public void validateTime(Timeslot timeslot, Errors errors) { public void validateTime(Timeslot timeslot, Errors errors) {
if (timeslot.getStarts() == null) { if (timeslot.getStarts() == null) {
errors.rejectValue("starts", "REQUIRED"); errors.rejectValue("starts", "REQUIRED");
return;
} }
if (timeslot.getEnds() == null) { if (timeslot.getEnds() == null) {
errors.rejectValue("ends", "REQUIRED"); errors.rejectValue("ends", "REQUIRED");
return;
} }
if (timeslot.getStarts() != null && timeslot.getEnds() != null) { timeslot.setStarts(InstantHelper.truncate(timeslot.getStarts(), ChronoUnit.SECONDS));
if (timeslot.getStarts().isAfter(timeslot.getStarts())) { timeslot.setEnds(InstantHelper.truncate(timeslot.getEnds(), ChronoUnit.SECONDS));
errors.rejectValue("starts", "NOT_VALID");
errors.rejectValue("ends", "NOT_VALID");
} else {
BooleanBuilder timeQuery = new BooleanBuilder();
// same type if (timeslot.getStarts().isAfter(timeslot.getStarts())) {
timeQuery.and(qTimeslot.type.eq(timeslot.getType())); errors.rejectValue("starts", "NOT_VALID");
errors.rejectValue("ends", "NOT_VALID");
} else {
BooleanBuilder timeQuery = new BooleanBuilder();
switch (timeslot.getType()) { // same type
case AUDIO: timeQuery.and(qTimeslot.type.eq(timeslot.getType()));
case AUDIO_STREAM:
timeQuery.and(qTimeslot.type
.in(Lists.newArrayList(TimeslotType.AUDIO, TimeslotType.AUDIO_STREAM)));
break;
case VIDEO:
case VIDEO_STREAM:
timeQuery.and(qTimeslot.type
.in(Lists.newArrayList(TimeslotType.VIDEO, TimeslotType.VIDEO_STREAM)));
break;
}
// ends after start switch (timeslot.getType()) {
timeQuery case AUDIO:
.and(qTimeslot.ends.after(timeslot.getStarts().minus( case AUDIO_STREAM:
systemPropertyManager.getLong(TimeslotManager.TIMESLOT_TOLERANCE, timeQuery.and(qTimeslot.type
TimeslotManager.TIMESLOT_TOLERANCE_DEFAULT), .in(Lists.newArrayList(TimeslotType.AUDIO, TimeslotType.AUDIO_STREAM)));
ChronoUnit.MINUTES))); break;
case VIDEO:
case VIDEO_STREAM:
timeQuery.and(qTimeslot.type
.in(Lists.newArrayList(TimeslotType.VIDEO, TimeslotType.VIDEO_STREAM)));
break;
}
// starts before end // ends after start
timeQuery timeQuery
.and(qTimeslot.starts.before(timeslot.getEnds().plus( .and(qTimeslot.ends.after(timeslot.getStarts()
systemPropertyManager.getLong(TimeslotManager.TIMESLOT_TOLERANCE, .minus(systemPropertyManager.getLong(TimeslotManager.TIMESLOT_TOLERANCE,
TimeslotManager.TIMESLOT_TOLERANCE_DEFAULT), TimeslotManager.TIMESLOT_TOLERANCE_DEFAULT),
ChronoUnit.MINUTES))); ChronoUnit.MINUTES)));
if (timeslot.getId() != null && timeslotRepository.existsById(timeslot.getId())) { // starts before end
timeQuery.and(qTimeslot.id.ne(timeslot.getId())); timeQuery
} .and(qTimeslot.starts.before(timeslot.getEnds()
.plus(systemPropertyManager.getLong(TimeslotManager.TIMESLOT_TOLERANCE,
TimeslotManager.TIMESLOT_TOLERANCE_DEFAULT),
ChronoUnit.MINUTES)));
if (timeslotRepository.exists(timeQuery.getValue())) { if (timeslot.getId() != null && timeslotRepository.existsById(timeslot.getId())) {
errors.rejectValue("starts", "ALREADY_EXISTS"); timeQuery.and(qTimeslot.id.ne(timeslot.getId()));
errors.rejectValue("ends", "ALREADY_EXISTS"); }
} else if (((timeslot.getEnds().getEpochSecond()
- timeslot.getStarts().getEpochSecond()) / 60) > systemPropertyManager if (timeslotRepository.exists(timeQuery.getValue())) {
.getLong(TimeslotManager.TIMESLOT_MINUTES, errors.rejectValue("starts", "ALREADY_EXISTS");
TimeslotManager.TIMESLOT_MINUTES_DEFAULT)) { errors.rejectValue("ends", "ALREADY_EXISTS");
errors.rejectValue("ends", "TOO_LONG", } else if (((timeslot.getEnds().getEpochSecond()
String.valueOf( - timeslot.getStarts().getEpochSecond()) / 60) > systemPropertyManager.getLong(
systemPropertyManager.getLong(TimeslotManager.TIMESLOT_MINUTES, TimeslotManager.TIMESLOT_MINUTES,
TimeslotManager.TIMESLOT_MINUTES_DEFAULT))); TimeslotManager.TIMESLOT_MINUTES_DEFAULT)) {
} errors.rejectValue("ends", "TOO_LONG",
String.valueOf(
systemPropertyManager.getLong(TimeslotManager.TIMESLOT_MINUTES,
TimeslotManager.TIMESLOT_MINUTES_DEFAULT)));
} }
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version> <java.version>11</java.version>
<revision>1.4.1-SNAPSHOT</revision> <revision>1.4.2-SNAPSHOT</revision>
</properties> </properties>
<parent> <parent>