feat : complete review entity
complete review controller and CQRS , change service handlers to Core projectrelease
parent
0a1c080581
commit
ef97797c5e
|
@ -1,4 +1,6 @@
|
|||
namespace NetinaShop.Api.Controller;
|
||||
using NetinaShop.Domain.Enums;
|
||||
|
||||
namespace NetinaShop.Api.Controller;
|
||||
|
||||
public class ProductController : ICarterModule
|
||||
{
|
||||
|
@ -28,8 +30,8 @@ public class ProductController : ICarterModule
|
|||
}
|
||||
|
||||
// GET:Get All Entity
|
||||
public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(page),cancellationToken));
|
||||
public async Task<IResult> GetAllAsync([FromQuery] int page, [FromQuery] QuerySortBy? sortBy,[FromQuery] Guid? categoryId , [FromQuery]Guid? brandId , [FromQuery]double? minPrice , [FromQuery] double? maxPrice, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(page,SortBy: sortBy ?? 0 , CategoryId: categoryId ?? default , BrandId: brandId ?? default , MinPrice: minPrice ?? -1 , MaxPrice:maxPrice ?? 0),cancellationToken));
|
||||
|
||||
// GET:Get An Entity By Id
|
||||
public async Task<IResult> GetAsync(Guid id, IMediator mediator,CancellationToken cancellationToken)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
namespace NetinaShop.Api.Controller;
|
||||
|
||||
public class ProductReviewController : ICarterModule
|
||||
{
|
||||
public void AddRoutes(IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.NewVersionedApi("ProductReview")
|
||||
.MapGroup("product/review")
|
||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
|
||||
|
||||
group.MapGet("{id}", GetAsync)
|
||||
.WithDisplayName("GetOneAsync")
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
group.MapGet("", GetAllAsync)
|
||||
.WithDisplayName("GetAllAsync")
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
group.MapPost("", PostAsync)
|
||||
.WithDisplayName("PostReview")
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
group.MapPut("confirm/{id}", ConfirmAsync)
|
||||
.WithDisplayName("ConfirmAsync")
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
group.MapDelete("{id}", DeleteAsync)
|
||||
.WithDisplayName("DeleteAsync")
|
||||
.HasApiVersion(1.0);
|
||||
}
|
||||
|
||||
public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetReviewsQuery(page), cancellationToken));
|
||||
|
||||
public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetReviewQuery(id), cancellationToken));
|
||||
|
||||
public async Task<IResult> PostAsync(CreateReviewCommand request, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
|
||||
|
||||
public async Task<IResult> ConfirmAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new ConfirmReviewCommand(id), cancellationToken));
|
||||
|
||||
public async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new DeleteReviewCommand(id), cancellationToken));
|
||||
}
|
|
@ -5,7 +5,7 @@ public class ShippingController : ICarterModule
|
|||
|
||||
public virtual void AddRoutes(IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.NewVersionedApi("Warehouse")
|
||||
var group = app.NewVersionedApi("WarehouseShipping")
|
||||
.MapGroup($"api/warehouse/shipping")
|
||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace NetinaShop.Repository.Handlers.Discounts;
|
||||
namespace NetinaShop.Core.EntityServices.DiscountHandlers;
|
||||
|
||||
public class CalculateDiscountCommandHandler : IRequestHandler<CalculateDiscountCommand , double>
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand,bool>
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,Order>
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
using Order = NetinaShop.Domain.Entities.Orders.Order;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderBagCommand,bool>
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class SubmitDiscountCommandHandler : IRequestHandler<SubmitDiscountCommand,bool>
|
||||
{
|
|
@ -1,7 +1,6 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
using NetinaShop.Domain.Entities.Warehouses;
|
||||
using NetinaShop.Domain.Entities.Warehouses;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeliveryCommand,bool>
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.OrderBags;
|
||||
namespace NetinaShop.Core.EntityServices.OrderBagHandlers;
|
||||
|
||||
public class SubmitOrderPaymentCommandHandler : IRequestHandler<SubmitOrderPaymentCommand , SubmitOrderPaymentResponseDto>
|
||||
{
|
|
@ -1,7 +1,4 @@
|
|||
using Microsoft.IdentityModel.Tokens;
|
||||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Orders;
|
||||
namespace NetinaShop.Core.EntityServices.OrderHandlers;
|
||||
|
||||
public class CalculateOrderCommandHandler : IRequestHandler<CalculateOrderCommand,Order>
|
||||
{
|
|
@ -0,0 +1,23 @@
|
|||
namespace NetinaShop.Core.EntityServices.ReviewHandlers;
|
||||
|
||||
public class ConfirmReviewCommandHandler : IRequestHandler<ConfirmReviewCommand , bool>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public ConfirmReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<bool> Handle(ConfirmReviewCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var review = await _repositoryWrapper.SetRepository<Review>().TableNoTracking
|
||||
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
|
||||
if (review == null)
|
||||
throw new AppException("Review not found", ApiResultStatusCode.NotFound);
|
||||
review.ConfirmReview();
|
||||
|
||||
_repositoryWrapper.SetRepository<Review>().Update(review);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -24,12 +24,14 @@
|
|||
<ItemGroup>
|
||||
<Folder Include="Abstracts\" />
|
||||
<Folder Include="BaseServices\Abstracts\" />
|
||||
<Folder Include="EntityServices\ReviewHandlers\" />
|
||||
<Folder Include="Models\Api\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Mapster" />
|
||||
<Using Include="MediatR" />
|
||||
<Using Include="Microsoft.AspNetCore.Identity" />
|
||||
<Using Include="Microsoft.AspNetCore.Mvc" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore" />
|
||||
|
@ -43,9 +45,14 @@
|
|||
<Using Include="NetinaShop.Core.BaseServices.Abstracts" />
|
||||
<Using Include="NetinaShop.Core.CoreServices.Abstracts" />
|
||||
<Using Include="NetinaShop.Core.EntityServices.Abstracts" />
|
||||
<Using Include="NetinaShop.Domain.CommandQueries.Commands" />
|
||||
<Using Include="NetinaShop.Domain.CommandQueries.Queries" />
|
||||
<Using Include="NetinaShop.Domain.Dtos.RequestDtos" />
|
||||
<Using Include="NetinaShop.Domain.Dtos.ResponseDtos" />
|
||||
<Using Include="NetinaShop.Domain.Dtos.SmallDtos" />
|
||||
<Using Include="NetinaShop.Domain.Entities.Discounts" />
|
||||
<Using Include="NetinaShop.Domain.Entities.Orders" />
|
||||
<Using Include="NetinaShop.Domain.Entities.Products" />
|
||||
<Using Include="NetinaShop.Domain.Entities.Users" />
|
||||
<Using Include="NetinaShop.Domain.Enums" />
|
||||
<Using Include="NetinaShop.Domain.Mappers" />
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
namespace NetinaShop.Domain.CommandQueries.Commands;
|
||||
|
||||
public sealed record CreateReviewCommand(string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId) : IRequest<ReviewSDto>;
|
||||
public sealed record UpdateReviewCommand(Guid Id,string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId): IRequest<bool>;
|
||||
public sealed record ConfirmReviewCommand(Guid Id) : IRequest<bool>;
|
||||
public sealed record DeleteReviewCommand(Guid Id) : IRequest<bool>;
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
|
||||
public sealed record GetProductQuery(Guid Id) : IRequest<ProductLDto>;
|
||||
public sealed record GetProductsQuery(int Page = 0) : IRequest<List<ProductSDto>>;
|
||||
public sealed record GetProductsQuery(int Page = 0 , QuerySortBy SortBy = QuerySortBy.None , Guid CategoryId = default , Guid BrandId = default , double MinPrice = -1 , double MaxPrice = 0) : IRequest<List<ProductSDto>>;
|
|
@ -0,0 +1,4 @@
|
|||
namespace NetinaShop.Domain.CommandQueries.Queries;
|
||||
|
||||
public record GetReviewsQuery(int Page = 0) : IRequest<List<ReviewSDto>>;
|
||||
public record GetReviewQuery(Guid Id) : IRequest<ReviewLDto>;
|
|
@ -0,0 +1,12 @@
|
|||
namespace NetinaShop.Domain.Dtos.LargDtos;
|
||||
|
||||
public class ReviewLDto : BaseDto<ReviewLDto,Review>
|
||||
{
|
||||
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 UserId { get; set; }
|
||||
}
|
|
@ -2,10 +2,29 @@
|
|||
|
||||
public partial class Product
|
||||
{
|
||||
public static Product Create(string persianName, string englishName, string summery, string expertCheck, string tags, string warranty, bool beDisplayed, double cost, double packingCost, Guid brandId,Guid categoryId)
|
||||
public static Product Create(string persianName, string englishName, string summery, string expertCheck, string tags, string warranty, bool beDisplayed, double cost, double packingCost,
|
||||
int reviewCount,
|
||||
float reviewRate,
|
||||
int viewed,
|
||||
Guid brandId,
|
||||
Guid categoryId)
|
||||
{
|
||||
return new Product(persianName, englishName, summery, expertCheck, tags, warranty, beDisplayed,cost,packingCost, brandId,categoryId);
|
||||
return new Product(persianName, englishName, summery, expertCheck, tags, warranty, beDisplayed,cost, packingCost, reviewCount, reviewRate, viewed, brandId,categoryId);
|
||||
}
|
||||
|
||||
public void AddRate(float rate)
|
||||
{
|
||||
Rate = ((Rate * ReviewCount) + rate) / (ReviewCount + 1);
|
||||
ReviewCount++;
|
||||
}
|
||||
|
||||
public void RemoveRate(float rate)
|
||||
{
|
||||
|
||||
Rate = ((Rate * ReviewCount) - rate) / (ReviewCount - 1);
|
||||
ReviewCount--;
|
||||
}
|
||||
|
||||
public ProductStorageFile AddFile(string name, string fileLocation, string fileName, bool isHeader, bool isPrimary, StorageFileType fileType)
|
||||
{
|
||||
var ent = ProductStorageFile.Create(name, fileLocation, fileName, isHeader, isPrimary, fileType, Id);
|
||||
|
@ -37,6 +56,8 @@ public partial class Review
|
|||
return new Review(title, comment, rate, isBuyer, productId, userId);
|
||||
}
|
||||
|
||||
public void ConfirmReview()
|
||||
=> IsConfirmed = true;
|
||||
}
|
||||
|
||||
public partial class Specification
|
||||
|
|
|
@ -10,7 +10,20 @@ public partial class Product : ApiEntity
|
|||
|
||||
}
|
||||
|
||||
public Product(string persianName, string englishName, string summery, string expertCheck, string tags, string warranty, bool beDisplayed, double cost, double packingCost, Guid brandId, Guid categoryId)
|
||||
public Product(string persianName,
|
||||
string englishName,
|
||||
string summery,
|
||||
string expertCheck,
|
||||
string tags,
|
||||
string warranty,
|
||||
bool beDisplayed,
|
||||
double cost,
|
||||
double packingCost,
|
||||
int reviewCount,
|
||||
float rate,
|
||||
int viewed,
|
||||
Guid brandId,
|
||||
Guid categoryId)
|
||||
{
|
||||
PersianName = persianName;
|
||||
EnglishName = englishName;
|
||||
|
@ -23,21 +36,27 @@ public partial class Product : ApiEntity
|
|||
PackingCost = packingCost;
|
||||
BrandId = brandId;
|
||||
CategoryId = categoryId;
|
||||
ReviewCount = reviewCount;
|
||||
Rate = rate;
|
||||
Viewed = viewed;
|
||||
}
|
||||
public string PersianName { get; internal set; } = string.Empty;
|
||||
public string EnglishName { get; internal set; } = string.Empty;
|
||||
public string Summery { get; internal set; } = string.Empty;
|
||||
public string ExpertCheck { get; internal set; } = string.Empty;
|
||||
public string Tags { get; internal set; } = string.Empty;
|
||||
public string Warranty { get; set; } = string.Empty;
|
||||
public double Cost { get; set; }
|
||||
public bool IsEnable { get; set; }
|
||||
public bool BeDisplayed { get; set; }
|
||||
public double PackingCost { get; set; }
|
||||
public string Warranty { get; internal set; } = string.Empty;
|
||||
public double Cost { get; internal set; }
|
||||
public bool IsEnable { get; internal set; }
|
||||
public bool BeDisplayed { get; internal set; }
|
||||
public double PackingCost { get; internal set; }
|
||||
public float Rate { get; internal set; }
|
||||
public int ReviewCount { get; internal set; }
|
||||
public int Viewed { get; internal set; }
|
||||
|
||||
|
||||
public Guid BrandId { get; internal set; }
|
||||
public Brand? Brand { get; set; }
|
||||
public Brand? Brand { get; internal set; }
|
||||
|
||||
public Guid CategoryId { get; internal set; }
|
||||
public Category? Category { get; internal set; }
|
||||
|
|
|
@ -23,6 +23,7 @@ public partial class Review : ApiEntity
|
|||
public string Comment { get; internal set; } = string.Empty;
|
||||
public float Rate { get; internal set; }
|
||||
public bool IsBuyer { get; internal set; }
|
||||
public bool IsConfirmed { get; internal set; }
|
||||
|
||||
public Guid ProductId { get; internal set; }
|
||||
public Product? Product { get; internal set; }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
namespace NetinaShop.Domain.Enums;
|
||||
|
||||
public enum QuerySortBy
|
||||
{
|
||||
[Display(Name = "هیچکدام")]
|
||||
None = 0,
|
||||
[Display(Name = "پربازدید ترین")]
|
||||
MostViewed = 1,
|
||||
[Display(Name = "محبوب ترین")]
|
||||
MostPopular = 2,
|
||||
[Display(Name = "گرانترین")]
|
||||
MostExpensive = 3,
|
||||
[Display(Name = "ارزانترین")]
|
||||
Cheapest = 4,
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using NetinaShop.Domain.Dtos.LargDtos;
|
||||
using NetinaShop.Domain.Dtos.SmallDtos;
|
||||
using NetinaShop.Domain.Entities.Products;
|
||||
|
||||
|
@ -7,7 +8,7 @@ namespace NetinaShop.Domain.Mappers
|
|||
{
|
||||
public static partial class ReviewMapper
|
||||
{
|
||||
public static Review AdaptToReview(this ReviewSDto p1)
|
||||
public static Review AdaptToReview(this ReviewLDto p1)
|
||||
{
|
||||
return p1 == null ? null : new Review()
|
||||
{
|
||||
|
@ -15,12 +16,13 @@ namespace NetinaShop.Domain.Mappers
|
|||
Comment = p1.Comment,
|
||||
Rate = p1.Rate,
|
||||
IsBuyer = p1.IsBuyer,
|
||||
IsConfirmed = p1.IsConfirmed,
|
||||
ProductId = p1.ProductId,
|
||||
UserId = p1.UserId,
|
||||
Id = p1.Id
|
||||
};
|
||||
}
|
||||
public static Review AdaptTo(this ReviewSDto p2, Review p3)
|
||||
public static Review AdaptTo(this ReviewLDto p2, Review p3)
|
||||
{
|
||||
if (p2 == null)
|
||||
{
|
||||
|
@ -32,52 +34,139 @@ namespace NetinaShop.Domain.Mappers
|
|||
result.Comment = p2.Comment;
|
||||
result.Rate = p2.Rate;
|
||||
result.IsBuyer = p2.IsBuyer;
|
||||
result.IsConfirmed = p2.IsConfirmed;
|
||||
result.ProductId = p2.ProductId;
|
||||
result.UserId = p2.UserId;
|
||||
result.Id = p2.Id;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static ReviewSDto AdaptToSDto(this Review p4)
|
||||
public static Expression<Func<ReviewLDto, Review>> ProjectToReview => p4 => new Review()
|
||||
{
|
||||
return p4 == null ? null : new ReviewSDto()
|
||||
Title = p4.Title,
|
||||
Comment = p4.Comment,
|
||||
Rate = p4.Rate,
|
||||
IsBuyer = p4.IsBuyer,
|
||||
IsConfirmed = p4.IsConfirmed,
|
||||
ProductId = p4.ProductId,
|
||||
UserId = p4.UserId,
|
||||
Id = p4.Id
|
||||
};
|
||||
public static ReviewLDto AdaptToLDto(this Review p5)
|
||||
{
|
||||
return p5 == null ? null : new ReviewLDto()
|
||||
{
|
||||
Title = p4.Title,
|
||||
Comment = p4.Comment,
|
||||
Rate = p4.Rate,
|
||||
IsBuyer = p4.IsBuyer,
|
||||
ProductId = p4.ProductId,
|
||||
UserId = p4.UserId,
|
||||
Id = p4.Id
|
||||
Title = p5.Title,
|
||||
Comment = p5.Comment,
|
||||
Rate = p5.Rate,
|
||||
IsBuyer = p5.IsBuyer,
|
||||
IsConfirmed = p5.IsConfirmed,
|
||||
ProductId = p5.ProductId,
|
||||
UserId = p5.UserId,
|
||||
Id = p5.Id
|
||||
};
|
||||
}
|
||||
public static ReviewSDto AdaptTo(this Review p5, ReviewSDto p6)
|
||||
public static ReviewLDto AdaptTo(this Review p6, ReviewLDto p7)
|
||||
{
|
||||
if (p5 == null)
|
||||
if (p6 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ReviewSDto result = p6 ?? new ReviewSDto();
|
||||
ReviewLDto result = p7 ?? new ReviewLDto();
|
||||
|
||||
result.Title = p5.Title;
|
||||
result.Comment = p5.Comment;
|
||||
result.Rate = p5.Rate;
|
||||
result.IsBuyer = p5.IsBuyer;
|
||||
result.ProductId = p5.ProductId;
|
||||
result.UserId = p5.UserId;
|
||||
result.Id = p5.Id;
|
||||
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.UserId = p6.UserId;
|
||||
result.Id = p6.Id;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static Expression<Func<Review, ReviewSDto>> ProjectToSDto => p7 => new ReviewSDto()
|
||||
public static Expression<Func<Review, ReviewLDto>> ProjectToLDto => p8 => new ReviewLDto()
|
||||
{
|
||||
Title = p7.Title,
|
||||
Comment = p7.Comment,
|
||||
Rate = p7.Rate,
|
||||
IsBuyer = p7.IsBuyer,
|
||||
ProductId = p7.ProductId,
|
||||
UserId = p7.UserId,
|
||||
Id = p7.Id
|
||||
Title = p8.Title,
|
||||
Comment = p8.Comment,
|
||||
Rate = p8.Rate,
|
||||
IsBuyer = p8.IsBuyer,
|
||||
IsConfirmed = p8.IsConfirmed,
|
||||
ProductId = p8.ProductId,
|
||||
UserId = p8.UserId,
|
||||
Id = p8.Id
|
||||
};
|
||||
public static Review AdaptToReview(this ReviewSDto p9)
|
||||
{
|
||||
return p9 == null ? null : new Review()
|
||||
{
|
||||
Title = p9.Title,
|
||||
Comment = p9.Comment,
|
||||
Rate = p9.Rate,
|
||||
IsBuyer = p9.IsBuyer,
|
||||
ProductId = p9.ProductId,
|
||||
UserId = p9.UserId,
|
||||
Id = p9.Id
|
||||
};
|
||||
}
|
||||
public static Review AdaptTo(this ReviewSDto p10, Review p11)
|
||||
{
|
||||
if (p10 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Review result = p11 ?? new Review();
|
||||
|
||||
result.Title = p10.Title;
|
||||
result.Comment = p10.Comment;
|
||||
result.Rate = p10.Rate;
|
||||
result.IsBuyer = p10.IsBuyer;
|
||||
result.ProductId = p10.ProductId;
|
||||
result.UserId = p10.UserId;
|
||||
result.Id = p10.Id;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static ReviewSDto AdaptToSDto(this Review p12)
|
||||
{
|
||||
return p12 == null ? null : new ReviewSDto()
|
||||
{
|
||||
Title = p12.Title,
|
||||
Comment = p12.Comment,
|
||||
Rate = p12.Rate,
|
||||
IsBuyer = p12.IsBuyer,
|
||||
ProductId = p12.ProductId,
|
||||
UserId = p12.UserId,
|
||||
Id = p12.Id
|
||||
};
|
||||
}
|
||||
public static ReviewSDto AdaptTo(this Review p13, ReviewSDto p14)
|
||||
{
|
||||
if (p13 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ReviewSDto result = p14 ?? new ReviewSDto();
|
||||
|
||||
result.Title = p13.Title;
|
||||
result.Comment = p13.Comment;
|
||||
result.Rate = p13.Rate;
|
||||
result.IsBuyer = p13.IsBuyer;
|
||||
result.ProductId = p13.ProductId;
|
||||
result.UserId = p13.UserId;
|
||||
result.Id = p13.Id;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static Expression<Func<Review, ReviewSDto>> ProjectToSDto => p15 => new ReviewSDto()
|
||||
{
|
||||
Title = p15.Title,
|
||||
Comment = p15.Comment,
|
||||
Rate = p15.Rate,
|
||||
IsBuyer = p15.IsBuyer,
|
||||
ProductId = p15.ProductId,
|
||||
UserId = p15.UserId,
|
||||
Id = p15.Id
|
||||
};
|
||||
}
|
||||
}
|
|
@ -12,7 +12,8 @@ public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand,
|
|||
public async Task<ProductLDto> Handle(CreateProductCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var ent = Product.Create(request.PersianName, request.EnglishName, request.Summery, request.ExpertCheck,
|
||||
request.Tags, request.Warranty,request.BeDisplayed,request.Cost,request.PackingCost, request.BrandId,request.CategoryId);
|
||||
request.Tags, request.Warranty,request.BeDisplayed,request.Cost,request.PackingCost,0,0,0,
|
||||
request.BrandId,request.CategoryId);
|
||||
foreach (var specification in request.Specifications)
|
||||
{
|
||||
ent.AddSpecification(specification.Title, specification.Detail, specification.Value,
|
||||
|
|
|
@ -10,8 +10,35 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, List<Pr
|
|||
}
|
||||
public async Task<List<ProductSDto>> Handle(GetProductsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _repositoryWrapper.SetRepository<Product>().TableNoTracking
|
||||
.OrderByDescending(b => b.CreatedAt).Skip(request.Page * 10)
|
||||
var products = _repositoryWrapper.SetRepository<Product>().TableNoTracking;
|
||||
if (request.CategoryId != default)
|
||||
products = products.Where(p => p.CategoryId == request.CategoryId);
|
||||
if (request.BrandId != default)
|
||||
products = products.Where(p => p.BrandId == request.BrandId);
|
||||
if (request.MinPrice > -1)
|
||||
products = products.Where(p => p.Cost >= request.MinPrice);
|
||||
if (request.MaxPrice > 0)
|
||||
products = products.Where(p => p.Cost <= request.MaxPrice);
|
||||
if (request.SortBy != QuerySortBy.None)
|
||||
{
|
||||
switch (request.SortBy)
|
||||
{
|
||||
case QuerySortBy.Cheapest:
|
||||
products = products.OrderBy(p => p.Cost);
|
||||
break;
|
||||
case QuerySortBy.MostExpensive:
|
||||
products = products.OrderByDescending(p => p.Cost);
|
||||
break;
|
||||
case QuerySortBy.MostPopular:
|
||||
products = products.OrderByDescending(p => p.Rate);
|
||||
break;
|
||||
case QuerySortBy.MostViewed:
|
||||
products = products.OrderByDescending(p => p.Viewed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return await products.Skip(request.Page * 10)
|
||||
.Take(10)
|
||||
.Select(ProductMapper.ProjectToSDto)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
|
|
@ -16,7 +16,16 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
|
|||
throw new AppException("Product not found", ApiResultStatusCode.NotFound);
|
||||
|
||||
var newEnt = Product.Create(request.PersianName, request.EnglishName, request.Summery, request.ExpertCheck,
|
||||
request.Tags, request.Warranty,request.BeDisplayed,request.Cost,request.PackingCost, request.BrandId,request.CategoryId);
|
||||
request.Tags,
|
||||
request.Warranty,
|
||||
request.BeDisplayed,
|
||||
request.Cost,
|
||||
request.PackingCost,
|
||||
ent.ReviewCount,
|
||||
ent.Rate,
|
||||
ent.Viewed,
|
||||
request.BrandId,
|
||||
request.CategoryId);
|
||||
newEnt.Id = ent.Id;
|
||||
|
||||
var dbSpecifications = await _repositoryWrapper.SetRepository<Specification>().TableNoTracking
|
||||
|
@ -29,6 +38,7 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
|
|||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var specification in request.Specifications.Where(s => s.Id == default))
|
||||
{
|
||||
newEnt.AddSpecification(specification.Title, specification.Detail, specification.Value, specification.IsFeature, specification.ParentId);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using AppException = NetinaShop.Common.Models.Exception.AppException;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Reviews;
|
||||
|
||||
public class CreateReviewCommandHandler : IRequestHandler<CreateReviewCommand,ReviewSDto>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public CreateReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<ReviewSDto> Handle(CreateReviewCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var review = Review.Create(request.Title, request.Comment, request.Rate, request.IsBuyer, request.ProductId,
|
||||
request.UserId);
|
||||
var product = await _repositoryWrapper.SetRepository<Product>()
|
||||
.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<Product>().Update(product);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_repositoryWrapper.SetRepository<Review>().Add(review);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return review.AdaptToSDto();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace NetinaShop.Repository.Handlers.Reviews;
|
||||
|
||||
public class DeleteReviewCommandHandler : IRequestHandler<DeleteReviewCommand,bool>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public DeleteReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<bool> Handle(DeleteReviewCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var review = await _repositoryWrapper.SetRepository<Review>().TableNoTracking
|
||||
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
|
||||
if (review == null)
|
||||
throw new AppException("Review not found", ApiResultStatusCode.NotFound);
|
||||
|
||||
_repositoryWrapper.SetRepository<Review>().Delete(review);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
namespace NetinaShop.Repository.Handlers.Reviews;
|
||||
|
||||
public class GetReviewQueryHandler : IRequestHandler<GetReviewQuery,ReviewLDto>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public GetReviewQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<ReviewLDto> Handle(GetReviewQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var review = await _repositoryWrapper.SetRepository<Review>()
|
||||
.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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
namespace NetinaShop.Repository.Handlers.Reviews;
|
||||
|
||||
public class GetReviewsQueryHandler : IRequestHandler<GetReviewsQuery,List<ReviewSDto>>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public GetReviewsQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<List<ReviewSDto>> Handle(GetReviewsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _repositoryWrapper.SetRepository<Review>()
|
||||
.TableNoTracking
|
||||
.OrderByDescending(r => r.CreatedAt)
|
||||
.Skip(request.Page * 15)
|
||||
.Take(15)
|
||||
.Select(ReviewMapper.ProjectToSDto)
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue