feat : add special offer

release
Amir Hossein Khademi 2024-02-03 10:34:48 +03:30
parent 36ae9bf0c3
commit 10892f9e82
21 changed files with 1765 additions and 31 deletions

View File

@ -16,6 +16,7 @@ bool HasPriceCeiling,
bool IsInfinity, bool IsInfinity,
long UseCount, long UseCount,
bool IsForInvitation, bool IsForInvitation,
bool IsSpecialOffer,
Guid ProductId, Guid ProductId,
Guid CategoryId) : IRequest<DiscountLDto>; Guid CategoryId) : IRequest<DiscountLDto>;
@ -36,6 +37,7 @@ public sealed record UpdateDiscountCommand(Guid Id,
bool IsInfinity, bool IsInfinity,
long UseCount, long UseCount,
bool IsForInvitation, bool IsForInvitation,
bool IsSpecialOffer,
Guid ProductId, Guid ProductId,
Guid CategoryId) : IRequest<bool>; Guid CategoryId) : IRequest<bool>;

View File

@ -12,8 +12,10 @@ double Cost,
double PackingCost, double PackingCost,
bool HasExpressDelivery, bool HasExpressDelivery,
int MaxOrderCount, int MaxOrderCount,
bool IsSpecialOffer,
Guid BrandId, Guid BrandId,
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files):IRequest<ProductLDto>; List<StorageFileSDto> Files):IRequest<ProductLDto>;
@ -30,8 +32,11 @@ public sealed record UpdateProductCommand(
double PackingCost, double PackingCost,
bool HasExpressDelivery, bool HasExpressDelivery,
int MaxOrderCount, int MaxOrderCount,
bool IsSpecialOffer,
Guid BrandId, Guid BrandId,
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files) : IRequest<bool>; List<StorageFileSDto> Files) : IRequest<bool>;
public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>; public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>;

View File

@ -17,7 +17,10 @@ public class DiscountLDto : BaseDto<DiscountLDto,Discount>
public bool HasPriceCeiling { get; set; } public bool HasPriceCeiling { get; set; }
public bool IsInfinity { get; set; } public bool IsInfinity { get; set; }
public long UseCount { get; set; } public long UseCount { get; set; }
public bool IsSpecialOffer { get; set; }
public bool IsForInvitation { get; set; } public bool IsForInvitation { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public string ProductName { get; set; } = string.Empty;
public Guid CategoryId { get; set; } public Guid CategoryId { get; set; }
public string CategoryName { get; set; } = string.Empty;
} }

View File

@ -17,9 +17,12 @@ public class ProductLDto : BaseDto<ProductLDto,Product>
public string BrandName { get; set; } = string.Empty; public string BrandName { get; set; } = string.Empty;
public Guid CategoryId { get; set; } public Guid CategoryId { get; set; }
public string CategoryName { get; set; } = string.Empty; public string CategoryName { get; set; } = string.Empty;
public bool IsSpecialOffer { get; set; }
public List<SpecificationSDto> Specifications { get; set; } = new(); public List<SpecificationSDto> Specifications { get; set; } = new();
public List<ReviewSDto> Reviews { get; set; } = new(); public List<ReviewSDto> Reviews { get; set; } = new();
public List<ProductCategorySDto> Categories { get; set; } = new(); public List<ProductCategorySDto> Categories { get; set; } = new();
public List<StorageFileSDto> Files { get; set; } = new(); public List<StorageFileSDto> Files { get; set; } = new();
public DiscountSDto? SpecialOffer { get; set; }
} }

View File

@ -17,5 +17,6 @@ public class DiscountSDto : BaseDto<DiscountSDto,Discount>
public bool HasPriceCeiling { get; set; } public bool HasPriceCeiling { get; set; }
public bool IsInfinity { get; set; } public bool IsInfinity { get; set; }
public long UseCount { get; set; } public long UseCount { get; set; }
public bool IsSpecialOffer { get; set; }
public bool IsForInvitation { get; set; } public bool IsForInvitation { get; set; }
} }

View File

@ -14,6 +14,7 @@ public class ProductSDto : BaseDto<ProductSDto, Product>
public bool HasDiscount { get; set; } public bool HasDiscount { get; set; }
public double CostWithDiscount { get; set; } public double CostWithDiscount { get; set; }
public bool IsEnable { get; set; } public bool IsEnable { get; set; }
public bool IsSpecial { get; set; }
public bool BeDisplayed { get; set; } public bool BeDisplayed { get; set; }
public double PackingCost { get; set; } public double PackingCost { get; set; }
public float Rate { get; set; } public float Rate { get; set; }

View File

@ -9,9 +9,9 @@ public partial class CategoryDiscount : Discount
} }
public CategoryDiscount(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation, Guid categoryId) public CategoryDiscount(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation,bool isSpecialOffer, Guid categoryId)
: base(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, : base(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount,
isForInvitation) isForInvitation, isSpecialOffer)
{ {
CategoryId = categoryId; CategoryId = categoryId;
} }

View File

@ -2,11 +2,25 @@
public partial class Discount public partial class Discount
{ {
public static Discount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation) public static Discount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation,bool isSpecialOffer)
{ {
return new Discount(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, return new Discount(code,
expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, discountPercent,
isForInvitation); discountAmount,
hasCode,
amountType,
type,
count,
startDate,
expireDate,
priceFloor,
hasPriceFloor,
priceCeiling,
hasPriceCeiling,
isInfinity,
useCount,
isForInvitation,
isSpecialOffer);
} }
public bool IsExpired() public bool IsExpired()
@ -15,20 +29,20 @@ public partial class Discount
public partial class ProductDiscount public partial class ProductDiscount
{ {
public static ProductDiscount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation , Guid productId) public static ProductDiscount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation ,bool isSpecialOffer, Guid productId)
{ {
return new ProductDiscount(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, return new ProductDiscount(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate,
expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount,
isForInvitation, productId); isForInvitation, isSpecialOffer, productId);
} }
} }
public partial class CategoryDiscount public partial class CategoryDiscount
{ {
public static CategoryDiscount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation, Guid categoryId) public static CategoryDiscount Create(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation, bool isSpecialOffer, Guid categoryId)
{ {
return new CategoryDiscount(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, return new CategoryDiscount(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate,
expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount,
isForInvitation, categoryId); isForInvitation,isSpecialOffer, categoryId);
} }
} }

View File

@ -12,7 +12,23 @@ public partial class Discount : ApiEntity
} }
public Discount(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation) public Discount(string code,
int discountPercent,
long discountAmount,
bool hasCode,
DiscountAmountType amountType,
DiscountType type,
int count,
DateTime startDate,
DateTime expireDate,
long priceFloor,
bool hasPriceFloor,
long priceCeiling,
bool hasPriceCeiling,
bool isInfinity,
long useCount,
bool isForInvitation,
bool isSpecialOffer)
{ {
Code = code; Code = code;
DiscountPercent = discountPercent; DiscountPercent = discountPercent;
@ -30,6 +46,7 @@ public partial class Discount : ApiEntity
IsInfinity = isInfinity; IsInfinity = isInfinity;
UseCount = useCount; UseCount = useCount;
IsForInvitation = isForInvitation; IsForInvitation = isForInvitation;
IsSpecialOffer = isSpecialOffer;
} }
public string Code { get; internal set; } = string.Empty; public string Code { get; internal set; } = string.Empty;
public int DiscountPercent { get; internal set; } public int DiscountPercent { get; internal set; }
@ -46,6 +63,7 @@ public partial class Discount : ApiEntity
public bool HasPriceCeiling { get; internal set; } public bool HasPriceCeiling { get; internal set; }
public bool IsInfinity { get; internal set; } public bool IsInfinity { get; internal set; }
public long UseCount { get; internal set; } public long UseCount { get; internal set; }
public bool IsSpecialOffer { get; internal set; }
public bool IsForInvitation { get; internal set; } public bool IsForInvitation { get; internal set; }
public List<Order> Orders { get; internal set; } = new(); public List<Order> Orders { get; internal set; } = new();

View File

@ -7,8 +7,8 @@ public partial class ProductDiscount : Discount
} }
public ProductDiscount(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation,Guid productId) public ProductDiscount(string code, int discountPercent, long discountAmount, bool hasCode, DiscountAmountType amountType, DiscountType type, int count, DateTime startDate, DateTime expireDate, long priceFloor, bool hasPriceFloor, long priceCeiling, bool hasPriceCeiling, bool isInfinity, long useCount, bool isForInvitation,bool isSpecialOffer,Guid productId)
: base(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, isForInvitation) : base(code, discountPercent, discountAmount, hasCode, amountType, type, count, startDate, expireDate, priceFloor, hasPriceFloor, priceCeiling, hasPriceCeiling, isInfinity, useCount, isForInvitation, isSpecialOffer)
{ {
ProductId = productId; ProductId = productId;
} }

View File

@ -13,14 +13,14 @@ public class CreateDiscountCommandHandler : IRequestHandler<CreateDiscountComman
switch (request.Type) switch (request.Type)
{ {
case DiscountType.All: case DiscountType.All:
var ent = 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); var ent = 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);
_repositoryWrapper.SetRepository<Discount>().Add(ent); _repositoryWrapper.SetRepository<Discount>().Add(ent);
break; break;
case DiscountType.Category: case DiscountType.Category:
var catDis = CategoryDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, var catDis = CategoryDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.CategoryId); request.IsForInvitation,request.IsSpecialOffer, request.CategoryId);
_repositoryWrapper.SetRepository<CategoryDiscount>().Add(catDis); _repositoryWrapper.SetRepository<CategoryDiscount>().Add(catDis);
break; break;
@ -28,14 +28,14 @@ public class CreateDiscountCommandHandler : IRequestHandler<CreateDiscountComman
var productDis = ProductDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, var productDis = ProductDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.ProductId); request.IsForInvitation, request.IsSpecialOffer,request.ProductId);
_repositoryWrapper.SetRepository<ProductDiscount>().Add(productDis); _repositoryWrapper.SetRepository<ProductDiscount>().Add(productDis);
break; break;
default: default:
var def = Discount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, var def = Discount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation); request.IsForInvitation,request.IsSpecialOffer);
_repositoryWrapper.SetRepository<Discount>().Add(def); _repositoryWrapper.SetRepository<Discount>().Add(def);
break; break;
} }

View File

@ -12,7 +12,7 @@ public class GetDiscountsQueryHandler : IRequestHandler<GetDiscountsQuery, List<
{ {
return await _repositoryWrapper.SetRepository<Discount>().TableNoTracking return await _repositoryWrapper.SetRepository<Discount>().TableNoTracking
.OrderByDescending(b => b.CreatedAt) .OrderByDescending(b => b.CreatedAt)
.Skip(request.Page * 10).Take(10) .Skip(request.Page * 15).Take(15)
.Select(DiscountMapper.ProjectToSDto) .Select(DiscountMapper.ProjectToSDto)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
} }

View File

@ -16,7 +16,7 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
var ent = await _repositoryWrapper.SetRepository<Discount>().TableNoTracking.FirstOrDefaultAsync(d=>d.Id==request.Id,cancellationToken); var ent = await _repositoryWrapper.SetRepository<Discount>().TableNoTracking.FirstOrDefaultAsync(d=>d.Id==request.Id,cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Discount not found", ApiResultStatusCode.NotFound); 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); 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.Id = ent.Id;
_repositoryWrapper.SetRepository<Discount>().Update(newEnt); _repositoryWrapper.SetRepository<Discount>().Update(newEnt);
break; break;
@ -28,7 +28,7 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
var catDis = CategoryDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, var catDis = CategoryDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.CategoryId); request.IsForInvitation,request.IsSpecialOffer, request.CategoryId);
catDis.Id = catEnt.Id; catDis.Id = catEnt.Id;
_repositoryWrapper.SetRepository<CategoryDiscount>().Update(catDis); _repositoryWrapper.SetRepository<CategoryDiscount>().Update(catDis);
break; break;
@ -41,7 +41,7 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
var productDis = ProductDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode, var productDis = ProductDiscount.Create(request.Code, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.ProductId); request.IsForInvitation, request.IsSpecialOffer, request.ProductId);
productDis.Id = productEnt.Id; productDis.Id = productEnt.Id;
_repositoryWrapper.SetRepository<ProductDiscount>().Update(productDis); _repositoryWrapper.SetRepository<ProductDiscount>().Update(productDis);
break; break;

View File

@ -3,10 +3,12 @@
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, ProductLDto> public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, ProductLDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper; private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public CreateProductCommandHandler(IRepositoryWrapper repositoryWrapper) public CreateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{ {
_repositoryWrapper = repositoryWrapper; _repositoryWrapper = repositoryWrapper;
_mediator = mediator;
} }
public async Task<ProductLDto> Handle(CreateProductCommand request, CancellationToken cancellationToken) public async Task<ProductLDto> Handle(CreateProductCommand request, CancellationToken cancellationToken)
@ -28,6 +30,27 @@ public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand,
_repositoryWrapper.SetRepository<Product>().Add(ent); _repositoryWrapper.SetRepository<Product>().Add(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await _repositoryWrapper.SaveChangesAsync(cancellationToken);
if (request.IsSpecialOffer)
{
var discount = request.SpecialOffer.Adapt<DiscountLDto>();
discount.ProductId = ent.Id;
discount.IsSpecialOffer = true;
discount.Type = DiscountType.Product;
discount.HasCode = false;
discount.IsInfinity = true;
if (request.SpecialOffer.Id == default)
{
var discountRequest = discount.Adapt<CreateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken);
}
else
{
var discountRequest = discount.Adapt<UpdateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken);
}
}
return ent.AdaptToLDto(); return ent.AdaptToLDto();
} }
} }

View File

@ -14,8 +14,23 @@ public class GetProductQueryHandler : IRequestHandler<GetProductQuery, ProductLD
.Where(b => b.Id == request.Id) .Where(b => b.Id == request.Id)
.Select(ProductMapper.ProjectToLDto) .Select(ProductMapper.ProjectToLDto)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound); throw new AppException("Product not found", ApiResultStatusCode.NotFound);
var specialOffer = await _repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking
.Where(pd => pd.IsSpecialOffer && pd.ProductId == ent.Id)
.Select(DiscountMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
ent.SpecialOffer = specialOffer;
if (ent.SpecialOffer == null || ent.SpecialOffer.ExpireDate.Date < DateTime.Today.Date)
ent.IsSpecialOffer = false;
else
ent.IsSpecialOffer = true;
return ent; return ent;
} }
} }

View File

@ -12,7 +12,7 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, List<Pr
{ {
var products = _repositoryWrapper.SetRepository<Product>().TableNoTracking; var products = _repositoryWrapper.SetRepository<Product>().TableNoTracking;
if (request.ProductName != null) if (request.ProductName != null)
products = products.Where( p => p.PersianName.ToLower().Trim().Contains(request.ProductName.ToLower().Trim())); products = products.Where(p => p.PersianName.ToLower().Trim().Contains(request.ProductName.ToLower().Trim()));
if (request.CategoryId != default) if (request.CategoryId != default)
products = products.Where(p => p.CategoryId == request.CategoryId); products = products.Where(p => p.CategoryId == request.CategoryId);
if (request.BrandId != default) if (request.BrandId != default)
@ -62,7 +62,9 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, List<Pr
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>() var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.HasCode == false && d.ProductId == productSDto.Id && d.ExpireDate.Date > DateTime.Today.Date, cancellationToken); .Where(d => d.HasCode == false && d.ProductId == productSDto.Id && d.ExpireDate.Date > DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt)
.FirstOrDefaultAsync(cancellationToken);
if (productDiscount != null && !productDiscount.IsExpired()) if (productDiscount != null && !productDiscount.IsExpired())
{ {
@ -73,7 +75,10 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, List<Pr
productSDto.CostWithDiscount = productSDto.CostWithDiscount - discountPrice; productSDto.CostWithDiscount = productSDto.CostWithDiscount - discountPrice;
productSDto.HasDiscount = true; productSDto.HasDiscount = true;
productSDto.DiscountPercent = (100 * productSDto.CostWithDiscount) / productSDto.Cost; if (productSDto.Cost > 0)
productSDto.DiscountPercent = (100 * productSDto.CostWithDiscount) / productSDto.Cost;
if (productDiscount.IsSpecialOffer)
productSDto.IsSpecial = true;
} }
} }

