mirror of
https://gitlab.com/etc404/software-engineering-project.git
synced 2026-05-10 20:52:58 +00:00
Edit RecipeServiceImpl.java
This commit is contained in:
@@ -1,265 +1,320 @@
|
|||||||
package com.example.demo.service.Impl;
|
package com.example.demo.service.Impl;
|
||||||
|
|
||||||
import com.example.demo.dto.RecipeDto;
|
import java.util.ArrayList;
|
||||||
import com.example.demo.dto.RecipeIngredientDto;
|
import java.util.List;
|
||||||
import com.example.demo.dto.StepDto;
|
|
||||||
import com.example.demo.dto.UserDto;
|
|
||||||
import com.example.demo.entity.*;
|
|
||||||
import com.example.demo.exception.NotFoundException;
|
|
||||||
import com.example.demo.repository.*;
|
|
||||||
import com.example.demo.service.RecipeService;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import com.example.demo.dto.RecipeDto;
|
||||||
import java.time.LocalDateTime;
|
import com.example.demo.dto.UserDto;
|
||||||
import java.util.*;
|
import com.example.demo.dto.StepDto;
|
||||||
import java.util.stream.Collectors;
|
import com.example.demo.dto.TagDto;
|
||||||
|
import com.example.demo.dto.ImageDto;
|
||||||
|
import com.example.demo.dto.RecipeIngredientDto;
|
||||||
|
import com.example.demo.entity.Image;
|
||||||
|
import com.example.demo.entity.Ingredient;
|
||||||
|
import com.example.demo.entity.Recipe;
|
||||||
|
import com.example.demo.entity.RecipeIngredient;
|
||||||
|
import com.example.demo.entity.Step;
|
||||||
|
import com.example.demo.entity.Tag;
|
||||||
|
import com.example.demo.entity.User;
|
||||||
|
import com.example.demo.exception.NotFoundException;
|
||||||
|
import com.example.demo.repository.ImageRepo;
|
||||||
|
import com.example.demo.repository.IngredientRepo;
|
||||||
|
import com.example.demo.repository.RecipeIngredientRepo;
|
||||||
|
import com.example.demo.repository.RecipeRepo;
|
||||||
|
import com.example.demo.repository.StepRepo;
|
||||||
|
import com.example.demo.repository.TagRepo;
|
||||||
|
import com.example.demo.repository.UserRepo;
|
||||||
|
import com.example.demo.service.RecipeService;
|
||||||
|
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class RecipeServiceImpl implements RecipeService {
|
public class RecipeServiceImpl implements RecipeService {
|
||||||
|
|
||||||
private final RecipeRepo recipeRepo;
|
private RecipeRepo recipeRepository;
|
||||||
private final UserRepo userRepo;
|
private IngredientRepo ingredientRepository;
|
||||||
private final IngredientRepo ingredientRepo;
|
private RecipeIngredientRepo recipeIngredientRepository;
|
||||||
private final StepRepo stepRepo;
|
private UserRepo userRepository;
|
||||||
private final RecipeIngredientRepo recipeIngredientRepo;
|
private StepRepo stepRepository;
|
||||||
|
private ImageRepo imageRepository;
|
||||||
|
private TagRepo tagRepository;
|
||||||
|
|
||||||
// DEV DEFAULT — must exist in DB
|
public RecipeServiceImpl(RecipeRepo recipeRepository, IngredientRepo ingredientRepository,
|
||||||
private static final int DEFAULT_USER_ID = 1;
|
RecipeIngredientRepo recipeIngredientRepository, UserRepo userRepository, StepRepo stepRepository,
|
||||||
|
ImageRepo imageRepository, TagRepo tagRepository) {
|
||||||
public RecipeServiceImpl(
|
super();
|
||||||
RecipeRepo recipeRepo,
|
this.recipeRepository = recipeRepository;
|
||||||
UserRepo userRepo,
|
this.ingredientRepository = ingredientRepository;
|
||||||
IngredientRepo ingredientRepo,
|
this.recipeIngredientRepository = recipeIngredientRepository;
|
||||||
StepRepo stepRepo,
|
this.userRepository = userRepository;
|
||||||
RecipeIngredientRepo recipeIngredientRepo
|
this.stepRepository = stepRepository;
|
||||||
) {
|
this.imageRepository = imageRepository;
|
||||||
this.recipeRepo = recipeRepo;
|
this.tagRepository = tagRepository;
|
||||||
this.userRepo = userRepo;
|
|
||||||
this.ingredientRepo = ingredientRepo;
|
|
||||||
this.stepRepo = stepRepo;
|
|
||||||
this.recipeIngredientRepo = recipeIngredientRepo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------- convertToDto --------------------
|
|
||||||
// Called by controller when it receives Recipe (entity) in request body.
|
|
||||||
// MUST be null-safe and MUST never return null lists.
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeDto convertToDto(Recipe recipe) {
|
public RecipeDto convertToDto(Recipe recipe) {
|
||||||
RecipeDto dto = new RecipeDto();
|
List<RecipeIngredientDto> ingredientDtos = recipe.getRecipeIngredients().stream()
|
||||||
|
.map(ri -> new RecipeIngredientDto(ri.getIngredient().getName(), ri.getQuantity(), ri.getUnit(),
|
||||||
|
ri.getNotes()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
dto.setTitle(recipe.getTitle());
|
List<StepDto> stepDtos = recipe.getSteps().stream()
|
||||||
dto.setDescription(recipe.getDescription());
|
.map(ri -> new StepDto(ri.getStepNumber(), ri.getInstruction())).toList();
|
||||||
dto.setPrepTimeMinutes(recipe.getPrepTimeMinutes());
|
|
||||||
dto.setCookTimeMinutes(recipe.getCookTimeMinutes());
|
|
||||||
dto.setServings(recipe.getServings());
|
|
||||||
dto.setStatus(recipe.getStatus());
|
|
||||||
dto.setId(recipe.getId());
|
|
||||||
|
|
||||||
// IMPORTANT: prevent null lists (this was your NPE earlier)
|
List<ImageDto> imageDtos = recipe.getImages().stream().map(ri -> new ImageDto(ri.getImageUrl())).toList();
|
||||||
dto.setIngredients(new java.util.ArrayList<>());
|
|
||||||
dto.setSteps(new java.util.ArrayList<>());
|
|
||||||
dto.setImages(new java.util.ArrayList<>());
|
|
||||||
dto.setTags(new java.util.ArrayList<>());
|
|
||||||
|
|
||||||
// userDto optional
|
List<TagDto> tagDtos = recipe.getTags().stream().map(ri -> new TagDto(ri.getName())).toList();
|
||||||
if (recipe.getUser() != null) {
|
|
||||||
com.example.demo.dto.UserDto ud = new com.example.demo.dto.UserDto();
|
UserDto userDto = new UserDto(recipe.getUser().getId(), recipe.getUser().getUsername(),
|
||||||
ud.setId(recipe.getUser().getId());
|
recipe.getUser().getEmail());
|
||||||
ud.setUsername(recipe.getUser().getUsername());
|
|
||||||
ud.setEmail(recipe.getUser().getEmail());
|
return new RecipeDto(recipe.getTitle(), recipe.getDescription(), recipe.getPrepTimeMinutes(),
|
||||||
dto.setUserDto(ud);
|
recipe.getCookTimeMinutes(), recipe.getServings(), userDto, recipe.getStatus(), ingredientDtos,
|
||||||
|
stepDtos, imageDtos, tagDtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------- CREATE --------------------
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
public RecipeDto saveRecipe(RecipeDto dto) {
|
||||||
public RecipeDto saveRecipe(RecipeDto recipeDto) {
|
|
||||||
|
|
||||||
List<RecipeIngredientDto> ingredientDtos =
|
User user = userRepository.findById(dto.getUserDto().getId())
|
||||||
recipeDto.getIngredients() == null ? Collections.emptyList() : recipeDto.getIngredients();
|
.orElseThrow(() -> new NotFoundException("User", "id", dto.getUserDto().getId()));
|
||||||
|
|
||||||
List<StepDto> stepDtos =
|
Recipe recipe = new Recipe(dto.getTitle(), dto.getDescription(), dto.getPrepTimeMinutes(),
|
||||||
recipeDto.getSteps() == null ? Collections.emptyList() : recipeDto.getSteps();
|
dto.getCookTimeMinutes(), dto.getServings(), user, dto.getStatus());
|
||||||
|
|
||||||
Recipe recipe = new Recipe();
|
for (RecipeIngredientDto riDto : dto.getIngredients()) {
|
||||||
recipe.setTitle(recipeDto.getTitle());
|
|
||||||
recipe.setDescription(recipeDto.getDescription());
|
|
||||||
recipe.setPrepTimeMinutes(recipeDto.getPrepTimeMinutes());
|
|
||||||
recipe.setCookTimeMinutes(recipeDto.getCookTimeMinutes());
|
|
||||||
recipe.setServings(recipeDto.getServings());
|
|
||||||
recipe.setStatus(recipeDto.getStatus());
|
|
||||||
recipe.setCreatedAt(LocalDateTime.now());
|
|
||||||
recipe.setUpdatedAt(LocalDateTime.now());
|
|
||||||
|
|
||||||
// REQUIRED user_id
|
Ingredient ingredient = ingredientRepository.findByNameIgnoreCase(riDto.getIngredientName())
|
||||||
recipe.setUser(resolveUser(recipeDto.getUserDto(), null));
|
.orElseGet(() -> new Ingredient(riDto.getIngredientName()));
|
||||||
|
|
||||||
// attach children (cascade = ALL on Recipe will persist them)
|
if (ingredient.getId() == null) {
|
||||||
attachSteps(recipe, stepDtos);
|
ingredientRepository.save(ingredient);
|
||||||
attachRecipeIngredients(recipe, ingredientDtos);
|
|
||||||
|
|
||||||
Recipe saved = recipeRepo.save(recipe);
|
|
||||||
return getRecipeById(saved.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------- READ ALL --------------------
|
RecipeIngredient ri = new RecipeIngredient(recipe, ingredient, riDto.getQuantity(), riDto.getUnit(),
|
||||||
@Override
|
riDto.getNotes());
|
||||||
public List<RecipeDto> getAllRecipes() {
|
|
||||||
// Return shallow for list to avoid lazy-loading issues
|
|
||||||
return recipeRepo.findAll().stream()
|
|
||||||
.map(r -> {
|
|
||||||
RecipeDto dto = new RecipeDto();
|
|
||||||
dto.setTitle(r.getTitle());
|
|
||||||
dto.setDescription(r.getDescription());
|
|
||||||
dto.setPrepTimeMinutes(r.getPrepTimeMinutes());
|
|
||||||
dto.setCookTimeMinutes(r.getCookTimeMinutes());
|
|
||||||
dto.setServings(r.getServings());
|
|
||||||
dto.setStatus(r.getStatus());
|
|
||||||
dto.setIngredients(new ArrayList<>());
|
|
||||||
dto.setSteps(new ArrayList<>());
|
|
||||||
dto.setImages(new ArrayList<>());
|
|
||||||
dto.setTags(new ArrayList<>());
|
|
||||||
dto.setId(r.getId());
|
|
||||||
return dto;
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------- READ ONE --------------------
|
|
||||||
@Override
|
|
||||||
@org.springframework.transaction.annotation.Transactional(readOnly = true)
|
|
||||||
public RecipeDto getRecipeById(Integer recipeId) {
|
|
||||||
Recipe recipe = recipeRepo.findById(recipeId)
|
|
||||||
.orElseThrow(() -> new NotFoundException("Recipe", "id", recipeId));
|
|
||||||
|
|
||||||
// Start with base fields
|
|
||||||
RecipeDto dto = convertToDto(recipe);
|
|
||||||
|
|
||||||
// Overwrite lists using repo results (no mutation of Recipe.steps / recipeIngredients)
|
|
||||||
dto.setSteps(
|
|
||||||
stepRepo.findById(recipeId).stream()
|
|
||||||
.map(s -> new com.example.demo.dto.StepDto(s.getStepNumber(), s.getInstruction()))
|
|
||||||
.collect(java.util.stream.Collectors.toList())
|
|
||||||
);
|
|
||||||
|
|
||||||
dto.setIngredients(
|
|
||||||
recipeIngredientRepo.findByRecipeId(recipeId).stream()
|
|
||||||
.map(ri -> new com.example.demo.dto.RecipeIngredientDto(
|
|
||||||
ri.getIngredient() != null ? ri.getIngredient().getName() : null,
|
|
||||||
ri.getQuantity(),
|
|
||||||
ri.getUnit(),
|
|
||||||
ri.getNotes()
|
|
||||||
))
|
|
||||||
.collect(java.util.stream.Collectors.toList())
|
|
||||||
);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
// -------------------- UPDATE --------------------
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public RecipeDto updateRecipe(RecipeDto recipeDto, Integer id) {
|
|
||||||
|
|
||||||
Recipe recipe = recipeRepo.findById(id)
|
|
||||||
.orElseThrow(() -> new NotFoundException("Recipe", "id", recipeDto));
|
|
||||||
|
|
||||||
List<RecipeIngredientDto> ingredientDtos =
|
|
||||||
recipeDto.getIngredients() == null ? Collections.emptyList() : recipeDto.getIngredients();
|
|
||||||
|
|
||||||
List<StepDto> stepDtos =
|
|
||||||
recipeDto.getSteps() == null ? Collections.emptyList() : recipeDto.getSteps();
|
|
||||||
|
|
||||||
recipe.setTitle(recipeDto.getTitle());
|
|
||||||
recipe.setDescription(recipeDto.getDescription());
|
|
||||||
recipe.setPrepTimeMinutes(recipeDto.getPrepTimeMinutes());
|
|
||||||
recipe.setCookTimeMinutes(recipeDto.getCookTimeMinutes());
|
|
||||||
recipe.setServings(recipeDto.getServings());
|
|
||||||
recipe.setStatus(recipeDto.getStatus());
|
|
||||||
recipe.setUpdatedAt(LocalDateTime.now());
|
|
||||||
|
|
||||||
// keep old user if not provided
|
|
||||||
recipe.setUser(resolveUser(recipeDto.getUserDto(), recipe.getUser()));
|
|
||||||
|
|
||||||
// Clear old children (orphanRemoval = true will delete)
|
|
||||||
recipe.getSteps().clear();
|
|
||||||
recipe.getRecipeIngredients().clear();
|
|
||||||
|
|
||||||
attachSteps(recipe, stepDtos);
|
|
||||||
attachRecipeIngredients(recipe, ingredientDtos);
|
|
||||||
|
|
||||||
Recipe saved = recipeRepo.save(recipe);
|
|
||||||
return getRecipeById(saved.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------- DELETE --------------------
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void deleteRecipe(Integer id) {
|
|
||||||
if (!recipeRepo.existsById(id)) {
|
|
||||||
throw new NotFoundException("Recipe not found", null, id);
|
|
||||||
}
|
|
||||||
recipeRepo.deleteById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------- Helpers --------------------
|
|
||||||
|
|
||||||
private User resolveUser(UserDto incoming, User existing) {
|
|
||||||
if (incoming != null && incoming.getId() != null) {
|
|
||||||
return userRepo.findById(incoming.getId())
|
|
||||||
.orElseThrow(() -> new NotFoundException("User not found: " + incoming.getId(), null, existing));
|
|
||||||
}
|
|
||||||
if (existing != null) return existing;
|
|
||||||
|
|
||||||
return userRepo.findById(DEFAULT_USER_ID)
|
|
||||||
.orElseThrow(() -> new IllegalStateException(
|
|
||||||
"DEFAULT_USER_ID=" + DEFAULT_USER_ID + " not found. Insert a user row or change DEFAULT_USER_ID."
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void attachSteps(Recipe recipe, List<StepDto> stepDtos) {
|
|
||||||
for (StepDto sd : stepDtos) {
|
|
||||||
if (sd == null) continue;
|
|
||||||
if (sd.getInstruction() == null || sd.getInstruction().isBlank()) continue;
|
|
||||||
|
|
||||||
Step s = new Step();
|
|
||||||
s.setRecipe(recipe);
|
|
||||||
s.setStepNumber(sd.getStepNumber() == null ? 1 : sd.getStepNumber());
|
|
||||||
s.setInstruction(sd.getInstruction());
|
|
||||||
|
|
||||||
recipe.getSteps().add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void attachRecipeIngredients(Recipe recipe, List<RecipeIngredientDto> ingredientDtos) {
|
|
||||||
for (RecipeIngredientDto rid : ingredientDtos) {
|
|
||||||
if (rid == null) continue;
|
|
||||||
if (rid.getIngredientName() == null || rid.getIngredientName().isBlank()) continue;
|
|
||||||
|
|
||||||
Ingredient ing = ingredientRepo.findByNameIgnoreCase(rid.getIngredientName().trim())
|
|
||||||
.orElseGet(() -> {
|
|
||||||
Ingredient i = new Ingredient();
|
|
||||||
i.setName(rid.getIngredientName().trim());
|
|
||||||
return ingredientRepo.save(i);
|
|
||||||
});
|
|
||||||
|
|
||||||
RecipeIngredient ri = new RecipeIngredient();
|
|
||||||
ri.setRecipe(recipe);
|
|
||||||
ri.setIngredient(ing);
|
|
||||||
ri.setQuantity(rid.getQuantity() == null ? BigDecimal.ZERO : rid.getQuantity());
|
|
||||||
ri.setUnit(rid.getUnit());
|
|
||||||
ri.setNotes(rid.getNotes());
|
|
||||||
|
|
||||||
recipe.getRecipeIngredients().add(ri);
|
recipe.getRecipeIngredients().add(ri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dto.getSteps() != null) {
|
||||||
|
for (StepDto stepDto : dto.getSteps()) {
|
||||||
|
Step step = new Step(recipe, stepDto.getStepNumber(), stepDto.getInstruction());
|
||||||
|
recipe.getSteps().add(step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dto.getImages() != null) {
|
||||||
|
for (ImageDto imageDto : dto.getImages()) {
|
||||||
|
Image image = new Image(recipe, imageDto.getImageUrl());
|
||||||
|
recipe.getImages().add(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TagDto tDto : dto.getTags()) {
|
||||||
|
|
||||||
|
Tag tag = tagRepository.findByName(tDto.getName()).orElseGet(() -> new Tag(tDto.getName()));
|
||||||
|
|
||||||
|
if (tag.getId() == null) {
|
||||||
|
tagRepository.save(tag);
|
||||||
|
}
|
||||||
|
recipe.getTags().add(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
Recipe saved = recipeRepository.save(recipe);
|
||||||
|
|
||||||
|
return getRecipeById(saved.getId());
|
||||||
|
//return convertToDto(saved);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<RecipeDto> getAllRecipes() {
|
||||||
|
|
||||||
|
List<RecipeDto> list = new ArrayList<>();
|
||||||
|
for (Recipe recipe : recipeRepository.findAll()) {
|
||||||
|
RecipeDto recipeDto = convertToDto(recipe);
|
||||||
|
list.add(recipeDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public RecipeDto getRecipeById(Integer Id) {
|
||||||
|
return convertToDto(recipeRepository.findById(Id).orElseThrow(() -> new NotFoundException("Recipe", "id", Id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public RecipeDto updateRecipe(RecipeDto recipeDto, Integer id) {
|
||||||
|
Recipe existingRecipe = recipeRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new NotFoundException("Recipe", "id", id));
|
||||||
|
|
||||||
|
existingRecipe.setTitle(recipeDto.getTitle());
|
||||||
|
existingRecipe.setDescription(recipeDto.getDescription());
|
||||||
|
existingRecipe.setPrepTimeMinutes(recipeDto.getPrepTimeMinutes());
|
||||||
|
existingRecipe.setCookTimeMinutes(recipeDto.getCookTimeMinutes());
|
||||||
|
existingRecipe.setServings(recipeDto.getServings());
|
||||||
|
existingRecipe.setStatus(recipeDto.getStatus());
|
||||||
|
|
||||||
|
List<RecipeIngredientDto> updatedIngredients = recipeDto.getIngredients();
|
||||||
|
List<RecipeIngredient> ingredientsToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
List<StepDto> updatedSteps = recipeDto.getSteps();
|
||||||
|
List<Step> stepsToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
List<ImageDto> updatedImages = recipeDto.getImages();
|
||||||
|
List<Image> imagesToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
List<TagDto> updatedTags = recipeDto.getTags();
|
||||||
|
List<Tag> tagsToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
for (RecipeIngredient ri : existingRecipe.getRecipeIngredients()) {
|
||||||
|
|
||||||
|
boolean existsInUpdatedList = false;
|
||||||
|
for (RecipeIngredientDto dto : updatedIngredients) {
|
||||||
|
String updatedName = dto.getIngredientName();
|
||||||
|
String existingName = ri.getIngredient().getName();
|
||||||
|
|
||||||
|
if (updatedName.equals(existingName)) {
|
||||||
|
existsInUpdatedList = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existsInUpdatedList) {
|
||||||
|
ingredientsToRemove.add(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRecipe.getRecipeIngredients().removeAll(ingredientsToRemove);
|
||||||
|
|
||||||
|
for (RecipeIngredientDto riDto : updatedIngredients) {
|
||||||
|
|
||||||
|
// go through the old list of ingredients until we find a match with updated
|
||||||
|
// list
|
||||||
|
RecipeIngredient existingRI = existingRecipe.getRecipeIngredients().stream()
|
||||||
|
.filter(ri -> ri.getIngredient().getName().equals(riDto.getIngredientName())).findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
// if old ingredient just update parameters
|
||||||
|
if (existingRI != null) {
|
||||||
|
|
||||||
|
existingRI.setQuantity(riDto.getQuantity());
|
||||||
|
existingRI.setUnit(riDto.getUnit());
|
||||||
|
existingRI.setNotes(riDto.getNotes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// if new ingredient, have to make a whole new thing
|
||||||
|
else {
|
||||||
|
|
||||||
|
Ingredient ingredient = ingredientRepository.findByNameIgnoreCase(riDto.getIngredientName())
|
||||||
|
.orElseGet(() -> new Ingredient(riDto.getIngredientName()));
|
||||||
|
|
||||||
|
if (ingredient.getId() == null) {
|
||||||
|
ingredientRepository.save(ingredient);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecipeIngredient newRI = new RecipeIngredient(existingRecipe, ingredient, riDto.getQuantity(),
|
||||||
|
riDto.getUnit(), riDto.getNotes());
|
||||||
|
|
||||||
|
existingRecipe.getRecipeIngredients().add(newRI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedSteps != null) {
|
||||||
|
// find steps that weren't included
|
||||||
|
for (Step step : existingRecipe.getSteps()) {
|
||||||
|
boolean existsInUpdatedList = updatedSteps.stream()
|
||||||
|
.anyMatch(dto -> dto.getStepNumber().equals(step.getStepNumber()));
|
||||||
|
|
||||||
|
if (!existsInUpdatedList)
|
||||||
|
stepsToRemove.add(step);
|
||||||
|
}
|
||||||
|
// delete those steps
|
||||||
|
existingRecipe.getSteps().removeAll(stepsToRemove);
|
||||||
|
|
||||||
|
// go through updated steps
|
||||||
|
for (StepDto stepDto : updatedSteps) {
|
||||||
|
|
||||||
|
// find matching step by step number
|
||||||
|
Step existingStep = existingRecipe.getSteps().stream()
|
||||||
|
.filter(s -> s.getStepNumber().equals(stepDto.getStepNumber())).findFirst().orElse(null);
|
||||||
|
|
||||||
|
// if there's a match update the instruction string
|
||||||
|
if (existingStep != null) {
|
||||||
|
existingStep.setInstruction(stepDto.getInstruction());
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no match then make a whole new step
|
||||||
|
else {
|
||||||
|
Step newStep = new Step(existingRecipe, stepDto.getStepNumber(), stepDto.getInstruction());
|
||||||
|
existingRecipe.getSteps().add(newStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// same process as above just with images instead
|
||||||
|
if (updatedImages != null) {
|
||||||
|
for (Image image : existingRecipe.getImages()) {
|
||||||
|
boolean existsInUpdatedList = updatedImages.stream()
|
||||||
|
.anyMatch(dto -> dto.getImageUrl().equals(image.getImageUrl()));
|
||||||
|
if (!existsInUpdatedList)
|
||||||
|
imagesToRemove.add(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRecipe.getImages().removeAll(imagesToRemove);
|
||||||
|
|
||||||
|
for (ImageDto imageDto : updatedImages) {
|
||||||
|
Image existingImage = existingRecipe.getImages().stream()
|
||||||
|
.filter(img -> img.getImageUrl().equals(imageDto.getImageUrl())).findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (existingImage != null) {
|
||||||
|
existingImage.setImageUrl(imageDto.getImageUrl());
|
||||||
|
} else {
|
||||||
|
Image newImage = new Image(existingRecipe, imageDto.getImageUrl());
|
||||||
|
existingRecipe.getImages().add(newImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// same process as above just with tags instead, except for saving the tag
|
||||||
|
// since the relationship for this one was slightly different
|
||||||
|
if (updatedTags != null) {
|
||||||
|
for (Tag tag : existingRecipe.getTags()) {
|
||||||
|
boolean existsInUpdatedList = updatedTags.stream().anyMatch(dto -> dto.getName().equals(tag.getName()));
|
||||||
|
if (!existsInUpdatedList)
|
||||||
|
tagsToRemove.add(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRecipe.getTags().removeAll(tagsToRemove);
|
||||||
|
|
||||||
|
for (TagDto tagDto : updatedTags) {
|
||||||
|
Tag existingTag = existingRecipe.getTags().stream()
|
||||||
|
.filter(tag -> tag.getName().equals(tagDto.getName())).findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (existingTag != null) {
|
||||||
|
existingTag.setName(tagDto.getName());
|
||||||
|
} else {
|
||||||
|
Tag newTag = tagRepository.findByName(tagDto.getName())
|
||||||
|
.orElseGet(() -> tagRepository.save(new Tag(tagDto.getName())));
|
||||||
|
|
||||||
|
existingRecipe.getTags().add(newTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recipeRepository.save(existingRecipe);
|
||||||
|
return convertToDto(existingRecipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRecipe(Integer Id) {
|
||||||
|
recipeRepository.findById(Id).orElseThrow(() -> new NotFoundException("Recipe", "id", Id));
|
||||||
|
recipeRepository.deleteById(Id);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user