Add Get queries for variants and categories
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using MediatR;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
using Printbase.Application.Products.Queries;
|
||||
|
||||
namespace Printbase.Application.Products.Handlers;
|
||||
|
||||
public class GetCategoriesHandler(IUnitOfWork unitOfWork)
|
||||
: IRequestHandler<GetCategoriesQuery, IEnumerable<CategoryDto>>
|
||||
{
|
||||
public async Task<IEnumerable<CategoryDto>> Handle(GetCategoriesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<Domain.Entities.Product.Category> categories;
|
||||
|
||||
if (request.RootCategoriesOnly)
|
||||
{
|
||||
categories = await unitOfWork.CategoryRepository.GetRootCategoriesAsync(cancellationToken);
|
||||
}
|
||||
else if (request.IsActive.HasValue && request.IsActive.Value)
|
||||
{
|
||||
categories = await unitOfWork.CategoryRepository.GetActiveAsync(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
categories = await unitOfWork.CategoryRepository.GetAllAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return categories.Select(c => new CategoryDto
|
||||
{
|
||||
Id = c.Id,
|
||||
Name = c.Name,
|
||||
Description = c.Description,
|
||||
ImageUrl = c.ImageUrl,
|
||||
SortOrder = c.SortOrder,
|
||||
IsActive = c.IsActive,
|
||||
ParentCategoryId = c.ParentCategoryId,
|
||||
CreatedAt = c.CreatedAt,
|
||||
ModifiedAt = c.ModifiedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using MediatR;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
using Printbase.Application.Products.Queries;
|
||||
|
||||
namespace Printbase.Application.Products.Handlers;
|
||||
|
||||
public class GetProductVariantsHandler(IUnitOfWork unitOfWork)
|
||||
: IRequestHandler<GetProductVariantsQuery, IEnumerable<ProductVariantDto>>
|
||||
{
|
||||
public async Task<IEnumerable<ProductVariantDto>> Handle(GetProductVariantsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<Domain.Entities.Product.ProductVariant> variants;
|
||||
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
if (request.InStockOnly)
|
||||
{
|
||||
variants = await unitOfWork.ProductVariantRepository.GetInStockByProductIdAsync(request.ProductId.Value, cancellationToken);
|
||||
}
|
||||
else if (request.IsActive.HasValue && request.IsActive.Value)
|
||||
{
|
||||
variants = await unitOfWork.ProductVariantRepository.GetActiveByProductIdAsync(request.ProductId.Value, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
variants = await unitOfWork.ProductVariantRepository.GetByProductIdAsync(request.ProductId.Value, cancellationToken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
variants = new List<Domain.Entities.Product.ProductVariant>();
|
||||
}
|
||||
|
||||
return variants.Select(pv => new ProductVariantDto
|
||||
{
|
||||
Id = pv.Id,
|
||||
ProductId = pv.ProductId,
|
||||
Size = pv.Size,
|
||||
Color = pv.Color,
|
||||
Price = pv.Price,
|
||||
ImageUrl = pv.ImageUrl,
|
||||
Sku = pv.Sku,
|
||||
StockQuantity = pv.StockQuantity,
|
||||
IsActive = pv.IsActive,
|
||||
Product = new ProductDto
|
||||
{
|
||||
Id = pv.Product.Id,
|
||||
Name = pv.Product.Name,
|
||||
Description = pv.Product.Description,
|
||||
BasePrice = pv.Product.BasePrice,
|
||||
IsCustomizable = pv.Product.IsCustomizable,
|
||||
IsActive = pv.Product.IsActive,
|
||||
ImageUrl = pv.Product.ImageUrl,
|
||||
CategoryId = pv.Product.CategoryId,
|
||||
CreatedAt = pv.Product.CreatedAt,
|
||||
ModifiedAt = pv.Product.ModifiedAt
|
||||
},
|
||||
CreatedAt = pv.CreatedAt,
|
||||
ModifiedAt = pv.ModifiedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using MediatR;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
|
||||
namespace Printbase.Application.Products.Queries;
|
||||
|
||||
public class GetCategoriesQuery : IRequest<IEnumerable<CategoryDto>>
|
||||
{
|
||||
public bool? IsActive { get; set; }
|
||||
public bool RootCategoriesOnly { get; set; } = false;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using MediatR;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
|
||||
namespace Printbase.Application.Products.Queries;
|
||||
|
||||
public class GetProductVariantsQuery : IRequest<IEnumerable<ProductVariantDto>>
|
||||
{
|
||||
public Guid? ProductId { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
public bool InStockOnly { get; set; } = false;
|
||||
}
|
||||
30
src/Printbase.WebApi/Controllers/CategoriesController.cs
Normal file
30
src/Printbase.WebApi/Controllers/CategoriesController.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Printbase.Application.Products.Commands;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
|
||||
namespace Printbase.WebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CategoriesController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<CategoryDto>> CreateCategory([FromBody] CreateCategoryCommand command)
|
||||
{
|
||||
var result = await mediator.Send(command);
|
||||
return CreatedAtAction(nameof(CreateCategory), new { id = result.Id }, result);
|
||||
}
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<ActionResult> DeleteCategory(Guid id)
|
||||
{
|
||||
var command = new DeleteCategoryCommand { Id = id };
|
||||
var result = await mediator.Send(command);
|
||||
|
||||
if (!result)
|
||||
return NotFound();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Printbase.Application.Products.Commands;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
|
||||
namespace Printbase.WebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ProductVariantsController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ProductVariantDto>> CreateProductVariant([FromBody] CreateProductVariantCommand command)
|
||||
{
|
||||
var result = await mediator.Send(command);
|
||||
return CreatedAtAction(nameof(CreateProductVariant), new { id = result.Id }, result);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult> DeleteProductVariant(Guid id)
|
||||
{
|
||||
var command = new DeleteProductVariantCommand { Id = id };
|
||||
var result = await mediator.Send(command);
|
||||
|
||||
if (!result)
|
||||
return NotFound();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
65
src/Printbase.WebApi/Controllers/ProductsController.cs
Normal file
65
src/Printbase.WebApi/Controllers/ProductsController.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Printbase.Application.Products.Commands;
|
||||
using Printbase.Application.Products.Dtos;
|
||||
using Printbase.Application.Products.Queries;
|
||||
using Printbase.Domain.Common.Models;
|
||||
|
||||
namespace Printbase.WebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ProductsController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PagedResultDto<ProductDto>>> GetProducts(
|
||||
[FromQuery] int pageNumber = 1,
|
||||
[FromQuery] int pageSize = 10,
|
||||
[FromQuery] string? searchTerm = null,
|
||||
[FromQuery] Guid? categoryId = null,
|
||||
[FromQuery] decimal? minPrice = null,
|
||||
[FromQuery] decimal? maxPrice = null,
|
||||
[FromQuery] bool? isActive = true,
|
||||
[FromQuery] bool? isCustomizable = null,
|
||||
[FromQuery] string sortBy = "Name",
|
||||
[FromQuery] string sortDirection = "ASC")
|
||||
{
|
||||
var filterParameters = new ProductFilterParameters
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
SearchTerm = searchTerm,
|
||||
CategoryId = categoryId,
|
||||
MinPrice = minPrice,
|
||||
MaxPrice = maxPrice,
|
||||
IsActive = isActive,
|
||||
IsCustomizable = isCustomizable,
|
||||
SortBy = sortBy,
|
||||
SortDirection = sortDirection
|
||||
};
|
||||
|
||||
var query = new GetProductsQuery { FilterParameters = filterParameters };
|
||||
var result = await mediator.Send(query);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ProductDto>> CreateProduct([FromBody] CreateProductCommand command)
|
||||
{
|
||||
var result = await mediator.Send(command);
|
||||
return CreatedAtAction(nameof(CreateProduct), new { id = result.Id }, result);
|
||||
}
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<ActionResult> DeleteProduct(Guid id)
|
||||
{
|
||||
var command = new DeleteProductCommand { Id = id };
|
||||
var result = await mediator.Send(command);
|
||||
|
||||
if (!result)
|
||||
return NotFound();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Printbase.Application;
|
||||
using Printbase.Application.Products.Handlers;
|
||||
using Printbase.Domain.Entities.Users;
|
||||
using Printbase.Domain.Repositories;
|
||||
using Printbase.Infrastructure;
|
||||
using Printbase.Infrastructure.Database;
|
||||
using Printbase.Infrastructure.Repositories;
|
||||
|
||||
namespace Printbase.WebApi;
|
||||
|
||||
@@ -12,6 +16,11 @@ public static class Startup
|
||||
{
|
||||
var services = builder.Services;
|
||||
|
||||
services.AddScoped<IProductRepository, ProductRepository>();
|
||||
services.AddScoped<IProductVariantRepository, ProductVariantRepository>();
|
||||
services.AddScoped<ICategoryRepository, CategoryRepository>();
|
||||
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
||||
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseSqlServer(
|
||||
builder.Configuration.GetConnectionString("DefaultConnection"),
|
||||
@@ -67,6 +76,9 @@ public static class Startup
|
||||
policy.RequireRole("Administrator", "ProductManager"))
|
||||
.AddPolicy("CustomerPolicy", policy =>
|
||||
policy.RequireRole("Customer", "Administrator", "OrderManager", "ProductManager"));
|
||||
|
||||
services.AddControllers();
|
||||
services.AddSwaggerGen();
|
||||
}
|
||||
|
||||
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
@@ -86,18 +98,22 @@ public static class Startup
|
||||
}
|
||||
}
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
app.UseHsts();
|
||||
app.UseHttpsRedirection();
|
||||
}
|
||||
// if (env.IsDevelopment())
|
||||
// {
|
||||
// app.UseSwagger();
|
||||
// app.UseSwaggerUI();
|
||||
// app.UseDeveloperExceptionPage();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// app.UseExceptionHandler("/Error");
|
||||
// app.UseHsts();
|
||||
// app.UseHttpsRedirection();
|
||||
// }
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user