fix(CateforyDiscount) , fix(ProductReviewCountInDTos) , VER 1.5.17.23

subProduct
Amir Hossein Khademi 2024-09-29 12:31:08 +03:30
parent c3abc322d4
commit a1f2e92863
16 changed files with 87 additions and 31 deletions

View File

@ -1 +1 @@
1.5.14.20
1.5.17.23

View File

@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"PostgresServer": "Host=185.220.227.246;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi",
"PostgresServer": "Host=185.220.227.39;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi",
"Postgres": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB",
"MartenDB": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB"
},

View File

@ -36,6 +36,10 @@ public class BlogController : ICarterModule
.WithDisplayName("Update Blog")
.HasApiVersion(1.0);
group.MapGet("{blogId}/comment", GetBlogCommentsAsync)
.WithDisplayName("Get Blog Comments")
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
@ -49,6 +53,10 @@ public class BlogController : ICarterModule
}
private async Task<IResult> GetBlogCommentsAsync([FromQuery] int page, [FromQuery] int count, [FromRoute] Guid blogId, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, null, blogId), cancellationToken));
private async Task<IResult> GetBlogNewLinkAsync([FromQuery]string slug,IRepositoryWrapper repositoryWrapper,IOptionsSnapshot<SiteSettings> snapshot,CancellationToken cancellationToken)
{
var htmlSlug = HttpUtility.UrlEncode(slug);

View File

@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>1.5.14.20</AssemblyVersion>
<FileVersion>1.5.14.20</FileVersion>
<AssemblyVersion>1.5.17.23</AssemblyVersion>
<FileVersion>1.5.17.23</FileVersion>
</PropertyGroup>
<ItemGroup>
@ -15,7 +15,7 @@
<PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="Carter" Version="8.2.1" />
<PackageReference Include="Carter" Version="8.1.0" />
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.1.0" />

View File

@ -72,7 +72,7 @@ public static class ServiceExtensions
serviceCollection.AddDbContextFactory<ApplicationContext>(options =>
{
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
options.UseNpgsql(Configuration.GetConnectionString("Postgres"), b => b.MigrationsAssembly("Netina.Repository"))
options.UseNpgsql(Configuration.GetConnectionString("PostgresServer"), b => b.MigrationsAssembly("Netina.Repository"))
.UseProjectAssembly(typeof(ApplicationUser).Assembly);
//options.EnableServiceProviderCaching(true);

View File

@ -17,6 +17,7 @@ namespace Netina.Common.Extensions
return outPut;
}
public static string ToPriceWhitPriceType(this long price, string priceType)
{
return price.ToString("N0") + " " + priceType;

View File

@ -1,4 +1,6 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
using Netina.Domain.Entities.ProductCategories;
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateOrderDiscountCommandHandler(
IRepositoryWrapper repositoryWrapper,
@ -51,8 +53,12 @@ public class CalculateOrderDiscountCommandHandler(
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if ( categoryDiscount!=null && !categoryDiscount.IsExpired())
{
totalPrice = request.Order.OrderProducts.Where(op => op.ProductCategoryId == categoryDiscount.CategoryId).Sum(op => op.ProductCost);
var subCats = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.Where(c => c.ParentId == categoryDiscount.CategoryId)
.Select(c => c.Id)
.ToListAsync(cancellationToken);
subCats.Add(categoryDiscount.CategoryId);
totalPrice = request.Order.OrderProducts.Where(op => subCats.Contains(op.ProductCategoryId)).Sum(op => op.ProductCost);
}
}
else if (discount.Type == DiscountType.Product)

View File

@ -68,6 +68,12 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost;
}
if (request.DiscountPercent == 0)
{
request.CostWithDiscount = 0;
request.HasDiscount = false;
}
return request;
}

View File

@ -23,8 +23,17 @@ public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper,
var deliveryPrice = order.OrderDelivery?.DeliveryCost ?? 0;
double productDiscountPrice = order.OrderProducts.Sum(op=>(op.ProductFee - op.ProductFeeWithDiscount) * op.Count);
double discountCodePrice = 0;
if (!order.DiscountCode.IsNullOrEmpty())
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),cancellationToken);
try
{
if (!order.DiscountCode.IsNullOrEmpty())
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),
cancellationToken);
}
catch (Exception )
{
order.RemoveDiscount();
}
var taxesPrice = (((totalProductPrice - (discountCodePrice + productDiscountPrice)) + totalPackingPrice + servicePrice) / 100) * taxesFee;

