Fixes method creating new time entry (collision check must be improved)

This commit is contained in:
szsa
2022-03-30 08:42:44 +02:00
parent dc9eb0f0bb
commit aff0f9fc94
4 changed files with 29 additions and 59 deletions

View File

@@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import net.szymonsawicki.reactivetimesheetapp.application.service.exception.TimeEntryServiceException;
import net.szymonsawicki.reactivetimesheetapp.application.service.exception.UserServiceException;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.TimeEntry;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.TimeEntryUtils;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.dto.CreateTimeEntryDto;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.dto.GetTimeEntryDto;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.repository.TimeEntryRepository;
@@ -22,34 +23,33 @@ public class TimeEntryService {
public Mono<GetTimeEntryDto> addTimeEntry(Mono<CreateTimeEntryDto> createTimeEntryDtoMono) {
return createTimeEntryDtoMono
.then(checkEntry(createTimeEntryDtoMono))
.flatMap(createTimeEntryDto -> {
return timeEntryRepository.save(createTimeEntryDto.toTimeEntry())
.map(TimeEntry::toGetTimeEntryDto);
.flatMap(this::checkEntry)
.flatMap(createTimeEntryDto -> timeEntryRepository.save(createTimeEntryDto.toTimeEntry())
.map(TimeEntry::toGetTimeEntryDto));
}
private Mono<CreateTimeEntryDto> checkEntry(CreateTimeEntryDto timeEntryToCheck) {
return userRepository
.findById(timeEntryToCheck.user().id())
.hasElement()
.flatMap(isUserPresent -> Boolean.TRUE.equals(isUserPresent)
?
findCollisions(timeEntryToCheck)
:
Mono.error(new UserServiceException("user not exists")));
}
private Mono<CreateTimeEntryDto> findCollisions(CreateTimeEntryDto timeEntryToCheck) {
return timeEntryRepository.findAllByUser(timeEntryToCheck.user().toUser())
.filter(entry -> !TimeEntryUtils.toTimeFrom.apply(entry).isAfter(timeEntryToCheck.timeTo())
&& !TimeEntryUtils.toTimeTo.apply(entry).isBefore(timeEntryToCheck.timeFrom()))
.collectList()
.flatMap(result -> {
if (result.isEmpty()) {
Mono.error(new TimeEntryServiceException("time entry collision"));
}
return Mono.just(timeEntryToCheck);
});
}
private Mono<CreateTimeEntryDto> checkEntry(Mono<CreateTimeEntryDto> timeEntryToCheck) {
return timeEntryToCheck.flatMap(t ->
// at first check if the user exists
userRepository
.findById(t.user().id())
.hasElement()
.flatMap(isUserPresent -> Boolean.TRUE.equals(isUserPresent)
?
Mono.just(timeEntryToCheck)
:
Mono.error(new UserServiceException("user not exists")))
// then collision check of the time entry
.flatMap(entry -> timeEntryRepository.timeCheck(t.timeFrom(), t.timeTo())
.flatMap(result -> result
?
Mono.error(new TimeEntryServiceException("time entry collision"))
:
Mono.just(t))));
}
}

View File

@@ -4,15 +4,8 @@ import net.szymonsawicki.reactivetimesheetapp.domain.configs.CrudRepository;
import net.szymonsawicki.reactivetimesheetapp.domain.time_entry.TimeEntry;
import net.szymonsawicki.reactivetimesheetapp.domain.user.User;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDate;
import java.time.LocalDateTime;
public interface TimeEntryRepository extends CrudRepository<TimeEntry, String> {
Flux<TimeEntry> findAllByUserAndDate(User user, LocalDate date);
Flux<TimeEntry> findAllByUser(User user);
Mono<Boolean> timeCheck(LocalDateTime dateFrom, LocalDateTime dateTo);
}

View File

@@ -2,19 +2,10 @@ package net.szymonsawicki.reactivetimesheetapp.infrastructure.persistence.dao;
import net.szymonsawicki.reactivetimesheetapp.infrastructure.persistence.entity.TimeEntryEntity;
import net.szymonsawicki.reactivetimesheetapp.infrastructure.persistence.entity.UserEntity;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDate;
import java.time.LocalDateTime;
public interface TimeEntryDao extends ReactiveMongoRepository<TimeEntryEntity, String> {
Flux<TimeEntryEntity> findAllByUserAndDate(UserEntity user, LocalDate date);
Flux<TimeEntryEntity> findAllByUser(UserEntity user);
@Query(value = "{'timeFrom':{ $gte: ?1},'timeTo':{ $lte: ?0}}")
Mono<Boolean> timeCheck(LocalDateTime timeFrom, LocalDateTime timeTo);
}
}

View File

@@ -10,8 +10,6 @@ import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@Repository
@@ -20,7 +18,6 @@ public class TimeEntryRepositoryImpl implements TimeEntryRepository {
private final TimeEntryDao timeEntryDao;
@Override
public Flux<TimeEntry> findAll() {
return timeEntryDao.findAll()
@@ -55,20 +52,9 @@ public class TimeEntryRepositoryImpl implements TimeEntryRepository {
.switchIfEmpty(Mono.error(new PersistenceException("cannot find team to delete")));
}
@Override
public Flux<TimeEntry> findAllByUserAndDate(User user, LocalDate date) {
return timeEntryDao.findAllByUserAndDate(user.toEntity(), date)
.flatMap(timeEntryEntity -> Mono.just(timeEntryEntity.toTimeEntry()));
}
@Override
public Flux<TimeEntry> findAllByUser(User user) {
return timeEntryDao.findAllByUser(user.toEntity())
.flatMap(timeEntryEntity -> Mono.just(timeEntryEntity.toTimeEntry()));
}
@Override
public Mono<Boolean> timeCheck(LocalDateTime dateFrom, LocalDateTime dateTo) {
return timeEntryDao.timeCheck(dateFrom, dateTo);
}
}