using Newtonsoft.Json; using System.Reflection; using Brizco.Domain; namespace Brizco.Core.EntityServices; public class BrewService : IBrewService { private readonly IMartenRepositoryWrapper _martenRepositoryWrapper; private readonly ICurrentUserService _currentUserService; public BrewService(IMartenRepositoryWrapper martenRepositoryWrapper,ICurrentUserService currentUserService) { _martenRepositoryWrapper = martenRepositoryWrapper; _currentUserService = currentUserService; } public async Task GetLastBrewAsync(string recipeName, CancellationToken cancellationToken = default) { var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); if (type == null) throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); if (_currentUserService.ComplexId == null) throw new BaseApiException(ApiResultStatusCode.BadRequest,"Complex id is null"); if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); var baseRecipe = await _martenRepositoryWrapper.SetRepository() .GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken); object? recipe; if (baseRecipe == null) recipe = Activator.CreateInstance(type); else recipe = JsonConvert.DeserializeObject(baseRecipe.CurrentBrewJson, type) ?? Activator.CreateInstance(type); if (recipe == null) throw new AppException("Recipe type or base is wrong"); return recipe; } public async Task GetBrewAsync(string recipeName, CancellationToken cancellationToken = default) { var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); if (type == null) throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); if (_currentUserService.ComplexId == null) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is null"); if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); var baseRecipe = await _martenRepositoryWrapper.SetRepository() .GetEntityAsync(s =>s.ComplexId==complexId && s.Name == recipeName, cancellationToken); object? recipe; if (baseRecipe == null) { recipe = Activator.CreateInstance(type); baseRecipe = new BaseBrew(); } else recipe = JsonConvert.DeserializeObject(baseRecipe.CurrentBrewJson, type) ?? Activator.CreateInstance(type); if (recipe == null) throw new AppException("Recipe type or base is wrong"); var pastRecipes = new List(); foreach (var json in baseRecipe.PastBrewsJson) { var pastRecipe = JsonConvert.DeserializeObject(json, type) ?? Activator.CreateInstance(type); if (pastRecipe != null) pastRecipes.Add(pastRecipe); } var dto = new BaseRecipeLDto { CurrentRecipe = recipe, Name = recipeName, PastRecipes = pastRecipes }; return dto; } public async Task AddBrewAsync(string recipeName, JsonDocument recipeObj, CancellationToken cancellationToken = default) { var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); if (type == null) throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); if (_currentUserService.ComplexId == null) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is null"); if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); var baseRecipe = await _martenRepositoryWrapper.SetRepository() .GetEntityAsync(s =>s.ComplexId == complexId && s.Name == recipeName, cancellationToken); if (baseRecipe == null) { baseRecipe = new BaseBrew() { CurrentBrewJson = JsonConvert.SerializeObject(recipeObj.Deserialize(type)), Name = recipeName, DotnetType = type.FullName ?? $"Brizco.Domain.MartenEntities.Recipes.{recipeName}", ComplexId = complexId }; } else { baseRecipe.PastBrewsJson.Add(baseRecipe.CurrentBrewJson); baseRecipe.CurrentBrewJson = JsonConvert.SerializeObject(recipeObj.Deserialize(type)); } await _martenRepositoryWrapper.SetRepository() .AddOrUpdateEntityAsync(baseRecipe, cancellationToken); } }