feat : version 0.3.2.11

fix upload file issue , fix cateogies and brands errors for web
release
Amir Hossein Khademi 2024-02-04 16:38:23 +03:30
parent 10892f9e82
commit 7867c79cc9
22 changed files with 132 additions and 21 deletions

View File

@ -1 +1 @@
0.2.1.10
0.3.2.11

View File

@ -17,7 +17,7 @@
"TaxesFee": 9
},
"SiteSettings": {
"BaseUrl": "http://localhost:32770",
"BaseUrl": "http://192.168.88.17:32770",
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
"UserSetting": {
"Username": "netinashop",

View File

@ -32,9 +32,9 @@ public class BrandController : ICarterModule
}
// GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int? page, [FromQuery]string? brandName, IMediator mediator, CancellationToken cancellationToken)
public async Task<IResult> 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

View File

@ -32,8 +32,8 @@ public class ProductController : ICarterModule
}
// GET:Get All Entity
public async Task<IResult> 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<IResult> 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<IResult> GetAsync(Guid id, IMediator mediator,CancellationToken cancellationToken)

View File

@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>0.2.1.10</AssemblyVersion>
<FileVersion>0.2.1.10</FileVersion>
<AssemblyVersion>0.3.2.11</AssemblyVersion>
<FileVersion>0.3.2.11</FileVersion>
</PropertyGroup>
<ItemGroup>

View File

@ -13,6 +13,7 @@ namespace NetinaShop.Common.Models.Mapper
public abstract class BaseDto<TDto, TEntity> : INotifyPropertyChanged, IBaseDto<TDto,TEntity> where TEntity : class where TDto : class
{
public Guid Id { get; set; }
public DateTime CreatedAt { get; set; }
public static Expression<Func<TEntity, TDto>> ProjectToDto
{
get => GetProjectToDto();

View File

@ -1,4 +1,4 @@
namespace NetinaShop.Domain.CommandQueries.Queries;
public record GetBrandQuery(Guid Id) : IRequest<BrandLDto>;
public record GetBrandsQuery(int? Page, string? BrandName) : IRequest<List<BrandSDto>>;
public record GetBrandsQuery(int? Page, string? BrandName , Guid CategoryId) : IRequest<List<BrandSDto>>;

View File

@ -1,4 +1,5 @@
namespace NetinaShop.Domain.CommandQueries.Queries;
public record GetProductCategoryQuery(Guid Id) : IRequest<ProductCategoryLDto>;
public record GetProductCategoriesQuery(int? Page , bool? SortByMain,string? CategoryName) : IRequest<List<ProductCategorySDto>>;
public record GetProductCategoriesQuery(int? Page , bool? SortByMain, string? CategoryName) : IRequest<List<ProductCategorySDto>>;
public record GetProductCategoryChildrenQuery(Guid Id) : IRequest<List<Guid>>;

View File

@ -2,10 +2,12 @@
public sealed record GetProductQuery(Guid Id) : IRequest<ProductLDto>;
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<List<ProductSDto>>;

View File

@ -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
};

View File

@ -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;

View File

@ -5,15 +5,39 @@ namespace NetinaShop.Repository.Handlers.Brands;
public class GetBrandsQueryHandler : IRequestHandler<GetBrandsQuery, List<BrandSDto>>
{
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<List<BrandSDto>> Handle(GetBrandsQuery request, CancellationToken cancellationToken)
{
IQueryable<Brand> baseBrands;
List<BrandSDto> brands;
List<BrandSDto> brands = new List<BrandSDto>();
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<Brand>()
.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<Brand>()

View File

@ -17,7 +17,9 @@ public class UpdateBrandCommandHandler : IRequestHandler<UpdateBrandCommand,bool
if (ent == null)
throw new AppException("Brand not found");
var newEnt = Brand.Create(request.Name, request.Description, request.HasSpecialPage, request.PageUrl);
newEnt.Id = ent.Id;
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
_repositoryWrapper.SetRepository<Brand>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;

View File

@ -11,6 +11,7 @@ public class GetDiscountsQueryHandler : IRequestHandler<GetDiscountsQuery, List<
public async Task<List<DiscountSDto>> Handle(GetDiscountsQuery request, CancellationToken cancellationToken)
{
return await _repositoryWrapper.SetRepository<Discount>().TableNoTracking
.Where(d=>!d.IsSpecialOffer)
.OrderByDescending(b => b.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(DiscountMapper.ProjectToSDto)

View File

@ -18,6 +18,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
throw new AppException("Discount not found", ApiResultStatusCode.NotFound);
var newEnt = Discount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.IsForInvitation, request.IsSpecialOffer);
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
_repositoryWrapper.SetRepository<Discount>().Update(newEnt);
break;
case DiscountType.Category:
@ -30,6 +32,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation,request.IsSpecialOffer, request.CategoryId);
catDis.Id = catEnt.Id;
catDis.CreatedAt = catEnt.CreatedAt;
catDis.CreatedBy = catEnt.CreatedBy;
_repositoryWrapper.SetRepository<CategoryDiscount>().Update(catDis);
break;
@ -43,6 +47,8 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.IsSpecialOffer, request.ProductId);
productDis.Id = productEnt.Id;
productDis.CreatedAt = productEnt.CreatedAt;
productDis.CreatedBy = productEnt.CreatedBy;
_repositoryWrapper.SetRepository<ProductDiscount>().Update(productDis);
break;
}

View File

@ -48,7 +48,8 @@ public class GetProductCategoriesQueryHandler : IRequestHandler<GetProductCatego
foreach (var cat in groupCats)
cat.Children = groupCats.Where(c => c.ParentId == cat.Id).ToList();
return groupCats.Where(c => c.IsMain).ToList();
var cats = groupCats.Where(c => c.IsMain).ToList();
return cats;
}
}

