mirror of
https://gitlab.com/etc404/software-engineering-project.git
synced 2026-05-10 20:52:58 +00:00
added searching for recipes and users plus some cleanup
This commit is contained in:
@@ -11,13 +11,17 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.example.demo.dto.RecipeDto;
|
import com.example.demo.dto.RecipeDto;
|
||||||
|
import com.example.demo.dto.UserDto;
|
||||||
import com.example.demo.entity.Recipe;
|
import com.example.demo.entity.Recipe;
|
||||||
import com.example.demo.entity.User;
|
import com.example.demo.entity.User;
|
||||||
import com.example.demo.service.RecipeService;
|
import com.example.demo.service.RecipeService;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/recipes")
|
@RequestMapping("/api/recipes")
|
||||||
public class RecipeController {
|
public class RecipeController {
|
||||||
@@ -31,7 +35,7 @@ public class RecipeController {
|
|||||||
|
|
||||||
// build create recipe REST API
|
// build create recipe REST API
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<RecipeDto> saveUser(@RequestBody Recipe recipe) {
|
public ResponseEntity<RecipeDto> saveRecipe(@Valid @RequestBody Recipe recipe) {
|
||||||
RecipeDto recipeDto = recipeService.convertToDto(recipe);
|
RecipeDto recipeDto = recipeService.convertToDto(recipe);
|
||||||
return new ResponseEntity<RecipeDto>(recipeService.saveRecipe(recipeDto), HttpStatus.CREATED);
|
return new ResponseEntity<RecipeDto>(recipeService.saveRecipe(recipeDto), HttpStatus.CREATED);
|
||||||
}
|
}
|
||||||
@@ -49,10 +53,23 @@ public class RecipeController {
|
|||||||
return new ResponseEntity<RecipeDto>(recipeService.getRecipeById(recipeId), HttpStatus.OK);
|
return new ResponseEntity<RecipeDto>(recipeService.getRecipeById(recipeId), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build get recipe by name REST API
|
||||||
|
@GetMapping("/search")
|
||||||
|
public ResponseEntity<List<RecipeDto>> searchRecipes(
|
||||||
|
@RequestParam(required = false) String name, // by not adding a name all recipes will appear basically
|
||||||
|
@RequestParam(required = false) List<String> tags // since users can choose no tags this isnt required
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<RecipeDto> recipes = recipeService.getRecipes(name, tags);
|
||||||
|
return new ResponseEntity<>(recipes, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
// build update recipe REST API
|
// build update recipe REST API
|
||||||
// http://localhost:8080/api/recipes/(id number goes here)
|
// http://localhost:8080/api/recipes/(id number goes here)
|
||||||
@PutMapping("{id}")
|
@PutMapping("{id}")
|
||||||
public ResponseEntity<RecipeDto> updateUser(@PathVariable("id") Integer recipeId, @RequestBody Recipe recipe) {
|
public ResponseEntity<RecipeDto> updateRecipe(@PathVariable("id") Integer recipeId, @RequestBody Recipe recipe) {
|
||||||
RecipeDto recipeDto = recipeService.convertToDto(recipe);
|
RecipeDto recipeDto = recipeService.convertToDto(recipe);
|
||||||
return new ResponseEntity<RecipeDto>(recipeService.updateRecipe(recipeDto, recipeId), HttpStatus.OK);
|
return new ResponseEntity<RecipeDto>(recipeService.updateRecipe(recipeDto, recipeId), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -60,7 +77,7 @@ public class RecipeController {
|
|||||||
// build delete recipe REST API
|
// build delete recipe REST API
|
||||||
// http://localhost:8080/api/recipes/(id number goes here)
|
// http://localhost:8080/api/recipes/(id number goes here)
|
||||||
@DeleteMapping("{id}")
|
@DeleteMapping("{id}")
|
||||||
public ResponseEntity<String> deleteUser(@PathVariable("id") Integer recipeId) {
|
public ResponseEntity<String> deleteRecipe(@PathVariable("id") Integer recipeId) {
|
||||||
recipeService.deleteRecipe(recipeId);
|
recipeService.deleteRecipe(recipeId);
|
||||||
return new ResponseEntity<String>("Recipe deleted succesfully!", HttpStatus.OK);
|
return new ResponseEntity<String>("Recipe deleted succesfully!", HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.example.demo.dto.UserDto;
|
import com.example.demo.dto.UserDto;
|
||||||
@@ -41,6 +42,14 @@ public class UserController {
|
|||||||
return userService.getAllUsers();
|
return userService.getAllUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build get user by name REST API
|
||||||
|
@GetMapping("/search")
|
||||||
|
public ResponseEntity<List<UserDto>> getUsersByName(@RequestParam String string) {
|
||||||
|
List<UserDto> users = userService.getUsersByName(string);
|
||||||
|
return new ResponseEntity<>(users, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// build get user by id REST API
|
// build get user by id REST API
|
||||||
// http://localhost:8080/api/users/(id number goes here)
|
// http://localhost:8080/api/users/(id number goes here)
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.example.demo.entity;
|
|||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Positive;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -23,8 +26,16 @@ public class Recipe {
|
|||||||
@Column(columnDefinition = "TEXT")
|
@Column(columnDefinition = "TEXT")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@NotNull(message = "Please Provide a prep time amount in mintutes")
|
||||||
|
@Positive(message = "This value cannot be negative")
|
||||||
private Integer prepTimeMinutes;
|
private Integer prepTimeMinutes;
|
||||||
|
|
||||||
|
@NotNull(message = "Please Provide a cook time amount in mintutes")
|
||||||
|
@Positive(message = "This value cannot be negative")
|
||||||
private Integer cookTimeMinutes;
|
private Integer cookTimeMinutes;
|
||||||
|
|
||||||
|
@NotNull(message = "Please Provide a serving amount")
|
||||||
|
@Positive(message = "This value cannot be negative")
|
||||||
private Integer servings;
|
private Integer servings;
|
||||||
|
|
||||||
private String status;
|
private String status;
|
||||||
@@ -32,6 +43,7 @@ public class Recipe {
|
|||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@NotNull(message = "Recipe must be associated with a user")
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "user_id", nullable = false)
|
@JoinColumn(name = "user_id", nullable = false)
|
||||||
@EqualsAndHashCode.Include
|
@EqualsAndHashCode.Include
|
||||||
@@ -39,6 +51,7 @@ public class Recipe {
|
|||||||
|
|
||||||
// Recipe ingredients relationship
|
// Recipe ingredients relationship
|
||||||
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||||
|
@NotEmpty(message = "At least one ingredient is required")
|
||||||
private Set<RecipeIngredient> recipeIngredients = new HashSet<>();
|
private Set<RecipeIngredient> recipeIngredients = new HashSet<>();
|
||||||
|
|
||||||
// Recipe Steps relationship
|
// Recipe Steps relationship
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.example.demo.entity;
|
|||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.FetchType;
|
import jakarta.persistence.FetchType;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.JoinColumn;
|
import jakarta.persistence.JoinColumn;
|
||||||
import jakarta.persistence.JoinTable;
|
import jakarta.persistence.JoinTable;
|
||||||
@@ -27,14 +29,17 @@ public class User implements UserDetails {
|
|||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@NotNull
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
@Column(nullable = false, unique = true)
|
@Column(nullable = false, unique = true)
|
||||||
|
@NotBlank(message = "Username is required")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
private String role;
|
private String role;
|
||||||
|
|
||||||
@Column(unique = true)
|
@Column(unique = true)
|
||||||
|
@NotBlank(message = "Email is required")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
private String hashedpassword;
|
private String hashedpassword;
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
package com.example.demo.repository;
|
package com.example.demo.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import com.example.demo.entity.Recipe;
|
import com.example.demo.entity.Recipe;
|
||||||
|
|
||||||
public interface RecipeRepo extends JpaRepository<Recipe, Integer> {
|
public interface RecipeRepo extends JpaRepository<Recipe, Integer> {
|
||||||
|
|
||||||
|
List<Recipe> findByTitleContainingIgnoreCase(String name);
|
||||||
|
List<Recipe> findByTitleContainingIgnoreCaseAndTags_NameIn(String title, List<String> tags);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,13 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
|
|
||||||
import com.example.demo.entity.User;
|
import com.example.demo.entity.User;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface UserRepo extends JpaRepository<User, Integer> {
|
public interface UserRepo extends JpaRepository<User, Integer> {
|
||||||
|
|
||||||
Optional<User> findByUsername(String username);
|
Optional<User> findByUsername(String username);
|
||||||
|
|
||||||
|
List<User> findByUsernameContainingIgnoreCase(String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.example.demo.service.Impl;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -318,4 +319,34 @@ public class RecipeServiceImpl implements RecipeService {
|
|||||||
recipeRepository.deleteById(Id);
|
recipeRepository.deleteById(Id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<RecipeDto> getRecipes(String name, List<String> tags) {
|
||||||
|
|
||||||
|
List<Recipe> recipes;
|
||||||
|
|
||||||
|
if(!name.isBlank()) {
|
||||||
|
recipes = recipeRepository.findByTitleContainingIgnoreCase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
recipes = recipeRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!tags.isEmpty() && !recipes.isEmpty()) {
|
||||||
|
recipes = recipes.stream()
|
||||||
|
.filter(recipe -> recipe.getTags().stream().anyMatch(tag -> tags.contains(tag.getName())))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RecipeDto> recipeList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Recipe recipe : recipes) {
|
||||||
|
RecipeDto dto = convertToDto(recipe);
|
||||||
|
recipeList.add(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipeList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -108,4 +108,21 @@ public class UserServiceImpl implements UserService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserDto> getUsersByName(String name) {
|
||||||
|
List<User> users = userRepository.findByUsernameContainingIgnoreCase(name);
|
||||||
|
|
||||||
|
if (users.isEmpty()) {
|
||||||
|
throw new NotFoundException("User", "username containing", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UserDto> userList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (User user : users) {
|
||||||
|
UserDto dto = convertToDto(user);
|
||||||
|
userList.add(dto);
|
||||||
|
}
|
||||||
|
return userList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public interface RecipeService {
|
|||||||
|
|
||||||
RecipeDto getRecipeById(Integer recipeId);
|
RecipeDto getRecipeById(Integer recipeId);
|
||||||
|
|
||||||
|
List<RecipeDto> getRecipes(String name, List<String> tags);
|
||||||
|
|
||||||
RecipeDto updateRecipe(RecipeDto recipedto, Integer Id);
|
RecipeDto updateRecipe(RecipeDto recipedto, Integer Id);
|
||||||
|
|
||||||
void deleteRecipe(Integer Id);
|
void deleteRecipe(Integer Id);
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public interface UserService {
|
|||||||
|
|
||||||
UserDto getUserById(Integer Id);
|
UserDto getUserById(Integer Id);
|
||||||
|
|
||||||
|
List<UserDto> getUsersByName(String name);
|
||||||
|
|
||||||
UserDto saveFavorite(Integer userId, Integer recipeId);
|
UserDto saveFavorite(Integer userId, Integer recipeId);
|
||||||
|
|
||||||
UserDto updateUser(User user, Integer Id);
|
UserDto updateUser(User user, Integer Id);
|
||||||
|
|||||||
Reference in New Issue
Block a user