View File

@ -3,10 +3,12 @@
public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand, bool> public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper; private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper) public UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{ {
_repositoryWrapper = repositoryWrapper; _repositoryWrapper = repositoryWrapper;
_mediator = mediator;
} }
public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken)
{ {
@ -37,7 +39,6 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await _repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
foreach (var specification in request.Specifications.Where(s => s.Id == default)) foreach (var specification in request.Specifications.Where(s => s.Id == default))
{ {
newEnt.AddSpecification(specification.Title, specification.Detail, specification.Value, specification.IsFeature, specification.ParentId); newEnt.AddSpecification(specification.Title, specification.Detail, specification.Value, specification.IsFeature, specification.ParentId);
@ -59,8 +60,31 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
{ {
newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
_repositoryWrapper.SetRepository<Product>().Update(newEnt); _repositoryWrapper.SetRepository<Product>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await _repositoryWrapper.SaveChangesAsync(cancellationToken);
if (request.IsSpecialOffer)
{
var discount = request.SpecialOffer.Adapt<DiscountLDto>();
discount.ProductId = newEnt.Id;
discount.IsSpecialOffer = true;
discount.Type = DiscountType.Product;
discount.HasCode = false;
discount.IsInfinity = true;
if (request.SpecialOffer.Id == default)
{
var discountRequest = discount.Adapt<CreateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken);
}
else
{
var discountRequest = discount.Adapt<UpdateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken);
}
}
return true; return true;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NetinaShop.Repository.Migrations
{
/// <inheritdoc />
public partial class editDiscount : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsSpecialOffer",
schema: "public",
table: "Discounts",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsSpecialOffer",
schema: "public",
table: "Discounts");
}
}
}

View File

@ -326,6 +326,9 @@ namespace NetinaShop.Repository.Migrations
b.Property<bool>("IsRemoved") b.Property<bool>("IsRemoved")
.HasColumnType("boolean"); .HasColumnType("boolean");
b.Property<bool>("IsSpecialOffer")
.HasColumnType("boolean");
b.Property<DateTime>("ModifiedAt") b.Property<DateTime>("ModifiedAt")
.HasColumnType("timestamp without time zone"); .HasColumnType("timestamp without time zone");

View File

@ -106,13 +106,13 @@ try
if (price != null && double.TryParse(price.meta_value, out double dPrice)) if (price != null && double.TryParse(price.meta_value, out double dPrice))
product = new CreateProductCommand(wordPressPostDto.post_title, string.Empty, wordPressPostDto.post_content, product = new CreateProductCommand(wordPressPostDto.post_title, string.Empty, wordPressPostDto.post_content,
wordPressPostDto.post_excerpt, string.Empty, string.Empty, true, dPrice, 0, wordPressPostDto.post_excerpt, string.Empty, string.Empty, true, dPrice, 0,
false,10, brandId, categoryId, false,10,false,brandId, categoryId,
new List<SpecificationSDto>(), new List<StorageFileSDto>()); new DiscountSDto(),new List<SpecificationSDto>(), new List<StorageFileSDto>());
else else
product = new CreateProductCommand(wordPressPostDto.post_title, string.Empty, wordPressPostDto.post_content, product = new CreateProductCommand(wordPressPostDto.post_title, string.Empty, wordPressPostDto.post_content,
wordPressPostDto.post_excerpt, string.Empty, string.Empty, true, 0, 0,false,10, wordPressPostDto.post_excerpt, string.Empty, string.Empty, true, 0, 0,false,10,
brandId,categoryId, false,brandId,categoryId,
new List<SpecificationSDto>(), new List<StorageFileSDto>()); new DiscountSDto(),new List<SpecificationSDto>(), new List<StorageFileSDto>());
products.Add(product); products.Add(product);
} }