diff --git a/pom.xml b/pom.xml index 7d87086..c7fdeab 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,11 @@ stripe-java 23.7.0 + + jakarta.validation + jakarta.validation-api + 3.0.2 + diff --git a/src/main/java/com/project/carsharingapp/controller/AuthenticationController.java b/src/main/java/com/project/carsharingapp/controller/AuthenticationController.java new file mode 100644 index 0000000..14a8e49 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/controller/AuthenticationController.java @@ -0,0 +1,34 @@ +package com.project.carsharingapp.controller; + +import com.project.carsharingapp.dto.user.UserLoginRequestDto; +import com.project.carsharingapp.dto.user.UserLoginResponseDto; +import com.project.carsharingapp.dto.user.UserRegistrationRequestDto; +import com.project.carsharingapp.dto.user.UserResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/auth") +@Tag(name = "Authentication", description = "Endpoints for managing login and register user") +public class AuthenticationController { + + @PostMapping("/login") + @Operation(summary = "Login user") + public UserLoginResponseDto login(@RequestBody @Valid UserLoginRequestDto requestDto) { + return null; + } + + @PostMapping("/register") + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Register user") + public UserResponseDto register(@RequestBody @Valid UserRegistrationRequestDto requestDto) { + return null; + } +} diff --git a/src/main/java/com/project/carsharingapp/controller/CarController.java b/src/main/java/com/project/carsharingapp/controller/CarController.java index e2c6c17..6ddebb9 100644 --- a/src/main/java/com/project/carsharingapp/controller/CarController.java +++ b/src/main/java/com/project/carsharingapp/controller/CarController.java @@ -3,10 +3,12 @@ import com.project.carsharingapp.dto.car.CarDto; import com.project.carsharingapp.dto.car.CreateCarRequestDto; import com.project.carsharingapp.dto.car.UpdateCarRequestDto; +import com.project.carsharingapp.service.CarService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import java.util.List; +import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.DeleteMapping; @@ -22,14 +24,17 @@ @Tag(name = "Car management", description = "Endpoints for managing cars") @RestController +@RequiredArgsConstructor @RequestMapping(value = "/cars") public class CarController { + private final CarService carService; + @PostMapping @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "Save new car", description = "Save new car") public CarDto add(@RequestBody @Valid CreateCarRequestDto requestDto) { - return null; + return carService.save(requestDto); } @GetMapping @@ -37,7 +42,7 @@ public CarDto add(@RequestBody @Valid CreateCarRequestDto requestDto) { @Operation(summary = "Get all cars", description = "Get list of all cars") public List getAll(Pageable pageable) { - return null; + return carService.getAll(pageable); } @GetMapping("/{id}") @@ -45,7 +50,7 @@ public List getAll(Pageable pageable) { @Operation(summary = "Get the car by id", description = "Get car's detailed information by identification number") public CarDto getById(@PathVariable Long id) { - return null; + return carService.get(id); } @PutMapping("/{id}") @@ -54,7 +59,7 @@ public CarDto getById(@PathVariable Long id) { description = "Update the car information by identification number") public CarDto update(@PathVariable Long id, @Valid @RequestBody UpdateCarRequestDto requestDto) { - return null; + return carService.update(id, requestDto); } @DeleteMapping("/{id}") @@ -62,6 +67,6 @@ public CarDto update(@PathVariable Long id, @Operation(summary = "Delete the car by id", description = "Delete the car by identification number") public void deleteById(@PathVariable Long id) { - + carService.delete(id); } } diff --git a/src/main/java/com/project/carsharingapp/controller/RentalController.java b/src/main/java/com/project/carsharingapp/controller/RentalController.java new file mode 100644 index 0000000..81e28ca --- /dev/null +++ b/src/main/java/com/project/carsharingapp/controller/RentalController.java @@ -0,0 +1,57 @@ +package com.project.carsharingapp.controller; + +import com.project.carsharingapp.dto.rental.CreateRentalRequestDto; +import com.project.carsharingapp.dto.rental.RentalDto; +import com.project.carsharingapp.dto.rental.SetActualReturnDateRequestDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "Rental management", + description = "Endpoints for managing rentals") +@RestController +@RequestMapping(value = "/rentals") +public class RentalController { + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Save new rental", + description = "Save new rental and decrease car inventory by 1") + public RentalDto add(@RequestBody @Valid CreateRentalRequestDto requestDto) { + return null; + } + + @GetMapping("/{userId}/{isActive}") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "Get the rentals by user id and active status", + description = "Retrieve rentals by user identification number" + + " and whether the rental is still active or not") + public RentalDto getByUserIdAndActiveStatus(@PathVariable Long userId, + @PathVariable boolean isActive) { + return null; + } + + @GetMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "Get the rental by id", + description = "Get specific rental by identification number") + public RentalDto getById(@PathVariable Long id) { + return null; + } + + @PostMapping("/{returnDate}") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "Set actual return date", + description = "Set actual return date and increase car inventory by 1") + public RentalDto setActualReturnDay(@RequestBody + @Valid SetActualReturnDateRequestDto returnDate) { + return null; + } +} diff --git a/src/main/java/com/project/carsharingapp/dto/car/CreateCarRequestDto.java b/src/main/java/com/project/carsharingapp/dto/car/CreateCarRequestDto.java index 7aa03a2..131a098 100644 --- a/src/main/java/com/project/carsharingapp/dto/car/CreateCarRequestDto.java +++ b/src/main/java/com/project/carsharingapp/dto/car/CreateCarRequestDto.java @@ -2,7 +2,6 @@ import com.project.carsharingapp.model.Car; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; import lombok.Getter; @@ -18,14 +17,12 @@ public class CreateCarRequestDto { @NotNull @Length(min = 1, max = 255) private String brand; - @NotBlank @NotNull @Min(0) private Integer inventory; - @NotBlank @NotNull private Car.CarType carType; - @NotBlank + @NotNull @Min(0) private BigDecimal dailyFee; } diff --git a/src/main/java/com/project/carsharingapp/dto/car/UpdateCarRequestDto.java b/src/main/java/com/project/carsharingapp/dto/car/UpdateCarRequestDto.java index ab91820..eeff190 100644 --- a/src/main/java/com/project/carsharingapp/dto/car/UpdateCarRequestDto.java +++ b/src/main/java/com/project/carsharingapp/dto/car/UpdateCarRequestDto.java @@ -2,7 +2,6 @@ import com.project.carsharingapp.model.Car; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; import lombok.Getter; @@ -18,14 +17,11 @@ public class UpdateCarRequestDto { @NotNull @Length(min = 1, max = 255) private String brand; - @NotBlank @NotNull @Min(0) private Integer inventory; - @NotBlank @NotNull private Car.CarType carType; - @NotBlank @Min(0) private BigDecimal dailyFee; } diff --git a/src/main/java/com/project/carsharingapp/dto/rental/CreateRentalRequestDto.java b/src/main/java/com/project/carsharingapp/dto/rental/CreateRentalRequestDto.java new file mode 100644 index 0000000..7a8af1a --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/rental/CreateRentalRequestDto.java @@ -0,0 +1,21 @@ +package com.project.carsharingapp.dto.rental; + +import jakarta.validation.constraints.NotNull; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CreateRentalRequestDto { + @NotNull + private LocalDateTime rentalDate; + @NotNull + private LocalDateTime returnDate; + @NotNull + private LocalDateTime actualReturnDate; + @NotNull + private Long carId; + @NotNull + private Long userId; +} diff --git a/src/main/java/com/project/carsharingapp/dto/rental/RentalDto.java b/src/main/java/com/project/carsharingapp/dto/rental/RentalDto.java new file mode 100644 index 0000000..51171ee --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/rental/RentalDto.java @@ -0,0 +1,16 @@ +package com.project.carsharingapp.dto.rental; + +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RentalDto { + private Long id; + private LocalDateTime rentalDate; + private LocalDateTime returnDate; + private LocalDateTime actualReturnDate; + private Long carId; + private Long userId; +} diff --git a/src/main/java/com/project/carsharingapp/dto/rental/SetActualReturnDateRequestDto.java b/src/main/java/com/project/carsharingapp/dto/rental/SetActualReturnDateRequestDto.java new file mode 100644 index 0000000..6abc61f --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/rental/SetActualReturnDateRequestDto.java @@ -0,0 +1,15 @@ +package com.project.carsharingapp.dto.rental; + +import jakarta.validation.constraints.NotNull; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; +import org.springframework.format.annotation.DateTimeFormat; + +@Getter +@Setter +public class SetActualReturnDateRequestDto { + @NotNull + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime actualReturnDate; +} diff --git a/src/main/java/com/project/carsharingapp/dto/user/UserLoginRequestDto.java b/src/main/java/com/project/carsharingapp/dto/user/UserLoginRequestDto.java new file mode 100644 index 0000000..1167a43 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/user/UserLoginRequestDto.java @@ -0,0 +1,12 @@ +package com.project.carsharingapp.dto.user; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; + +public class UserLoginRequestDto { + @NotEmpty + @Size(min = 8, max = 20) + private String email; + + private String password; +} diff --git a/src/main/java/com/project/carsharingapp/dto/user/UserLoginResponseDto.java b/src/main/java/com/project/carsharingapp/dto/user/UserLoginResponseDto.java new file mode 100644 index 0000000..4432603 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/user/UserLoginResponseDto.java @@ -0,0 +1,4 @@ +package com.project.carsharingapp.dto.user; + +public class UserLoginResponseDto { +} diff --git a/src/main/java/com/project/carsharingapp/dto/user/UserRegistrationRequestDto.java b/src/main/java/com/project/carsharingapp/dto/user/UserRegistrationRequestDto.java new file mode 100644 index 0000000..5813ff7 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/user/UserRegistrationRequestDto.java @@ -0,0 +1,17 @@ +package com.project.carsharingapp.dto.user; + +import jakarta.validation.constraints.NotEmpty; + +public class UserRegistrationRequestDto { + + private String email; + @NotEmpty + private String password; + private String repeatPassword; + @NotEmpty + private String firstName; + @NotEmpty + private String lastName; + @NotEmpty + private String shippingAddress; +} diff --git a/src/main/java/com/project/carsharingapp/dto/user/UserResponseDto.java b/src/main/java/com/project/carsharingapp/dto/user/UserResponseDto.java new file mode 100644 index 0000000..f5f5ac9 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/dto/user/UserResponseDto.java @@ -0,0 +1,14 @@ +package com.project.carsharingapp.dto.user; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UserResponseDto { + private Long id; + private String email; + private String firstName; + private String lastName; + private String shippingAddress; +} diff --git a/src/main/java/com/project/carsharingapp/mapper/CarMapper.java b/src/main/java/com/project/carsharingapp/mapper/CarMapper.java new file mode 100644 index 0000000..432ac05 --- /dev/null +++ b/src/main/java/com/project/carsharingapp/mapper/CarMapper.java @@ -0,0 +1,14 @@ +package com.project.carsharingapp.mapper; + +import com.project.carsharingapp.config.MapperConfig; +import com.project.carsharingapp.dto.car.CarDto; +import com.project.carsharingapp.dto.car.CreateCarRequestDto; +import com.project.carsharingapp.model.Car; +import org.mapstruct.Mapper; + +@Mapper(config = MapperConfig.class) +public interface CarMapper { + Car toEntity(CreateCarRequestDto createCarRequestDto); + + CarDto toDto(Car car); +} diff --git a/src/main/java/com/project/carsharingapp/security/AuthenticationService.java b/src/main/java/com/project/carsharingapp/security/AuthenticationService.java new file mode 100644 index 0000000..b2999ab --- /dev/null +++ b/src/main/java/com/project/carsharingapp/security/AuthenticationService.java @@ -0,0 +1,7 @@ +package com.project.carsharingapp.security; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class AuthenticationService { +} diff --git a/src/main/java/com/project/carsharingapp/service/CarService.java b/src/main/java/com/project/carsharingapp/service/CarService.java new file mode 100644 index 0000000..d14b28b --- /dev/null +++ b/src/main/java/com/project/carsharingapp/service/CarService.java @@ -0,0 +1,19 @@ +package com.project.carsharingapp.service; + +import com.project.carsharingapp.dto.car.CarDto; +import com.project.carsharingapp.dto.car.CreateCarRequestDto; +import com.project.carsharingapp.dto.car.UpdateCarRequestDto; +import java.util.List; +import org.springframework.data.domain.Pageable; + +public interface CarService { + CarDto save(CreateCarRequestDto createCarRequestDto); + + CarDto get(Long id); + + List getAll(Pageable pageable); + + CarDto update(Long id, UpdateCarRequestDto updateCarRequestDto); + + void delete(Long id); +} diff --git a/src/main/java/com/project/carsharingapp/service/CarServiceImpl.java b/src/main/java/com/project/carsharingapp/service/CarServiceImpl.java new file mode 100644 index 0000000..3fe66ab --- /dev/null +++ b/src/main/java/com/project/carsharingapp/service/CarServiceImpl.java @@ -0,0 +1,62 @@ +package com.project.carsharingapp.service; + +import com.project.carsharingapp.dto.car.CarDto; +import com.project.carsharingapp.dto.car.CreateCarRequestDto; +import com.project.carsharingapp.dto.car.UpdateCarRequestDto; +import com.project.carsharingapp.exception.EntityNotFoundException; +import com.project.carsharingapp.mapper.CarMapper; +import com.project.carsharingapp.model.Car; +import com.project.carsharingapp.repository.CarRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class CarServiceImpl implements CarService { + private final CarRepository carRepository; + private final CarMapper carMapper; + + @Override + public CarDto save(CreateCarRequestDto createCarRequestDto) { + Car car = carMapper.toEntity(createCarRequestDto); + return carMapper.toDto(carRepository.save(car)); + } + + @Override + public CarDto get(Long id) { + Car car = carRepository.findById(id).orElseThrow(() + -> new EntityNotFoundException("Car not found with id: " + id)); + return carMapper.toDto(car); + } + + @Override + public List getAll(Pageable pageable) { + return carRepository.findAll(pageable) + .getContent() + .stream() + .map(carMapper::toDto) + .toList(); + } + + @Transactional + @Override + public CarDto update(Long id, UpdateCarRequestDto updateCarRequestDto) { + Car car = carRepository.findById(id).orElseThrow(() + -> new EntityNotFoundException("Car not found")); + car.setModel(updateCarRequestDto.getModel()); + car.setBrand(updateCarRequestDto.getBrand()); + car.setInventory(updateCarRequestDto.getInventory()); + car.setCarType(updateCarRequestDto.getCarType()); + car.setDailyFee(updateCarRequestDto.getDailyFee()); + car = carRepository.save(car); + return carMapper.toDto(car); + } + + @Override + public void delete(Long id) { + carRepository.deleteById(id); + } +} diff --git a/src/main/java/com/project/carsharingapp/service/UserService.java b/src/main/java/com/project/carsharingapp/service/UserService.java new file mode 100644 index 0000000..5f1e70e --- /dev/null +++ b/src/main/java/com/project/carsharingapp/service/UserService.java @@ -0,0 +1,5 @@ +package com.project.carsharingapp.service; + +public interface UserService { + +}