diff --git a/ShoppingAssistantApi.Application/Exceptions/UnAuthorizedException.cs b/ShoppingAssistantApi.Application/Exceptions/UnAuthorizedException.cs new file mode 100644 index 0000000..da8a0fa --- /dev/null +++ b/ShoppingAssistantApi.Application/Exceptions/UnAuthorizedException.cs @@ -0,0 +1,11 @@ +using MongoDB.Bson; +using ShoppingAssistantApi.Domain.Common; + +namespace ShoppingAssistantApi.Application.Exceptions; + +public class UnAuthorizedException : Exception where TEntity : EntityBase +{ + public UnAuthorizedException() { } + + public UnAuthorizedException(ObjectId id) : base(String.Format($"Access to object {id} of type {typeof(TEntity).Name} denied.")) { } +} diff --git a/ShoppingAssistantApi.Application/IRepositories/IMessagerepository.cs b/ShoppingAssistantApi.Application/IRepositories/IMessagerepository.cs new file mode 100644 index 0000000..5387549 --- /dev/null +++ b/ShoppingAssistantApi.Application/IRepositories/IMessagerepository.cs @@ -0,0 +1,5 @@ +using ShoppingAssistantApi.Domain.Entities; + +namespace ShoppingAssistantApi.Application.IRepositories; + +public interface IMessagesRepository : IBaseRepository { } diff --git a/ShoppingAssistantApi.Application/IRepositories/IWishlistRepository.cs b/ShoppingAssistantApi.Application/IRepositories/IWishlistRepository.cs new file mode 100644 index 0000000..f5789e5 --- /dev/null +++ b/ShoppingAssistantApi.Application/IRepositories/IWishlistRepository.cs @@ -0,0 +1,5 @@ +using ShoppingAssistantApi.Domain.Entities; + +namespace ShoppingAssistantApi.Application.IRepositories; + +public interface IWishlistsRepository : IBaseRepository { } diff --git a/ShoppingAssistantApi.Application/IServices/IWishlistService.cs b/ShoppingAssistantApi.Application/IServices/IWishlistService.cs new file mode 100644 index 0000000..5ba8be9 --- /dev/null +++ b/ShoppingAssistantApi.Application/IServices/IWishlistService.cs @@ -0,0 +1,11 @@ +using ShoppingAssistantApi.Application.Models.CreateDtos; +using ShoppingAssistantApi.Application.Models.Dtos; + +namespace ShoppingAssistantApi.Application.IServices; + +public interface IWishlistsService +{ + Task StartPersonalWishlistAsync(WishlistCreateDto dto, CancellationToken cancellationToken); + + Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken); +} diff --git a/ShoppingAssistantApi.Infrastructure/InfrastructureExtentions/ServicesExtention.cs b/ShoppingAssistantApi.Infrastructure/InfrastructureExtentions/ServicesExtention.cs index a462de4..0db9d03 100644 --- a/ShoppingAssistantApi.Infrastructure/InfrastructureExtentions/ServicesExtention.cs +++ b/ShoppingAssistantApi.Infrastructure/InfrastructureExtentions/ServicesExtention.cs @@ -14,6 +14,7 @@ public static class ServicesExtention services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); return services; } diff --git a/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs b/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs new file mode 100644 index 0000000..f667126 --- /dev/null +++ b/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs @@ -0,0 +1,74 @@ +using AutoMapper; +using MongoDB.Bson; +using ShoppingAssistantApi.Application.Exceptions; +using ShoppingAssistantApi.Application.GlobalInstances; +using ShoppingAssistantApi.Application.IRepositories; +using ShoppingAssistantApi.Application.IServices; +using ShoppingAssistantApi.Application.Models.CreateDtos; +using ShoppingAssistantApi.Application.Models.Dtos; +using ShoppingAssistantApi.Application.Paging; +using ShoppingAssistantApi.Domain.Entities; +using ShoppingAssistantApi.Domain.Enums; + +namespace ShoppingAssistantApi.Infrastructure.Services; + +public class WishlistsService : IWishlistsService +{ + private readonly IWishlistsRepository _wishlistsRepository; + private readonly IMessagesRepository _messagesRepository; + private readonly IMapper _mapper; + + public WishlistsService(IWishlistsRepository wishlistRepository, IMessagesRepository messageRepository, IMapper mapper) + { + _wishlistsRepository = wishlistRepository; + _messagesRepository = messageRepository; + _mapper = mapper; + } + + public async Task StartPersonalWishlistAsync(WishlistCreateDto dto, CancellationToken cancellationToken) + { + var newWishlist = _mapper.Map(dto); + + newWishlist.CreatedById = (ObjectId) GlobalUser.Id; + newWishlist.CreatedDateUtc = DateTime.UtcNow; + newWishlist.Name = $"{newWishlist.Type} Search"; + + var createdWishlist = await _wishlistsRepository.AddAsync(newWishlist, cancellationToken); + + var newMessage = new Message + { + Text = dto.FirstMessageText, + Role = MessageRoles.User.ToString(), + WishlistId = createdWishlist.Id + }; + var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken); + + return _mapper.Map(createdWishlist); + } + + public async Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken) + { + var newMessage = _mapper.Map(dto); + + if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId)) + { + throw new InvalidDataException("Provided id is invalid."); + } + newMessage.WishlistId = wishlistObjectId; + newMessage.Role = MessageRoles.User.ToString(); + newMessage.CreatedById = (ObjectId) GlobalUser.Id; + newMessage.CreatedDateUtc = DateTime.UtcNow; + + var relatedWishlistPage = await _wishlistsRepository.GetPageAsync(1, 1, x => x.Id == wishlistObjectId && x.CreatedById == GlobalUser.Id, cancellationToken); + var relatedWishlist = relatedWishlistPage.FirstOrDefault(); + + if (relatedWishlist == null) + { + throw new UnAuthorizedException(); + } + + var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken); + + return _mapper.Map(createdMessage); + } +} diff --git a/ShoppingAssistantApi.Persistance/PersistanceExtentions/RepositoriesExtention.cs b/ShoppingAssistantApi.Persistance/PersistanceExtentions/RepositoriesExtention.cs index 1ff1855..e48ae73 100644 --- a/ShoppingAssistantApi.Persistance/PersistanceExtentions/RepositoriesExtention.cs +++ b/ShoppingAssistantApi.Persistance/PersistanceExtentions/RepositoriesExtention.cs @@ -13,6 +13,8 @@ public static class RepositoriesExtention services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); return services; } diff --git a/ShoppingAssistantApi.Persistance/Repositories/MessagesRepository.cs b/ShoppingAssistantApi.Persistance/Repositories/MessagesRepository.cs new file mode 100644 index 0000000..06481f6 --- /dev/null +++ b/ShoppingAssistantApi.Persistance/Repositories/MessagesRepository.cs @@ -0,0 +1,10 @@ +using ShoppingAssistantApi.Application.IRepositories; +using ShoppingAssistantApi.Domain.Entities; +using ShoppingAssistantApi.Persistance.Database; + +namespace ShoppingAssistantApi.Persistance.Repositories; + +public class MessagesRepository : BaseRepository, IMessagesRepository +{ + public MessagesRepository(MongoDbContext db) : base(db, "Messages") { } +} diff --git a/ShoppingAssistantApi.Persistance/Repositories/WishlistsRepository.cs b/ShoppingAssistantApi.Persistance/Repositories/WishlistsRepository.cs new file mode 100644 index 0000000..da92066 --- /dev/null +++ b/ShoppingAssistantApi.Persistance/Repositories/WishlistsRepository.cs @@ -0,0 +1,10 @@ +using ShoppingAssistantApi.Application.IRepositories; +using ShoppingAssistantApi.Domain.Entities; +using ShoppingAssistantApi.Persistance.Database; + +namespace ShoppingAssistantApi.Persistance.Repositories; + +public class WishlistsRepository : BaseRepository, IWishlistsRepository +{ + public WishlistsRepository(MongoDbContext db) : base(db, "Wishlists") { } +}