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; ...@@ -4,7 +4,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeFridgeMatch;
import ntnu.idatt2016.v233.SmartMat.entity.Recipe; import ntnu.idatt2016.v233.SmartMat.entity.Recipe;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService; import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
...@@ -56,17 +55,6 @@ public class RecipeController { ...@@ -56,17 +55,6 @@ public class RecipeController {
return ResponseEntity.ok(recipes); 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 * add recipe to favorites in user
......
...@@ -9,7 +9,9 @@ import java.util.List; ...@@ -9,7 +9,9 @@ import java.util.List;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import ntnu.idatt2016.v233.SmartMat.dto.response.RecipeWithMatchCount;
import ntnu.idatt2016.v233.SmartMat.dto.response.WeeklyMenuResponse; import ntnu.idatt2016.v233.SmartMat.dto.response.WeeklyMenuResponse;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService; import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
@AllArgsConstructor @AllArgsConstructor
...@@ -17,6 +19,7 @@ import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService; ...@@ -17,6 +19,7 @@ import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
@RequestMapping("/api/weeklymenu") @RequestMapping("/api/weeklymenu")
public class WeeklyMenuController { public class WeeklyMenuController {
/*
private WeeklyMenuService weeklyMenuService; private WeeklyMenuService weeklyMenuService;
@GetMapping("/{fridgeId}") @GetMapping("/{fridgeId}")
...@@ -29,5 +32,19 @@ public class WeeklyMenuController { ...@@ -29,5 +32,19 @@ public class WeeklyMenuController {
return ResponseEntity.ok(weeklyMenu); 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; ...@@ -12,15 +12,11 @@ import lombok.NoArgsConstructor;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class RecipeDetails {
public class RecipeFridgeMatch {
private Integer recipeId; private Integer recipeId;
private String recipeName; private String recipeName;
private String recipeDescription; private String recipeDescription;
private long ean; private String recipeImage;
private String productName;
private String productDescription; }
private boolean inFridge; \ 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> { ...@@ -23,25 +23,19 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
List<Recipe> findAllByName(String name); List<Recipe> findAllByName(String name);
@Query( value = """ @Query( value = """
SELECT r.recipe_id, r.recipe_name,r.recipe_description,r.image_url, COUNT(fp.ean) as product_count select p2.item_name, f.fridge_id
FROM recipe r from fridge f
LEFT JOIN recipe_product rp ON r.recipe_id = rp.recipe_id inner join fridge_product fp on f.fridge_id = fp.fridge_id and f.fridge_id = :fridgeId
LEFT JOIN fridge_product fp ON rp.ean = fp.ean AND fp.fridge_id = :fridgeId inner join product p2 on p2.ean = fp.ean
GROUP BY r.recipe_id, r.recipe_name
ORDER BY product_count DESC
LIMIT 5;
""", nativeQuery = true) """, nativeQuery = true)
List<Object[]> findWeeklyMenu(@Param("fridgeId") long fridgeId); List<Object[]> findWeeklyMenu(long fridgeId);
@Query( value = """ @Query( value = """
SELECT r.recipe_id, r.recipe_name, r.recipe_description, p.ean, p.item_name, p.description as product_description, SELECT r.recipe_id, r.recipe_name, r.recipe_description, r.image_url, p.item_name
CASE WHEN fp.fridge_id IS NOT NULL THEN TRUE ELSE FALSE END as in_fridge FROM recipe r
FROM recipe AS r inner JOIN recipe_product rp ON r.recipe_id = rp.recipe_id
JOIN recipe_product AS rp ON r.recipe_id = rp.recipe_id inner join product p on rp.ean = p.ean
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 ;
""" , nativeQuery = true) """ , nativeQuery = true)
List<Object[]> findRecipeWithMatchingProductsInFridge(long fridgeId, long recipeId); List<Object[]> findRecipeProductsWithName();
} }
package ntnu.idatt2016.v233.SmartMat.service; 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.Recipe;
import ntnu.idatt2016.v233.SmartMat.entity.user.User; import ntnu.idatt2016.v233.SmartMat.entity.user.User;
import ntnu.idatt2016.v233.SmartMat.repository.RecipeRepository; import ntnu.idatt2016.v233.SmartMat.repository.RecipeRepository;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -110,25 +114,6 @@ public class RecipeService { ...@@ -110,25 +114,6 @@ public class RecipeService {
recipeRepository.save(recipe); 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 * Adds a recipe to a users favorites
* @param recipeId id of the recipe * @param recipeId id of the recipe
...@@ -180,4 +165,55 @@ public class RecipeService { ...@@ -180,4 +165,55 @@ public class RecipeService {
return ResponseEntity.ok("Recipe deleted from favorites"); 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; 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.dto.response.WeeklyMenuResponse;
import ntnu.idatt2016.v233.SmartMat.service.RecipeService;
import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService; import ntnu.idatt2016.v233.SmartMat.service.WeeklyMenuService;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -23,6 +26,9 @@ public class WeeklyMenuControllerTest { ...@@ -23,6 +26,9 @@ public class WeeklyMenuControllerTest {
@InjectMocks @InjectMocks
private WeeklyMenuController weeklyMenuController; private WeeklyMenuController weeklyMenuController;
@Mock
private RecipeService recipeService;
@Mock @Mock
private WeeklyMenuService weeklyMenuService; private WeeklyMenuService weeklyMenuService;
...@@ -48,10 +54,15 @@ public class WeeklyMenuControllerTest { ...@@ -48,10 +54,15 @@ public class WeeklyMenuControllerTest {
@Test @Test
public void getWeeklyMenu_found() { public void getWeeklyMenu_found() {
long fridgeId = 1L; Integer fridgeId = 1;
when(weeklyMenuService.getWeeklyMenu(fridgeId)).thenReturn(weeklyMenu); 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(HttpStatus.OK, response.getStatusCode());
assertEquals(weeklyMenu, response.getBody()); assertEquals(weeklyMenu, response.getBody());
...@@ -59,10 +70,10 @@ public class WeeklyMenuControllerTest { ...@@ -59,10 +70,10 @@ public class WeeklyMenuControllerTest {
@Test @Test
public void getWeeklyMenu_notFound() { public void getWeeklyMenu_notFound() {
long fridgeId = 1L; Integer fridgeId = 1;
when(weeklyMenuService.getWeeklyMenu(fridgeId)).thenReturn(new ArrayList<>()); 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()); 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