Merge branch 'feature-backend-recipe' into develop-backend

feature-backend-datainit
Masaharu.Kato 4 months ago
commit a4994e20b9
  1. 116
      backend/src/main/java/com/example/todoapp/controller/RecipesController.java
  2. 58
      backend/src/main/java/com/example/todoapp/controller/StocksController.java
  3. 21
      backend/src/main/java/com/example/todoapp/controller/ToBuysController.java
  4. 31
      backend/src/main/java/com/example/todoapp/dto/BuyRequestDTO.java
  5. 19
      backend/src/main/java/com/example/todoapp/dto/DeleteStockRequestDTO.java
  6. 9
      backend/src/main/java/com/example/todoapp/dto/DeleteToBuyRequest.java
  7. 25
      backend/src/main/java/com/example/todoapp/dto/DeleteToBuyRequestDTO.java
  8. 39
      backend/src/main/java/com/example/todoapp/dto/RecipeDetailDTO.java
  9. 39
      backend/src/main/java/com/example/todoapp/dto/RecipeRequestDTO.java
  10. 31
      backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java
  11. 6
      backend/src/main/java/com/example/todoapp/dto/StockResponseDTO.java
  12. 30
      backend/src/main/java/com/example/todoapp/dto/StuffDetailDTO.java
  13. 36
      backend/src/main/java/com/example/todoapp/dto/StuffRequestDTO.java
  14. 12
      backend/src/main/java/com/example/todoapp/dto/ToBuyResponse.java
  15. 44
      backend/src/main/java/com/example/todoapp/dto/ToBuyResponseDTO.java
  16. 12
      backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java
  17. 2
      backend/src/main/java/com/example/todoapp/model/Recipes.java
  18. 15
      backend/src/main/java/com/example/todoapp/model/Stocks.java
  19. 14
      backend/src/main/java/com/example/todoapp/repository/RecipesRepository.java
  20. 37
      backend/src/main/java/com/example/todoapp/repository/RecipesStuffsRepository.java
  21. 7
      backend/src/main/java/com/example/todoapp/repository/StocksRepository.java
  22. 210
      backend/src/main/java/com/example/todoapp/service/RecipeService.java
  23. 9
      backend/src/main/java/com/example/todoapp/service/StocksService.java

@ -0,0 +1,116 @@
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;
/**
* 料理レシピ管理のコントローラー
* <p>
* このコントローラーはレシピの取得作成更新削除などの
* エンドポイントを提供しますすべてのエンドポイントは認証が必要です
* </p>
*/
@RestController
@RequestMapping("/recipes")
public class RecipesController {
@Autowired
private RecipeService recipeService;
/**
* 新しいレシピを作成する
*
* @param dto 作成するレシピの情報
* @return 作成結果recipeIdとメッセージを含む
*/
@PostMapping("/add")
public ResponseEntity<Map<String, Object>> addRecipe(@RequestBody RecipeRequestDTO dto) {
Recipes createAllReipes = recipeService.addRecipe(dto);
Map<String, Object> response = new HashMap<>();
response.put("result", true);
response.put("recipeId", createAllReipes.getRecipeId());
response.put("message", "追加に成功しました");
return ResponseEntity.ok(response);
}
/**
* すべてのレシピを取得する
*
* @param authentication 認証情報
* @return レシピ情報リスト
*/
@GetMapping("/getAll")
public ResponseEntity<List<RecipeResponseDTO>> getRecipe(Authentication authentication) {
List<Recipes> recipes = recipeService.getAllRecipes();
// エンティティからDTOへの変換
List<RecipeResponseDTO> 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<RecipeDetailDTO> getRecipeById(
Authentication authentication,
@RequestParam Long recipeId) {
recipeService.getRecipeDetailsById(recipeId);
return ResponseEntity.ok(recipeService.getRecipeDetailsById(recipeId));
}
/**
* レシピ情報を更新する
*
* @param dto 更新するレシピの詳細情報
* @return 更新結果成功/失敗メッセージを含む
*/
@PutMapping("/update")
public ResponseEntity<Map<String, Object>> updateRecipe(@RequestBody RecipeDetailDTO dto) {
Recipes recipes = recipeService.updateRecipe(dto);
Map<String, Object> 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);
}
}