View File

@ -10,6 +10,8 @@ public class BlogLDto : BaseDto<BlogLDto , Blog>
public string Summery { get; set; } = string.Empty;
public string MainImage { get; set; } = string.Empty;
public bool IsSuggested { get; set; }
public float Rate { get; set; }
public int CommentCount { get; set; }
public Guid CategoryId { get; set; }
public string CategoryName { get; set; } = string.Empty;
public Guid AuthorId { get; set; }

View File

@ -19,6 +19,8 @@ public class ProductLDto : BaseDto<ProductLDto,Product>
public double PackingCost { get; set; }
public int MaxOrderCount { get; set; }
public int Stock { get; set; }
public float Rate { get; set; }
public int CommentCount { get; set; }
public Guid BrandId { get; set; }
public string BrandName { get; set; } = string.Empty;
public Guid CategoryId { get; set; }

View File

@ -8,6 +8,8 @@ public class BlogSDto : BaseDto<BlogSDto , Blog>
public int ReadingTime { get; set; }
public string Summery { get; set; } = string.Empty;
public bool IsSuggested { get; set; }
public float Rate { get; set; }
public int CommentCount { get; set; }
public Guid CategoryId { get; set; }
public string CategoryName { get; set; } = string.Empty;
public string MainImage { get; set; } = string.Empty;

View File

@ -21,7 +21,7 @@ public class ProductSDto : BaseDto<ProductSDto, Product>
public bool BeDisplayed { get; set; }
public double PackingCost { get; set; }
public float Rate { get; set; }
public int ReviewCount { get; set; }
public int CommentCount { get; set; }
public int Viewed { get; set; }
public string MainImage { get; set; } = string.Empty;
public Guid CategoryId { get; set; }

View File

