diff --git a/Netina.Api/Controllers/ProductReviewController.cs b/Netina.Api/Controllers/ProductCommentController.cs similarity index 69% rename from Netina.Api/Controllers/ProductReviewController.cs rename to Netina.Api/Controllers/ProductCommentController.cs index 9bc9202..aaa76af 100644 --- a/Netina.Api/Controllers/ProductReviewController.cs +++ b/Netina.Api/Controllers/ProductCommentController.cs @@ -1,50 +1,50 @@ namespace Netina.Api.Controllers; -public class ProductReviewController : ICarterModule +public class ProductCommentController : ICarterModule { public void AddRoutes(IEndpointRouteBuilder app) { - var group = app.NewVersionedApi("ProductReview") - .MapGroup("api/product/review"); + var group = app.NewVersionedApi("ProductComment") + .MapGroup("api/product/comment"); group.MapGet("{id}", GetAsync) - .WithDisplayName("Get Product Review") + .WithDisplayName("Get Product Comment") .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews,ApplicationPermission.ManageReview)) .HasApiVersion(1.0); group.MapGet("", GetAllAsync) - .WithDisplayName("Get Product Reviews") + .WithDisplayName("Get Product Comments") .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews, ApplicationPermission.ManageReview)) .HasApiVersion(1.0); group.MapPost("", PostAsync) - .WithDisplayName("Create Product Review") + .WithDisplayName("Create Product Comment") .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()) .HasApiVersion(1.0); group.MapPut("confirm/{id}", ConfirmAsync) - .WithDisplayName("Confirm Product Review") + .WithDisplayName("Confirm Product Comment") .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ConfirmReview, ApplicationPermission.ManageReview)) .HasApiVersion(1.0); group.MapDelete("{id}", DeleteAsync) - .WithDisplayName("Delete Product Review") + .WithDisplayName("Delete Product Comment") .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview)) .HasApiVersion(1.0); } public async Task GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken) - => TypedResults.Ok(await mediator.Send(new GetReviewsQuery(page), cancellationToken)); + => TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page), cancellationToken)); public async Task GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) - => TypedResults.Ok(await mediator.Send(new GetReviewQuery(id), cancellationToken)); + => TypedResults.Ok(await mediator.Send(new GetCommentQuery(id), cancellationToken)); - public async Task PostAsync(CreateReviewCommand request, IMediator mediator, CancellationToken cancellationToken) + public async Task PostAsync(CreateCommentCommand request, IMediator mediator, CancellationToken cancellationToken) => TypedResults.Ok(await mediator.Send(request, cancellationToken)); public async Task ConfirmAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) - => TypedResults.Ok(await mediator.Send(new ConfirmReviewCommand(id), cancellationToken)); + => TypedResults.Ok(await mediator.Send(new ConfirmCommentCommand(id), cancellationToken)); public async Task DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) - => TypedResults.Ok(await mediator.Send(new DeleteReviewCommand(id), cancellationToken)); + => TypedResults.Ok(await mediator.Send(new DeleteCommentCommand(id), cancellationToken)); } \ No newline at end of file diff --git a/Netina.Api/Controllers/ProductController.cs b/Netina.Api/Controllers/ProductController.cs index 768b1d0..16d477a 100644 --- a/Netina.Api/Controllers/ProductController.cs +++ b/Netina.Api/Controllers/ProductController.cs @@ -38,7 +38,7 @@ public class ProductController : ICarterModule .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .HasApiVersion(1.0); - group.MapGet("{productId}/review",GetProductReviewsAsync) + group.MapGet("{productId}/comment",GetProductCommentsAsync) .WithDisplayName("Get Product Reviews") .HasApiVersion(1.0); @@ -48,8 +48,8 @@ public class ProductController : ICarterModule .HasApiVersion(1.0); } - private async Task GetProductReviewsAsync([FromQuery] int page, [FromRoute] Guid productId, IMediator mediator, CancellationToken cancellationToken) - => TypedResults.Ok(await mediator.Send(new GetReviewsQuery(page, productId), cancellationToken)); + private async Task GetProductCommentsAsync([FromQuery] int page, [FromQuery]int count, [FromRoute] Guid productId, IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, productId), cancellationToken)); // GET:Get All Entity public async Task GetAllAsync([FromQuery] int page, diff --git a/Netina.Core/BaseServices/SettingService.cs b/Netina.Core/BaseServices/SettingService.cs index c31f0d0..c125fb7 100644 --- a/Netina.Core/BaseServices/SettingService.cs +++ b/Netina.Core/BaseServices/SettingService.cs @@ -1,5 +1,7 @@  +namespace Netina.Core.BaseServices; + public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) : ISettingService { public async Task GetSettingAsync(string settingName, CancellationToken cancellationToken = default) diff --git a/Netina.Core/EntityServices/CommentHandlers/ConfirmCommentCommandHandler.cs b/Netina.Core/EntityServices/CommentHandlers/ConfirmCommentCommandHandler.cs new file mode 100644 index 0000000..9d41c84 --- /dev/null +++ b/Netina.Core/EntityServices/CommentHandlers/ConfirmCommentCommandHandler.cs @@ -0,0 +1,37 @@ +using Netina.Domain.Entities.Comments; + +namespace Netina.Core.EntityServices.CommentHandlers; + +public class ConfirmCommentCommandHandler(IRepositoryWrapper repositoryWrapper) + : IRequestHandler +{ + public async Task Handle(ConfirmCommentCommand request, CancellationToken cancellationToken) + { + var review = await repositoryWrapper.SetRepository().TableNoTracking + .FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken); + if (review == null) + throw new AppException("Comment not found", ApiResultStatusCode.NotFound); + review.ConfirmReview(); + + var productComment = await repositoryWrapper.SetRepository() + .TableNoTracking.FirstOrDefaultAsync(f => f.Id == request.Id, cancellationToken); + if (productComment != null) + { + + var product = await repositoryWrapper.SetRepository() + .TableNoTracking + .FirstOrDefaultAsync(p => p.Id == productComment.ProductId, cancellationToken); + if (product == null) + throw new AppException("Product not found", ApiResultStatusCode.NotFound); + + product.AddRate(productComment.Rate); + + repositoryWrapper.SetRepository().Update(product); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + } + + repositoryWrapper.SetRepository().Update(review); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + return review.Id; + } +} \ No newline at end of file diff --git a/Netina.Core/EntityServices/ReviewHandlers/ConfirmReviewCommandHandler.cs b/Netina.Core/EntityServices/ReviewHandlers/ConfirmReviewCommandHandler.cs deleted file mode 100644 index 871a401..0000000 --- a/Netina.Core/EntityServices/ReviewHandlers/ConfirmReviewCommandHandler.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Review = Netina.Domain.Entities.Reviews.Review; - -namespace Netina.Core.EntityServices.ReviewHandlers; - -public class ConfirmReviewCommandHandler(IRepositoryWrapper repositoryWrapper) - : IRequestHandler -{ - public async Task Handle(ConfirmReviewCommand request, CancellationToken cancellationToken) - { - var review = await repositoryWrapper.SetRepository().TableNoTracking - .FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken); - if (review == null) - throw new AppException("Review not found", ApiResultStatusCode.NotFound); - review.ConfirmReview(); - - repositoryWrapper.SetRepository().Update(review); - await repositoryWrapper.SaveChangesAsync(cancellationToken); - return review.Id; - } -} \ No newline at end of file diff --git a/Netina.Core/Netina.Core.csproj b/Netina.Core/Netina.Core.csproj index 338e582..a3e0306 100644 --- a/Netina.Core/Netina.Core.csproj +++ b/Netina.Core/Netina.Core.csproj @@ -26,7 +26,6 @@ - diff --git a/Netina.Domain/CommandQueries/Commands/CommentCommands.cs b/Netina.Domain/CommandQueries/Commands/CommentCommands.cs new file mode 100644 index 0000000..49a2fa3 --- /dev/null +++ b/Netina.Domain/CommandQueries/Commands/CommentCommands.cs @@ -0,0 +1,27 @@ +namespace Netina.Domain.CommandQueries.Commands; + +public sealed record CreateCommentCommand( + string Title, + string Content, + float Rate, + bool IsBuyer, + bool IsAdmin, + Guid? ParentId, + Guid? BlogId = null, + Guid? ProductId = null, + Guid? UserId = null) : IRequest; + +public sealed record UpdateCommentCommand( + Guid Id, + string Title, + string Content, + float Rate, + bool IsBuyer, + bool IsAdmin, + Guid? ParentId, + Guid? BlogId = null, + Guid? ProductId = null, + Guid? UserId = null) : IRequest; + +public sealed record ConfirmCommentCommand(Guid Id) : IRequest; +public sealed record DeleteCommentCommand(Guid Id) : IRequest; \ No newline at end of file diff --git a/Netina.Domain/CommandQueries/Commands/ReviewCommands.cs b/Netina.Domain/CommandQueries/Commands/ReviewCommands.cs deleted file mode 100644 index 1bed074..0000000 --- a/Netina.Domain/CommandQueries/Commands/ReviewCommands.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Netina.Domain.CommandQueries.Commands; - -public sealed record CreateReviewCommand(string Title, string Comment, float Rate, bool IsBuyer,bool IsAdmin, Guid ProductId, Guid UserId) : IRequest; -public sealed record UpdateReviewCommand(Guid Id,string Title, string Comment, float Rate, bool IsBuyer, bool IsAdmin, Guid ProductId, Guid UserId): IRequest; -public sealed record ConfirmReviewCommand(Guid Id) : IRequest; -public sealed record DeleteReviewCommand(Guid Id) : IRequest; \ No newline at end of file diff --git a/Netina.Domain/CommandQueries/Queries/CommentQueries.cs b/Netina.Domain/CommandQueries/Queries/CommentQueries.cs new file mode 100644 index 0000000..76c63b4 --- /dev/null +++ b/Netina.Domain/CommandQueries/Queries/CommentQueries.cs @@ -0,0 +1,4 @@ +namespace Netina.Domain.CommandQueries.Queries; + +public record GetCommentsQuery(int Page = 0,int Count = Refers.SizeM ,Guid? ProductId = null, Guid? BlogId = null) : IRequest>; +public record GetCommentQuery(Guid Id) : IRequest; \ No newline at end of file diff --git a/Netina.Domain/CommandQueries/Queries/ReviewQueries.cs b/Netina.Domain/CommandQueries/Queries/ReviewQueries.cs deleted file mode 100644 index 6dcfd72..0000000 --- a/Netina.Domain/CommandQueries/Queries/ReviewQueries.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Netina.Domain.CommandQueries.Queries; - -public record GetReviewsQuery(int Page = 0,Guid? ProductId = null) : IRequest>; -public record GetReviewQuery(Guid Id) : IRequest; \ No newline at end of file diff --git a/Netina.Domain/Dtos/LargDtos/ReviewLDto.cs b/Netina.Domain/Dtos/LargDtos/CommentLDto.cs similarity index 52% rename from Netina.Domain/Dtos/LargDtos/ReviewLDto.cs rename to Netina.Domain/Dtos/LargDtos/CommentLDto.cs index 2d1f587..f7438cd 100644 --- a/Netina.Domain/Dtos/LargDtos/ReviewLDto.cs +++ b/Netina.Domain/Dtos/LargDtos/CommentLDto.cs @@ -1,14 +1,19 @@ -using Review = Netina.Domain.Entities.Reviews.Review; +using Netina.Domain.Entities.Comments; namespace Netina.Domain.Dtos.LargDtos; -public class ReviewLDto : BaseDto +public class CommentLDto : BaseDto { public string Title { get; set; } = string.Empty; public string Comment { get; set; } = string.Empty; public float Rate { get; set; } public bool IsBuyer { get; set; } public bool IsConfirmed { get; set; } - public Guid ProductId { get; set; } + public Guid ParentId { get; set; } public Guid UserId { get; set; } + + public string UserFullName { get; set; } = string.Empty; + + [AdaptIgnore] + public List Children { get; set; } = new(); } \ No newline at end of file diff --git a/Netina.Domain/Dtos/LargDtos/ProductLDto.cs b/Netina.Domain/Dtos/LargDtos/ProductLDto.cs index 1fbd3de..6785f5e 100644 --- a/Netina.Domain/Dtos/LargDtos/ProductLDto.cs +++ b/Netina.Domain/Dtos/LargDtos/ProductLDto.cs @@ -27,7 +27,7 @@ public class ProductLDto : BaseDto public bool IsSpecialOffer { get; set; } public List Specifications { get; set; } = new(); - public List Reviews { get; set; } = new(); + public List Reviews { get; set; } = new(); public List Files { get; set; } = new(); public DiscountSDto? SpecialOffer { get; set; } diff --git a/Netina.Domain/Dtos/SmallDtos/CommentSDto.cs b/Netina.Domain/Dtos/SmallDtos/CommentSDto.cs new file mode 100644 index 0000000..4016ee6 --- /dev/null +++ b/Netina.Domain/Dtos/SmallDtos/CommentSDto.cs @@ -0,0 +1,20 @@ +using Netina.Domain.Entities.Comments; + +namespace Netina.Domain.Dtos.SmallDtos; + +public class CommentSDto : BaseDto +{ + public string Title { get; set; } = string.Empty; + public string Content { get; set; } = string.Empty; + public string FullName { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string PhoneNumber { get; set; } = string.Empty; + public bool IsConfirmed { get; set; } + public Guid ParentId { get; set; } + public Guid UserId { get; set; } + + public string UserFullName { get; set; } = string.Empty; + + [AdaptIgnore] + public List Children { get; set; } = new(); +} \ No newline at end of file diff --git a/Netina.Domain/Dtos/SmallDtos/ReviewSDto.cs b/Netina.Domain/Dtos/SmallDtos/ReviewSDto.cs deleted file mode 100644 index 21394d0..0000000 --- a/Netina.Domain/Dtos/SmallDtos/ReviewSDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Review = Netina.Domain.Entities.Reviews.Review; - -namespace Netina.Domain.Dtos.SmallDtos; - -public class ReviewSDto : BaseDto -{ - public string Title { get; set; } = string.Empty; - public string Comment { get; set; } = string.Empty; - public float Rate { get; set; } - public bool IsBuyer { get; set; } - public bool IsAdmin { get; set; } - public Guid ProductId { get; set; } - public Guid UserId { get; set; } -} \ No newline at end of file diff --git a/Netina.Domain/Entities/Blogs/Blog.Aggregate.cs b/Netina.Domain/Entities/Blogs/Blog.Aggregate.cs index 60d13d3..7de2dc5 100644 --- a/Netina.Domain/Entities/Blogs/Blog.Aggregate.cs +++ b/Netina.Domain/Entities/Blogs/Blog.Aggregate.cs @@ -30,6 +30,11 @@ public partial class BlogStorageFile } } +public partial class BlogComment +{ + public static BlogComment Create(string title, string content, float rate, bool isAdmin, Guid userId, Guid blogId) + => new(title, content, rate, isAdmin, userId, blogId); +} public partial class BlogCategory { public static BlogCategory Create(string name, string description, bool isMain) diff --git a/Netina.Domain/Entities/Blogs/BlogComment.cs b/Netina.Domain/Entities/Blogs/BlogComment.cs new file mode 100644 index 0000000..9c41936 --- /dev/null +++ b/Netina.Domain/Entities/Blogs/BlogComment.cs @@ -0,0 +1,20 @@ +using Netina.Domain.Entities.Comments; + +namespace Netina.Domain.Entities.Blogs; + +public partial class BlogComment : Comment +{ + public BlogComment() + { + + } + + public BlogComment(string title, string content, float rate, bool isAdmin, Guid userId, Guid blogId) + : base(title, content, rate, isAdmin, userId) + { + BlogId = blogId; + } + public Guid BlogId { get; internal set; } + public Blog? Blog { get; internal set; } + +} \ No newline at end of file diff --git a/Netina.Domain/Entities/Comments/Comment.Aggregate.cs b/Netina.Domain/Entities/Comments/Comment.Aggregate.cs new file mode 100644 index 0000000..b3db4e7 --- /dev/null +++ b/Netina.Domain/Entities/Comments/Comment.Aggregate.cs @@ -0,0 +1,18 @@ +namespace Netina.Domain.Entities.Comments; + +public partial class Comment +{ + public static Comment Create(string title, string content, float rate,bool isAdmin, Guid userId) + { + return new Comment(title, content, rate,isAdmin, userId); + } + + public void ConfirmReview() + => IsConfirmed = true; + + public void SetParent(Guid parentId) + { + ParentId = parentId; + IsRoot = false; + } +} \ No newline at end of file diff --git a/Netina.Domain/Entities/Reviews/Review.cs b/Netina.Domain/Entities/Comments/Comment.cs similarity index 61% rename from Netina.Domain/Entities/Reviews/Review.cs rename to Netina.Domain/Entities/Comments/Comment.cs index f1db25b..d17a185 100644 --- a/Netina.Domain/Entities/Reviews/Review.cs +++ b/Netina.Domain/Entities/Comments/Comment.cs @@ -1,34 +1,35 @@ -namespace Netina.Domain.Entities.Reviews; +namespace Netina.Domain.Entities.Comments; [AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] [AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)] [AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)] [GenerateMapper] -public partial class Review : ApiEntity +public partial class Comment : ApiEntity { - public Review() + public Comment() { - + } - public Review(string title, string comment, float rate, bool isBuyer,bool isAdmin, Guid productId, Guid userId) + public Comment(string title, string content, float rate, bool isAdmin, Guid userId) { Title = title; - Comment = comment; + Content = content; Rate = rate; - IsBuyer = isBuyer; IsAdmin = isAdmin; - ProductId = productId; + IsRoot = true; UserId = userId; } public string Title { get; internal set; } = string.Empty; - public string Comment { get; internal set; } = string.Empty; + public string Content { get; internal set; } = string.Empty; public float Rate { get; internal set; } - public bool IsBuyer { get; internal set; } public bool IsConfirmed { get; internal set; } public bool IsAdmin { get; internal set; } + public bool IsRoot { get; internal set; } + public Guid? ParentId { get; internal set; } + public Comment? Parent { get; internal set; } - public Guid ProductId { get; internal set; } - public Product? Product { get; internal set; } + + public List Children { get; internal set; } = new(); public Guid UserId { get; internal set; } public ApplicationUser? User { get; internal set; } diff --git a/Netina.Domain/Entities/Products/Product.Aggregate.cs b/Netina.Domain/Entities/Products/Product.Aggregate.cs index 7978bce..927cac2 100644 --- a/Netina.Domain/Entities/Products/Product.Aggregate.cs +++ b/Netina.Domain/Entities/Products/Product.Aggregate.cs @@ -60,6 +60,12 @@ public partial class Product } } +public partial class ProductComment +{ + public static ProductComment Create(string title, string content, float rate, bool isBuyer, bool isAdmin, Guid userId, Guid productId) + => new(title, content, rate, isBuyer, isAdmin, userId, productId); +} + public partial class ProductStorageFile { public static ProductStorageFile Create(string name, string fileLocation, string fileName, bool isHeader, diff --git a/Netina.Domain/Entities/Products/Product.cs b/Netina.Domain/Entities/Products/Product.cs index fb662df..e326edb 100644 --- a/Netina.Domain/Entities/Products/Product.cs +++ b/Netina.Domain/Entities/Products/Product.cs @@ -1,4 +1,6 @@ -namespace Netina.Domain.Entities.Products; +using Netina.Domain.Entities.Comments; + +namespace Netina.Domain.Entities.Products; [AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] [AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget )] @@ -80,7 +82,7 @@ public partial class Product : ApiEntity public ProductCategory? Category { get; internal set; } public List Specifications { get; internal set; } = new(); - public List Reviews { get; internal set; } = new(); + public List Reviews { get; internal set; } = new(); public List Files { get; internal set; } = new(); public List OrderProducts { get; internal set; } = new(); diff --git a/Netina.Domain/Entities/Products/ProductComment.cs b/Netina.Domain/Entities/Products/ProductComment.cs new file mode 100644 index 0000000..aad9a23 --- /dev/null +++ b/Netina.Domain/Entities/Products/ProductComment.cs @@ -0,0 +1,21 @@ +using Netina.Domain.Entities.Comments; + +namespace Netina.Domain.Entities.Products; + +public partial class ProductComment : Comment +{ + public ProductComment() + { + + } + + public ProductComment(string title, string content, float rate, bool isBuyer, bool isAdmin, Guid userId, Guid productId) + : base(title, content, rate, isAdmin, userId) + { + ProductId = productId; + IsBuyer = isBuyer; + } + public bool IsBuyer { get; internal set; } + public Guid ProductId { get; internal set; } + public Product? Product { get; internal set; } +} \ No newline at end of file diff --git a/Netina.Domain/Entities/Reviews/Review.Aggregate.cs b/Netina.Domain/Entities/Reviews/Review.Aggregate.cs deleted file mode 100644 index 6b39c80..0000000 --- a/Netina.Domain/Entities/Reviews/Review.Aggregate.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Netina.Domain.Entities.Reviews; - -public partial class Review -{ - public static Reviews.Review Create(string title, string comment, float rate, bool isBuyer,bool isAdmin, Guid productId, Guid userId) - { - return new Reviews.Review(title, comment, rate, isBuyer,isAdmin, productId, userId); - } - - public void ConfirmReview() - => IsConfirmed = true; -} \ No newline at end of file diff --git a/Netina.Domain/Mappers/BlogCommentMapper.g.cs b/Netina.Domain/Mappers/BlogCommentMapper.g.cs new file mode 100644 index 0000000..a71feda --- /dev/null +++ b/Netina.Domain/Mappers/BlogCommentMapper.g.cs @@ -0,0 +1,6 @@ +namespace Netina.Domain.Mappers +{ + public static partial class BlogCommentMapper + { + } +} \ No newline at end of file diff --git a/Netina.Domain/Mappers/ReviewMapper.g.cs b/Netina.Domain/Mappers/CommentMapper.g.cs similarity index 50% rename from Netina.Domain/Mappers/ReviewMapper.g.cs rename to Netina.Domain/Mappers/CommentMapper.g.cs index a8a0cb2..29d8681 100644 --- a/Netina.Domain/Mappers/ReviewMapper.g.cs +++ b/Netina.Domain/Mappers/CommentMapper.g.cs @@ -2,184 +2,162 @@ using System; using System.Linq.Expressions; using Netina.Domain.Dtos.LargDtos; using Netina.Domain.Dtos.SmallDtos; -using Netina.Domain.Entities.Reviews; +using Netina.Domain.Entities.Comments; namespace Netina.Domain.Mappers { - public static partial class ReviewMapper + public static partial class CommentMapper { - public static Review AdaptToReview(this ReviewLDto p1) + public static Comment AdaptToComment(this CommentLDto p1) { - return p1 == null ? null : new Review() + return p1 == null ? null : new Comment() { Title = p1.Title, - Comment = p1.Comment, Rate = p1.Rate, - IsBuyer = p1.IsBuyer, IsConfirmed = p1.IsConfirmed, - ProductId = p1.ProductId, + ParentId = (Guid?)p1.ParentId, UserId = p1.UserId, Id = p1.Id, CreatedAt = p1.CreatedAt }; } - public static Review AdaptTo(this ReviewLDto p2, Review p3) + public static Comment AdaptTo(this CommentLDto p2, Comment p3) { if (p2 == null) { return null; } - Review result = p3 ?? new Review(); + Comment result = p3 ?? new Comment(); result.Title = p2.Title; - result.Comment = p2.Comment; result.Rate = p2.Rate; - result.IsBuyer = p2.IsBuyer; result.IsConfirmed = p2.IsConfirmed; - result.ProductId = p2.ProductId; + result.ParentId = (Guid?)p2.ParentId; result.UserId = p2.UserId; result.Id = p2.Id; result.CreatedAt = p2.CreatedAt; return result; } - public static Expression> ProjectToReview => p4 => new Review() + public static Expression> ProjectToComment => p4 => new Comment() { Title = p4.Title, - Comment = p4.Comment, Rate = p4.Rate, - IsBuyer = p4.IsBuyer, IsConfirmed = p4.IsConfirmed, - ProductId = p4.ProductId, + ParentId = (Guid?)p4.ParentId, UserId = p4.UserId, Id = p4.Id, CreatedAt = p4.CreatedAt }; - public static ReviewLDto AdaptToLDto(this Review p5) + public static CommentLDto AdaptToLDto(this Comment p5) { - return p5 == null ? null : new ReviewLDto() + return p5 == null ? null : new CommentLDto() { Title = p5.Title, - Comment = p5.Comment, Rate = p5.Rate, - IsBuyer = p5.IsBuyer, IsConfirmed = p5.IsConfirmed, - ProductId = p5.ProductId, + ParentId = p5.ParentId == null ? default(Guid) : (Guid)p5.ParentId, UserId = p5.UserId, Id = p5.Id, CreatedAt = p5.CreatedAt }; } - public static ReviewLDto AdaptTo(this Review p6, ReviewLDto p7) + public static CommentLDto AdaptTo(this Comment p6, CommentLDto p7) { if (p6 == null) { return null; } - ReviewLDto result = p7 ?? new ReviewLDto(); + CommentLDto result = p7 ?? new CommentLDto(); result.Title = p6.Title; - result.Comment = p6.Comment; result.Rate = p6.Rate; - result.IsBuyer = p6.IsBuyer; result.IsConfirmed = p6.IsConfirmed; - result.ProductId = p6.ProductId; + result.ParentId = p6.ParentId == null ? default(Guid) : (Guid)p6.ParentId; result.UserId = p6.UserId; result.Id = p6.Id; result.CreatedAt = p6.CreatedAt; return result; } - public static Expression> ProjectToLDto => p8 => new ReviewLDto() + public static Expression> ProjectToLDto => p8 => new CommentLDto() { Title = p8.Title, - Comment = p8.Comment, Rate = p8.Rate, - IsBuyer = p8.IsBuyer, IsConfirmed = p8.IsConfirmed, - ProductId = p8.ProductId, + ParentId = p8.ParentId == null ? default(Guid) : (Guid)p8.ParentId, UserId = p8.UserId, Id = p8.Id, CreatedAt = p8.CreatedAt }; - public static Review AdaptToReview(this ReviewSDto p9) + public static Comment AdaptToComment(this CommentSDto p9) { - return p9 == null ? null : new Review() + return p9 == null ? null : new Comment() { Title = p9.Title, - Comment = p9.Comment, - Rate = p9.Rate, - IsBuyer = p9.IsBuyer, - IsAdmin = p9.IsAdmin, - ProductId = p9.ProductId, + Content = p9.Content, + IsConfirmed = p9.IsConfirmed, + ParentId = (Guid?)p9.ParentId, UserId = p9.UserId, Id = p9.Id, CreatedAt = p9.CreatedAt }; } - public static Review AdaptTo(this ReviewSDto p10, Review p11) + public static Comment AdaptTo(this CommentSDto p10, Comment p11) { if (p10 == null) { return null; } - Review result = p11 ?? new Review(); + Comment result = p11 ?? new Comment(); result.Title = p10.Title; - result.Comment = p10.Comment; - result.Rate = p10.Rate; - result.IsBuyer = p10.IsBuyer; - result.IsAdmin = p10.IsAdmin; - result.ProductId = p10.ProductId; + result.Content = p10.Content; + result.IsConfirmed = p10.IsConfirmed; + result.ParentId = (Guid?)p10.ParentId; result.UserId = p10.UserId; result.Id = p10.Id; result.CreatedAt = p10.CreatedAt; return result; } - public static ReviewSDto AdaptToSDto(this Review p12) + public static CommentSDto AdaptToSDto(this Comment p12) { - return p12 == null ? null : new ReviewSDto() + return p12 == null ? null : new CommentSDto() { Title = p12.Title, - Comment = p12.Comment, - Rate = p12.Rate, - IsBuyer = p12.IsBuyer, - IsAdmin = p12.IsAdmin, - ProductId = p12.ProductId, + Content = p12.Content, + IsConfirmed = p12.IsConfirmed, + ParentId = p12.ParentId == null ? default(Guid) : (Guid)p12.ParentId, UserId = p12.UserId, Id = p12.Id, CreatedAt = p12.CreatedAt }; } - public static ReviewSDto AdaptTo(this Review p13, ReviewSDto p14) + public static CommentSDto AdaptTo(this Comment p13, CommentSDto p14) { if (p13 == null) { return null; } - ReviewSDto result = p14 ?? new ReviewSDto(); + CommentSDto result = p14 ?? new CommentSDto(); result.Title = p13.Title; - result.Comment = p13.Comment; - result.Rate = p13.Rate; - result.IsBuyer = p13.IsBuyer; - result.IsAdmin = p13.IsAdmin; - result.ProductId = p13.ProductId; + result.Content = p13.Content; + result.IsConfirmed = p13.IsConfirmed; + result.ParentId = p13.ParentId == null ? default(Guid) : (Guid)p13.ParentId; result.UserId = p13.UserId; result.Id = p13.Id; result.CreatedAt = p13.CreatedAt; return result; } - public static Expression> ProjectToSDto => p15 => new ReviewSDto() + public static Expression> ProjectToSDto => p15 => new CommentSDto() { Title = p15.Title, - Comment = p15.Comment, - Rate = p15.Rate, - IsBuyer = p15.IsBuyer, - IsAdmin = p15.IsAdmin, - ProductId = p15.ProductId, + Content = p15.Content, + IsConfirmed = p15.IsConfirmed, + ParentId = p15.ParentId == null ? default(Guid) : (Guid)p15.ParentId, UserId = p15.UserId, Id = p15.Id, CreatedAt = p15.CreatedAt diff --git a/Netina.Domain/Mappers/ProductCommentMapper.g.cs b/Netina.Domain/Mappers/ProductCommentMapper.g.cs new file mode 100644 index 0000000..db2413a --- /dev/null +++ b/Netina.Domain/Mappers/ProductCommentMapper.g.cs @@ -0,0 +1,6 @@ +namespace Netina.Domain.Mappers +{ + public static partial class ProductCommentMapper + { + } +} \ No newline at end of file diff --git a/Netina.Domain/Mappers/ProductMapper.g.cs b/Netina.Domain/Mappers/ProductMapper.g.cs index e413248..0c9bfec 100644 --- a/Netina.Domain/Mappers/ProductMapper.g.cs +++ b/Netina.Domain/Mappers/ProductMapper.g.cs @@ -7,9 +7,9 @@ using Netina.Domain.Dtos.LargDtos; using Netina.Domain.Dtos.ResponseDtos.Torob; using Netina.Domain.Dtos.SmallDtos; using Netina.Domain.Entities.Brands; +using Netina.Domain.Entities.Comments; using Netina.Domain.Entities.ProductCategories; using Netina.Domain.Entities.Products; -using Netina.Domain.Entities.Reviews; using Netina.Domain.Entities.Users; namespace Netina.Domain.Mappers @@ -121,18 +121,16 @@ namespace Netina.Domain.Mappers Id = p20.Id, CreatedAt = p20.CreatedAt }).ToList(), - Reviews = p19.Reviews.Select(p21 => new Review() + Reviews = p19.Reviews.Select(p21 => new Comment() { Title = p21.Title, - Comment = p21.Comment, - Rate = p21.Rate, - IsBuyer = p21.IsBuyer, - IsAdmin = p21.IsAdmin, - ProductId = p21.ProductId, + Content = p21.Content, + IsConfirmed = p21.IsConfirmed, + ParentId = (Guid?)p21.ParentId, UserId = p21.UserId, Id = p21.Id, CreatedAt = p21.CreatedAt - }).ToList(), + }).ToList(), Files = p19.Files.Select(p22 => new ProductStorageFile() { Name = p22.Name, @@ -242,18 +240,16 @@ namespace Netina.Domain.Mappers Id = p36.Id, CreatedAt = p36.CreatedAt }).ToList(), - Reviews = p35.Reviews.Select(p37 => new ReviewSDto() + Reviews = p35.Reviews.Select(p37 => new CommentSDto() { Title = p37.Title, - Comment = p37.Comment, - Rate = p37.Rate, - IsBuyer = p37.IsBuyer, - IsAdmin = p37.IsAdmin, - ProductId = p37.ProductId, + Content = p37.Content, + IsConfirmed = p37.IsConfirmed, + ParentId = p37.ParentId == null ? default(Guid) : (Guid)p37.ParentId, UserId = p37.UserId, Id = p37.Id, CreatedAt = p37.CreatedAt - }).ToList(), + }).ToList(), Files = p35.Files.Select(p38 => new StorageFileSDto() { Name = p38.Name, @@ -476,28 +472,26 @@ namespace Netina.Domain.Mappers } - private static List funcMain2(List p3) + private static List funcMain2(List p3) { if (p3 == null) { return null; } - List result = new List(p3.Count); + List result = new List(p3.Count); int i = 0; int len = p3.Count; while (i < len) { - ReviewSDto item = p3[i]; - result.Add(item == null ? null : new Review() + CommentSDto item = p3[i]; + result.Add(item == null ? null : new Comment() { Title = item.Title, - Comment = item.Comment, - Rate = item.Rate, - IsBuyer = item.IsBuyer, - IsAdmin = item.IsAdmin, - ProductId = item.ProductId, + Content = item.Content, + IsConfirmed = item.IsConfirmed, + ParentId = (Guid?)item.ParentId, UserId = item.UserId, Id = item.Id, CreatedAt = item.CreatedAt @@ -598,28 +592,26 @@ namespace Netina.Domain.Mappers } - private static List funcMain8(List p15, List p16) + private static List funcMain8(List p15, List p16) { if (p15 == null) { return null; } - List result = new List(p15.Count); + List result = new List(p15.Count); int i = 0; int len = p15.Count; while (i < len) { - ReviewSDto item = p15[i]; - result.Add(item == null ? null : new Review() + CommentSDto item = p15[i]; + result.Add(item == null ? null : new Comment() { Title = item.Title, - Comment = item.Comment, - Rate = item.Rate, - IsBuyer = item.IsBuyer, - IsAdmin = item.IsAdmin, - ProductId = item.ProductId, + Content = item.Content, + IsConfirmed = item.IsConfirmed, + ParentId = (Guid?)item.ParentId, UserId = item.UserId, Id = item.Id, CreatedAt = item.CreatedAt @@ -692,28 +684,26 @@ namespace Netina.Domain.Mappers } - private static List funcMain11(List p25) + private static List funcMain11(List p25) { if (p25 == null) { return null; } - List result = new List(p25.Count); + List result = new List(p25.Count); int i = 0; int len = p25.Count; while (i < len) { - Review item = p25[i]; - result.Add(item == null ? null : new ReviewSDto() + Comment item = p25[i]; + result.Add(item == null ? null : new CommentSDto() { Title = item.Title, - Comment = item.Comment, - Rate = item.Rate, - IsBuyer = item.IsBuyer, - IsAdmin = item.IsAdmin, - ProductId = item.ProductId, + Content = item.Content, + IsConfirmed = item.IsConfirmed, + ParentId = item.ParentId == null ? default(Guid) : (Guid)item.ParentId, UserId = item.UserId, Id = item.Id, CreatedAt = item.CreatedAt @@ -785,28 +775,26 @@ namespace Netina.Domain.Mappers } - private static List funcMain14(List p31, List p32) + private static List funcMain14(List p31, List p32) { if (p31 == null) { return null; } - List result = new List(p31.Count); + List result = new List(p31.Count); int i = 0; int len = p31.Count; while (i < len) { - Review item = p31[i]; - result.Add(item == null ? null : new ReviewSDto() + Comment item = p31[i]; + result.Add(item == null ? null : new CommentSDto() { Title = item.Title, - Comment = item.Comment, - Rate = item.Rate, - IsBuyer = item.IsBuyer, - IsAdmin = item.IsAdmin, - ProductId = item.ProductId, + Content = item.Content, + IsConfirmed = item.IsConfirmed, + ParentId = item.ParentId == null ? default(Guid) : (Guid)item.ParentId, UserId = item.UserId, Id = item.Id, CreatedAt = item.CreatedAt diff --git a/Netina.Domain/Models/Refers.cs b/Netina.Domain/Models/Refers.cs new file mode 100644 index 0000000..78ecd6f --- /dev/null +++ b/Netina.Domain/Models/Refers.cs @@ -0,0 +1,8 @@ +namespace Netina.Domain.Models; + +public static class Refers +{ + public const int SizeS = 10; + public const int SizeM = 15; + public const int SizeL = 20; +} \ No newline at end of file diff --git a/Netina.Domain/Netina.Domain.csproj b/Netina.Domain/Netina.Domain.csproj index 8e0cfa8..66dcdca 100644 --- a/Netina.Domain/Netina.Domain.csproj +++ b/Netina.Domain/Netina.Domain.csproj @@ -82,6 +82,7 @@ + diff --git a/Netina.Repository/Handlers/Comments/CreateCommentCommandHandler.cs b/Netina.Repository/Handlers/Comments/CreateCommentCommandHandler.cs new file mode 100644 index 0000000..b1227b7 --- /dev/null +++ b/Netina.Repository/Handlers/Comments/CreateCommentCommandHandler.cs @@ -0,0 +1,52 @@ +using AppException = Netina.Common.Models.Exception.AppException; + +namespace Netina.Repository.Handlers.Comments; + +public class CreateCommentCommandHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService) + : IRequestHandler +{ + public async Task Handle(CreateCommentCommand request, CancellationToken cancellationToken) + { + Guid userId; + if (request.UserId == null) + { + if (!Guid.TryParse(currentUserService.UserId, out userId)) + throw new AppException("User id is wrong", ApiResultStatusCode.BadRequest); + } + else + userId = request.UserId.Value; + + if (request.BlogId != null) + { + var entBlog = BlogComment.Create(request.Title, request.Content, request.Rate, request.IsAdmin, userId, + request.BlogId.Value); + + if (request.ParentId != null) + entBlog.SetParent(request.ParentId.Value); + repositoryWrapper.SetRepository().Add(entBlog); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + return entBlog.Id; + } + + if (request.ProductId != null) + { + + var entBlog = ProductComment.Create(request.Title, request.Content, request.Rate, request.IsBuyer, + request.IsAdmin, userId, request.ProductId.Value); + if (request.ParentId != null) + entBlog.SetParent(request.ParentId.Value); + + repositoryWrapper.SetRepository().Add(entBlog); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + return entBlog.Id; + + } + + var ent = Comment.Create(request.Title, request.Content, request.Rate, request.IsAdmin, userId); + if (request.ParentId != null) + ent.SetParent(request.ParentId.Value); + repositoryWrapper.SetRepository().Add(ent); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + return ent.Id; + } +} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Comments/DeleteCommentCommandHandler.cs b/Netina.Repository/Handlers/Comments/DeleteCommentCommandHandler.cs new file mode 100644 index 0000000..67a848f --- /dev/null +++ b/Netina.Repository/Handlers/Comments/DeleteCommentCommandHandler.cs @@ -0,0 +1,35 @@ +namespace Netina.Repository.Handlers.Comments; + +public class DeleteCommentCommandHandler(IRepositoryWrapper repositoryWrapper) + : IRequestHandler +{ + public async Task Handle(DeleteCommentCommand request, CancellationToken cancellationToken) + { + var review = await repositoryWrapper.SetRepository().TableNoTracking + .FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken); + if (review == null) + throw new AppException("Comment not found", ApiResultStatusCode.NotFound); + + if (review.IsConfirmed) + { + var productComment = await repositoryWrapper.SetRepository() + .TableNoTracking.FirstOrDefaultAsync(f => f.Id == request.Id, cancellationToken); + if (productComment != null) + { + var product = await repositoryWrapper.SetRepository() + .TableNoTracking + .FirstOrDefaultAsync(p => p.Id == productComment.ProductId, cancellationToken); + if (product != null) + { + product.RemoveRate(review.Rate); + repositoryWrapper.SetRepository().Update(product); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + } + } + } + + repositoryWrapper.SetRepository().Delete(review); + await repositoryWrapper.SaveChangesAsync(cancellationToken); + return review.Id; + } +} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Comments/GetCommentQueryHandler.cs b/Netina.Repository/Handlers/Comments/GetCommentQueryHandler.cs new file mode 100644 index 0000000..0d0bbf6 --- /dev/null +++ b/Netina.Repository/Handlers/Comments/GetCommentQueryHandler.cs @@ -0,0 +1,19 @@ +using Netina.Domain.Entities.Comments; + +namespace Netina.Repository.Handlers.Comments; + +public class GetCommentQueryHandler(IRepositoryWrapper repositoryWrapper) : IRequestHandler +{ + public async Task Handle(GetCommentQuery request, CancellationToken cancellationToken) + { + var review = await repositoryWrapper.SetRepository() + .TableNoTracking + .Where(r => r.Id == request.Id) + .Select(CommentMapper.ProjectToLDto) + .FirstOrDefaultAsync(cancellationToken); + if (review == null) + throw new AppException("Comment not found", ApiResultStatusCode.NotFound); + + return review; + } +} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Comments/GetCommentsQueryHandler.cs b/Netina.Repository/Handlers/Comments/GetCommentsQueryHandler.cs new file mode 100644 index 0000000..89662fb --- /dev/null +++ b/Netina.Repository/Handlers/Comments/GetCommentsQueryHandler.cs @@ -0,0 +1,62 @@ +namespace Netina.Repository.Handlers.Comments; + +public class GetCommentsQueryHandler(IRepositoryWrapper repositoryWrapper) + : IRequestHandler> +{ + public async Task> Handle(GetCommentsQuery request, CancellationToken cancellationToken) + { + var count = request.Count == 0 ? Refers.SizeL : request.Count; + if (count > 50) + throw new BaseApiException(ApiResultStatusCode.BadRequest, "Count limit is 50"); + + if (request.BlogId != null) + { + var blogQuery = repositoryWrapper.SetRepository().TableNoTracking + .Where(b => b.IsRoot && b.BlogId == request.BlogId) + .Skip(request.Page * count) + .Take(count) + .Select(CommentMapper.ProjectToSDto); + var blogRoots = await blogQuery.ToListAsync(cancellationToken); + foreach (var root in blogRoots) + await LoadChildrenAsync(root, cancellationToken); + } + + if (request.ProductId != null) + { + + var blogQuery = repositoryWrapper.SetRepository().TableNoTracking + .Where(b => b.IsRoot && b.ProductId == request.ProductId) + .Skip(request.Page * count) + .Take(count) + .Select(CommentMapper.ProjectToSDto); + var blogRoots = await blogQuery.ToListAsync(cancellationToken); + foreach (var root in blogRoots) + await LoadChildrenAsync(root, cancellationToken); + } + + var query = repositoryWrapper.SetRepository().TableNoTracking + .Where(b => b.IsRoot) + .Skip(request.Page * count) + .Take(count) + .Select(CommentMapper.ProjectToSDto); + var roots = await query.ToListAsync(cancellationToken); + foreach (var root in roots) + await LoadChildrenAsync(root, cancellationToken); + + return roots; + } + + private async Task LoadChildrenAsync(CommentSDto comment, CancellationToken cancellationToken) + { + var children = await repositoryWrapper.SetRepository() + .TableNoTracking + .Where(c => c.ParentId == comment.Id) + .Select(CommentMapper.ProjectToSDto) + .ToListAsync(cancellationToken); + + foreach (var blogComment in children) + await LoadChildrenAsync(blogComment, cancellationToken); + + comment.Children = children; + } +} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs b/Netina.Repository/Handlers/Comments/Validators/CreateCommentCommandValidator.cs similarity index 69% rename from Netina.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs rename to Netina.Repository/Handlers/Comments/Validators/CreateCommentCommandValidator.cs index 2bd6876..5a6271a 100644 --- a/Netina.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs +++ b/Netina.Repository/Handlers/Comments/Validators/CreateCommentCommandValidator.cs @@ -1,17 +1,17 @@ using FluentValidation; -namespace Netina.Repository.Handlers.Reviews.Validators; +namespace Netina.Repository.Handlers.Comments.Validators; -public class CreateReviewCommandValidator : AbstractValidator +public class CreateCommentCommandValidator : AbstractValidator { - public CreateReviewCommandValidator() + public CreateCommentCommandValidator() { RuleFor(d => d.Title) .NotNull() .NotEmpty() .WithMessage("عنوان نظر مورد نظر را وارد کنید"); - RuleFor(d => d.Comment) + RuleFor(d => d.Content) .NotNull() .NotEmpty() .WithMessage("متن نظر مورد نظر را وارد کنید"); diff --git a/Netina.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs b/Netina.Repository/Handlers/Comments/Validators/UpdateCommentCommandValidator.cs similarity index 69% rename from Netina.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs rename to Netina.Repository/Handlers/Comments/Validators/UpdateCommentCommandValidator.cs index 646da75..8e8d4bb 100644 --- a/Netina.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs +++ b/Netina.Repository/Handlers/Comments/Validators/UpdateCommentCommandValidator.cs @@ -1,17 +1,17 @@ using FluentValidation; -namespace Netina.Repository.Handlers.Reviews.Validators; +namespace Netina.Repository.Handlers.Comments.Validators; -public class UpdateReviewCommandValidator : AbstractValidator +public class UpdateCommentCommandValidator : AbstractValidator { - public UpdateReviewCommandValidator() + public UpdateCommentCommandValidator() { RuleFor(d => d.Title) .NotNull() .NotEmpty() .WithMessage("عنوان نظر مورد نظر را وارد کنید"); - RuleFor(d => d.Comment) + RuleFor(d => d.Content) .NotNull() .NotEmpty() .WithMessage("متن نظر مورد نظر را وارد کنید"); diff --git a/Netina.Repository/Handlers/Reviews/CreateReviewCommandHandler.cs b/Netina.Repository/Handlers/Reviews/CreateReviewCommandHandler.cs deleted file mode 100644 index 5f8aa44..0000000 --- a/Netina.Repository/Handlers/Reviews/CreateReviewCommandHandler.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AppException = Netina.Common.Models.Exception.AppException; - -namespace Netina.Repository.Handlers.Reviews; - -public class CreateReviewCommandHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService) - : IRequestHandler -{ - public async Task Handle(CreateReviewCommand request, CancellationToken cancellationToken) - { - Guid userId = request.UserId; - if (userId == default) - { - if (!Guid.TryParse(currentUserService.UserId, out userId)) - throw new AppException("User id is wrong", ApiResultStatusCode.BadRequest); - } - var review = Review.Create(request.Title, request.Comment, request.Rate, request.IsBuyer, request.IsAdmin, request.ProductId, - userId); - var product = await repositoryWrapper.SetRepository() - .TableNoTracking - .FirstOrDefaultAsync(p => p.Id == request.ProductId, cancellationToken); - if (product == null) - throw new AppException("Product not found", ApiResultStatusCode.NotFound); - - product.AddRate(request.Rate); - - repositoryWrapper.SetRepository().Update(product); - await repositoryWrapper.SaveChangesAsync(cancellationToken); - - repositoryWrapper.SetRepository().Add(review); - await repositoryWrapper.SaveChangesAsync(cancellationToken); - - return review.Id; - } -} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Reviews/DeleteReviewCommandHandler.cs b/Netina.Repository/Handlers/Reviews/DeleteReviewCommandHandler.cs deleted file mode 100644 index 3d2dd43..0000000 --- a/Netina.Repository/Handlers/Reviews/DeleteReviewCommandHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Netina.Repository.Handlers.Reviews; - -public class DeleteReviewCommandHandler(IRepositoryWrapper repositoryWrapper) - : IRequestHandler -{ - public async Task Handle(DeleteReviewCommand request, CancellationToken cancellationToken) - { - var review = await repositoryWrapper.SetRepository().TableNoTracking - .FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken); - if (review == null) - throw new AppException("Review not found", ApiResultStatusCode.NotFound); - - var product = await repositoryWrapper.SetRepository() - .TableNoTracking - .FirstOrDefaultAsync(p => p.Id == review.ProductId, cancellationToken); - if (product != null) - { - product.RemoveRate(review.Rate); - repositoryWrapper.SetRepository().Update(product); - await repositoryWrapper.SaveChangesAsync(cancellationToken); - } - repositoryWrapper.SetRepository().Delete(review); - await repositoryWrapper.SaveChangesAsync(cancellationToken); - return review.Id; - } -} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Reviews/GetReviewQueryHandler.cs b/Netina.Repository/Handlers/Reviews/GetReviewQueryHandler.cs deleted file mode 100644 index 3d40833..0000000 --- a/Netina.Repository/Handlers/Reviews/GetReviewQueryHandler.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Review = Netina.Domain.Entities.Reviews.Review; - -namespace Netina.Repository.Handlers.Reviews; - -public class GetReviewQueryHandler(IRepositoryWrapper repositoryWrapper) : IRequestHandler -{ - public async Task Handle(GetReviewQuery request, CancellationToken cancellationToken) - { - var review = await repositoryWrapper.SetRepository() - .TableNoTracking - .Where(r => r.Id == request.Id) - .Select(ReviewMapper.ProjectToLDto) - .FirstOrDefaultAsync(cancellationToken); - if (review == null) - throw new AppException("Review not found", ApiResultStatusCode.NotFound); - - return review; - } -} \ No newline at end of file diff --git a/Netina.Repository/Handlers/Reviews/GetReviewsQueryHandler.cs b/Netina.Repository/Handlers/Reviews/GetReviewsQueryHandler.cs deleted file mode 100644 index efbeb55..0000000 --- a/Netina.Repository/Handlers/Reviews/GetReviewsQueryHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Review = Netina.Domain.Entities.Reviews.Review; - -namespace Netina.Repository.Handlers.Reviews; - -public class GetReviewsQueryHandler(IRepositoryWrapper repositoryWrapper) - : IRequestHandler> -{ - public async Task> Handle(GetReviewsQuery request, CancellationToken cancellationToken) - { - var query = repositoryWrapper.SetRepository() - .TableNoTracking; - if (request.ProductId != null) - query = query.Where(q => q.ProductId == request.ProductId); - - return await query - .OrderByDescending(r => r.CreatedAt) - .Skip(request.Page * 15) - .Take(15) - .Select(ReviewMapper.ProjectToSDto) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/Netina.Repository/Netina.Repository.csproj b/Netina.Repository/Netina.Repository.csproj index 95b22e6..ddb30b0 100644 --- a/Netina.Repository/Netina.Repository.csproj +++ b/Netina.Repository/Netina.Repository.csproj @@ -59,15 +59,17 @@ + - + +