View File

@ -0,0 +1,46 @@
using MediatR;
using System.Threading;
namespace NetinaShop.Repository.Handlers.ProductCategories;
public class GetProductCategoryChildrenQueryHandler : IRequestHandler<GetProductCategoryChildrenQuery,List<Guid>>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public GetProductCategoryChildrenQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<List<Guid>> 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<List<Guid>> Recursive(Guid id,CancellationToken cancellationToken)
{
var children = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.Where(c => c.ParentId == id)
.Select(c => c.Id)
.ToListAsync(cancellationToken);
var returnList = new List<Guid> { 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;
}
}

View File

@ -18,6 +18,9 @@ public class GetProductCategoryQueryHandler : IRequestHandler<GetProductCategory
.FirstOrDefaultAsync(cancellationToken);
if (ent == null)
throw new AppException("ProductCategory not found", ApiResultStatusCode.NotFound);
//ent.
return ent;
}
}

View File

@ -19,6 +19,8 @@ public class UpdateProductCategoryCommandHandler : IRequestHandler<UpdateProduct
var newEnt = ProductCategory.Create(request.Name, request.Description, request.IsMain);
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
if (request.ParentId != default)
newEnt.SetParent(request.ParentId);

View File

@ -3,20 +3,27 @@
public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, List<ProductSDto>>
{
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<List<ProductSDto>> Handle(GetProductsQuery request, CancellationToken cancellationToken)
{
var products = _repositoryWrapper.SetRepository<Product>().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)

View File

@ -28,6 +28,8 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
request.BrandId,
request.CategoryId);
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
var dbSpecifications = await _repositoryWrapper.SetRepository<Specification>().TableNoTracking
.Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken);

View File

@ -20,6 +20,8 @@ public class UpdateShippingCommandHandler : IRequestHandler<UpdateShippingComman
var newEnt = Shipping.Create(request.Title, request.WarehouseName, request.IsFastShipping, request.IsShipBySeller,
request.IsOriginalWarehouse,request.DeliveryCost);
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
_repositoryWrapper.SetRepository<Shipping>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;