@ -30,6 +30,7 @@ namespace Netina.Domain.Mappers
BeDisplayed = p1.BeDisplayed,
PackingCost = p1.PackingCost,
Stock = p1.Stock,
Rate = p1.Rate,
HasExpressDelivery = p1.HasExpressDelivery,
MaxOrderCount = p1.MaxOrderCount,
BrandId = p1.BrandId,
@ -67,6 +68,7 @@ namespace Netina.Domain.Mappers
result.BeDisplayed = p4.BeDisplayed;
result.PackingCost = p4.PackingCost;
result.Stock = p4.Stock;
result.Rate = p4.Rate;
result.HasExpressDelivery = p4.HasExpressDelivery;
result.MaxOrderCount = p4.MaxOrderCount;
result.BrandId = p4.BrandId;
@ -95,6 +97,7 @@ namespace Netina.Domain.Mappers
BeDisplayed = p16.BeDisplayed,
PackingCost = p16.PackingCost,
Stock = p16.Stock,
Rate = p16.Rate,
HasExpressDelivery = p16.HasExpressDelivery,
MaxOrderCount = p16.MaxOrderCount,
BrandId = p16.BrandId,
@ -149,6 +152,8 @@ namespace Netina.Domain.Mappers
PackingCost = p19.PackingCost,
MaxOrderCount = p19.MaxOrderCount,
Stock = p19.Stock,
Rate = (float)(p19.Rate == 0f ? 4.5d : (double)p19.Rate),
CommentCount = p19.ReviewCount,
BrandId = p19.BrandId,
BrandName = p19.Brand == null ? null : p19.Brand.PersianName,
CategoryId = p19.CategoryId,
@ -182,6 +187,8 @@ namespace Netina.Domain.Mappers
result.PackingCost = p22.PackingCost;
result.MaxOrderCount = p22.MaxOrderCount;
result.Stock = p22.Stock;
result.Rate = (float)(p22.Rate == 0f ? 4.5d : (double)p22.Rate);
result.CommentCount = p22.ReviewCount;
result.BrandId = p22.BrandId;
result.BrandName = p22.Brand == null ? null : p22.Brand.PersianName;
result.CategoryId = p22.CategoryId;
@ -210,6 +217,8 @@ namespace Netina.Domain.Mappers
PackingCost = p28.PackingCost,
MaxOrderCount = p28.MaxOrderCount,
Stock = p28.Stock,
Rate = (float)(p28.Rate == 0f ? 4.5d : (double)p28.Rate),
CommentCount = p28.ReviewCount,
BrandId = p28.BrandId,
BrandName = p28.Brand == null ? null : p28.Brand.PersianName,
CategoryId = p28.CategoryId,
@ -257,7 +266,6 @@ namespace Netina.Domain.Mappers
PackingCost = p31.PackingCost,
Stock = p31.Stock,
Rate = p31.Rate,
ReviewCount = p31.ReviewCount,
Viewed = p31.Viewed,
MaxOrderCount = p31.MaxOrderCount,
BrandId = p31.BrandId,
@ -296,7 +304,6 @@ namespace Netina.Domain.Mappers
result.PackingCost = p32.PackingCost;
result.Stock = p32.Stock;
result.Rate = p32.Rate;
result.ReviewCount = p32.ReviewCount;
result.Viewed = p32.Viewed;
result.MaxOrderCount = p32.MaxOrderCount;
result.BrandId = p32.BrandId;
@ -328,8 +335,8 @@ namespace Netina.Domain.Mappers
MaxOrderCount = p40.MaxOrderCount,
BeDisplayed = p40.BeDisplayed,
PackingCost = p40.PackingCost,
Rate = p40.Rate,
ReviewCount = p40.ReviewCount,
Rate = (float)(p40.Rate == 0f ? 4.5d : (double)p40.Rate),
CommentCount = p40.ReviewCount,
Viewed = p40.Viewed,
MainImage = p40.Files.FirstOrDefault<ProductStorageFile>(funcMain15) != null ? p40.Files.FirstOrDefault<ProductStorageFile>(funcMain16).FileLocation : (p40.Files.Count > 0 ? p40.Files.FirstOrDefault<ProductStorageFile>().FileLocation : string.Empty),
CategoryId = p40.CategoryId,
@ -364,8 +371,8 @@ namespace Netina.Domain.Mappers
result.MaxOrderCount = p41.MaxOrderCount;
result.BeDisplayed = p41.BeDisplayed;
result.PackingCost = p41.PackingCost;
result.Rate = p41.Rate;
result.ReviewCount = p41.ReviewCount;
result.Rate = (float)(p41.Rate == 0f ? 4.5d : (double)p41.Rate);
result.CommentCount = p41.ReviewCount;
result.Viewed = p41.Viewed;
result.MainImage = p41.Files.FirstOrDefault<ProductStorageFile>(funcMain15) != null ? p41.Files.FirstOrDefault<ProductStorageFile>(funcMain16).FileLocation : (p41.Files.Count > 0 ? p41.Files.FirstOrDefault<ProductStorageFile>().FileLocation : string.Empty);
result.CategoryId = p41.CategoryId;
@ -395,8 +402,8 @@ namespace Netina.Domain.Mappers
MaxOrderCount = p43.MaxOrderCount,
BeDisplayed = p43.BeDisplayed,
PackingCost = p43.PackingCost,
Rate = p43.Rate,
ReviewCount = p43.ReviewCount,
Rate = (float)(p43.Rate == 0f ? 4.5d : (double)p43.Rate),
CommentCount = p43.ReviewCount,
Viewed = p43.Viewed,
MainImage = p43.Files.FirstOrDefault<ProductStorageFile>(f => f.IsPrimary) != null ? p43.Files.FirstOrDefault<ProductStorageFile>(f => f.IsPrimary).FileLocation : (p43.Files.Count > 0 ? p43.Files.FirstOrDefault<ProductStorageFile>().FileLocation : string.Empty),
CategoryId = p43.CategoryId,

