Add category support to products commands and queries
This commit is contained in:
@@ -25,5 +25,7 @@ public record CreateNewProductsCommand : IRequest<CreateNewProductsResponseDto>
|
||||
public int ViewCount { get; init; }
|
||||
//
|
||||
public int RemainingCount { get; init; }
|
||||
// لیست شناسه دستهبندیهای محصول
|
||||
public ICollection<long>? CategoryIds { get; init; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Events;
|
||||
namespace CMSMicroservice.Application.ProductsCQ.Commands.CreateNewProducts;
|
||||
public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProductsCommand, CreateNewProductsResponseDto>
|
||||
@@ -14,8 +15,30 @@ public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProducts
|
||||
{
|
||||
var entity = request.Adapt<Products>();
|
||||
await _context.Productss.AddAsync(entity, cancellationToken);
|
||||
entity.AddDomainEvent(new CreateNewProductsEvent(entity));
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// ثبت دستهبندیهای محصول (در صورت ارسال)
|
||||
if (request.CategoryIds is { Count: > 0 })
|
||||
{
|
||||
var distinctCategoryIds = request.CategoryIds
|
||||
.Where(id => id > 0)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var categoryId in distinctCategoryIds)
|
||||
{
|
||||
var rel = new PruductCategory
|
||||
{
|
||||
ProductId = entity.Id,
|
||||
CategoryId = categoryId
|
||||
};
|
||||
await _context.PruductCategorys.AddAsync(rel, cancellationToken);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
entity.AddDomainEvent(new CreateNewProductsEvent(entity));
|
||||
return entity.Adapt<CreateNewProductsResponseDto>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,5 +27,7 @@ public record UpdateProductsCommand : IRequest<Unit>
|
||||
public int ViewCount { get; init; }
|
||||
//
|
||||
public int RemainingCount { get; init; }
|
||||
// لیست شناسه دستهبندیهای محصول
|
||||
public ICollection<long>? CategoryIds { get; init; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
using CMSMicroservice.Application.Common.Exceptions;
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Events;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
namespace CMSMicroservice.Application.ProductsCQ.Commands.UpdateProducts;
|
||||
public class UpdateProductsCommandHandler : IRequestHandler<UpdateProductsCommand, Unit>
|
||||
{
|
||||
@@ -12,9 +16,47 @@ public class UpdateProductsCommandHandler : IRequestHandler<UpdateProductsComman
|
||||
public async Task<Unit> Handle(UpdateProductsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.Productss
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(Products), request.Id);
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken)
|
||||
?? throw new NotFoundException(nameof(Products), request.Id);
|
||||
|
||||
request.Adapt(entity);
|
||||
_context.Productss.Update(entity);
|
||||
|
||||
// بهروزرسانی دستهبندیهای محصول در صورت ارسال CategoryIds
|
||||
if (request.CategoryIds is not null)
|
||||
{
|
||||
var targetIds = (request.CategoryIds ?? Array.Empty<long>())
|
||||
.Where(id => id > 0)
|
||||
.Distinct()
|
||||
.ToHashSet();
|
||||
|
||||
var existingRelations = await _context.PruductCategorys
|
||||
.Where(x => x.ProductId == entity.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var existingIds = existingRelations
|
||||
.Select(x => x.CategoryId)
|
||||
.ToHashSet();
|
||||
|
||||
var toAdd = targetIds.Except(existingIds).ToList();
|
||||
var toRemove = existingRelations.Where(x => !targetIds.Contains(x.CategoryId)).ToList();
|
||||
|
||||
foreach (var categoryId in toAdd)
|
||||
{
|
||||
var rel = new PruductCategory
|
||||
{
|
||||
ProductId = entity.Id,
|
||||
CategoryId = categoryId
|
||||
};
|
||||
await _context.PruductCategorys.AddAsync(rel, cancellationToken);
|
||||
}
|
||||
|
||||
if (toRemove.Count > 0)
|
||||
{
|
||||
_context.PruductCategorys.RemoveRange(toRemove);
|
||||
}
|
||||
}
|
||||
|
||||
entity.AddDomainEvent(new UpdateProductsEvent(entity));
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
return Unit.Value;
|
||||
|
||||
@@ -32,11 +32,35 @@ public class GetAllProductsByFilterQueryHandler : IRequestHandler<GetAllProducts
|
||||
.Where(x => request.Filter.RemainingCount == null || x.RemainingCount == request.Filter.RemainingCount)
|
||||
;
|
||||
}
|
||||
var meta = await query.GetMetaData(request.PaginationState, cancellationToken);
|
||||
|
||||
var models = await query
|
||||
.PaginatedListAsync(paginationState: request.PaginationState)
|
||||
.Select(x => new GetAllProductsByFilterResponseModel
|
||||
{
|
||||
Id = x.Id,
|
||||
Title = x.Title,
|
||||
Description = x.Description,
|
||||
ShortInfomation = x.ShortInfomation,
|
||||
FullInformation = x.FullInformation,
|
||||
Price = x.Price,
|
||||
Discount = x.Discount,
|
||||
Rate = x.Rate,
|
||||
ImagePath = x.ImagePath,
|
||||
ThumbnailPath = x.ThumbnailPath,
|
||||
SaleCount = x.SaleCount,
|
||||
ViewCount = x.ViewCount,
|
||||
RemainingCount = x.RemainingCount,
|
||||
CategoryIds = x.PruductCategorys
|
||||
.Select(pc => pc.CategoryId)
|
||||
.ToList()
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return new GetAllProductsByFilterResponseDto
|
||||
{
|
||||
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
|
||||
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
|
||||
.ProjectToType<GetAllProductsByFilterResponseModel>().ToListAsync(cancellationToken)
|
||||
MetaData = meta,
|
||||
Models = models
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ public class GetAllProductsByFilterResponseDto
|
||||
//مدل خروجی
|
||||
public List<GetAllProductsByFilterResponseModel>? Models { get; set; }
|
||||
|
||||
}public class GetAllProductsByFilterResponseModel
|
||||
}
|
||||
|
||||
public class GetAllProductsByFilterResponseModel
|
||||
{
|
||||
//
|
||||
public long Id { get; set; }
|
||||
@@ -34,4 +36,6 @@ public class GetAllProductsByFilterResponseDto
|
||||
public int ViewCount { get; set; }
|
||||
//
|
||||
public int RemainingCount { get; set; }
|
||||
// لیست شناسه دستهبندیهای محصول
|
||||
public List<long> CategoryIds { get; set; } = new();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,25 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, GetProd
|
||||
var response = await _context.Productss
|
||||
.AsNoTracking()
|
||||
.Where(x => x.Id == request.Id)
|
||||
.ProjectToType<GetProductsResponseDto>()
|
||||
.Select(x => new GetProductsResponseDto
|
||||
{
|
||||
Id = x.Id,
|
||||
Title = x.Title,
|
||||
Description = x.Description,
|
||||
ShortInfomation = x.ShortInfomation,
|
||||
FullInformation = x.FullInformation,
|
||||
Price = x.Price,
|
||||
Discount = x.Discount,
|
||||
Rate = x.Rate,
|
||||
ImagePath = x.ImagePath,
|
||||
ThumbnailPath = x.ThumbnailPath,
|
||||
SaleCount = x.SaleCount,
|
||||
ViewCount = x.ViewCount,
|
||||
RemainingCount = x.RemainingCount,
|
||||
CategoryIds = x.PruductCategorys
|
||||
.Select(pc => pc.CategoryId)
|
||||
.ToList()
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
return response ?? throw new NotFoundException(nameof(Products), request.Id);
|
||||
|
||||
@@ -27,5 +27,7 @@ public class GetProductsResponseDto
|
||||
public int ViewCount { get; set; }
|
||||
//
|
||||
public int RemainingCount { get; set; }
|
||||
// لیست شناسه دستهبندیهای محصول
|
||||
public List<long> CategoryIds { get; set; } = new();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user