@ -1,10 +1,13 @@
package com.example.todoapp.controller;
import com.example.todoapp.dto.DeleteStockRequest;
import com.example.todoapp.dto.ResponseStockDTO;
import com.example.todoapp.dto.DeleteStockRequestDTO;
import com.example.todoapp.dto.StockResponseDTO;
import com.example.todoapp.dto.StockDTO;
import com.example.todoapp.dto.UpdateStockRequest;
import com.example.todoapp.model.Stocks;
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;
@ -12,8 +15,8 @@ import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.*;
import lombok.Data;
import java.util.HashMap;
import java.util.List;
@ -34,6 +37,9 @@ public class StocksController {
@Autowired
private StocksService stockService;
@Autowired
private UserRepository userRepository;
/**
* ログインユーザーのすべての在庫を取得する
*
@ -41,11 +47,11 @@ public class StocksController {
* @return ユーザーの在庫リスト
*/
@GetMapping("/get")
public ResponseEntity<List<ResponseStockDTO>> getAllStocks(Authentication authentication) {
public ResponseEntity<List<StockResponseDTO>> getAllStocks(Authentication authentication) {
List<Stocks> stocks = stockService.getALLStocksByUser(authentication.getName());
// エンティティからDTOへの変換
List<ResponseStockDTO> stockDTOs = stocks.stream()
.map(ResponseStockDTO::fromEntity)
List<StockResponseDTO> stockDTOs = stocks.stream()
.map(StockResponseDTO::fromEntity)
.collect(Collectors.toList());
return ResponseEntity.ok(stockDTOs);
}
@ -91,12 +97,21 @@ public class StocksController {
@PutMapping("/update")
public ResponseEntity<Map<String, Object>> updateStock(
Authentication authentication,
@Valid @RequestBody UpdateStockRequest stockDetails) {
stockService.updateStocks(authentication.getName(), stockDetails);
@Valid @RequestBody UpdateStockRequest updateStockRequest) {
Stocks updatedStock = stockService.updateStocks(authentication.getName(), updateStockRequest);
Map<String, Object> response = new HashMap<>();
response.put("result", true);
if (updatedStock == null) {
response.put("result", false);
response.put("message", "指定されたIDの在庫が見つかりませんでした");
return ResponseEntity.ok(response);
}else {
response.put("result", true);
response.put("message", "变更成功しました");
}
return ResponseEntity.ok(response);
}
@ -108,13 +123,30 @@ public class StocksController {
* @return レスポンス
*/
@DeleteMapping("/delete")
public ResponseEntity<Map<String, Object>> deleteStock(
public ResponseEntity<?> deleteStock(
Authentication authentication,
@Valid @RequestBody DeleteStockRequest request) {
stockService.deleteStock(authentication.getName(), request.getStockId());
@RequestBody DeleteStockRequestDTO request
) {
// 認証されたユーザー名を取得
String username = authentication.getName();
// ユーザー情報を取得
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
int deletedCount = stockService.deleteStockById(user.getId(), request.getStockId());
Map<String, Object> response = new HashMap<>();
response.put("result", true);
if (deletedCount > 0) {
response.put("result", true);
response.put("message", "削除成功しました");
} else {
response.put("result", false);
response.put("message", "指定された在庫が見つかりませんでした");
}
return ResponseEntity.ok(response);
}
}

@ -8,14 +8,13 @@
package com.example.todoapp.controller;
import com.example.todoapp.dto.BuyRequestDTO;
import com.example.todoapp.dto.DeleteToBuyRequest;
import com.example.todoapp.dto.ToBuyResponse;
import com.example.todoapp.dto.DeleteToBuyRequestDTO;
import com.example.todoapp.dto.ToBuyResponseDTO;
import com.example.todoapp.dto.ToBuysDTO;
import com.example.todoapp.model.Stuffs;
import com.example.todoapp.model.ToBuys;
import com.example.todoapp.model.User;
import com.example.todoapp.repository.UserRepository;
import com.example.todoapp.repository.StuffsRepository;
import com.example.todoapp.service.ToBuysService;
import jakarta.validation.Valid;
@ -23,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;
@ -62,7 +60,6 @@ public class ToBuysController {
ToBuys createdToBuy = toBuysService.addToBuys(dto, authentication);
// 构建响应体
Map<String, Object> response = new HashMap<>();
response.put("result", true);
response.put("tobuyId", createdToBuy.getTobuyId());
@ -72,6 +69,13 @@ public class ToBuysController {
return ResponseEntity.ok(response);
}
/**
* 指定されたIDの在庫を更新する
*
* @param authentication 認証情報
* @param dto 更新内容
* @return 更新された
*/
@PutMapping("/update")
public ResponseEntity<Map<String, Object>> updateToBuys(
@Valid @RequestBody ToBuysDTO dto,
@ -80,7 +84,6 @@ public class ToBuysController {
ToBuys updatedToBuy = toBuysService.updateToBuys(dto, authentication);
Map<String, Object> response = new HashMap<>();
response.put("tobuyId", updatedToBuy.getTobuyId());
response.put("stuffId", updatedToBuy.getStuff().getStuffId());
@ -109,9 +112,9 @@ public class ToBuysController {
List<ToBuys> toBuysList = toBuysService.getToBuysByUser(user);
// DTO形式に変換して返す
List<ToBuyResponse> responseList = toBuysList.stream()
List<ToBuyResponseDTO> responseList = toBuysList.stream()
.map(toBuy -> {
ToBuyResponse resp = new ToBuyResponse();
ToBuyResponseDTO resp = new ToBuyResponseDTO();
Stuffs stuff = toBuy.getStuff();
resp.setTobuyId(toBuy.getTobuyId());
resp.setStuffId(stuff.getStuffId());
@ -136,7 +139,7 @@ public class ToBuysController {
*/
@DeleteMapping("/delete")
public ResponseEntity<Map<String, Boolean>> deleteToBuy(
@RequestBody DeleteToBuyRequest request,
@RequestBody DeleteToBuyRequestDTO request,
Authentication authentication) {
int deletedCount = toBuysService.deleteToBuyById(request.getTobuyId());

@ -4,11 +4,42 @@ import java.time.LocalDate;
import lombok.Data;
/**
* 購入情報更新のデータ転送オブジェクトDTO
* <p>
* このクラスは既存の購入予定情報を更新するために使用されます
* 更新に必要な全情報を含みます
* </p>
*/
@Data
public class BuyRequestDTO {
/**
* 購入ID
* 更新対象の購入予定を識別します
*/
private Long tobuyId;
/**
* 価格
* 実際の購入金額を設定します
*/
private int price;
/**
* 消費期限
* 食材の消費期限を設定します
*/
private LocalDate expDate;
/**
* 最終更新日
* レコードの最終更新日時を保持します
*/
private LocalDate lastUpdate;
/**
* 購入日
* 食材の実際の購入日を設定します
*/
private LocalDate buyDate;
}

@ -0,0 +1,19 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* 在庫削除要求のデータ転送オブジェクトDTO
* <p>
* このクラスは在庫削除操作をサーバーに送信するために使用されます
* 削除対象を特定するための情報を含みます
* </p>
*/
@Data
public class DeleteStockRequestDTO {
/**
* 在庫ID
* 削除対象の在庫を識別するためのID
*/
private Long stockId;
}

@ -1,9 +0,0 @@
package com.example.todoapp.dto;
import lombok.Data;
@Data
public class DeleteToBuyRequest {
private Long userId;
private Long tobuyId;
}

@ -0,0 +1,25 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* 購入予定削除要求のデータ転送オブジェクトDTO
* <p>
* このクラスは購入予定情報の削除要求をサーバーに送信するために使用されます
* 削除対象を特定するための必要情報を含みます
* </p>
*/
@Data
public class DeleteToBuyRequestDTO {
/**
* ユーザーID
* 操作対象のユーザーを識別するためのID
*/
private Long userId;
/**
* 購入予定ID
* 削除対象の購入予定情報を識別するためのID
*/
private Long tobuyId;
}

@ -0,0 +1,39 @@
package com.example.todoapp.dto;
import java.util.List;
import lombok.Data;
/**
* レシピ詳細情報のデータ転送オブジェクトDTO
* <p>
* このクラスはレシピの詳細情報を伝送するために使用されます
* レシピ基本情報に加えて関連食材情報を含みます
* </p>
*/
@Data
public class RecipeDetailDTO {
/**
* レシピID
* ユニークなレシピを識別するためのID
*/
private Long recipeId;
/**
* レシピ名
* レシピの名称を表します
*/
private String recipeName;
/**
* 概要
* レシピの簡単な説明文
*/
private String summary;
/**
* 食材リスト
* このレシピに必要な食材とその数量のリスト
*/
private List<StuffDetailDTO> stuffs;
}

@ -0,0 +1,39 @@
package com.example.todoapp.dto;
import java.util.List;
import lombok.Data;
/**
* レシピ操作要求のデータ転送オブジェクトDTO
* <p>
* このクラスはレシピ操作要求をサーバーに送信するために使用されます
* 新規作成および更新時の情報を含みます
* </p>
*/
@Data
public class RecipeRequestDTO {
/**
* レシピID
* 新規作成時は未指定更新時は必須
*/
private Long recipeId;
/**
* レシピ名
* レシピの名称を表します
*/
private String recipeName;
/**
* 概要
* レシピの簡単な説明文
*/
private String summary;
/**
* 食材と数量リスト
* このレシピに必要な食材とその数量のリスト
*/
private List<StuffRequestDTO> stuffAndAmountArray;
}

@ -0,0 +1,31 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* レシピ情報のデータ転送オブジェクトDTO
* <p>
* このクラスはクライアントとサーバー間で基本的なレシピ情報をやり取りするために使用されます
* エンティティとは異なり必要な情報のみを含みます
* </p>
*/
@Data
public class RecipeResponseDTO {
/**
* レシピID
* ユニークなレシピを識別するためのID
*/
private Long recipeId;
/**
* レシピ名
* レシピの名称を表します
*/
private String recipeName;
/**
* 概要
* レシピの簡単な説明文
*/
private String summary;
}

@ -16,7 +16,7 @@ import java.time.LocalDate;
*/
@Data
public class ResponseStockDTO {
public class StockResponseDTO {
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 StockResponseDTO fromEntity(Stocks stock) {
StockResponseDTO dto = new StockResponseDTO();
Stuffs stuff = stock.getStuff();
dto.setStockId(stock.getStockId());

@ -0,0 +1,30 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* 食材詳細情報のデータ転送オブジェクトDTO
* <p>
* このクラスはレシピに含まれる個別食材情報を伝送するために使用されます
* 必要最小限の食材情報を含みます
* </p>
*/
@Data
public class StuffDetailDTO {
/**
* 食材ID
* ユニークな食材を識別するためのID
*/
private Long stuffId;
/**
* 食材名
* 食材の名称を表します
*/
private String stuffName;
/**
* 数量
* レシピに必要な食材の量
*/
private Integer amount;
}

@ -0,0 +1,36 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* 食材操作要求のデータ転送オブジェクトDTO
* <p>
* このクラスは食材操作要求をサーバーに送信するために使用されます
* 新規作成時の必須情報を含みます
* </p>
*/
@Data
public class StuffRequestDTO {
/**
* 食材ID
* 新規作成時は未指定
*/
private String stuffId;
/**
* 食材名
* 食材の名称を表します
*/
private String stuffName;
/**
* カテゴリ
* 食材の分類を示します
*/
private String category;
/**
* 数量
* 食材の保有量を示します
*/
private String amount;
}

@ -1,12 +0,0 @@
package com.example.todoapp.dto;
import lombok.Data;
@Data
public class ToBuyResponse {
private Long tobuyId;
private Long stuffId;
private String stuffName;
private int amount;
private String shop;
}

@ -0,0 +1,44 @@
package com.example.todoapp.dto;
import lombok.Data;
/**
* 購入予定情報のデータ転送オブジェクトDTO
* <p>
* このクラスは購入予定食材情報をクライアントとサーバー間でやり取りするために使用されます
* 必要な情報を含み関連エンティティへの参照ではなくIDのみを保持します
* </p>
*/
@Data
public class ToBuyResponseDTO {
/**
* 購入ID
* 購入予定を識別するためのID
*/
private Long tobuyId;
/**
* 食材ID
* 関連する食材のID
*/
private Long stuffId;
/**
* 食材名
* 購入予定の食材名称
*/
private String stuffName;
/**
* 数量
* 購入予定数量
*/
private int amount;
/**
* 購入先
* 購入を予定している店舗名
*/
private String shop;
}

@ -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;
}

@ -43,7 +43,7 @@ public class Recipes {
*/
@NotNull
@Column(name="recipeName", unique = true, length = 255, nullable = false)
private String recipieName;
private String recipeName;
/**
* カテゴリ

@ -54,20 +54,7 @@ public class Stocks {
)
private Stuffs stuff;
// /**
// * ユーザーテーブル参照用の外部キー
// */
// @NotNull
// @ManyToOne(fetch = FetchType.LAZY)
// @JoinColumn(
// name = "userId",
// referencedColumnName = "id",
// nullable = false
// )
// private User user;
/**
/**
* タスクの所有者ユーザー
* 多対一の関係で遅延ロードを使用
*/

@ -0,0 +1,14 @@
package com.example.todoapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.todoapp.model.Recipes;
/**
* レシピエンティティのリポジトリインターフェース
* <p>
* このインターフェースはレシピデータへのアクセスと操作を提供します
* Spring Data JPAによって自動的に実装されます
* </p>
*/
public interface RecipesRepository extends JpaRepository<Recipes, Long> {}

@ -0,0 +1,37 @@
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;
/**
* レシピ食材関連データのリポジトリインターフェース
* <p>
* このインターフェースはレシピと食材の関連データへのアクセスを提供します
* Spring Data JPAによって自動的に実装されます
* </p>
*/
public interface RecipesStuffsRepository extends JpaRepository<RecipeStuffs, Long> {
/**
* レシピIDで食材情報を検索する
*
* @param recipeId 検索するレシピID
* @return 関連する食材情報リスト
*/
List<RecipeStuffs> findByRecipesRecipeId(Long recipeId);
/**
* レシピIDと食材IDで関連情報を検索する
*
* @param recipeId 検索するレシピID
* @param stuffId 検索する食材ID
* @return 関連情報存在する場合
*/
Optional<RecipeStuffs> findByRecipesRecipeIdAndStuffStuffId(Long recipeId, Long stuffId);
}

@ -58,5 +58,10 @@ public interface StocksRepository extends JpaRepository<Stocks, Long> {
* @param stockId 削除する在庫
* @param userId 削除するユーザー
*/
void deleteStocksByStockIdAndUserId(Long stockId, Long userId);
// void deleteStocksByStockIdAndUserId(Long stockId, Long userId);
@Modifying
@Transactional
@Query("DELETE FROM Stocks t WHERE t.user.id = :userId AND t.stockId = :stockId")
int deleteByUserIdAndStockId(@Param("userId") Long userId, @Param("stockId") Long stockId);
}

@ -0,0 +1,210 @@
//--------------------------------
// 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.RecipesStuffsRepository;
import com.example.todoapp.repository.RecipesRepository;
import com.example.todoapp.repository.StuffsRepository;
import jakarta.transaction.Transactional;
/**
* レシピ管理サービスクラス
* <p>
* このクラスはレシピの登録処理を提供します
* 材料の存在確認新規作成数量管理などの機能を含みます
* </p>
*/
@Service
public class RecipeService {
@Autowired
private RecipesRepository recipesRepository;
@Autowired
private StuffsRepository stuffsRepository;
@Autowired
private RecipesStuffsRepository 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<RecipeStuffs> 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;
}
/**
* すべてのレシピ情報を取得する
*
* @return 登録済みレシピ情報リスト
*/
public List<Recipes> getAllRecipes() {
return recipesRepository.findAll();
}
/**
* 指定されたIDのレシピ詳細情報を取得する
*
* @param recipeId 検索するレシピID
* @return レシピ詳細情報レシピ基本情報と関連食材情報
* @throws RuntimeException レシピが見つからない場合
*/
public RecipeDetailDTO getRecipeDetailsById(Long recipeId) {
Recipes recipe = recipesRepository.findById(recipeId)
.orElseThrow(() -> new RuntimeException("レシピが見つかりません"));
List<RecipeStuffs> recipeStuffsList = recipeStuffsRepository.findByRecipesRecipeId(recipeId);
List<StuffDetailDTO> 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;
}
/**
* レシピ情報を更新する
*
* @param dto 更新するレシピ詳細情報
* @return 更新されたレシピエンティティ
* @throws RuntimeException レシピまたは材料情報が見つからない場合
*/
@Transactional
public Recipes updateRecipe(RecipeDetailDTO dto) {
// IDでレシピを検索し、見つからない場合は例外をスロー
Recipes recipe = recipesRepository.findById(dto.getRecipeId())
.orElseThrow(() -> new RuntimeException("レシピが見つかりません"));
// レシピ名と概要を更新
recipe.setRecipeName(dto.getRecipeName());
recipe.setSummary(dto.getSummary());
recipesRepository.save(recipe);
Set<Long> incomingStuffIds = new HashSet<>();
// 提供された材料の詳細を繰り返し処理
for (StuffDetailDTO stuffDTO : dto.getStuffs()) {
if (stuffDTO.getStuffId() == null) {
// 材料IDがnullの場合、新しい材料を作成
Stuffs newStuff = new Stuffs();
newStuff.setStuffName(stuffDTO.getStuffName());
newStuff.setCategory("その他");
newStuff = stuffsRepository.save(newStuff);
// 新しいRecipeStuffsエントリを作成
RecipeStuffs rs = new RecipeStuffs();
rs.setRecipes(recipe);
rs.setStuff(newStuff);
rs.setAmount(stuffDTO.getAmount());
recipeStuffsRepository.save(rs);
incomingStuffIds.add(newStuff.getStuffId());
} else {
// 材料IDが提供されている場合、既存のRecipeStuffsエントリを検索
Optional<RecipeStuffs> optionalRs = recipeStuffsRepository
.findByRecipesRecipeIdAndStuffStuffId(dto.getRecipeId(), stuffDTO.getStuffId());
if (optionalRs.isPresent()) {
// RecipeStuffsエントリが存在する場合、数量を更新
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());
}
}
}
// 入ってきたリストにないRecipeStuffsエントリを削除
List<RecipeStuffs> existingStuffs = recipeStuffsRepository.findByRecipesRecipeId(dto.getRecipeId());
for (RecipeStuffs rs : existingStuffs) {
if (!incomingStuffIds.contains(rs.getStuff().getStuffId())) {
recipeStuffsRepository.delete(rs);
}
}
return recipe;
}
}

@ -89,12 +89,11 @@ public class StocksService {
/**
* 指定された在庫を削除する
*
* @param username ユーザー名
* @param taskId 削除する在庫のID
* @param userId ユーザー名
* @param stockId 削除する在庫のID
*/
public void deleteStock(String username, Long stockId) {
Stocks stock = getStockById(username, stockId);
stocksRepository.delete(stock);
public int deleteStockById(Long userId, Long stockId) {
return stocksRepository.deleteByUserIdAndStockId(userId, stockId);
}

Loading…
Cancel
Save