Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving challenge 1, 5 and TODOs #184

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
69 changes: 69 additions & 0 deletions src/main/java/com/tenniscourts/guests/GuestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.tenniscourts.guests;

import com.tenniscourts.config.BaseRestController;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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;

import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

@RequestMapping("/guests")
@RestController
@AllArgsConstructor
public class GuestController extends BaseRestController {

@Autowired
private GuestService guestService;

@ApiOperation("Find Guests by Id")
@GetMapping("/{id}")
public ResponseEntity<Optional<Guest>> findById(@PathVariable Long id) {
return ResponseEntity.ok(guestService.findById(id));
}

@ApiOperation("Retrieve Guests List, with support to filter by name")
@GetMapping("/")
public ResponseEntity<List<Guest>> listGuests(@RequestParam(value = "name", required = false) String name) {
if (name == null) {
return ResponseEntity.ok(guestService.listAllGuests());
}
return ResponseEntity.ok(guestService.findByName(name));
}

@ApiOperation("Create a new Guest")
@PostMapping("/")
public ResponseEntity<Guest> createGuest(@RequestBody @Valid GuestDTO guestDTO) {
return new ResponseEntity<Guest>(guestService.createGuest(guestDTO), HttpStatus.CREATED);
}

@ApiOperation("Update a Guest")
@PutMapping("/{id}")
public ResponseEntity<Optional<Guest>> putGuest(@RequestBody @Valid GuestDTO guestDTO, @PathVariable Long id) {
Optional<Guest> guest = guestService.putGuest(guestDTO, id);
if (guest.isPresent()) {
return ResponseEntity.ok(guest);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

@ApiOperation("Delete a Guest")
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteGuest(@PathVariable Long id) {
guestService.deleteGuest(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

}
16 changes: 16 additions & 0 deletions src/main/java/com/tenniscourts/guests/GuestDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.tenniscourts.guests;

import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Getter
@Setter
public class GuestDTO {

@NotNull
@NotEmpty
public String name;
}
14 changes: 14 additions & 0 deletions src/main/java/com/tenniscourts/guests/GuestMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tenniscourts.guests;

import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface GuestMapper {

Guest map(GuestDTO source);

@InheritInverseConfiguration
GuestDTO map(Guest source);

}
13 changes: 13 additions & 0 deletions src/main/java/com/tenniscourts/guests/GuestRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.tenniscourts.guests;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface GuestRepository extends JpaRepository<Guest, Long> {
List<Guest> findAll();

List<Guest> findByName(String name);
}
50 changes: 50 additions & 0 deletions src/main/java/com/tenniscourts/guests/GuestService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.tenniscourts.guests;

import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class GuestService {

@Autowired
private GuestRepository guestRepository;

@Autowired
private GuestMapper guestMapper;

public Guest createGuest(GuestDTO guestDTO) {

Guest guest = guestMapper.map(guestDTO);
return guestRepository.save(guest);
}

public List<Guest> listAllGuests() {
return guestRepository.findAll();
}

public List<Guest> findByName(String name) {
return guestRepository.findByName(name);
}

public Optional<Guest> findById(Long id) {
return guestRepository.findById(id);
}

public void deleteGuest(Long id){
guestRepository.deleteById(id);
}

public Optional<Guest> putGuest(GuestDTO guestDTO, Long id) {
Optional<Guest> guest = guestRepository.findById(id);
return guest.map(value -> {
Guest newGuest = guestMapper.map(guestDTO);
newGuest.setId(id);
return guestRepository.save(newGuest);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
package com.tenniscourts.reservations;

import com.tenniscourts.config.BaseRestController;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@AllArgsConstructor
@RequestMapping("/reservation")
@RestController
public class ReservationController extends BaseRestController {

private final ReservationService reservationService;

@ApiOperation("Create a book reservation")
@PostMapping("/")
public ResponseEntity<Void> bookReservation(CreateReservationRequestDTO createReservationRequestDTO) {
return ResponseEntity.created(locationByEntity(reservationService.bookReservation(createReservationRequestDTO).getId())).build();
}

@ApiOperation("Find a reservation")
@GetMapping("/{id}")
public ResponseEntity<ReservationDTO> findReservation(Long reservationId) {
return ResponseEntity.ok(reservationService.findReservation(reservationId));
}

@ApiOperation("Cancel a reservation")
@DeleteMapping("/{id}")
public ResponseEntity<ReservationDTO> cancelReservation(Long reservationId) {
return ResponseEntity.ok(reservationService.cancelReservation(reservationId));
}

@ApiOperation("Reschedule a reservation")
@PutMapping("/{id}")
public ResponseEntity<ReservationDTO> rescheduleReservation(Long reservationId, Long scheduleId) {
return ResponseEntity.ok(reservationService.rescheduleReservation(reservationId, scheduleId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,11 @@ public BigDecimal getRefundValue(Reservation reservation) {
return BigDecimal.ZERO;
}

/*TODO: This method actually not fully working, find a way to fix the issue when it's throwing the error:
"Cannot reschedule to the same slot.*/
public ReservationDTO rescheduleReservation(Long previousReservationId, Long scheduleId) {
Reservation previousReservation = cancel(previousReservationId);

if (scheduleId.equals(previousReservation.getSchedule().getId())) {
if (scheduleId.equals(previousReservation.getSchedule().getId()) &&
previousReservation.getReservationStatus().name().equals(ReservationStatus.READY_TO_PLAY.name())) {
throw new IllegalArgumentException("Cannot reschedule to the same slot.");
}

Expand Down
42 changes: 33 additions & 9 deletions src/main/java/com/tenniscourts/schedules/ScheduleController.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,56 @@
package com.tenniscourts.schedules;

import com.tenniscourts.config.BaseRestController;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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;

import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;

@AllArgsConstructor
@RequestMapping("/schedule")
@RestController
public class ScheduleController extends BaseRestController {

private final ScheduleService scheduleService;
@Autowired
private ScheduleService scheduleService;

//TODO: implement rest and swagger
public ResponseEntity<Void> addScheduleTennisCourt(CreateScheduleRequestDTO createScheduleRequestDTO) {
@ApiOperation("Register a schedule")
@PostMapping("/")
public ResponseEntity<Void> addScheduleTennisCourt(@RequestBody @Valid CreateScheduleRequestDTO createScheduleRequestDTO) {
return ResponseEntity.created(locationByEntity(scheduleService.addSchedule(createScheduleRequestDTO.getTennisCourtId(), createScheduleRequestDTO).getId())).build();
}

//TODO: implement rest and swagger
public ResponseEntity<List<ScheduleDTO>> findSchedulesByDates(LocalDate startDate,
LocalDate endDate) {
@ApiOperation("Find schedules by timestamp")
@GetMapping("/")
public ResponseEntity<List<ScheduleDTO>> findSchedulesByDates(
@RequestParam(value = "startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
@RequestParam(value = "endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
return ResponseEntity.ok(scheduleService.findSchedulesByDates(LocalDateTime.of(startDate, LocalTime.of(0, 0)), LocalDateTime.of(endDate, LocalTime.of(23, 59))));
}

//TODO: implement rest and swagger
public ResponseEntity<ScheduleDTO> findByScheduleId(Long scheduleId) {
return ResponseEntity.ok(scheduleService.findSchedule(scheduleId));
@ApiOperation("Retrieve schedule by given id")
@GetMapping("/{scheduleId}")
public ResponseEntity<Optional<ScheduleDTO>> findByScheduleId(@PathVariable Long scheduleId) {
Optional<ScheduleDTO> scheduleDTO = scheduleService.findSchedule(scheduleId);
if (scheduleDTO.isPresent()) {
return ResponseEntity.ok(scheduleDTO);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDateTime;
import java.util.List;

public interface ScheduleRepository extends JpaRepository<Schedule, Long> {

List<Schedule> findByTennisCourt_IdOrderByStartDateTime(Long id);

List<Schedule> findAllByStartDateTimeIsGreaterThanEqualAndEndDateTimeIsLessThanEqual(
LocalDateTime startDateTime, LocalDateTime endDateTime);
}
43 changes: 34 additions & 9 deletions src/main/java/com/tenniscourts/schedules/ScheduleService.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,57 @@
package com.tenniscourts.schedules;

import com.tenniscourts.exceptions.AlreadyExistsEntityException;
import com.tenniscourts.tenniscourts.TennisCourt;
import com.tenniscourts.tenniscourts.TennisCourtRepository;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class ScheduleService {

private final ScheduleRepository scheduleRepository;
@Autowired
private ScheduleRepository scheduleRepository;

private final ScheduleMapper scheduleMapper;
@Autowired
private TennisCourtRepository tennisCourtRepository;

@Autowired
private ScheduleMapper scheduleMapper;

public ScheduleDTO addSchedule(Long tennisCourtId, CreateScheduleRequestDTO createScheduleRequestDTO) {
//TODO: implement addSchedule
return null;
LocalDateTime startDateTime = createScheduleRequestDTO.getStartDateTime();
LocalDateTime endDateTime = startDateTime.plusHours(1);
List<ScheduleDTO> scheduleDTOList = findSchedulesByTennisCourtId(tennisCourtId);
if(scheduleDTOList.stream().anyMatch(l -> l.getStartDateTime().isAfter(startDateTime) && l.getStartDateTime().isBefore(endDateTime))){
throw new AlreadyExistsEntityException("The schedule already exist");
}

TennisCourt tennisCourt = tennisCourtRepository.getOne(tennisCourtId);

Schedule schedule = Schedule.builder()
.tennisCourt(tennisCourt)
.startDateTime(startDateTime).endDateTime(endDateTime).build();

scheduleRepository.save(schedule);

return scheduleMapper.map(schedule);
}

public List<ScheduleDTO> findSchedulesByDates(LocalDateTime startDate, LocalDateTime endDate) {
//TODO: implement
return null;
List<Schedule> scheduleList = scheduleRepository.
findAllByStartDateTimeIsGreaterThanEqualAndEndDateTimeIsLessThanEqual(startDate, endDate);
return scheduleMapper.map(scheduleList);
}

public ScheduleDTO findSchedule(Long scheduleId) {
//TODO: implement
return null;
public Optional<ScheduleDTO> findSchedule(Long scheduleId) {
Optional<Schedule> schedule = scheduleRepository.findById(scheduleId);
return schedule.map(scheduleMapper::map);
}

public List<ScheduleDTO> findSchedulesByTennisCourtId(Long tennisCourtId) {
Expand Down
Loading