Implement product categories CRUD operations with CMS integration
This commit is contained in:
@@ -8,6 +8,7 @@ using CMSMicroservice.Protobuf.Protos.Products;
|
||||
using CMSMicroservice.Protobuf.Protos.ProductImages;
|
||||
using CMSMicroservice.Protobuf.Protos.ProductGallerys;
|
||||
using CMSMicroservice.Protobuf.Protos.Category;
|
||||
using CMSMicroservice.Protobuf.Protos.PruductCategory;
|
||||
using FMSMicroservice.Protobuf.Protos.FileInfo;
|
||||
|
||||
namespace BackOffice.BFF.Application.Common.Interfaces;
|
||||
@@ -24,6 +25,7 @@ public interface IApplicationContractContext
|
||||
ProductGallerysContract.ProductGallerysContractClient ProductGallerys { get; }
|
||||
RoleContract.RoleContractClient Roles { get; }
|
||||
CategoryContract.CategoryContractClient Categories { get; }
|
||||
PruductCategoryContract.PruductCategoryContractClient ProductCategories { get; }
|
||||
UserAddressContract.UserAddressContractClient UserAddress { get; }
|
||||
UserContract.UserContractClient Users { get; }
|
||||
UserOrderContract.UserOrderContractClient UserOrders { get; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BackOffice.BFF.Application.Common.Interfaces;
|
||||
using CMSPruductCategory = CMSMicroservice.Protobuf.Protos.PruductCategory;
|
||||
|
||||
namespace BackOffice.BFF.Application.ProductsCQ.Commands.UpdateProductCategories;
|
||||
|
||||
@@ -13,9 +14,49 @@ public class UpdateProductCategoriesCommandHandler : IRequestHandler<UpdateProdu
|
||||
|
||||
public async Task<Unit> Handle(UpdateProductCategoriesCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// Stub: until CMS Category services are available via the protobuf package,
|
||||
// this handler is a no-op to keep the pipeline consistent.
|
||||
await Task.CompletedTask;
|
||||
var targetIds = request.CategoryIds?.ToHashSet() ?? new HashSet<long>();
|
||||
|
||||
// Load existing product-category relations
|
||||
var existingRequest = new CMSPruductCategory.GetAllPruductCategoryByFilterRequest
|
||||
{
|
||||
Filter = new CMSPruductCategory.GetAllPruductCategoryByFilterFilter
|
||||
{
|
||||
ProductId = request.ProductId
|
||||
},
|
||||
PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState
|
||||
{
|
||||
PageNumber = 1,
|
||||
PageSize = 1000
|
||||
}
|
||||
};
|
||||
|
||||
var existingResponse = await _context.ProductCategories.GetAllPruductCategoryByFilterAsync(existingRequest, cancellationToken: cancellationToken);
|
||||
var existing = existingResponse.Models ?? new();
|
||||
|
||||
var existingIds = existing.Select(x => x.CategoryId).ToHashSet();
|
||||
|
||||
// Determine which relations to add and which to remove
|
||||
var toAdd = targetIds.Except(existingIds).ToList();
|
||||
var toRemove = existing.Where(x => !targetIds.Contains(x.CategoryId)).ToList();
|
||||
|
||||
foreach (var categoryId in toAdd)
|
||||
{
|
||||
var createRequest = new CMSPruductCategory.CreateNewPruductCategoryRequest
|
||||
{
|
||||
ProductId = request.ProductId,
|
||||
CategoryId = categoryId
|
||||
};
|
||||
|
||||
await _context.ProductCategories.CreateNewPruductCategoryAsync(createRequest, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
foreach (var rel in toRemove)
|
||||
{
|
||||
await _context.ProductCategories.DeletePruductCategoryAsync(
|
||||
new CMSPruductCategory.DeletePruductCategoryRequest { Id = rel.Id },
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
return Unit.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,67 @@
|
||||
using BackOffice.BFF.Application.Common.Interfaces;
|
||||
using CMSCategory = CMSMicroservice.Protobuf.Protos.Category;
|
||||
using CMSPruductCategory = CMSMicroservice.Protobuf.Protos.PruductCategory;
|
||||
|
||||
namespace BackOffice.BFF.Application.ProductsCQ.Queries.GetCategories;
|
||||
|
||||
public class GetCategoriesQueryHandler : IRequestHandler<GetCategoriesQuery, GetCategoriesResponseDto>
|
||||
{
|
||||
private readonly IApplicationContractContext _context;
|
||||
|
||||
public GetCategoriesQueryHandler(IApplicationContractContext context)
|
||||
{
|
||||
// context is currently unused; reserved for future CMS integration
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<GetCategoriesResponseDto> Handle(GetCategoriesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// Stub implementation: returns empty list.
|
||||
// When CMS protobuf package with Category support is available,
|
||||
// this handler can be updated to call Category and PruductCategory services.
|
||||
await Task.CompletedTask;
|
||||
return new GetCategoriesResponseDto();
|
||||
// Load all categories
|
||||
var categoryRequest = new CMSCategory.GetAllCategoryByFilterRequest
|
||||
{
|
||||
Filter = new CMSCategory.GetAllCategoryByFilterFilter(),
|
||||
PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState
|
||||
{
|
||||
PageNumber = 1,
|
||||
PageSize = 1000
|
||||
}
|
||||
};
|
||||
|
||||
var categoriesResponse = await _context.Categories.GetAllCategoryByFilterAsync(categoryRequest, cancellationToken: cancellationToken);
|
||||
var categories = categoriesResponse.Models ?? new();
|
||||
|
||||
// Load existing product-category relations for this product
|
||||
var productCategoryRequest = new CMSPruductCategory.GetAllPruductCategoryByFilterRequest
|
||||
{
|
||||
Filter = new CMSPruductCategory.GetAllPruductCategoryByFilterFilter
|
||||
{
|
||||
ProductId = request.ProductId
|
||||
},
|
||||
PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState
|
||||
{
|
||||
PageNumber = 1,
|
||||
PageSize = 1000
|
||||
}
|
||||
};
|
||||
|
||||
var productCategoriesResponse = await _context.ProductCategories.GetAllPruductCategoryByFilterAsync(productCategoryRequest, cancellationToken: cancellationToken);
|
||||
var productCategories = productCategoriesResponse.Models ?? new();
|
||||
|
||||
var selectedIds = productCategories
|
||||
.Select(pc => pc.CategoryId)
|
||||
.ToHashSet();
|
||||
|
||||
var result = new GetCategoriesResponseDto
|
||||
{
|
||||
Items = categories
|
||||
.Select(c => new CategoryItemDto
|
||||
{
|
||||
Id = c.Id,
|
||||
Title = c.Title,
|
||||
Selected = selectedIds.Contains(c.Id)
|
||||
})
|
||||
.ToList()
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using CMSMicroservice.Protobuf.Protos.Products;
|
||||
using CMSMicroservice.Protobuf.Protos.ProductImages;
|
||||
using CMSMicroservice.Protobuf.Protos.ProductGallerys;
|
||||
using CMSMicroservice.Protobuf.Protos.Category;
|
||||
using CMSMicroservice.Protobuf.Protos.PruductCategory;
|
||||
using FMSMicroservice.Protobuf.Protos.FileInfo;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -48,6 +49,7 @@ public class ApplicationContractContext : IApplicationContractContext
|
||||
public ProductGallerysContract.ProductGallerysContractClient ProductGallerys => GetService<ProductGallerysContract.ProductGallerysContractClient>();
|
||||
public RoleContract.RoleContractClient Roles => GetService<RoleContract.RoleContractClient>();
|
||||
public CategoryContract.CategoryContractClient Categories => GetService<CategoryContract.CategoryContractClient>();
|
||||
public PruductCategoryContract.PruductCategoryContractClient ProductCategories => GetService<PruductCategoryContract.PruductCategoryContractClient>();
|
||||
public UserAddressContract.UserAddressContractClient UserAddress => GetService<UserAddressContract.UserAddressContractClient>();
|
||||
public UserContract.UserContractClient Users => GetService<UserContract.UserContractClient>();
|
||||
public UserOrderContract.UserOrderContractClient UserOrders => GetService<UserOrderContract.UserOrderContractClient>();
|
||||
|
||||
Reference in New Issue
Block a user