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 ViewCount { get; init; }
|
||||||
//
|
//
|
||||||
public int RemainingCount { 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;
|
using CMSMicroservice.Domain.Events;
|
||||||
namespace CMSMicroservice.Application.ProductsCQ.Commands.CreateNewProducts;
|
namespace CMSMicroservice.Application.ProductsCQ.Commands.CreateNewProducts;
|
||||||
public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProductsCommand, CreateNewProductsResponseDto>
|
public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProductsCommand, CreateNewProductsResponseDto>
|
||||||
@@ -14,8 +15,30 @@ public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProducts
|
|||||||
{
|
{
|
||||||
var entity = request.Adapt<Products>();
|
var entity = request.Adapt<Products>();
|
||||||
await _context.Productss.AddAsync(entity, cancellationToken);
|
await _context.Productss.AddAsync(entity, cancellationToken);
|
||||||
entity.AddDomainEvent(new CreateNewProductsEvent(entity));
|
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
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>();
|
return entity.Adapt<CreateNewProductsResponseDto>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,7 @@ public record UpdateProductsCommand : IRequest<Unit>
|
|||||||
public int ViewCount { get; init; }
|
public int ViewCount { get; init; }
|
||||||
//
|
//
|
||||||
public int RemainingCount { 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 CMSMicroservice.Domain.Events;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
namespace CMSMicroservice.Application.ProductsCQ.Commands.UpdateProducts;
|
namespace CMSMicroservice.Application.ProductsCQ.Commands.UpdateProducts;
|
||||||
public class UpdateProductsCommandHandler : IRequestHandler<UpdateProductsCommand, Unit>
|
public class UpdateProductsCommandHandler : IRequestHandler<UpdateProductsCommand, Unit>
|
||||||
{
|
{
|
||||||
@@ -12,9 +16,47 @@ public class UpdateProductsCommandHandler : IRequestHandler<UpdateProductsComman
|
|||||||
public async Task<Unit> Handle(UpdateProductsCommand request, CancellationToken cancellationToken)
|
public async Task<Unit> Handle(UpdateProductsCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entity = await _context.Productss
|
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);
|
request.Adapt(entity);
|
||||||
_context.Productss.Update(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));
|
entity.AddDomainEvent(new UpdateProductsEvent(entity));
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
return Unit.Value;
|
return Unit.Value;
|
||||||
|
|||||||
@@ -32,11 +32,35 @@ public class GetAllProductsByFilterQueryHandler : IRequestHandler<GetAllProducts
|
|||||||
.Where(x => request.Filter.RemainingCount == null || x.RemainingCount == request.Filter.RemainingCount)
|
.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
|
return new GetAllProductsByFilterResponseDto
|
||||||
{
|
{
|
||||||
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
|
MetaData = meta,
|
||||||
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
|
Models = models
|
||||||
.ProjectToType<GetAllProductsByFilterResponseModel>().ToListAsync(cancellationToken)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ public class GetAllProductsByFilterResponseDto
|
|||||||
//مدل خروجی
|
//مدل خروجی
|
||||||
public List<GetAllProductsByFilterResponseModel>? Models { get; set; }
|
public List<GetAllProductsByFilterResponseModel>? Models { get; set; }
|
||||||
|
|
||||||
}public class GetAllProductsByFilterResponseModel
|
}
|
||||||
|
|
||||||
|
public class GetAllProductsByFilterResponseModel
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
@@ -34,4 +36,6 @@ public class GetAllProductsByFilterResponseDto
|
|||||||
public int ViewCount { get; set; }
|
public int ViewCount { get; set; }
|
||||||
//
|
//
|
||||||
public int RemainingCount { 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
|
var response = await _context.Productss
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.Id == request.Id)
|
.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);
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
return response ?? throw new NotFoundException(nameof(Products), request.Id);
|
return response ?? throw new NotFoundException(nameof(Products), request.Id);
|
||||||
|
|||||||
@@ -27,5 +27,7 @@ public class GetProductsResponseDto
|
|||||||
public int ViewCount { get; set; }
|
public int ViewCount { get; set; }
|
||||||
//
|
//
|
||||||
public int RemainingCount { get; set; }
|
public int RemainingCount { get; set; }
|
||||||
|
// لیست شناسه دستهبندیهای محصول
|
||||||
|
public List<long> CategoryIds { get; set; } = new();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ message CreateNewProductsRequest
|
|||||||
int32 sale_count = 10;
|
int32 sale_count = 10;
|
||||||
int32 view_count = 11;
|
int32 view_count = 11;
|
||||||
int32 remaining_count = 12;
|
int32 remaining_count = 12;
|
||||||
|
// لیست شناسه دستهبندیهای محصول
|
||||||
|
repeated int64 category_ids = 13;
|
||||||
}
|
}
|
||||||
message CreateNewProductsResponse
|
message CreateNewProductsResponse
|
||||||
{
|
{
|
||||||
@@ -78,6 +80,8 @@ message UpdateProductsRequest
|
|||||||
int32 sale_count = 11;
|
int32 sale_count = 11;
|
||||||
int32 view_count = 12;
|
int32 view_count = 12;
|
||||||
int32 remaining_count = 13;
|
int32 remaining_count = 13;
|
||||||
|
// لیست شناسه دستهبندیهای محصول
|
||||||
|
repeated int64 category_ids = 14;
|
||||||
}
|
}
|
||||||
message DeleteProductsRequest
|
message DeleteProductsRequest
|
||||||
{
|
{
|
||||||
@@ -102,6 +106,8 @@ message GetProductsResponse
|
|||||||
int32 sale_count = 11;
|
int32 sale_count = 11;
|
||||||
int32 view_count = 12;
|
int32 view_count = 12;
|
||||||
int32 remaining_count = 13;
|
int32 remaining_count = 13;
|
||||||
|
// لیست شناسه دستهبندیهای محصول
|
||||||
|
repeated int64 category_ids = 14;
|
||||||
}
|
}
|
||||||
message GetAllProductsByFilterRequest
|
message GetAllProductsByFilterRequest
|
||||||
{
|
{
|
||||||
@@ -145,4 +151,6 @@ message GetAllProductsByFilterResponseModel
|
|||||||
int32 sale_count = 11;
|
int32 sale_count = 11;
|
||||||
int32 view_count = 12;
|
int32 view_count = 12;
|
||||||
int32 remaining_count = 13;
|
int32 remaining_count = 13;
|
||||||
|
// لیست شناسه دستهبندیهای محصول
|
||||||
|
repeated int64 category_ids = 14;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user