From 7867c79cc9ee402b9b88aa77d9a0f0ffc467999f Mon Sep 17 00:00:00 2001 From: "Amir.H Khademi" Date: Sun, 4 Feb 2024 16:38:23 +0330 Subject: [PATCH] feat : version 0.3.2.11 fix upload file issue , fix cateogies and brands errors for web --- .version | 2 +- .../AppSettings/appsettings.Development.json | 2 +- NetinaShop.Api/Controller/BrandController.cs | 4 +- .../Controller/ProductController.cs | 4 +- NetinaShop.Api/NetinaShop.Api.csproj | 4 +- NetinaShop.Common/Models/Mapper/BaseDto.cs | 1 + .../CommandQueries/Queries/BrandQueries.cs | 2 +- .../Queries/ProductCategoryQueries.cs | 3 +- .../CommandQueries/Queries/ProductQueries.cs | 6 ++- NetinaShop.Domain/Mappers/DiscountMapper.g.cs | 11 +++++ .../Services/StorageService.cs | 2 +- .../Handlers/Brands/GetBrandsQueryHandler.cs | 28 ++++++++++- .../Brands/UpdateBrandCommandHandler.cs | 4 +- .../Discounts/GetDiscountsQueryHandler.cs | 1 + .../Discounts/UpdateDiscountCommandHandler.cs | 6 +++ .../GetProductCategoriesQueryHandler.cs | 3 +- .../GetProductCategoryChildrenQueryHandler.cs | 46 +++++++++++++++++++ .../GetProductCategoryQueryHandler.cs | 3 ++ .../UpdateProductCategoryCommandHandler.cs | 2 + .../Products/GetProductsQueryHandler.cs | 15 ++++-- .../Products/UpdateProductCommandHandler.cs | 2 + .../UpdateShippingCommandHandler.cs | 2 + 22 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryChildrenQueryHandler.cs diff --git a/.version b/.version index d370b3e..d1dd92c 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.1.10 \ No newline at end of file +0.3.2.11 \ No newline at end of file diff --git a/NetinaShop.Api/AppSettings/appsettings.Development.json b/NetinaShop.Api/AppSettings/appsettings.Development.json index 1bc8273..83b7d93 100644 --- a/NetinaShop.Api/AppSettings/appsettings.Development.json +++ b/NetinaShop.Api/AppSettings/appsettings.Development.json @@ -17,7 +17,7 @@ "TaxesFee": 9 }, "SiteSettings": { - "BaseUrl": "http://localhost:32770", + "BaseUrl": "http://192.168.88.17:32770", "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B", "UserSetting": { "Username": "netinashop", diff --git a/NetinaShop.Api/Controller/BrandController.cs b/NetinaShop.Api/Controller/BrandController.cs index 36c8051..ab9dc1f 100644 --- a/NetinaShop.Api/Controller/BrandController.cs +++ b/NetinaShop.Api/Controller/BrandController.cs @@ -32,9 +32,9 @@ public class BrandController : ICarterModule } // GET:Get All Entity - public async Task GetAllAsync([FromQuery] int? page, [FromQuery]string? brandName, IMediator mediator, CancellationToken cancellationToken) + public async Task GetAllAsync([FromQuery] int? page, [FromQuery]string? brandName, [FromQuery]Guid? categoryId, IMediator mediator, CancellationToken cancellationToken) { - return TypedResults.Ok(await mediator.Send(new GetBrandsQuery(Page: page, BrandName: brandName),cancellationToken)); + return TypedResults.Ok(await mediator.Send(new GetBrandsQuery(Page: page, BrandName: brandName, CategoryId : categoryId ?? default),cancellationToken)); } // GET:Get An Entity By Id diff --git a/NetinaShop.Api/Controller/ProductController.cs b/NetinaShop.Api/Controller/ProductController.cs index 94bac24..ab29685 100644 --- a/NetinaShop.Api/Controller/ProductController.cs +++ b/NetinaShop.Api/Controller/ProductController.cs @@ -32,8 +32,8 @@ public class ProductController : ICarterModule } // GET:Get All Entity - public async Task GetAllAsync([FromQuery] int page, [FromQuery]string? productName, [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 ,ProductName: productName, CategoryId: categoryId ?? default , BrandId: brandId ?? default , MinPrice: minPrice ?? -1 , MaxPrice:maxPrice ?? 0),cancellationToken)); + public async Task GetAllAsync([FromQuery] int page, [FromQuery]string? productName, [FromQuery] QuerySortBy? sortBy,[FromQuery] Guid? categoryId , [FromQuery] Guid[]? brandIds , [FromQuery]double? minPrice , [FromQuery] double? maxPrice, [FromQuery]bool? isActive, IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new GetProductsQuery(Page: page,SortBy: sortBy ?? 0 ,ProductName: productName, CategoryId: categoryId ?? default , BrandIds: brandIds , MinPrice: minPrice ?? -1 , MaxPrice:maxPrice ?? 0,IsActive:isActive),cancellationToken)); // GET:Get An Entity By Id public async Task GetAsync(Guid id, IMediator mediator,CancellationToken cancellationToken) diff --git a/NetinaShop.Api/NetinaShop.Api.csproj b/NetinaShop.Api/NetinaShop.Api.csproj index 1f2b1cc..a5e62c2 100644 --- a/NetinaShop.Api/NetinaShop.Api.csproj +++ b/NetinaShop.Api/NetinaShop.Api.csproj @@ -6,8 +6,8 @@ enable true Linux - 0.2.1.10 - 0.2.1.10 + 0.3.2.11 + 0.3.2.11 diff --git a/NetinaShop.Common/Models/Mapper/BaseDto.cs b/NetinaShop.Common/Models/Mapper/BaseDto.cs index cf3f69b..f74a484 100644 --- a/NetinaShop.Common/Models/Mapper/BaseDto.cs +++ b/NetinaShop.Common/Models/Mapper/BaseDto.cs @@ -13,6 +13,7 @@ namespace NetinaShop.Common.Models.Mapper public abstract class BaseDto : INotifyPropertyChanged, IBaseDto where TEntity : class where TDto : class { public Guid Id { get; set; } + public DateTime CreatedAt { get; set; } public static Expression> ProjectToDto { get => GetProjectToDto(); diff --git a/NetinaShop.Domain/CommandQueries/Queries/BrandQueries.cs b/NetinaShop.Domain/CommandQueries/Queries/BrandQueries.cs index d6700e2..b7bee2a 100644 --- a/NetinaShop.Domain/CommandQueries/Queries/BrandQueries.cs +++ b/NetinaShop.Domain/CommandQueries/Queries/BrandQueries.cs @@ -1,4 +1,4 @@ namespace NetinaShop.Domain.CommandQueries.Queries; public record GetBrandQuery(Guid Id) : IRequest; -public record GetBrandsQuery(int? Page, string? BrandName) : IRequest>; \ No newline at end of file +public record GetBrandsQuery(int? Page, string? BrandName , Guid CategoryId) : IRequest>; \ No newline at end of file diff --git a/NetinaShop.Domain/CommandQueries/Queries/ProductCategoryQueries.cs b/NetinaShop.Domain/CommandQueries/Queries/ProductCategoryQueries.cs index 012a057..4a0cd75 100644 --- a/NetinaShop.Domain/CommandQueries/Queries/ProductCategoryQueries.cs +++ b/NetinaShop.Domain/CommandQueries/Queries/ProductCategoryQueries.cs @@ -1,4 +1,5 @@ namespace NetinaShop.Domain.CommandQueries.Queries; public record GetProductCategoryQuery(Guid Id) : IRequest; -public record GetProductCategoriesQuery(int? Page , bool? SortByMain,string? CategoryName) : IRequest>; \ No newline at end of file +public record GetProductCategoriesQuery(int? Page , bool? SortByMain, string? CategoryName) : IRequest>; +public record GetProductCategoryChildrenQuery(Guid Id) : IRequest>; \ No newline at end of file diff --git a/NetinaShop.Domain/CommandQueries/Queries/ProductQueries.cs b/NetinaShop.Domain/CommandQueries/Queries/ProductQueries.cs index 79b0752..156275a 100644 --- a/NetinaShop.Domain/CommandQueries/Queries/ProductQueries.cs +++ b/NetinaShop.Domain/CommandQueries/Queries/ProductQueries.cs @@ -2,10 +2,12 @@ public sealed record GetProductQuery(Guid Id) : IRequest; -public sealed record GetProductsQuery(int Page = 0 , +public sealed record GetProductsQuery( + Guid[]? BrandIds, + bool? IsActive, + int Page = 0 , string? ProductName = default, QuerySortBy SortBy = QuerySortBy.None , Guid CategoryId = default , - Guid BrandId = default , double MinPrice = -1 , double MaxPrice = 0) : IRequest>; \ No newline at end of file diff --git a/NetinaShop.Domain/Mappers/DiscountMapper.g.cs b/NetinaShop.Domain/Mappers/DiscountMapper.g.cs index 5f57af0..9343730 100644 --- a/NetinaShop.Domain/Mappers/DiscountMapper.g.cs +++ b/NetinaShop.Domain/Mappers/DiscountMapper.g.cs @@ -27,6 +27,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p1.HasPriceCeiling, IsInfinity = p1.IsInfinity, UseCount = p1.UseCount, + IsSpecialOffer = p1.IsSpecialOffer, IsForInvitation = p1.IsForInvitation, Id = p1.Id }; @@ -54,6 +55,7 @@ namespace NetinaShop.Domain.Mappers result.HasPriceCeiling = p2.HasPriceCeiling; result.IsInfinity = p2.IsInfinity; result.UseCount = p2.UseCount; + result.IsSpecialOffer = p2.IsSpecialOffer; result.IsForInvitation = p2.IsForInvitation; result.Id = p2.Id; return result; @@ -76,6 +78,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p4.HasPriceCeiling, IsInfinity = p4.IsInfinity, UseCount = p4.UseCount, + IsSpecialOffer = p4.IsSpecialOffer, IsForInvitation = p4.IsForInvitation, Id = p4.Id }; @@ -98,6 +101,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p5.HasPriceCeiling, IsInfinity = p5.IsInfinity, UseCount = p5.UseCount, + IsSpecialOffer = p5.IsSpecialOffer, IsForInvitation = p5.IsForInvitation, Id = p5.Id }; @@ -125,6 +129,7 @@ namespace NetinaShop.Domain.Mappers result.HasPriceCeiling = p6.HasPriceCeiling; result.IsInfinity = p6.IsInfinity; result.UseCount = p6.UseCount; + result.IsSpecialOffer = p6.IsSpecialOffer; result.IsForInvitation = p6.IsForInvitation; result.Id = p6.Id; return result; @@ -147,6 +152,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p8.HasPriceCeiling, IsInfinity = p8.IsInfinity, UseCount = p8.UseCount, + IsSpecialOffer = p8.IsSpecialOffer, IsForInvitation = p8.IsForInvitation, Id = p8.Id }; @@ -169,6 +175,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p9.HasPriceCeiling, IsInfinity = p9.IsInfinity, UseCount = p9.UseCount, + IsSpecialOffer = p9.IsSpecialOffer, IsForInvitation = p9.IsForInvitation, Id = p9.Id }; @@ -196,6 +203,7 @@ namespace NetinaShop.Domain.Mappers result.HasPriceCeiling = p10.HasPriceCeiling; result.IsInfinity = p10.IsInfinity; result.UseCount = p10.UseCount; + result.IsSpecialOffer = p10.IsSpecialOffer; result.IsForInvitation = p10.IsForInvitation; result.Id = p10.Id; return result; @@ -220,6 +228,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p12.HasPriceCeiling, IsInfinity = p12.IsInfinity, UseCount = p12.UseCount, + IsSpecialOffer = p12.IsSpecialOffer, IsForInvitation = p12.IsForInvitation, Id = p12.Id }; @@ -247,6 +256,7 @@ namespace NetinaShop.Domain.Mappers result.HasPriceCeiling = p13.HasPriceCeiling; result.IsInfinity = p13.IsInfinity; result.UseCount = p13.UseCount; + result.IsSpecialOffer = p13.IsSpecialOffer; result.IsForInvitation = p13.IsForInvitation; result.Id = p13.Id; return result; @@ -269,6 +279,7 @@ namespace NetinaShop.Domain.Mappers HasPriceCeiling = p15.HasPriceCeiling, IsInfinity = p15.IsInfinity, UseCount = p15.UseCount, + IsSpecialOffer = p15.IsSpecialOffer, IsForInvitation = p15.IsForInvitation, Id = p15.Id }; diff --git a/NetinaShop.Infrastructure/Services/StorageService.cs b/NetinaShop.Infrastructure/Services/StorageService.cs index 65ee924..4e26ba6 100644 --- a/NetinaShop.Infrastructure/Services/StorageService.cs +++ b/NetinaShop.Infrastructure/Services/StorageService.cs @@ -61,7 +61,7 @@ public class StorageService : IStorageService CannedACL = S3CannedACL.PublicRead }; - putRequest.Metadata.Add("x-amz-meta-title", fileName); + //putRequest.Metadata.Add("x-amz-meta-title", fileName); PutObjectResponse response = await client.PutObjectAsync(putRequest); return fileName; diff --git a/NetinaShop.Repository/Handlers/Brands/GetBrandsQueryHandler.cs b/NetinaShop.Repository/Handlers/Brands/GetBrandsQueryHandler.cs index 2fa29ad..893d2a9 100644 --- a/NetinaShop.Repository/Handlers/Brands/GetBrandsQueryHandler.cs +++ b/NetinaShop.Repository/Handlers/Brands/GetBrandsQueryHandler.cs @@ -5,15 +5,39 @@ namespace NetinaShop.Repository.Handlers.Brands; public class GetBrandsQueryHandler : IRequestHandler> { private readonly IRepositoryWrapper _repositoryWrapper; + private readonly IMediator _mediator; - public GetBrandsQueryHandler(IRepositoryWrapper repositoryWrapper) + public GetBrandsQueryHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator) { _repositoryWrapper = repositoryWrapper; + _mediator = mediator; } public async Task> Handle(GetBrandsQuery request, CancellationToken cancellationToken) { IQueryable baseBrands; - List brands; + List brands = new List(); + if (request.CategoryId != default) + { + var products = await _mediator.Send(new GetProductsQuery(BrandIds: null, Page:0, SortBy: QuerySortBy.None,CategoryId: request.CategoryId, IsActive : null), + cancellationToken); + var brandGrouped = products.GroupBy(p => p.BrandId); + foreach (var grouping in brandGrouped) + { + if (grouping.Key != default) + { + var brand = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(b => b.Id == grouping.Key) + .Select(BrandMapper.ProjectToSDto) + .FirstOrDefaultAsync(cancellationToken); + if(brand!=null) + brands.Add(brand); + } + } + + return brands; + } + if (request.BrandName != null) { baseBrands = _repositoryWrapper.SetRepository() diff --git a/NetinaShop.Repository/Handlers/Brands/UpdateBrandCommandHandler.cs b/NetinaShop.Repository/Handlers/Brands/UpdateBrandCommandHandler.cs index feee57b..d876d4f 100644 --- a/NetinaShop.Repository/Handlers/Brands/UpdateBrandCommandHandler.cs +++ b/NetinaShop.Repository/Handlers/Brands/UpdateBrandCommandHandler.cs @@ -17,7 +17,9 @@ public class UpdateBrandCommandHandler : IRequestHandler().Update(newEnt); await _repositoryWrapper.SaveChangesAsync(cancellationToken); return true; diff --git a/NetinaShop.Repository/Handlers/Discounts/GetDiscountsQueryHandler.cs b/NetinaShop.Repository/Handlers/Discounts/GetDiscountsQueryHandler.cs index b230bf9..15a4ed5 100644 --- a/NetinaShop.Repository/Handlers/Discounts/GetDiscountsQueryHandler.cs +++ b/NetinaShop.Repository/Handlers/Discounts/GetDiscountsQueryHandler.cs @@ -11,6 +11,7 @@ public class GetDiscountsQueryHandler : IRequestHandler> Handle(GetDiscountsQuery request, CancellationToken cancellationToken) { return await _repositoryWrapper.SetRepository().TableNoTracking + .Where(d=>!d.IsSpecialOffer) .OrderByDescending(b => b.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(DiscountMapper.ProjectToSDto) diff --git a/NetinaShop.Repository/Handlers/Discounts/UpdateDiscountCommandHandler.cs b/NetinaShop.Repository/Handlers/Discounts/UpdateDiscountCommandHandler.cs index cb34b04..68612de 100644 --- a/NetinaShop.Repository/Handlers/Discounts/UpdateDiscountCommandHandler.cs +++ b/NetinaShop.Repository/Handlers/Discounts/UpdateDiscountCommandHandler.cs @@ -18,6 +18,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler().Update(newEnt); break; case DiscountType.Category: @@ -30,6 +32,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler().Update(catDis); break; @@ -43,6 +47,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler().Update(productDis); break; } diff --git a/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoriesQueryHandler.cs b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoriesQueryHandler.cs index 1bac69d..b99bf7e 100644 --- a/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoriesQueryHandler.cs +++ b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoriesQueryHandler.cs @@ -48,7 +48,8 @@ public class GetProductCategoriesQueryHandler : IRequestHandler c.ParentId == cat.Id).ToList(); - return groupCats.Where(c => c.IsMain).ToList(); + var cats = groupCats.Where(c => c.IsMain).ToList(); + return cats; } } \ No newline at end of file diff --git a/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryChildrenQueryHandler.cs b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryChildrenQueryHandler.cs new file mode 100644 index 0000000..18da4d6 --- /dev/null +++ b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryChildrenQueryHandler.cs @@ -0,0 +1,46 @@ +using MediatR; +using System.Threading; + +namespace NetinaShop.Repository.Handlers.ProductCategories; + +public class GetProductCategoryChildrenQueryHandler : IRequestHandler> +{ + private readonly IRepositoryWrapper _repositoryWrapper; + + public GetProductCategoryChildrenQueryHandler(IRepositoryWrapper repositoryWrapper) + { + _repositoryWrapper = repositoryWrapper; + } + + public async Task> Handle(GetProductCategoryChildrenQuery request, CancellationToken cancellationToken) + { + if (request.Id == default) + throw new AppException("Category id is null"); + + return await Recursive(request.Id, cancellationToken); + + } + + private async Task> Recursive(Guid id,CancellationToken cancellationToken) + { + + var children = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(c => c.ParentId == id) + .Select(c => c.Id) + .ToListAsync(cancellationToken); + var returnList = new List { id }; + if (children.Count > 0) + { + foreach (var child in children) + { + var chs = await Recursive(child,cancellationToken); + chs.ForEach(c=>returnList.Add(c)); + } + + return returnList; + } + else + return returnList; + } +} \ No newline at end of file diff --git a/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryQueryHandler.cs b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryQueryHandler.cs index a0ff467..9be3c35 100644 --- a/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryQueryHandler.cs +++ b/NetinaShop.Repository/Handlers/ProductCategories/GetProductCategoryQueryHandler.cs @@ -18,6 +18,9 @@ public class GetProductCategoryQueryHandler : IRequestHandler> { private readonly IRepositoryWrapper _repositoryWrapper; + private readonly IMediator _mediator; - public GetProductsQueryHandler(IRepositoryWrapper repositoryWrapper) + public GetProductsQueryHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator) { _repositoryWrapper = repositoryWrapper; + _mediator = mediator; } public async Task> Handle(GetProductsQuery request, CancellationToken cancellationToken) { var products = _repositoryWrapper.SetRepository().TableNoTracking; + if (request.IsActive != null) + products = products.Where(p => p.IsEnable == request.IsActive ); if (request.ProductName != null) products = products.Where(p => p.PersianName.ToLower().Trim().Contains(request.ProductName.ToLower().Trim())); if (request.CategoryId != default) - products = products.Where(p => p.CategoryId == request.CategoryId); - if (request.BrandId != default) - products = products.Where(p => p.BrandId == request.BrandId); + { + var cats = await _mediator.Send(new GetProductCategoryChildrenQuery(request.CategoryId), cancellationToken); + products = products.Where(p => cats.Contains(p.CategoryId)); + } + if (request.BrandIds is { Length: > 0 }) + products = products.Where(p => request.BrandIds.Contains(p.BrandId)); if (request.MinPrice > -1) products = products.Where(p => p.Cost >= request.MinPrice); if (request.MaxPrice > 0) diff --git a/NetinaShop.Repository/Handlers/Products/UpdateProductCommandHandler.cs b/NetinaShop.Repository/Handlers/Products/UpdateProductCommandHandler.cs index d5884fe..0412472 100644 --- a/NetinaShop.Repository/Handlers/Products/UpdateProductCommandHandler.cs +++ b/NetinaShop.Repository/Handlers/Products/UpdateProductCommandHandler.cs @@ -28,6 +28,8 @@ public class UpdateProductCommandHandler : IRequestHandler().TableNoTracking .Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken); diff --git a/NetinaShop.Repository/Handlers/Warehouses/UpdateShippingCommandHandler.cs b/NetinaShop.Repository/Handlers/Warehouses/UpdateShippingCommandHandler.cs index e08fd14..878a459 100644 --- a/NetinaShop.Repository/Handlers/Warehouses/UpdateShippingCommandHandler.cs +++ b/NetinaShop.Repository/Handlers/Warehouses/UpdateShippingCommandHandler.cs @@ -20,6 +20,8 @@ public class UpdateShippingCommandHandler : IRequestHandler().Update(newEnt); await _repositoryWrapper.SaveChangesAsync(cancellationToken); return true;