Skip to content
Snippets Groups Projects
Commit 734030fa authored by Stian Lyng's avatar Stian Lyng
Browse files

enhanced weekly menu

parent afa187a8
No related branches found
No related tags found
No related merge requests found
......@@ -4,7 +4,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.RestController;
import lombok.AllArgsConstructor;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeFridgeMatch;
import ntnu.idatt2016.v233.SmartMat.entity.Recipe;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
......@@ -56,17 +55,6 @@ public class RecipeController {
return ResponseEntity.ok(recipes);
}
@GetMapping("/match/{fridgeId}/{recipeId}")
public ResponseEntity<List<RecipeFridgeMatch>> getRecipeWithByProductsInFridge(
@PathVariable("fridgeId") Long fridgeId, @PathVariable("recipeId") Long recipeId) {
List<RecipeFridgeMatch> recipe = recipeService.getRecipeWithFridgeProductMatch(fridgeId, recipeId);
if (recipe.isEmpty()) {
return ResponseEntity.notFound().build();
} else {
return ResponseEntity.ok(recipe);
}
}
/**
* add recipe to favorites in user
......
......@@ -9,7 +9,9 @@ import java.util.List;
import org.springframework.http.ResponseEntity;
import lombok.AllArgsConstructor;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeWithMatchCount;
import ntnu.idatt2016.v233.SmartMat.dto.response.WeeklyMenuResponse;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
@AllArgsConstructor
......@@ -17,6 +19,7 @@ import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
@RequestMapping("/api/weeklymenu")
public class WeeklyMenuController {
/*
private WeeklyMenuService weeklyMenuService;
@GetMapping("/{fridgeId}")
......@@ -29,5 +32,19 @@ public class WeeklyMenuController {
return ResponseEntity.ok(weeklyMenu);
}
}
*/
final private RecipeService recipeService;
@GetMapping("/{fridgeId}")
public ResponseEntity<Object> compareWeeklyMenuAndRecipeProducts(@PathVariable("fridgeId") Integer fridgeId) {
List<RecipeWithMatchCount> weeklyMenuDetails = recipeService.getWeeklyMenu(fridgeId);
if (weeklyMenuDetails.isEmpty()) {
return ResponseEntity.notFound().build();
} else {
return ResponseEntity.ok(weeklyMenuDetails);
}
}
}
......@@ -12,15 +12,11 @@ import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RecipeDetails {
public class RecipeFridgeMatch {
private Integer recipeId;
private String recipeName;
private String recipeDescription;
private long ean;
private String productName;
private String productDescription;
private boolean inFridge;
}
private String recipeImage;
}
\ No newline at end of file
package ntnu.idatt2016.v233.SmartMat.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* This class represents a response for a weekly menu.
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RecipeWithMatchCount {
private RecipeDetails recipeDetails;
private int matchCount;
}
\ No newline at end of file
......@@ -23,25 +23,19 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
List<Recipe> findAllByName(String name);
@Query( value = """
SELECT r.recipe_id, r.recipe_name,r.recipe_description,r.image_url, COUNT(fp.ean) as product_count
FROM recipe r
LEFT JOIN recipe_product rp ON r.recipe_id = rp.recipe_id
LEFT JOIN fridge_product fp ON rp.ean = fp.ean AND fp.fridge_id = :fridgeId
GROUP BY r.recipe_id, r.recipe_name
ORDER BY product_count DESC
LIMIT 5;
select p2.item_name, f.fridge_id
from fridge f
inner join fridge_product fp on f.fridge_id = fp.fridge_id and f.fridge_id = :fridgeId
inner join product p2 on p2.ean = fp.ean
""", nativeQuery = true)
List<Object[]> findWeeklyMenu(@Param("fridgeId") long fridgeId);
List<Object[]> findWeeklyMenu(long fridgeId);
@Query( value = """
SELECT r.recipe_id, r.recipe_name, r.recipe_description, p.ean, p.item_name, p.description as product_description,
CASE WHEN fp.fridge_id IS NOT NULL THEN TRUE ELSE FALSE END as in_fridge
FROM recipe AS r
JOIN recipe_product AS rp ON r.recipe_id = rp.recipe_id
JOIN product AS p ON rp.ean = p.ean
LEFT JOIN fridge_product AS fp ON p.ean = fp.ean AND fp.fridge_id = :fridgeId
WHERE r.recipe_id = :recipeId ;
SELECT r.recipe_id, r.recipe_name, r.recipe_description, r.image_url, p.item_name
FROM recipe r
inner JOIN recipe_product rp ON r.recipe_id = rp.recipe_id
inner join product p on rp.ean = p.ean
""" , nativeQuery = true)
List<Object[]> findRecipeWithMatchingProductsInFridge(long fridgeId, long recipeId);
List<Object[]> findRecipeProductsWithName();
}
package ntnu.idatt2016.v233.SmartMat.service;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeFridgeMatch;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeDetails;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeWithMatchCount;
import ntnu.idatt2016.v233.SmartMat.entity.Recipe;
import ntnu.idatt2016.v233.SmartMat.entity.user.User;
import ntnu.idatt2016.v233.SmartMat.repository.RecipeRepository;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -110,25 +114,6 @@ public class RecipeService {
recipeRepository.save(recipe);
}
public List<RecipeFridgeMatch> getRecipeWithFridgeProductMatch(long fridgeId, long recipeId) {
List<Object[]> rawData = recipeRepository.findRecipeWithMatchingProductsInFridge(fridgeId, recipeId);
List<RecipeFridgeMatch> result = rawData.stream()
.map(row -> new RecipeFridgeMatch(
(Integer) row[0],
(String) row[1],
(String) row[2],
(Long) row[3],
(String) row[4],
(String) row[5],
(Boolean) row[6]
))
.collect(Collectors.toList());
return result;
}
/**
* Adds a recipe to a users favorites
* @param recipeId id of the recipe
......@@ -180,4 +165,55 @@ public class RecipeService {
return ResponseEntity.ok("Recipe deleted from favorites");
}
}
public List<RecipeWithMatchCount> getWeeklyMenu(Integer fridgeId) {
// Get the results from both repository methods
List<Object[]> weeklyMenu = recipeRepository.findWeeklyMenu(fridgeId);
List<Object[]> recipeProducts = recipeRepository.findRecipeProductsWithName();
// Prepare a map to store RecipeDetails with their match count
Map<RecipeDetails, Integer> recipeMatchCountMap = new HashMap<>();
// Compare the item_name on both lists
for (Object[] menuRow : weeklyMenu) {
String menuRowItemName = (String) menuRow[0];
for (Object[] recipeProductRow : recipeProducts) {
String recipeProductRowItemName = (String) recipeProductRow[4];
List<String> recipeProductWords = Arrays.asList(recipeProductRowItemName.split("\\s+"));
boolean allWordsContained = recipeProductWords.stream()
.allMatch(word -> menuRowItemName.contains(word));
if (allWordsContained) {
Integer recipeId = ((Integer) recipeProductRow[0]).intValue();
String recipeName = (String) recipeProductRow[1];
String recipeDescription = (String) recipeProductRow[2];
String recipeImage = (String) recipeProductRow[3];
RecipeDetails recipeDetails = new RecipeDetails(recipeId, recipeName, recipeDescription, recipeImage);
recipeMatchCountMap.put(recipeDetails, recipeMatchCountMap.getOrDefault(recipeDetails, 0) + 1);
}
}
}
// Get a list of unique RecipeDetails from recipeProducts
List<RecipeDetails> uniqueRecipeDetails = recipeProducts.stream()
.map(row -> new RecipeDetails(((Integer) row[0]).intValue(), (String) row[1], (String) row[2], (String) row[3]))
.distinct()
.collect(Collectors.toList());
// Convert the map to a list of RecipeWithMatchCount
List<RecipeWithMatchCount> commonRecipes = recipeMatchCountMap.entrySet().stream()
.map(entry -> new RecipeWithMatchCount(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
// Add additional recipes from uniqueRecipeDetails with a count of 0 if the list has less than 5 recipes
for (RecipeDetails recipeDetails : uniqueRecipeDetails) {
if (commonRecipes.size() < 5 && !recipeMatchCountMap.containsKey(recipeDetails)) {
commonRecipes.add(new RecipeWithMatchCount(recipeDetails, 0));
}
}
return commonRecipes;
}
}
\ No newline at end of file
package ntnu.idatt2016.v233.SmartMat.controller;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeDetails;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeWithMatchCount;
import ntnu.idatt2016.v233.SmartMat.dto.response.WeeklyMenuResponse;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
......@@ -23,6 +26,9 @@ public class WeeklyMenuControllerTest {
@InjectMocks
private WeeklyMenuController weeklyMenuController;
@Mock
private RecipeService recipeService;
@Mock
private WeeklyMenuService weeklyMenuService;
......@@ -48,10 +54,15 @@ public class WeeklyMenuControllerTest {
@Test
public void getWeeklyMenu_found() {
long fridgeId = 1L;
when(weeklyMenuService.getWeeklyMenu(fridgeId)).thenReturn(weeklyMenu);
Integer fridgeId = 1;
List<RecipeWithMatchCount> weeklyMenu = List.of(
new RecipeWithMatchCount(new RecipeDetails(1, "Recipe 1", "Description 1", "ImageURL 1"), 3),
new RecipeWithMatchCount(new RecipeDetails(2, "Recipe 2", "Description 2", "ImageURL 2"), 1)
);
when(recipeService.getWeeklyMenu(fridgeId)).thenReturn(weeklyMenu);
ResponseEntity<List<WeeklyMenuResponse>> response = weeklyMenuController.getWeeklyMenu(fridgeId);
ResponseEntity<Object> response = weeklyMenuController.compareWeeklyMenuAndRecipeProducts(fridgeId);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(weeklyMenu, response.getBody());
......@@ -59,10 +70,10 @@ public class WeeklyMenuControllerTest {
@Test
public void getWeeklyMenu_notFound() {
long fridgeId = 1L;
when(weeklyMenuService.getWeeklyMenu(fridgeId)).thenReturn(new ArrayList<>());
Integer fridgeId = 1;
when(recipeService.getWeeklyMenu(fridgeId)).thenReturn(new ArrayList<>());
ResponseEntity<List<WeeklyMenuResponse>> response = weeklyMenuController.getWeeklyMenu(fridgeId);
ResponseEntity<Object> response = weeklyMenuController.compareWeeklyMenuAndRecipeProducts(fridgeId);
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment