change some logic to the repositories
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Category
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Category;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class CategoryRepository : ICategoryRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
|
||||
public CategoryRepository(FrancescosRecipesWorldDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Category> GetCategoryByIdAsync(Guid categoryId)
|
||||
{
|
||||
var category = await _context.Categories.FindAsync(categoryId);
|
||||
return category ?? throw new InvalidDataException($"Category {categoryId} not found.");
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Category>> GetAllCategoriesAsync()
|
||||
{
|
||||
return await _context.Categories.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Recipe>> GetRecipesByCategoryAsync(Guid categoryId)
|
||||
{
|
||||
var category = await _context.Categories
|
||||
.Include(c => c.Recipes)
|
||||
.FirstOrDefaultAsync(c => c.Id == categoryId);
|
||||
|
||||
if (category == null)
|
||||
{
|
||||
throw new InvalidDataException($"Category {categoryId} not found.");
|
||||
}
|
||||
|
||||
return category.Recipes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Category
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Category;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
|
||||
public interface ICategoryRepository
|
||||
{
|
||||
Task<Category> GetCategoryByIdAsync(Guid categoryId);
|
||||
|
||||
Task<IEnumerable<Category>> GetAllCategoriesAsync();
|
||||
|
||||
Task<IEnumerable<Recipe>> GetRecipesByCategoryAsync(Guid categoryId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Ingredient
|
||||
{
|
||||
using Francesco.Recipes.World.Models.BackendModels.Ingredient;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.RecipeIngredient;
|
||||
|
||||
public interface IIngredientRepository
|
||||
{
|
||||
Task<Ingredient> CreateIngredientToRecipeAsync(Recipe recipe, string ingredientName);
|
||||
|
||||
Task UpdateIngredientAsync(Ingredient ingredient);
|
||||
|
||||
Task<List<RecipeIngredient>> GetIngredientsByRecipeIdAsync(Guid recipeId);
|
||||
|
||||
Task<List<Ingredient>> GetIngredientsByNameAsync(string name);
|
||||
|
||||
Task RemoveIngredientFromRecipeAsync(Recipe recipe, Guid ingredientId);
|
||||
|
||||
Task<Ingredient> GetIngredientByIdAsync(Guid ingredientId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Ingredient
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Ingredient;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.RecipeIngredient;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class IngredientRepository : IIngredientRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
|
||||
public IngredientRepository(
|
||||
FrancescosRecipesWorldDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Ingredient> CreateIngredientToRecipeAsync(Recipe recipe, string ingredientName)
|
||||
{
|
||||
if (recipe is null)
|
||||
{
|
||||
throw new ArgumentException("Recipe not found", nameof(recipe));
|
||||
}
|
||||
|
||||
var newIngredient = new Ingredient
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = ingredientName,
|
||||
};
|
||||
|
||||
var recipeIngredient = new RecipeIngredient
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Recipe = recipe,
|
||||
Ingredient = newIngredient,
|
||||
Quantity = 1,
|
||||
};
|
||||
|
||||
_context.Ingredients.Add(newIngredient);
|
||||
_context.RecipeIngredients.Add(recipeIngredient);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return newIngredient;
|
||||
}
|
||||
|
||||
public async Task RemoveIngredientFromRecipeAsync(Recipe recipe, Guid ingredientId)
|
||||
{
|
||||
if (recipe == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(recipe));
|
||||
}
|
||||
|
||||
var ingredientToRemove = recipe.RecipeIngredients.FirstOrDefault(i => i.Id == ingredientId);
|
||||
|
||||
if (ingredientToRemove != null)
|
||||
{
|
||||
recipe.RecipeIngredients.Remove(ingredientToRemove);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Ingredient>> GetIngredientsByNameAsync(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return await _context.Ingredients.ToListAsync();
|
||||
}
|
||||
|
||||
return await _context.Ingredients
|
||||
.Where(i => i.Name.ToLower().Contains(name.ToLower()))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<List<RecipeIngredient>> GetIngredientsByRecipeIdAsync(Guid recipeId)
|
||||
{
|
||||
return await _context.RecipeIngredients
|
||||
.Include(ri => ri.Ingredient)
|
||||
.Include(ri => ri.Unit)
|
||||
.Where(ri => ri.Recipe.Id == recipeId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateIngredientAsync(Ingredient ingredient)
|
||||
{
|
||||
if (ingredient == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ingredient));
|
||||
}
|
||||
|
||||
var existingIngredient = await _context.Ingredients.FindAsync(ingredient.Id);
|
||||
if (existingIngredient == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Ingredient with ID {ingredient.Id} not found.");
|
||||
}
|
||||
|
||||
existingIngredient.Name = ingredient.Name;
|
||||
|
||||
_context.Ingredients.Update(existingIngredient);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<Ingredient> GetIngredientByIdAsync(Guid ingredientId)
|
||||
{
|
||||
var ingredient = await _context.Ingredients.FindAsync(ingredientId);
|
||||
return ingredient ?? throw new InvalidDataException($"Address {ingredientId} not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Instruction
|
||||
{
|
||||
using Francesco.Recipes.World.Models.BackendModels.Instruction;
|
||||
|
||||
public interface IInstructionRepository
|
||||
{
|
||||
Task<Instruction> GetInstructionAsync(Guid instructionId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Instruction
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Instruction;
|
||||
|
||||
public class InstructionRepository : IInstructionRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
|
||||
public InstructionRepository(FrancescosRecipesWorldDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Instruction> GetInstructionAsync(Guid instructionId)
|
||||
{
|
||||
var instruction = await _context.Instructions.FindAsync(instructionId);
|
||||
return instruction ?? throw new InvalidDataException($"Instruction {instructionId} not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Francesco.Recipes.World.Repositories.MediaFile
|
||||
{
|
||||
public interface IMediaFileRepository
|
||||
{
|
||||
Task ReplaceInstructionImageAsync(Guid instructionId, IFormFile? newPhoto);
|
||||
|
||||
Task UploadInstructionImageAsync(Guid instructionId, IFormFile? photo);
|
||||
|
||||
Task ReplaceRecipeImageAsync(Guid recipeId, IFormFile? newPhoto);
|
||||
|
||||
Task UploadRecipeImageAsync(Guid recipeId, IFormFile? photo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
namespace Francesco.Recipes.World.Repositories.MediaFile
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.MediaFile;
|
||||
using Francesco.Recipes.World.Repositories.Instruction;
|
||||
using Francesco.Recipes.World.Repositories.Recipe;
|
||||
|
||||
public class MediaFileRepository : IMediaFileRepository
|
||||
{
|
||||
private readonly IInstructionRepository _instructionRepository;
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
private readonly IRecipeRepository _recipeRepository;
|
||||
|
||||
public MediaFileRepository(IInstructionRepository instructionRepository, FrancescosRecipesWorldDbContext context, IRecipeRepository recipeRepository)
|
||||
{
|
||||
_instructionRepository = instructionRepository;
|
||||
_context = context;
|
||||
_recipeRepository = recipeRepository;
|
||||
}
|
||||
|
||||
public async Task ReplaceInstructionImageAsync(Guid instructionId, IFormFile? newPhoto)
|
||||
{
|
||||
if (newPhoto is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(newPhoto));
|
||||
}
|
||||
|
||||
var instruction = await _instructionRepository.GetInstructionAsync(instructionId);
|
||||
_context.RemoveRange(instruction.MediaFiles);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
await UploadInstructionImageAsync(instructionId, newPhoto);
|
||||
}
|
||||
|
||||
public async Task ReplaceRecipeImageAsync(Guid recipeId, IFormFile? newPhoto)
|
||||
{
|
||||
if (newPhoto is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(newPhoto));
|
||||
}
|
||||
|
||||
var recipe = await _recipeRepository.GetRecipeAsync(recipeId);
|
||||
_context.RemoveRange(recipe.MediaFiles);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
await UploadInstructionImageAsync(recipeId, newPhoto);
|
||||
}
|
||||
|
||||
public async Task UploadInstructionImageAsync(Guid instructionId, IFormFile? photo)
|
||||
{
|
||||
if (photo is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(photo));
|
||||
}
|
||||
|
||||
var instruction = await _instructionRepository.GetInstructionAsync(instructionId);
|
||||
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await photo.CopyToAsync(memoryStream);
|
||||
|
||||
var instructionImage = new MediaFile
|
||||
{
|
||||
FileName = photo.FileName,
|
||||
MimeType = photo.ContentType,
|
||||
Data = memoryStream.ToArray(),
|
||||
Instruction = instruction,
|
||||
};
|
||||
|
||||
_context.Add(instructionImage);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UploadRecipeImageAsync(Guid recipeId, IFormFile? photo)
|
||||
{
|
||||
if (photo is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(photo));
|
||||
}
|
||||
|
||||
var recipe = await _recipeRepository.GetRecipeAsync(recipeId);
|
||||
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await photo.CopyToAsync(memoryStream);
|
||||
|
||||
var recipeImage = new MediaFile
|
||||
{
|
||||
FileName = photo.FileName,
|
||||
MimeType = photo.ContentType,
|
||||
Data = memoryStream.ToArray(),
|
||||
Recipe = recipe,
|
||||
};
|
||||
|
||||
_context.Add(recipeImage);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Recipe
|
||||
{
|
||||
using Francesco.Recipes.World.Models.BackendModels.Category;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Unit;
|
||||
|
||||
public interface IRecipeRepository
|
||||
{
|
||||
Task<Recipe> GetRecipeAsync(Guid recipeId);
|
||||
|
||||
Task AddOrCreateIngredientToRecipeAsync(Guid recipeId, string ingredientName, int quantity, Guid unitId);
|
||||
|
||||
Task RemoveIngredientFromRecipeAsync(Guid recipeId, Guid ingredientId);
|
||||
|
||||
Task<IEnumerable<Recipe>> GetRecipesByNameOrIngredientAsync(string name, string ingredient);
|
||||
|
||||
Task<IEnumerable<Recipe>> GetRecipesByDifficultyAsync(Difficulty difficulty);
|
||||
|
||||
Task<Unit> AddUnitToRecipeAsync(string name, string symbol);
|
||||
|
||||
Task<Recipe> CreateRecipeForCategoryAsync(Category category, string name, string description, Difficulty difficulty, int servings, TimeSpan preparationTime, TimeSpan cookingTime);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Recipe
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Category;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Ingredient;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.RecipeIngredient;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Unit;
|
||||
using Francesco.Recipes.World.Repositories.Ingredient;
|
||||
using Francesco.Recipes.World.Repositories.Unit;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class RecipeRepository : IRecipeRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
private readonly IIngredientRepository _ingredientRepository;
|
||||
private readonly IUnitRepository _unitRepository;
|
||||
|
||||
public RecipeRepository(
|
||||
FrancescosRecipesWorldDbContext context, IIngredientRepository ingredientRepository, IUnitRepository unitRepository)
|
||||
{
|
||||
_context = context;
|
||||
_ingredientRepository = ingredientRepository;
|
||||
_unitRepository = unitRepository;
|
||||
}
|
||||
|
||||
public async Task<Recipe> GetRecipeAsync(Guid recipeId)
|
||||
{
|
||||
var recipe = await _context.Recipes.FindAsync(recipeId);
|
||||
return recipe ?? throw new InvalidDataException($"Address {recipeId} not found.");
|
||||
}
|
||||
|
||||
public async Task AddOrCreateIngredientToRecipeAsync(Guid recipeId, string ingredientName, int quantity, Guid unitId)
|
||||
{
|
||||
var recipe = await GetRecipeAsync(recipeId);
|
||||
var unit = await _unitRepository.GetUnitByIdAsync(unitId);
|
||||
|
||||
if (quantity <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(quantity), "Die Menge muss größer als 0 sein.");
|
||||
}
|
||||
|
||||
var ingredients = await _ingredientRepository.GetIngredientsByNameAsync(ingredientName);
|
||||
Ingredient ingredient;
|
||||
|
||||
if (ingredients == null || !ingredients.Any())
|
||||
{
|
||||
ingredient = new Ingredient
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = ingredientName,
|
||||
};
|
||||
_context.Ingredients.Add(ingredient);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
ingredient = ingredients.First();
|
||||
}
|
||||
|
||||
var existingEntry = await _context.RecipeIngredients
|
||||
.FirstOrDefaultAsync(ri => ri.Recipe.Id == recipeId && ri.Ingredient.Id == ingredient.Id);
|
||||
if (existingEntry != null)
|
||||
{
|
||||
throw new InvalidOperationException("Das Rezept enthält diese Zutat bereits.");
|
||||
}
|
||||
|
||||
var recipeIngredient = new RecipeIngredient
|
||||
{
|
||||
Recipe = recipe,
|
||||
Ingredient = ingredient,
|
||||
Unit = unit,
|
||||
Quantity = quantity,
|
||||
};
|
||||
_context.Add(recipeIngredient);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<Recipe> CreateRecipeForCategoryAsync(
|
||||
Category category,
|
||||
string name,
|
||||
string description,
|
||||
Difficulty difficulty,
|
||||
int servings,
|
||||
TimeSpan preparationTime,
|
||||
TimeSpan cookingTime)
|
||||
{
|
||||
if (category == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(category), "Category cannot be null.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name), "Name cannot be empty.");
|
||||
}
|
||||
|
||||
if (servings <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(servings), "Servings must be greater than 0.");
|
||||
}
|
||||
|
||||
var recipe = new Recipe
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = name,
|
||||
Description = description,
|
||||
Difficulty = difficulty,
|
||||
Servings = servings,
|
||||
PreparationTime = preparationTime,
|
||||
CookingTime = cookingTime,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
Category = category,
|
||||
};
|
||||
|
||||
_context.Recipes.Add(recipe);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return recipe;
|
||||
}
|
||||
|
||||
public async Task RemoveIngredientFromRecipeAsync(Guid recipeId, Guid ingredientId)
|
||||
{
|
||||
var recipe = await GetRecipeAsync(recipeId);
|
||||
var recipeIngredient = await _context.RecipeIngredients
|
||||
.FirstOrDefaultAsync(ri => ri.Recipe.Id == recipeId && ri.Ingredient.Id == ingredientId);
|
||||
|
||||
if (recipeIngredient == null)
|
||||
{
|
||||
throw new ArgumentException("Diese Zutat ist nicht mit dem Rezept verknüpft.");
|
||||
}
|
||||
|
||||
_context.RecipeIngredients.Remove(recipeIngredient);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Recipe>> GetRecipesByNameOrIngredientAsync(string name, string ingredient)
|
||||
{
|
||||
var query = _context.Recipes
|
||||
.Include(r => r.RecipeIngredients)
|
||||
.ThenInclude(ri => ri.Ingredient)
|
||||
.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
query = query.Where(r => r.Name.Contains(name, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ingredient))
|
||||
{
|
||||
var ingredientMatches = await _ingredientRepository.GetIngredientsByNameAsync(ingredient);
|
||||
var ingredientIds = ingredientMatches.Select(i => i.Id).ToList();
|
||||
|
||||
if (ingredientIds.Any())
|
||||
{
|
||||
query = query.Where(r => r.RecipeIngredients.Any(ri => ingredientIds.Contains(ri.Ingredient.Id)));
|
||||
}
|
||||
}
|
||||
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Recipe>> GetRecipesByDifficultyAsync(Difficulty difficulty)
|
||||
{
|
||||
return await _context.Recipes
|
||||
.Where(r => r.Difficulty == difficulty)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Unit> AddUnitToRecipeAsync(string name, string symbol)
|
||||
{
|
||||
return await _unitRepository.AddUnitAsync(name, symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace Francesco.Recipes.World.Repositories.ShoppingList
|
||||
{
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Shoppinglist;
|
||||
|
||||
public interface IShoppingListRepository
|
||||
{
|
||||
Task AddIngredientToShoppingListAsync(Guid recipeIngredientId, Guid shoppingListId);
|
||||
|
||||
Task RemoveRecipeIngredientFromShoppingListAsync(Guid recipeIngredientId);
|
||||
|
||||
Task RemoveRecipeFromShoppingListIfEmptyAsync(Guid recipeId, Guid shoppingListId);
|
||||
|
||||
Task<IEnumerable<ShoppingList>> GetShoppingListsByIngredientOfRecipeAsync(Guid ingredientId, Guid recipeId);
|
||||
|
||||
Task<Recipe?> GetRecipeByNameAndImageAsync(string recipeName, string imageFileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
namespace Francesco.Recipes.World.Repositories.ShoppingList
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.IngredientShoppingList;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Recipe;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Shoppinglist;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class ShoppingListRepository : IShoppingListRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
|
||||
public ShoppingListRepository(FrancescosRecipesWorldDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task AddIngredientToShoppingListAsync(Guid recipeIngredientId, Guid shoppingListId)
|
||||
{
|
||||
var existingEntry = await _context.RecipeIngredientsShoppingLists
|
||||
.FirstOrDefaultAsync(risl => risl.RecipeIngredient.Id == recipeIngredientId && risl.ShoppingList.Id == shoppingListId);
|
||||
|
||||
if (existingEntry != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var recipeIngredient = await _context.RecipeIngredients
|
||||
.FirstOrDefaultAsync(ri => ri.Id == recipeIngredientId);
|
||||
|
||||
if (recipeIngredient == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Recipe ingredient with ID {recipeIngredientId} not found.");
|
||||
}
|
||||
|
||||
var shoppingList = await _context.ShoppingLists
|
||||
.FirstOrDefaultAsync(sl => sl.Id == shoppingListId);
|
||||
|
||||
if (shoppingList == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Shopping list with ID {shoppingListId} not found.");
|
||||
}
|
||||
|
||||
var newEntry = new RecipeIngredientShoppingList
|
||||
{
|
||||
RecipeIngredient = recipeIngredient,
|
||||
ShoppingList = shoppingList,
|
||||
};
|
||||
|
||||
_context.RecipeIngredientsShoppingLists.Add(newEntry);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task RemoveRecipeIngredientFromShoppingListAsync(Guid recipeIngredientId)
|
||||
{
|
||||
var entry = await _context.RecipeIngredientsShoppingLists
|
||||
.FirstOrDefaultAsync(risl => risl.RecipeIngredient.Id == recipeIngredientId);
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
_context.RecipeIngredientsShoppingLists.Remove(entry);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RemoveRecipeFromShoppingListIfEmptyAsync(Guid recipeId, Guid shoppingListId)
|
||||
{
|
||||
var hasIngredients = await _context.RecipeIngredientsShoppingLists
|
||||
.AnyAsync(risl => risl.RecipeIngredient.Recipe.Id == recipeId && risl.ShoppingList.Id == shoppingListId);
|
||||
|
||||
if (!hasIngredients)
|
||||
{
|
||||
var shoppingList = await _context.ShoppingLists
|
||||
.Include(sl => sl.RecipeIngredientShoppingLists)
|
||||
.FirstOrDefaultAsync(sl => sl.Id == shoppingListId);
|
||||
|
||||
if (shoppingList != null)
|
||||
{
|
||||
var recipeToRemove = shoppingList.RecipeIngredientShoppingLists
|
||||
.FirstOrDefault(risl => risl.RecipeIngredient.Recipe.Id == recipeId);
|
||||
|
||||
if (recipeToRemove != null)
|
||||
{
|
||||
_context.RecipeIngredientsShoppingLists.Remove(recipeToRemove);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ShoppingList>> GetShoppingListsByIngredientOfRecipeAsync(Guid ingredientId, Guid recipeId)
|
||||
{
|
||||
return await _context.ShoppingLists
|
||||
.Where(sl => sl.RecipeIngredientShoppingLists.Any(risl => risl.RecipeIngredient.Ingredient.Id == ingredientId && risl.RecipeIngredient.Recipe.Id == recipeId))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Recipe?> GetRecipeByNameAndImageAsync(string recipeName, string imageFileName)
|
||||
{
|
||||
return await _context.Recipes
|
||||
.Where(r => r.Name == recipeName && r.MediaFiles.Any(mf => mf.FileName == imageFileName))
|
||||
.Include(r => r.MediaFiles.Where(mf => mf.FileName == imageFileName))
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Unit
|
||||
{
|
||||
using Francesco.Recipes.World.Models.BackendModels.Unit;
|
||||
|
||||
public interface IUnitRepository
|
||||
{
|
||||
Task<Unit> GetUnitByIdAsync(Guid unitId);
|
||||
|
||||
Task<Unit> AddUnitAsync(string name, string symbol);
|
||||
|
||||
Task<IEnumerable<Unit>> GetAllUnitsAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace Francesco.Recipes.World.Repositories.Unit
|
||||
{
|
||||
using Francesco.Recipes.World.Data;
|
||||
using Francesco.Recipes.World.Models.BackendModels.Unit;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class UnitRepository : IUnitRepository
|
||||
{
|
||||
private readonly FrancescosRecipesWorldDbContext _context;
|
||||
|
||||
public UnitRepository(
|
||||
FrancescosRecipesWorldDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Unit> GetUnitByIdAsync(Guid unitId)
|
||||
{
|
||||
var unit = await _context.Units.FindAsync(unitId);
|
||||
return unit ?? throw new InvalidDataException($"Address {unitId} not found.");
|
||||
}
|
||||
|
||||
public async Task<Unit> AddUnitAsync(string name, string symbol)
|
||||
{
|
||||
var unit = new Unit
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = name,
|
||||
Symbol = symbol,
|
||||
};
|
||||
|
||||
_context.Units.Add(unit);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Unit>> GetAllUnitsAsync()
|
||||
{
|
||||
return await _context.Units.ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user