diff --git a/backend/src/main/java/com/example/todoapp/controller/RecipesController.java b/backend/src/main/java/com/example/todoapp/controller/RecipesController.java new file mode 100644 index 0000000..45702a3 --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/controller/RecipesController.java @@ -0,0 +1,92 @@ +package com.example.todoapp.controller; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.example.todoapp.dto.RecipeDetailDTO; +import com.example.todoapp.dto.RecipeRequestDTO; +import com.example.todoapp.dto.RecipeResponseDTO; +import com.example.todoapp.model.Recipes; +import com.example.todoapp.service.RecipeService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + + +@RestController +@RequestMapping("/recipes") +public class RecipesController { + + @Autowired + private RecipeService recipeService; + + @PostMapping("/add") + public ResponseEntity> addRecipe(@RequestBody RecipeRequestDTO dto) { + Recipes createAllReipes = recipeService.addRecipe(dto); + + Map response = new HashMap<>(); + response.put("result", true); + response.put("recipeId", createAllReipes.getRecipeId()); + response.put("message", "追加に成功しました"); + + return ResponseEntity.ok(response); + } + + @GetMapping("/getAll") + public ResponseEntity> getRecipe(Authentication authentication) { + List recipes = recipeService.getAllRecipes(); + // エンティティからDTOへの変換 + List responseList = recipes.stream() + .map(recipe -> { + RecipeResponseDTO dto = new RecipeResponseDTO(); + dto.setRecipeId(recipe.getRecipeId()); + dto.setRecipeName(recipe.getRecipeName()); + dto.setSummary(recipe.getSummary()); + return dto; + }) + .collect(Collectors.toList()); + return ResponseEntity.ok(responseList); + } + + /** + * 指定されたIDの在庫を取得する + * + * @param authentication 認証情報 + * @param recipeId 在庫ID + * @return 在庫情報 + */ + @GetMapping("/getById") + public ResponseEntity getRecipeById( + Authentication authentication, + @RequestParam Long recipeId) { + recipeService.getRecipeDetailsById(recipeId); + return ResponseEntity.ok(recipeService.getRecipeDetailsById(recipeId)); + } + + @PutMapping("/update") + public ResponseEntity> updateRecipe(@RequestBody RecipeDetailDTO dto) { + Recipes recipes = recipeService.updateRecipe(dto); + Map response = new HashMap<>(); + + if (recipes != null) { + response.put("result",true ); + response.put("message", "料理リストの編集が完了しました"); + } else { + response.put("result", false); + response.put("message", "編集に失敗しました"); + + } + return ResponseEntity.ok(response); + } + +} \ No newline at end of file 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 ffa7910..b2866c5 100644 --- a/backend/src/main/java/com/example/todoapp/controller/StocksController.java +++ b/backend/src/main/java/com/example/todoapp/controller/StocksController.java @@ -1,7 +1,7 @@ package com.example.todoapp.controller; import com.example.todoapp.dto.DeleteStockRequest; -import com.example.todoapp.dto.ResponseStockDTO; +import com.example.todoapp.dto.StockDTOResponse; import com.example.todoapp.dto.StockDTO; import com.example.todoapp.model.Stocks; import com.example.todoapp.model.User; @@ -43,11 +43,11 @@ public class StocksController { * @return ユーザーの在庫リスト */ @GetMapping("/get") - public ResponseEntity> getAllStocks(Authentication authentication) { + public ResponseEntity> getAllStocks(Authentication authentication) { List stocks = stockService.getALLStocksByUser(authentication.getName()); // エンティティからDTOへの変換 - List stockDTOs = stocks.stream() - .map(ResponseStockDTO::fromEntity) + List stockDTOs = stocks.stream() + .map(StockDTOResponse::fromEntity) .collect(Collectors.toList()); return ResponseEntity.ok(stockDTOs); } 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 8467c37..6c3f84f 100644 --- a/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java +++ b/backend/src/main/java/com/example/todoapp/controller/ToBuysController.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; diff --git a/backend/src/main/java/com/example/todoapp/dto/RecipeDetailDTO.java b/backend/src/main/java/com/example/todoapp/dto/RecipeDetailDTO.java new file mode 100644 index 0000000..dea793f --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/dto/RecipeDetailDTO.java @@ -0,0 +1,14 @@ +package com.example.todoapp.dto; + +import java.util.List; + +import lombok.Data; + +@Data +public class RecipeDetailDTO { + private Long recipeId; + private String recipeName; + private String summary; + + private List stuffs; +} \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/dto/RecipeRequestDTO.java b/backend/src/main/java/com/example/todoapp/dto/RecipeRequestDTO.java new file mode 100644 index 0000000..5b26b9b --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/dto/RecipeRequestDTO.java @@ -0,0 +1,13 @@ +package com.example.todoapp.dto; + +import java.util.List; + +import lombok.Data; + +@Data +public class RecipeRequestDTO { + private Long recipeId; + private String recipeName; + private String summary; + private List stuffAndAmountArray; +} \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java b/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java new file mode 100644 index 0000000..2464cbc --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java @@ -0,0 +1,11 @@ +package com.example.todoapp.dto; + +import lombok.Data; + +@Data +public class RecipeResponseDTO { + private Long recipeId; + private String recipeName; + private String summary; + +} diff --git a/backend/src/main/java/com/example/todoapp/dto/ResponseStockDTO.java b/backend/src/main/java/com/example/todoapp/dto/StockDTOResponse.java similarity index 91% rename from backend/src/main/java/com/example/todoapp/dto/ResponseStockDTO.java rename to backend/src/main/java/com/example/todoapp/dto/StockDTOResponse.java index 1de5012..e2eb002 100644 --- a/backend/src/main/java/com/example/todoapp/dto/ResponseStockDTO.java +++ b/backend/src/main/java/com/example/todoapp/dto/StockDTOResponse.java @@ -16,7 +16,7 @@ import java.time.LocalDate; */ @Data -public class ResponseStockDTO { +public class StockDTOResponse { private Long stockId; private Long stuffId; private Long userId; @@ -34,8 +34,8 @@ public class ResponseStockDTO { * @param stock 変換元の在庫エンティティ * @return 変換されたStockDTOオブジェクト */ - public static ResponseStockDTO fromEntity(Stocks stock) { - ResponseStockDTO dto = new ResponseStockDTO(); + public static StockDTOResponse fromEntity(Stocks stock) { + StockDTOResponse dto = new StockDTOResponse(); Stuffs stuff = stock.getStuff(); dto.setStockId(stock.getStockId()); diff --git a/backend/src/main/java/com/example/todoapp/dto/StuffDetailDTO.java b/backend/src/main/java/com/example/todoapp/dto/StuffDetailDTO.java new file mode 100644 index 0000000..adde9bb --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/dto/StuffDetailDTO.java @@ -0,0 +1,10 @@ +package com.example.todoapp.dto; + +import lombok.Data; + +@Data +public class StuffDetailDTO { + private Long stuffId; + private String stuffName; + private Integer amount; +} \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/dto/StuffRequestDTO.java b/backend/src/main/java/com/example/todoapp/dto/StuffRequestDTO.java new file mode 100644 index 0000000..ce06291 --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/dto/StuffRequestDTO.java @@ -0,0 +1,10 @@ +package com.example.todoapp.dto; +import lombok.Data; + +@Data +public class StuffRequestDTO { + private String stuffId; + private String stuffName; + private String category; + private String amount; +} \ No newline at end of file diff --git a/backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java b/backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java index 74d5738..c21eb9a 100644 --- a/backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java +++ b/backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java @@ -1,5 +1,5 @@ //-------------------------------- -// RecipiesStuffs.java +// RecipesStuffs.java // // 分類:社員管理システムV2・ビジネスロジック層 // @@ -18,7 +18,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.NoArgsConstructor; @@ -43,7 +43,7 @@ public class RecipeStuffs { /** * 料理の一意識別子 FK */ - @NotBlank + @NotNull @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( name = "recipeId", @@ -56,7 +56,7 @@ public class RecipeStuffs { /** * 材料の一意識別子 FK */ - @NotBlank + @NotNull @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( name = "stuffId", @@ -68,8 +68,8 @@ public class RecipeStuffs { /** * 材料の数量(デフォルト1) */ - @NotBlank + @NotNull @Column(nullable = false) - private int amount = 1; + private Integer amount = 1; } diff --git a/backend/src/main/java/com/example/todoapp/model/Recipes.java b/backend/src/main/java/com/example/todoapp/model/Recipes.java index c4a986d..35a9b36 100644 --- a/backend/src/main/java/com/example/todoapp/model/Recipes.java +++ b/backend/src/main/java/com/example/todoapp/model/Recipes.java @@ -43,7 +43,7 @@ public class Recipes { */ @NotNull @Column(name="recipeName", unique = true, length = 255, nullable = false) - private String recipieName; + private String recipeName; /** * カテゴリ diff --git a/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java b/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java new file mode 100644 index 0000000..000574b --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java @@ -0,0 +1,18 @@ +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; + +public interface RecipeStuffsRepository extends JpaRepository { + List findByRecipesRecipeId(Long recipeId); + + + Optional findByRecipesRecipeIdAndStuffStuffId(Long recipeId, Long stuffId); +} + + + diff --git a/backend/src/main/java/com/example/todoapp/repository/RecipesRepository.java b/backend/src/main/java/com/example/todoapp/repository/RecipesRepository.java new file mode 100644 index 0000000..6151530 --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/repository/RecipesRepository.java @@ -0,0 +1,7 @@ +package com.example.todoapp.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.todoapp.model.Recipes; + +public interface RecipesRepository extends JpaRepository {} diff --git a/backend/src/main/java/com/example/todoapp/service/RecipeService.java b/backend/src/main/java/com/example/todoapp/service/RecipeService.java new file mode 100644 index 0000000..9b50deb --- /dev/null +++ b/backend/src/main/java/com/example/todoapp/service/RecipeService.java @@ -0,0 +1,197 @@ +//-------------------------------- +// RecipeService.java +// +// +// 更新履歴:2025/06/05 新規作成 +// Copyright(c) 2025 IVIS All rights reserved. +//-------------------------------------------- +package com.example.todoapp.service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.example.todoapp.dto.RecipeDetailDTO; +import com.example.todoapp.dto.RecipeRequestDTO; +import com.example.todoapp.dto.StuffDetailDTO; +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.RecipeStuffsRepository; +import com.example.todoapp.repository.RecipesRepository; +import com.example.todoapp.repository.StuffsRepository; + +import jakarta.transaction.Transactional; + +/** + * レシピ管理サービスクラス + *

+ * このクラスは、レシピの登録処理を提供します。 + * 材料の存在確認・新規作成・数量管理などの機能を含みます。 + *

+ */ +@Service +public class RecipeService { + + @Autowired + private RecipesRepository recipesRepository; + + @Autowired + private StuffsRepository stuffsRepository; + + @Autowired + private RecipeStuffsRepository recipeStuffsRepository; + + /** + * レシピを新規登録する + * + * @param dto レシピ登録情報(レシピ名、概要、材料情報含む) + * @return レシピ登録結果(成功/失敗、レシピID含む) + */ + @Transactional // トランザクション管理を実施 + public Recipes addRecipe(RecipeRequestDTO dto) { + Recipes recipe = new Recipes(); + recipe.setRecipeName(dto.getRecipeName()); + recipe.setSummary(dto.getSummary()); + recipe = recipesRepository.save(recipe); + + List recipeStuffsList = new ArrayList<>(); + for (StuffRequestDTO stuffDTO : dto.getStuffAndAmountArray()) { + Stuffs stuff; + if (stuffDTO.getStuffId() != null && !stuffDTO.getStuffId().isEmpty()) { + // stuffIdが存在する + stuff = stuffsRepository.findById(Long.valueOf(stuffDTO.getStuffId())) + .orElseThrow(() -> new RuntimeException("材料がありません")); + } else { + // stuffIdが存在しない + stuff = new Stuffs(); + stuff.setStuffName(stuffDTO.getStuffName()); + stuff.setCategory(stuffDTO.getCategory()); + stuff = stuffsRepository.save(stuff); + } + + RecipeStuffs recipeStuffs = new RecipeStuffs(); + recipeStuffs.setRecipes(recipe); // 関連レシピ設定 + recipeStuffs.setStuff(stuff); // 関連材料設定 + + // 数量設定、defaultは1 + if (stuffDTO.getAmount() == null || stuffDTO.getAmount().isEmpty()) { + stuffDTO.setAmount("1"); + } + recipeStuffs.setAmount(Integer.parseInt(stuffDTO.getAmount())); + recipeStuffsList.add(recipeStuffs); + } + + recipeStuffsRepository.saveAll(recipeStuffsList); + return recipe; + } + + /** + * 登録済のレシピを取得する + * + * @param authentication 認証情報 + * @return 登録済のレシピ情報 + */ + public List getAllRecipes() { + return recipesRepository.findAll(); + } + + /** + * レシピをIDで取得する + * + * @param recipeId 検索するレシピID + * @return 検索結果のレシピ情報 + */ + public RecipeDetailDTO getRecipeDetailsById(Long recipeId) { + Recipes recipe = recipesRepository.findById(recipeId) + .orElseThrow(() -> new RuntimeException("レシピが見つかりません")); + + List recipeStuffsList = recipeStuffsRepository.findByRecipesRecipeId(recipeId); + + List stuffList = recipeStuffsList.stream() + .map(rs -> { + StuffDetailDTO stuffDTO = new StuffDetailDTO(); + stuffDTO.setStuffId(rs.getStuff().getStuffId()); + stuffDTO.setStuffName(rs.getStuff().getStuffName()); + stuffDTO.setAmount(rs.getAmount()); + return stuffDTO; + }) + .collect(Collectors.toList()); + + RecipeDetailDTO dto = new RecipeDetailDTO(); + dto.setRecipeId(recipe.getRecipeId()); + dto.setRecipeName(recipe.getRecipeName()); + dto.setSummary(recipe.getSummary()); + dto.setStuffs(stuffList); + + return dto; + } + + + @Transactional + public Recipes updateRecipe(RecipeDetailDTO dto) { + Recipes recipe = recipesRepository.findById(dto.getRecipeId()) + .orElseThrow(() -> new RuntimeException("レシピが見つかりません")); + + recipe.setRecipeName(dto.getRecipeName()); + recipe.setSummary(dto.getSummary()); + recipesRepository.save(recipe); + + Set incomingStuffIds = new HashSet<>(); + + for (StuffDetailDTO stuffDTO : dto.getStuffs()) { + if (stuffDTO.getStuffId() == null) { + Stuffs newStuff = new Stuffs(); + newStuff.setStuffName(stuffDTO.getStuffName()); + newStuff.setCategory("その他"); + newStuff = stuffsRepository.save(newStuff); + + RecipeStuffs rs = new RecipeStuffs(); + rs.setRecipes(recipe); + rs.setStuff(newStuff); + rs.setAmount(stuffDTO.getAmount()); + recipeStuffsRepository.save(rs); + + incomingStuffIds.add(newStuff.getStuffId()); + } else { + Optional optionalRs = recipeStuffsRepository + .findByRecipesRecipeIdAndStuffStuffId(dto.getRecipeId(), stuffDTO.getStuffId()); + + if (optionalRs.isPresent()) { + RecipeStuffs rs = optionalRs.get(); + rs.setAmount(stuffDTO.getAmount()); + recipeStuffsRepository.save(rs); + incomingStuffIds.add(rs.getStuff().getStuffId()); + } else { + // 可选:创建新的 RecipeStuffs + Stuffs existingStuff = stuffsRepository.findById(stuffDTO.getStuffId()) + .orElseThrow(() -> new RuntimeException("材料が見つかりません")); + + RecipeStuffs rs = new RecipeStuffs(); + rs.setRecipes(recipe); + rs.setStuff(existingStuff); + rs.setAmount(stuffDTO.getAmount()); + recipeStuffsRepository.save(rs); + incomingStuffIds.add(existingStuff.getStuffId()); + } + } + } + + List existingStuffs = recipeStuffsRepository.findByRecipesRecipeId(dto.getRecipeId()); + for (RecipeStuffs rs : existingStuffs) { + System.out.println("dddddwtestst" + rs.getStuff().getStuffId()); + if (!incomingStuffIds.contains(rs.getStuff().getStuffId())) { + recipeStuffsRepository.delete(rs); + } + } + + return recipe; + } +} \ No newline at end of file