diff --git a/backend/src/main/java/com/example/todoapp/config/InitTables.java b/backend/src/main/java/com/example/todoapp/config/InitTables.java index 413f9f2..10bfa66 100644 --- a/backend/src/main/java/com/example/todoapp/config/InitTables.java +++ b/backend/src/main/java/com/example/todoapp/config/InitTables.java @@ -36,7 +36,7 @@ public class InitTables { @Autowired private RecipesRepository recipesRepository; @Autowired - private RecipeStuffsRepository recipeStuffsRepository; + private RecipeStuffsRepository RecipeStuffsRepository; @Autowired private StuffsRepository stuffsRepository; @@ -128,6 +128,6 @@ public class InitTables { recipeStuff.setRecipes(recipe); recipeStuff.setRecipeStuffsId(stuffId); recipeStuff.setAmount(amount); - recipeStuffsRepository.save(recipeStuff); + RecipeStuffsRepository.save(recipeStuff); } } diff --git a/backend/src/main/java/com/example/todoapp/controller/StocksController.java b/backend/src/main/java/com/example/todoapp/controller/StocksController.java index 932f450..c419af8 100644 --- a/backend/src/main/java/com/example/todoapp/controller/StocksController.java +++ b/backend/src/main/java/com/example/todoapp/controller/StocksController.java @@ -1,6 +1,5 @@ package com.example.todoapp.controller; -import com.example.todoapp.dto.DeleteStockRequest; import com.example.todoapp.dto.DeleteStockRequestDTO; import com.example.todoapp.dto.StockResponseDTO; import com.example.todoapp.dto.StockDTO; @@ -10,7 +9,6 @@ import com.example.todoapp.model.User; import com.example.todoapp.repository.UserRepository; import com.example.todoapp.service.StocksService; import jakarta.validation.Valid; -import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; diff --git a/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java b/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java index 1b4b919..799d3f9 100644 --- a/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java +++ b/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java @@ -96,7 +96,7 @@ public class ToBuysController { /** * 指定されたユーザーIDに基づいてすべての「買うもの」リストを取得する * - * @param userId ユーザーID + * @param authentication 認証情報 * @return ユーザーに紐づく「買うもの」リスト */ @GetMapping("/get") @@ -135,14 +135,14 @@ public class ToBuysController { * ユーザーが指定したIDの「買うもの」を削除する * * @param request 削除する「買うもの」の情報を含むリクエストボディ + * @param authentication 認証情報 * @return 削除が成功した場合にtrueを含むレスポンス */ @DeleteMapping("/delete") public ResponseEntity> deleteToBuy( - @RequestBody DeleteToBuyRequestDTO request, - Authentication authentication) { + @RequestBody DeleteToBuyRequestDTO request) { - int deletedCount = toBuysService.deleteToBuyById(request.getTobuyId()); + int deletedCount = toBuysService.deleteToBuysByTobuyId(request.getTobuyId()); Map response = new HashMap<>(); @@ -160,7 +160,8 @@ public class ToBuysController { * 買うものリストから削除し,追加情報を付加して在庫リストに追加 * * @param request 「買うもの」の情報を含むリクエストボディ - * @return + * @param authentication 認証情報 + * @return 購入処理が成功した場合にtrueを含むレスポンス */ @PostMapping("/buy") public ResponseEntity> buyToBuys( @@ -174,4 +175,39 @@ public class ToBuysController { return ResponseEntity.ok(response); } + + /** + * レシピから「買うもの」を追加する + * + * @param payload レシピIDを含むペイロード + * @param authentication 認証情報 + * @return 追加された「買うもの」のリスト + */ + @PostMapping("/addByRecipe") + public ResponseEntity> addByRecipe( + @RequestBody Map payload, + Authentication authentication) { + + Long recipeId = payload.get("recipeId"); + List responseList = toBuysService.addByRecipeId(recipeId, authentication); + + //shopのフィールドを削除 + List> filteredList = responseList.stream() + .map(dto -> { + Map map = new HashMap<>(); + map.put("tobuyId", dto.getTobuyId()); + map.put("stuffId", dto.getStuffId()); + map.put("stuffName", dto.getStuffName()); + map.put("amount", dto.getAmount()); + return map; + }) + .collect(Collectors.toList()); + + Map response = new HashMap<>(); + response.put("result", true); + response.put("data", filteredList); + + return ResponseEntity.ok(response); +} + } \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/model/ToBuys.java b/backend/src/main/java/com/example/todoapp/model/ToBuys.java index 6ab9052..e33edfb 100644 --- a/backend/src/main/java/com/example/todoapp/model/ToBuys.java +++ b/backend/src/main/java/com/example/todoapp/model/ToBuys.java @@ -74,7 +74,6 @@ public class ToBuys { /** * 購入するお店 */ - @NotNull @Column(nullable = false) private String store; diff --git a/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java b/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java index a660f21..cbbb485 100644 --- a/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java +++ b/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java @@ -1,33 +1,37 @@ -//-------------------------------- -// RecipeStuffsRepository.java -// -// -// 更新履歴:2025/06/10 新規作成 -// Copyright(c) 2025 IVIS All rights reserved. -//-------------------------------------------- package com.example.todoapp.repository; -import com.example.todoapp.model.RecipeStuffs; - -import jakarta.transaction.Transactional; +import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; -import java.util.List; +import com.example.todoapp.model.RecipeStuffs; /** - * 料理-材料エンティティのリポジトリインターフェース + * レシピ食材関連データのリポジトリインターフェース *

- * このインターフェースは料理-材料データへのアクセスと操作を提供します。 + * このインターフェースはレシピと食材の関連データへのアクセスを提供します。 * Spring Data JPAによって自動的に実装されます。 *

*/ - -@Repository public interface RecipeStuffsRepository extends JpaRepository { - -} \ No newline at end of file + /** + * レシピIDで食材情報を検索する + * + * @param recipeId 検索するレシピID + * @return 関連する食材情報リスト + */ + List findByRecipesRecipeId(Long recipeId); + + /** + * レシピIDと食材IDで関連情報を検索する + * + * @param recipeId 検索するレシピID + * @param stuffId 検索する食材ID + * @return 関連情報(存在する場合) + */ + Optional findByRecipesRecipeIdAndStuffStuffId(Long recipeId, Long stuffId); +} + + + diff --git a/backend/src/main/java/com/example/todoapp/repository/RecipesStuffsRepository.java b/backend/src/main/java/com/example/todoapp/repository/RecipesStuffsRepository.java deleted file mode 100644 index 729b825..0000000 --- a/backend/src/main/java/com/example/todoapp/repository/RecipesStuffsRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.example.todoapp.repository; - -import java.util.List; -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; - -import com.example.todoapp.model.RecipeStuffs; - -/** - * レシピ食材関連データのリポジトリインターフェース - *

- * このインターフェースはレシピと食材の関連データへのアクセスを提供します。 - * Spring Data JPAによって自動的に実装されます。 - *

- */ -public interface RecipesStuffsRepository extends JpaRepository { - /** - * レシピIDで食材情報を検索する - * - * @param recipeId 検索するレシピID - * @return 関連する食材情報リスト - */ - List findByRecipesRecipeId(Long recipeId); - - /** - * レシピIDと食材IDで関連情報を検索する - * - * @param recipeId 検索するレシピID - * @param stuffId 検索する食材ID - * @return 関連情報(存在する場合) - */ - Optional findByRecipesRecipeIdAndStuffStuffId(Long recipeId, Long stuffId); -} - - - diff --git a/backend/src/main/java/com/example/todoapp/repository/StuffsRepository.java b/backend/src/main/java/com/example/todoapp/repository/StuffsRepository.java index 065fe18..15fb1c3 100644 --- a/backend/src/main/java/com/example/todoapp/repository/StuffsRepository.java +++ b/backend/src/main/java/com/example/todoapp/repository/StuffsRepository.java @@ -16,6 +16,7 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; /** @@ -28,7 +29,8 @@ import org.springframework.stereotype.Repository; @Repository public interface StuffsRepository extends JpaRepository { // 材料情報を主キーで取得するメソッド(必要に応じて追加) - Stuffs findByStuffId(Long stuffId); + @Query("SELECT s FROM Stuffs s WHERE s.stuffId = ?1") + Optional findByStuffId(Long stuffId); Optional findByStuffName(String stuffName); diff --git a/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java b/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java index f07f742..d9b6861 100644 --- a/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java +++ b/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java @@ -7,9 +7,12 @@ //-------------------------------------------- package com.example.todoapp.repository; +import com.example.todoapp.model.Stuffs; import com.example.todoapp.model.ToBuys; +import com.example.todoapp.model.User; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; @@ -34,7 +37,7 @@ public interface ToBuysRepository extends JpaRepository { * @return 「買うもの」レコード */ @Query("SELECT t FROM ToBuys t WHERE t.tobuyId = ?1") - ToBuys findById(Long tobuyId); + ToBuys findByTobuyId(Long tobuyId); /** * 指定されたユーザーIDに基づいて「買うもの」リストを取得する @@ -43,15 +46,26 @@ public interface ToBuysRepository extends JpaRepository { * @return 「買うもの」リスト */ @Query("SELECT t FROM ToBuys t WHERE t.user.id = ?1") - List findByUser(Long userId); + List findByUserIdOrderByTobuyIdAsc(Long userId); /** * 指定された「買うもの」IDに基づいて「買うもの」リストを削除 * * @param tobuyId 「買うもの」ID - * @return + * @return 削除された行数 */ @Modifying @Query("DELETE FROM ToBuys t WHERE t.tobuyId = :tobuyId") int deleteByTobuyId(@Param("tobuyId") Long tobuyId); + + /** + * ユーザーとスタッフに基づいて「買うもの」レコードを取得する + * + * @param user ユーザー + * @param stuff スタッフ + * @return 「買うもの」レコード + */ + @Query("SELECT t FROM ToBuys t WHERE t.user = :user AND t.stuff = :stuff") + Optional findByUserAndStuff(@Param("user") User user, @Param("stuff") Stuffs stuff); + } \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/service/RecipeService.java b/backend/src/main/java/com/example/todoapp/service/RecipeService.java index f1a0d0d..194d48c 100644 --- a/backend/src/main/java/com/example/todoapp/service/RecipeService.java +++ b/backend/src/main/java/com/example/todoapp/service/RecipeService.java @@ -24,7 +24,7 @@ import com.example.todoapp.dto.StuffRequestDTO; import com.example.todoapp.model.RecipeStuffs; import com.example.todoapp.model.Recipes; import com.example.todoapp.model.Stuffs; -import com.example.todoapp.repository.RecipesStuffsRepository; +import com.example.todoapp.repository.RecipeStuffsRepository; import com.example.todoapp.repository.RecipesRepository; import com.example.todoapp.repository.StuffsRepository; @@ -47,7 +47,7 @@ public class RecipeService { private StuffsRepository stuffsRepository; @Autowired - private RecipesStuffsRepository recipeStuffsRepository; + private RecipeStuffsRepository RecipeStuffsRepository; /** * レシピを新規登録する @@ -89,7 +89,7 @@ public class RecipeService { recipeStuffsList.add(recipeStuffs); } - recipeStuffsRepository.saveAll(recipeStuffsList); + RecipeStuffsRepository.saveAll(recipeStuffsList); return recipe; } @@ -113,7 +113,7 @@ public class RecipeService { Recipes recipe = recipesRepository.findById(recipeId) .orElseThrow(() -> new RuntimeException("レシピが見つかりません")); - List recipeStuffsList = recipeStuffsRepository.findByRecipesRecipeId(recipeId); + List recipeStuffsList = RecipeStuffsRepository.findByRecipesRecipeId(recipeId); List stuffList = recipeStuffsList.stream() .map(rs -> { @@ -170,19 +170,19 @@ public class RecipeService { rs.setRecipes(recipe); rs.setStuff(newStuff); rs.setAmount(stuffDTO.getAmount()); - recipeStuffsRepository.save(rs); + RecipeStuffsRepository.save(rs); incomingStuffIds.add(newStuff.getStuffId()); } else { // 材料IDが提供されている場合、既存のRecipeStuffsエントリを検索 - Optional optionalRs = recipeStuffsRepository - .findByRecipesRecipeIdAndStuffStuffId(dto.getRecipeId(), stuffDTO.getStuffId()); + Optional optionalRs = RecipeStuffsRepository + .findByRecipesRecipeIdAndStuffStuffId(dto.getRecipeId(), stuffDTO.getStuffId()); if (optionalRs.isPresent()) { // RecipeStuffsエントリが存在する場合、数量を更新 RecipeStuffs rs = optionalRs.get(); rs.setAmount(stuffDTO.getAmount()); - recipeStuffsRepository.save(rs); + RecipeStuffsRepository.save(rs); incomingStuffIds.add(rs.getStuff().getStuffId()); } else { // オプション:見つからない場合、新しいRecipeStuffsエントリを作成 @@ -193,17 +193,17 @@ public class RecipeService { rs.setRecipes(recipe); rs.setStuff(existingStuff); rs.setAmount(stuffDTO.getAmount()); - recipeStuffsRepository.save(rs); + RecipeStuffsRepository.save(rs); incomingStuffIds.add(existingStuff.getStuffId()); } } } // 入ってきたリストにないRecipeStuffsエントリを削除 - List existingStuffs = recipeStuffsRepository.findByRecipesRecipeId(dto.getRecipeId()); + List existingStuffs = RecipeStuffsRepository.findByRecipesRecipeId(dto.getRecipeId()); for (RecipeStuffs rs : existingStuffs) { if (!incomingStuffIds.contains(rs.getStuff().getStuffId())) { - recipeStuffsRepository.delete(rs); + RecipeStuffsRepository.delete(rs); } } diff --git a/backend/src/main/java/com/example/todoapp/service/ToBuysService.java b/backend/src/main/java/com/example/todoapp/service/ToBuysService.java index 5cc9cde..8172606 100644 --- a/backend/src/main/java/com/example/todoapp/service/ToBuysService.java +++ b/backend/src/main/java/com/example/todoapp/service/ToBuysService.java @@ -10,11 +10,14 @@ package com.example.todoapp.service; import com.example.todoapp.util.MessageUtils; import com.example.todoapp.dto.BuyRequestDTO; +import com.example.todoapp.dto.ToBuyResponseDTO; import com.example.todoapp.dto.ToBuysDTO; +import com.example.todoapp.model.RecipeStuffs; import com.example.todoapp.model.Stocks; import com.example.todoapp.model.Stuffs; import com.example.todoapp.model.ToBuys; import com.example.todoapp.model.User; +import com.example.todoapp.repository.RecipeStuffsRepository; import com.example.todoapp.repository.StocksRepository; import com.example.todoapp.repository.StuffsRepository; import com.example.todoapp.repository.ToBuysRepository; @@ -27,6 +30,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -56,11 +60,15 @@ public class ToBuysService { @Autowired private MessageUtils messageUtils; + @Autowired + private RecipeStuffsRepository RecipeStuffsRepository; /** * 購入リストに新しいアイテムを追加する * * @param toBuyDTO 追加する購入アイテムのデータ(DTO) + * @param authentication 認証情報 + * @return 追加された購入アイテム */ public ToBuys addToBuys(ToBuysDTO toBuyDTO, Authentication authentication) { @@ -78,7 +86,7 @@ public class ToBuysService { stuff = stuffsRepository.save(stuff); } else { // 材料情報を取得 - Optional optionalStuffs = stuffsRepository.findById(toBuyDTO.getStuffId()); + Optional optionalStuffs = stuffsRepository.findByStuffId(toBuyDTO.getStuffId()); if (!optionalStuffs.isPresent()) { throw new RuntimeException("材料がありません"); } @@ -114,11 +122,11 @@ public class ToBuysService { Optional existingStuffs = stuffsRepository.findByStuffName(toBuyDTO.getStuffName()); // 新しい材料を作成 if (existingStuffs.isPresent()) { - // 如果存在,更新已有材料的属性 + // 材料が存在する場合、更新 stuffs = existingStuffs.get(); stuffs.setCategory(toBuyDTO.getCategory()); // 可选:更新分类 } else { - // 否则新建材料 + // 材料が存在しない場合、新規作成 stuffs = new Stuffs(); stuffs.setStuffName(toBuyDTO.getStuffName()); stuffs.setCategory(toBuyDTO.getCategory()); @@ -154,7 +162,7 @@ public class ToBuysService { * @return ユーザーに紐づく「買うもの」リスト */ public List getToBuysByUser(User user) { - return toBuysRepository.findByUser(user.getId()); + return toBuysRepository.findByUserIdOrderByTobuyIdAsc(user.getId()); } /** @@ -163,7 +171,7 @@ public class ToBuysService { * @param tobuyId 購入リストID */ @Transactional - public int deleteToBuyById(Long tobuyId) { + public int deleteToBuysByTobuyId(Long tobuyId) { return toBuysRepository.deleteByTobuyId(tobuyId); } @@ -179,7 +187,7 @@ public class ToBuysService { User user = getUserByUsername(username); // Tobuy情報の取得 - ToBuys tobuy = toBuysRepository.findById(dto.getTobuyId()); + ToBuys tobuy = toBuysRepository.findByTobuyId(dto.getTobuyId()); // 新しい在庫を作成 Stocks stock = new Stocks(); @@ -193,12 +201,64 @@ public class ToBuysService { // 買うものリストから削除 System.out.println("tobuy.getTobuyId()=" + tobuy.getTobuyId()); - deleteToBuyById(tobuy.getTobuyId()); + deleteToBuysByTobuyId(tobuy.getTobuyId()); // データベースに保存 return stocksRepository.save(stock); } + /** + * 指定されたレシピIDに基づいて「買うもの」を追加する + * + * @param recipeId レシピID + * @param authentication 認証情報 + * @return 追加された「買うもの」のリスト + */ + public List addByRecipeId(Long recipeId, Authentication authentication) { + // ユーザー情報を取得 + String username = authentication.getName(); + User user = userRepository.findByUsername(username) + .orElseThrow(() -> new RuntimeException("ユーザーが見つかりません: " + username)); + + // 料理情報を取得 + List recipeStuffsList = RecipeStuffsRepository.findByRecipesRecipeId(recipeId); + + List result = new ArrayList<>(); + + for (RecipeStuffs rs : recipeStuffsList) { + Stuffs stuff = rs.getStuff(); + int requiredAmount = rs.getAmount(); + + Optional existingToBuyOpt = toBuysRepository.findByUserAndStuff(user, stuff); + + ToBuys toBuy; + if (existingToBuyOpt.isPresent()) { + toBuy = existingToBuyOpt.get(); + toBuy.setAmount(toBuy.getAmount() + requiredAmount); // 既存の数量を更新 + } else { + toBuy = new ToBuys(); + toBuy.setUser(user); + toBuy.setStuff(stuff); + toBuy.setAmount(requiredAmount); + toBuy.setStore(""); + } + + toBuy = toBuysRepository.save(toBuy); + + // ToBuyResponseDTOに変換 + ToBuyResponseDTO dto = new ToBuyResponseDTO(); + dto.setTobuyId(toBuy.getTobuyId()); + dto.setStuffId(toBuy.getStuff().getStuffId()); + dto.setStuffName(toBuy.getStuff().getStuffName()); + dto.setAmount(toBuy.getAmount()); + + result.add(dto); + } + + return result; + + } + /** * ユーザー名からユーザーエンティティを取得する * @@ -211,4 +271,7 @@ public class ToBuysService { .orElseThrow(() -> new UsernameNotFoundException(messageUtils.getMessage("error.auth.user.not.found.with.name", new Object[]{username}))); } + + + } \ No newline at end of file diff --git a/frontend/public/index.html b/frontend/public/index.html index 8793c25..ce35ac2 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -2,7 +2,7 @@ - + { - ToDoアプリ ログイン + shopchop ログイン {/* エラーがある場合のみアラートを表示 */} {error && (