View File

@ -63,6 +63,8 @@ public class MapsterRegister : IRegister
.Map("MainImage", o => o.Files.FirstOrDefault(f => f.IsPrimary) != null ? o.Files.FirstOrDefault(f => f.IsPrimary).FileLocation : o.Files.Count > 0 ? o.Files.FirstOrDefault().FileLocation : string.Empty)
.Map("CategoryName", o => o.Category == null ? null : o.Category.Name)
.Map("BrandName", o => o.Brand == null ? null : o.Brand.PersianName)
.Map(d=>d.Rate , o=>o.Rate == 0 ? 4.5 : o.Rate)
.Map(d => d.CommentCount, o => o.ReviewCount)
.IgnoreNullValues(false)
.TwoWays();
@ -79,6 +81,8 @@ public class MapsterRegister : IRegister
.Map(o => o.AuthorFullName, d => d.Author != null ? d.Author.FirstName + " " + d.Author.LastName : string.Empty)
.Map("CategoryName", o => o.Category == null ? null : o.Category.Name)
.Map("BrandName", o => o.Brand == null ? null : o.Brand.PersianName)
.Map(d => d.Rate, o => o.Rate == 0 ? 4.5 : o.Rate)
.Map(d => d.CommentCount, o => o.ReviewCount)
.IgnoreNullValues(false)
.TwoWays();

View File

@ -1,4 +1,6 @@
namespace Netina.Repository.Handlers.Discounts;
using BaseApiException = Netina.Common.Models.Exception.BaseApiException;
namespace Netina.Repository.Handlers.Discounts;
public class CreateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<CreateDiscountCommand, DiscountLDto>
@ -15,35 +17,42 @@ public class CreateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
if (foundDiscount != null)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "کد تخفیف مورد نظر تکراری می باشد");
}
if (request is { AmountType: DiscountAmountType.Percent, DiscountPercent: 0 })
throw new BaseApiException(ApiResultStatusCode.BadRequest, "در تخفیف درصدی ، درصد تخفیف نمی تواند صفر باشد");
if (request is { AmountType: DiscountAmountType.Amount, DiscountAmount: 0 })
throw new BaseApiException(ApiResultStatusCode.BadRequest, "در تخفیف مبلغی ، مبلغ تخفیف نمی تواند صفر باشد");
switch (request.Type)
{
case DiscountType.All:
var ent = Discount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount,
request.HasCode, request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate,
var ent = Discount.Create(request.Code, request.Description, request.DiscountPercent, request.DiscountAmount,
request.HasCode, request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate,
request.ExpireDate, request.PriceFloor, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling,
request.IsInfinity, request.UseCount, request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer);
request.IsInfinity, request.UseCount, request.IsForInvitation, request.IsForFirstPurchase, request.IsSpecialOffer);
repositoryWrapper.SetRepository<Discount>().Add(ent);
break;
case DiscountType.Category:
var catDis = CategoryDiscount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
var catDis = CategoryDiscount.Create(request.Code, request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer, request.CategoryId);
request.IsForInvitation, request.IsForFirstPurchase, request.IsSpecialOffer, request.CategoryId);
repositoryWrapper.SetRepository<CategoryDiscount>().Add(catDis);
break;
case DiscountType.Product:
var productDis = ProductDiscount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
var productDis = ProductDiscount.Create(request.Code, request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation,request.IsForFirstPurchase, request.IsSpecialOffer,request.ProductId);
request.IsForInvitation, request.IsForFirstPurchase, request.IsSpecialOffer, request.ProductId);
repositoryWrapper.SetRepository<ProductDiscount>().Add(productDis);
break;
default:
var def = Discount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
var def = Discount.Create(request.Code, request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.IsForFirstPurchase,request.IsSpecialOffer);
request.IsForInvitation, request.IsForFirstPurchase, request.IsSpecialOffer);
repositoryWrapper.SetRepository<Discount>().Add(def);
break;
}