Merge branch 'develop-backend' into develop

feature-backend-stock-service^2
Masaharu.Kato 4 months ago
commit 97b8e8883f
  1. 12
      backend/src/main/java/com/example/todoapp/controller/RecipesController.java
  2. 6
      backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java
  3. 11
      backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java
  4. 31
      backend/src/main/java/com/example/todoapp/service/RecipeService.java
  5. 22
      backend/src/main/java/com/example/todoapp/service/ToBuysService.java
  6. 7
      frontend/src/services/api.ts
  7. 3
      frontend/src/types/types.ts

@ -8,6 +8,7 @@ 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.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -18,6 +19,8 @@ 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.model.User;
import com.example.todoapp.repository.UserRepository;
import com.example.todoapp.service.RecipeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@ -36,6 +39,9 @@ public class RecipesController {
@Autowired
private RecipeService recipeService;
@Autowired
private UserRepository userRepository;
/**
* 新しいレシピを作成する
*
@ -62,7 +68,12 @@ public class RecipesController {
*/
@GetMapping("/getAll")
public ResponseEntity<List<RecipeResponseDTO>> getRecipe(Authentication authentication) {
User user = userRepository.findByUsername(authentication.getName())
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
List<Recipes> recipes = recipeService.getAllRecipes();
// エンティティからDTOへの変換
List<RecipeResponseDTO> responseList = recipes.stream()
.map(recipe -> {
@ -70,6 +81,7 @@ public class RecipesController {
dto.setRecipeId(recipe.getRecipeId());
dto.setRecipeName(recipe.getRecipeName());
dto.setSummary(recipe.getSummary());
dto.setMaxServings(recipeService.getRecipeMaxServings(user.getId(), recipe));
return dto;
})
.collect(Collectors.toList());

@ -28,4 +28,10 @@ public class RecipeResponseDTO {
* レシピの簡単な説明文
*/
private String summary;
/**
* 最大調理可能数
* そのレシピを何人分調理可能か
*/
private int maxServings;
}

@ -47,6 +47,17 @@ public interface ToBuysRepository extends JpaRepository<ToBuys, Integer> {
*/
@Query("SELECT t FROM ToBuys t WHERE t.user.id = :userId ORDER BY t.tobuyId ASC")
List<ToBuys> findByUserIdOrderByTobuyIdAsc(@Param("userId") Long userId);
/**
* 指定された買うものIDに基づいて買うものでの数量を更新
*
* @param tobuyId 買うものID
* @param amount 買うもの数量
* @return 更新された行数
*/
@Modifying
@Query("UPDATE ToBuys t SET t.amount = :amount WHERE t.tobuyId = :tobuyId")
int updateAmountByTobuyId(Long tobuyId, int amount);
/**
* 指定された買うものIDに基づいて買うものリストを削除

@ -49,6 +49,9 @@ public class RecipeService {
@Autowired
private RecipeStuffsRepository recipeStuffsRepository;
@Autowired
private StocksService stockService;
/**
* レシピを新規登録する
*
@ -102,6 +105,34 @@ public class RecipeService {
return recipesRepository.findAll();
}
/**
* レシピを指定して現在の在庫を参照しそのレシピが最大何人分作れるか返す
*
* @param userId ユーザーID
* @param recipe レシピのエンティティ
* @throws RuntimeException レシピが材料を持たないなど計算に失敗したとき
* @return 最大何人分作れるか
*/
public int getRecipeMaxServings(Long userId, Recipes recipe) {
List<RecipeStuffs> recipeStuffs = recipeStuffsRepository.findByRecipesRecipeId(recipe.getRecipeId());
// 各材料がその料理のレシピで何人分在庫があるか計算し,それらの最小値が料理全体での人数になる
Integer minNServings = null;
for (RecipeStuffs recipeStuff : recipeStuffs) {
int stockAmount = stockService.calcAmountByStuffId(userId, recipeStuff.getStuff().getStuffId());
int nServings = stockAmount / recipeStuff.getAmount(); // 小数点以下切り捨て(整数除算)
if (minNServings == null || minNServings > nServings) {
minNServings = nServings;
}
}
// recipeStuffs が空の場合などに null のままになる(通常は起こりえない)
if (minNServings == null) throw new RuntimeException("Failed to calculate recipeMaxServings");
return minNServings;
}
/**
* 指定されたIDのレシピ詳細情報を取得する
*

@ -174,6 +174,16 @@ public class ToBuysService {
return toBuysRepository.findByUserIdOrderByTobuyIdAsc(user.getId());
}
/**
* 指定された購入リストIDに基づいて数量を変更する
*
* @param tobuyId 購入リストID
*/
@Transactional
public int updateToBuysAmountByTobuyId(Long tobuyId, int amount) {
return toBuysRepository.updateAmountByTobuyId(tobuyId, amount);
}
/**
* 指定された購入リストIDに基づいて買うものを削除する
*
@ -210,9 +220,17 @@ public class ToBuysService {
stock.setBuyDate(dto.getBuyDate());
stock.setExpDate(dto.getExpDate());
// 買うものリストから削除
// まだ買うべき数量を計算
int remainAmount = Math.max(tobuy.getAmount() - dto.getAmount(), 0);
System.out.println("remainAmount=" + remainAmount);
// 買うものリストから削除または数量変更
System.out.println("tobuy.getTobuyId()=" + tobuy.getTobuyId());
deleteToBuysByTobuyId(tobuy.getTobuyId());
if (remainAmount > 0) {
updateToBuysAmountByTobuyId(tobuy.getTobuyId(), remainAmount);
} else {
deleteToBuysByTobuyId(tobuy.getTobuyId());
}
// データベースに保存
return stocksRepository.save(stock);

@ -456,7 +456,12 @@ export const recipeApi = {
errorData?.message
);
}
return response.json();
// デバッグ用に表示
const recipes = response.json();
console.log('recipes: ', recipes);
return recipes;
},
/**

@ -142,7 +142,8 @@ export interface Recipe {
}
export interface RecipeWithId extends Recipe {
recipeId: number;
recipeId: number; // レシピID
maxServings: number; // 最大調理可能数
}
/**

Loading…
Cancel
Save