Skip to content

Commit

Permalink
feature: add calendar view for reminder occurrences
Browse files Browse the repository at this point in the history
  • Loading branch information
MDeLuise committed Oct 10, 2024
1 parent dbf7a8f commit 54f5d0b
Show file tree
Hide file tree
Showing 22 changed files with 944 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package com.github.mdeluise.plantit.reminder;

import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;

import com.github.mdeluise.plantit.diary.entry.DiaryEntryType;
import com.github.mdeluise.plantit.reminder.occurrence.ReminderOccurrence;
import com.github.mdeluise.plantit.reminder.occurrence.ReminderOccurrenceDTO;
import com.github.mdeluise.plantit.reminder.occurrence.ReminderOccurrenceDTOConverter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -14,6 +22,7 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
Expand All @@ -22,12 +31,15 @@
public class ReminderController {
private final ReminderService reminderService;
private final ReminderDTOConverter reminderDtoConverter;
private final ReminderOccurrenceDTOConverter reminderOccurrenceDtoConverter;


@Autowired
public ReminderController(ReminderService reminderService, ReminderDTOConverter reminderDtoConverter) {
public ReminderController(ReminderService reminderService, ReminderDTOConverter reminderDtoConverter,
ReminderOccurrenceDTOConverter reminderOccurrenceDtoConverter) {
this.reminderService = reminderService;
this.reminderDtoConverter = reminderDtoConverter;
this.reminderOccurrenceDtoConverter = reminderOccurrenceDtoConverter;
}


Expand Down Expand Up @@ -67,4 +79,16 @@ public ResponseEntity<ReminderDTO> update(@PathVariable Long id, @RequestBody Re
final Reminder result = reminderService.update(id, reminderDtoConverter.convertFromDTO(reminderDTO));
return ResponseEntity.ok(reminderDtoConverter.convertToDTO(result));
}


@GetMapping("/occurrences")
public ResponseEntity<Page<ReminderOccurrenceDTO>> getOccurrences(@RequestParam(required = false) Long plantId,
@RequestParam(required = false) DiaryEntryType type,
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Date from,
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Date to,
Pageable pageable) {
final Page<ReminderOccurrence> allOccurrences = reminderService.getAllOccurrences(type, plantId, from, to, pageable);
final Page<ReminderOccurrenceDTO> result = allOccurrences.map(reminderOccurrenceDtoConverter::convertToDTO);
return ResponseEntity.ok(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;

import com.github.mdeluise.plantit.authentication.User;
import com.github.mdeluise.plantit.diary.entry.DiaryEntryType;
import com.github.mdeluise.plantit.plant.Plant;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
Expand All @@ -14,4 +15,8 @@ public interface ReminderRepository extends JpaRepository<Reminder, Long> {
List<Reminder> findAllByTargetOwner(User user);

List<Reminder> findAllByTargetAndTargetOwner(Plant target, User owner);

List<Reminder> findAllByTargetOwnerAndAction(User owner, DiaryEntryType type);

List<Reminder> findAllByTargetOwnerAndTargetAndAction(User owner, Plant target, DiaryEntryType type);
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
package com.github.mdeluise.plantit.reminder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import com.github.mdeluise.plantit.authentication.User;
import com.github.mdeluise.plantit.common.AuthenticatedUserService;
import com.github.mdeluise.plantit.diary.entry.DiaryEntryType;
import com.github.mdeluise.plantit.exception.ResourceNotFoundException;
import com.github.mdeluise.plantit.exception.UnauthorizedException;
import com.github.mdeluise.plantit.plant.Plant;
import com.github.mdeluise.plantit.plant.PlantService;
import com.github.mdeluise.plantit.reminder.occurrence.ReminderOccurrence;
import com.github.mdeluise.plantit.reminder.occurrence.ReminderOccurrenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
public class ReminderService {
private final ReminderRepository reminderRepository;
private final PlantService plantService;
private final AuthenticatedUserService authenticatedUserService;
private final ReminderOccurrenceService reminderOccurrenceService;


@Autowired
public ReminderService(ReminderRepository reminderRepository, PlantService plantService,
AuthenticatedUserService authenticatedUserService) {
AuthenticatedUserService authenticatedUserService,
ReminderOccurrenceService reminderOccurrenceService) {
this.reminderRepository = reminderRepository;
this.plantService = plantService;
this.authenticatedUserService = authenticatedUserService;
this.reminderOccurrenceService = reminderOccurrenceService;
}


Expand Down Expand Up @@ -87,4 +99,31 @@ public Reminder save(Reminder reminder) {
public void deleteAll() {
reminderRepository.findAll().forEach(reminder -> remove(reminder.getId()));
}


public Collection<Reminder> getAllFiltered(DiaryEntryType type, Long plantId) {
final User authenticatedUser = authenticatedUserService.getAuthenticatedUser();
if (type == null && plantId == null) {
return reminderRepository.findAllByTargetOwner(authenticatedUser);
} else if (type == null) {
final Plant plant = plantService.get(plantId);
return reminderRepository.findAllByTargetAndTargetOwner(plant, authenticatedUser);
} else {
return reminderRepository.findAllByTargetOwnerAndAction(authenticatedUser, type);
}
}


public Page<ReminderOccurrence> getAllOccurrences(DiaryEntryType type, Long plantId, Date from, Date to,
Pageable pageable) {
final Collection<Reminder> allFiltered = getAllFiltered(type, plantId);
final List<ReminderOccurrence> occurrences = new ArrayList<>();
for (Reminder reminder : allFiltered) {
occurrences.addAll(reminderOccurrenceService.getOccurrences(reminder, from, to));
}
final int start = Math.min((int) pageable.getOffset(), occurrences.size());
final int end = Math.min(start + pageable.getPageSize(), occurrences.size());
final List<ReminderOccurrence> pageContent = occurrences.subList(start, end);
return new PageImpl<>(pageContent, pageable, occurrences.size());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
package com.github.mdeluise.plantit.reminder.frequency;

import java.util.Calendar;

public enum Unit {
DAYS,
WEEKS,
MONTHS,
YEARS
DAYS(Calendar.DAY_OF_MONTH),
WEEKS(Calendar.WEEK_OF_YEAR),
MONTHS(Calendar.MONTH),
YEARS(Calendar.YEAR);

private final int calendarField;

Unit(int calendarField) {
this.calendarField = calendarField;
}

public int toCalendarField() {
return this.calendarField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.github.mdeluise.plantit.reminder.occurrence;

import java.util.Date;

import com.github.mdeluise.plantit.reminder.Reminder;

public class ReminderOccurrence {
private Date date;
private Reminder reminder;


public Date getDate() {
return date;
}


public void setDate(Date date) {
this.date = date;
}


public Reminder getReminder() {
return reminder;
}


public void setReminder(Reminder reminder) {
this.reminder = reminder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.github.mdeluise.plantit.reminder.occurrence;

import java.util.Date;

import com.github.mdeluise.plantit.reminder.frequency.FrequencyDTO;

public class ReminderOccurrenceDTO {
private Date date;
private Long reminderId;
private FrequencyDTO reminderFrequency;
private String reminderAction;
private Long reminderTargetId;
private String reminderTargetInfoPersonalName;


public Date getDate() {
return date;
}


public void setDate(Date date) {
this.date = date;
}


public Long getReminderId() {
return reminderId;
}


public void setReminderId(Long reminderId) {
this.reminderId = reminderId;
}


public FrequencyDTO getReminderFrequency() {
return reminderFrequency;
}


public void setReminderFrequency(FrequencyDTO reminderFrequency) {
this.reminderFrequency = reminderFrequency;
}


public String getReminderAction() {
return reminderAction;
}


public void setReminderAction(String reminderAction) {
this.reminderAction = reminderAction;
}


public Long getReminderTargetId() {
return reminderTargetId;
}


public void setReminderTargetId(Long reminderTargetId) {
this.reminderTargetId = reminderTargetId;
}


public String getReminderTargetInfoPersonalName() {
return reminderTargetInfoPersonalName;
}


public void setReminderTargetInfoPersonalName(String reminderTargetInfoPersonalName) {
this.reminderTargetInfoPersonalName = reminderTargetInfoPersonalName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.github.mdeluise.plantit.reminder.occurrence;

import com.github.mdeluise.plantit.common.AbstractDTOConverter;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Controller;

@Controller
public class ReminderOccurrenceDTOConverter extends AbstractDTOConverter<ReminderOccurrence, ReminderOccurrenceDTO> {
public ReminderOccurrenceDTOConverter(ModelMapper modelMapper) {
super(modelMapper);
}


@Override
public ReminderOccurrence convertFromDTO(ReminderOccurrenceDTO dto) {
return modelMapper.map(dto, ReminderOccurrence.class);
}


@Override
public ReminderOccurrenceDTO convertToDTO(ReminderOccurrence data) {
return modelMapper.map(data, ReminderOccurrenceDTO.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.github.mdeluise.plantit.reminder.occurrence;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import com.github.mdeluise.plantit.diary.entry.DiaryEntry;
import com.github.mdeluise.plantit.diary.entry.DiaryEntryService;
import com.github.mdeluise.plantit.reminder.Reminder;
import com.github.mdeluise.plantit.reminder.frequency.Frequency;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ReminderOccurrenceService {
private final DiaryEntryService diaryEntryService;


@Autowired
public ReminderOccurrenceService(DiaryEntryService diaryEntryService) {
this.diaryEntryService = diaryEntryService;
}


public Collection<ReminderOccurrence> getOccurrences(Reminder reminder, Date start, Date end) {
if (!reminder.isEnabled() || reminder.getStart().after(end) ||
reminder.getEnd() != null && reminder.getEnd().before(start)) {
return List.of();
}

final List<ReminderOccurrence> occurrences = new ArrayList<>();
final Optional<DiaryEntry> lastAction = diaryEntryService.getLast(
reminder.getTarget().getId(), reminder.getAction());
Date occurrenceDate;
if (lastAction.isPresent()) {
final Date lastActionDate = lastAction.get().getDate();
occurrenceDate = addToDateOneStep(lastActionDate, reminder.getFrequency());
} else {
occurrenceDate = reminder.getStart();
}
while (occurrenceDate.before(end)) {
if (occurrenceDate.after(start)) {
final ReminderOccurrence occurrence = new ReminderOccurrence();
occurrence.setDate(occurrenceDate);
occurrence.setReminder(reminder);
occurrences.add(occurrence);
}
occurrenceDate = addToDateOneStep(occurrenceDate, reminder.getFrequency());
}
return occurrences;
}


private Date addToDateOneStep(Date date, Frequency frequency) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(frequency.getUnit().toCalendarField(), Math.max(1, frequency.getQuantity()));
return calendar.getTime();
}

}
Loading

0 comments on commit 54f5d0b

Please sign in to comment.