feat: Added Product controller and endpoints (Service Layer)
This commit is contained in:
		| @@ -0,0 +1,19 @@ | ||||
| using Core.Adapters.Lib.Inventory; | ||||
| using Core.Inventory.Application.UseCases.Product.Ports; | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Adapter | ||||
| { | ||||
|     public class ProductPort : BasePresenter, IProductPort | ||||
|     { | ||||
|         public void Success(ProductAdapter output) | ||||
|         { | ||||
|             ViewModel = new OkObjectResult(output); | ||||
|         } | ||||
|         public void Success(List<ProductAdapter> output) | ||||
|         { | ||||
|             ViewModel = new OkObjectResult(output); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,16 @@ | ||||
| using Core.Adapters.Lib.Inventory; | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class ChangeProductStatusRequest : Notificator, ICommand | ||||
|     { | ||||
|         public string Id { get; set; } = null!; | ||||
|         public ProductStatus NewStatus { get; set; } | ||||
|  | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return Id != null; | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,18 @@ | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class CreateProductRequest : Notificator, ICommand | ||||
|     { | ||||
|         public string TenantId { get; set; } = null!; | ||||
|         public string ProductName { get; set; } = null!; | ||||
|         public string Description { get; set; } = null!; | ||||
|         public string Status { get; set; } = null!; | ||||
|         public List<string> TagIds { get; set; } = new List<string>(); | ||||
|  | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return ProductName != null; | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,14 @@ | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class GetAllProductsByListRequest : Notificator, ICommand | ||||
|     { | ||||
|         public string[] Products { get; set; } = null!; | ||||
|  | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return Products != null && Products.Any(); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,12 @@ | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class GetAllProductsRequest : Notificator, ICommand | ||||
|     { | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,14 @@ | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class GetProductRequest : Notificator, ICommand | ||||
|     { | ||||
|         public string Id { get; set; } = null!; | ||||
|  | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return Id != null; | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,20 @@ | ||||
| using Core.Adapters.Lib.Inventory; | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Input | ||||
| { | ||||
|     public class UpdateProductRequest : Notificator, ICommand | ||||
|     { | ||||
|         public string Id { get; set; } = null!; | ||||
|         public string TenantId { get; set; } = null!; | ||||
|         public string ProductName { get; set; } = null!; | ||||
|         public string Description { get; set; } = null!; | ||||
|         public string Status { get; set; } = null!; | ||||
|         public List<string> TagIds { get; set; } = new List<string>(); | ||||
|  | ||||
|         public bool Validate() | ||||
|         { | ||||
|             return Id != null && ProductName != null; | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,14 @@ | ||||
| using Core.Adapters.Lib.Inventory; | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Ports | ||||
| { | ||||
|     public interface IProductPort : IBasePort, | ||||
|         ICommandSuccessPort<ProductAdapter>, | ||||
|         ICommandSuccessPort<List<ProductAdapter>>, | ||||
|         INoContentPort, IBusinessErrorPort, ITimeoutPort, IValidationErrorPort, | ||||
|         INotFoundPort, IForbiddenPort, IUnauthorizedPort, IInternalServerErrorPort, | ||||
|         IBadRequestPort | ||||
|     { | ||||
|     } | ||||
| }  | ||||
							
								
								
									
										214
									
								
								Core.Inventory.Application/UseCases/Product/ProductHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								Core.Inventory.Application/UseCases/Product/ProductHandler.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| using Core.Adapters.Lib.Inventory; | ||||
| using Core.Inventory.Application.UseCases.Product.Input; | ||||
| using Core.Inventory.Application.UseCases.Product.Ports; | ||||
| using Core.Inventory.External.Clients; | ||||
| using Core.Inventory.External.Clients.Requests; | ||||
| using FluentValidation; | ||||
| using Lib.Architecture.BuildingBlocks; | ||||
| using Lib.Architecture.BuildingBlocks.Helpers; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product | ||||
| { | ||||
|     public class ProductHandler : | ||||
|         IComponentHandler<ChangeProductStatusRequest>, | ||||
|         IComponentHandler<GetAllProductsRequest>, | ||||
|         IComponentHandler<GetAllProductsByListRequest>, | ||||
|         IComponentHandler<UpdateProductRequest>, | ||||
|         IComponentHandler<GetProductRequest>, | ||||
|         IComponentHandler<CreateProductRequest> | ||||
|     { | ||||
|         private readonly IProductPort _port; | ||||
|         private readonly IValidator<ChangeProductStatusRequest> _changeProductStatusValidator; | ||||
|         private readonly IValidator<CreateProductRequest> _registerProductValidator; | ||||
|         private readonly IValidator<UpdateProductRequest> _updateProductValidator; | ||||
|         private readonly IValidator<GetAllProductsByListRequest> _productsByListValidator; | ||||
|         private readonly IInventoryServiceClient _inventoryServiceClient; | ||||
|  | ||||
|         public ProductHandler( | ||||
|             IProductPort port, | ||||
|             IValidator<ChangeProductStatusRequest> changeProductStatusValidator, | ||||
|             IValidator<CreateProductRequest> registerProductValidator, | ||||
|             IValidator<UpdateProductRequest> updateProductValidator, | ||||
|             IValidator<GetAllProductsByListRequest> productsByListValidator, | ||||
|             IInventoryServiceClient inventoryDALService) | ||||
|         { | ||||
|             _port = port ?? throw new ArgumentNullException(nameof(port)); | ||||
|             _changeProductStatusValidator = changeProductStatusValidator ?? throw new ArgumentNullException(nameof(changeProductStatusValidator)); | ||||
|             _registerProductValidator = registerProductValidator ?? throw new ArgumentNullException(nameof(registerProductValidator)); | ||||
|             _updateProductValidator = updateProductValidator ?? throw new ArgumentNullException(nameof(updateProductValidator)); | ||||
|             _inventoryServiceClient = inventoryDALService ?? throw new ArgumentNullException(nameof(inventoryDALService)); | ||||
|             _productsByListValidator = productsByListValidator ?? throw new ArgumentNullException(nameof(productsByListValidator)); | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(GetProductRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 var result = await _inventoryServiceClient.GetProductByIdAsync(command.Id, cancellationToken).ConfigureAwait(false); | ||||
|  | ||||
|                 if (result == null) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 _port.Success(result); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(GetAllProductsRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 var _result = await _inventoryServiceClient.GetAllProductsAsync(cancellationToken).ConfigureAwait(false); | ||||
|                 if (!_result.Any()) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|                 _port.Success(_result.ToList()); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(GetAllProductsByListRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 if (!command.IsValid(_productsByListValidator)) | ||||
|                 { | ||||
|                     _port.ValidationErrors(command.Notifications); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var _result = await _inventoryServiceClient.GetAllProductsByListAsync(command.Products, cancellationToken).ConfigureAwait(false); | ||||
|                 if (!_result.Any()) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|                 _port.Success(_result.ToList()); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(ChangeProductStatusRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 if (!command.IsValid(_changeProductStatusValidator)) | ||||
|                 { | ||||
|                     _port.ValidationErrors(command.Notifications); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var result = await _inventoryServiceClient.ChangeProductStatusAsync(command.Id, command.NewStatus, cancellationToken).ConfigureAwait(false); | ||||
|  | ||||
|                 if (result == null) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 _port.Success(result); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(CreateProductRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 if (!command.IsValid(_registerProductValidator)) | ||||
|                 { | ||||
|                     _port.ValidationErrors(command.Notifications); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var productRequest = new ProductRequest | ||||
|                 { | ||||
|                     TenantId = command.TenantId, | ||||
|                     ProductName = command.ProductName, | ||||
|                     Description = command.Description, | ||||
|                     Status = command.Status, | ||||
|                     TagIds = command.TagIds | ||||
|                 }; | ||||
|  | ||||
|                 var result = await _inventoryServiceClient.CreateProductAsync(productRequest, cancellationToken).ConfigureAwait(false); | ||||
|  | ||||
|                 if (result == null) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 _port.Success(result); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async ValueTask ExecuteAsync(UpdateProductRequest command, CancellationToken cancellationToken = default) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArgumentNullException.ThrowIfNull(command); | ||||
|  | ||||
|                 if (!command.IsValid(_updateProductValidator)) | ||||
|                 { | ||||
|                     _port.ValidationErrors(command.Notifications); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var productAdapter = new ProductAdapter | ||||
|                 { | ||||
|                     Id = command.Id, | ||||
|                     TenantId = command.TenantId, | ||||
|                     ProductName = command.ProductName, | ||||
|                     Description = command.Description, | ||||
|                     Status = Enum.Parse<ProductStatus>(command.Status), | ||||
|                     TagIds = command.TagIds.Select(id => MongoDB.Bson.ObjectId.Parse(id)).ToList() | ||||
|                 }; | ||||
|  | ||||
|                 var result = await _inventoryServiceClient.UpdateProductAsync(productAdapter, command.Id, cancellationToken).ConfigureAwait(false); | ||||
|  | ||||
|                 if (result == null) | ||||
|                 { | ||||
|                     _port.NoContentSuccess(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 _port.Success(result); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ApiResponseHelper.EvaluatePort(ex, _port); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,13 @@ | ||||
| using Core.Inventory.Application.UseCases.Product.Input; | ||||
| using FluentValidation; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Validator | ||||
| { | ||||
|     public class ChangeProductStatusValidator : AbstractValidator<ChangeProductStatusRequest> | ||||
|     { | ||||
|         public ChangeProductStatusValidator() | ||||
|         { | ||||
|             RuleFor(i => i.Id).NotEmpty().NotNull().OverridePropertyName(x => x.Id).WithName("Product Id").WithMessage("Product Id is Obligatory."); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,14 @@ | ||||
| using Core.Inventory.Application.UseCases.Product.Input; | ||||
| using FluentValidation; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Validator | ||||
| { | ||||
|     public class CreateProductValidator : AbstractValidator<CreateProductRequest> | ||||
|     { | ||||
|         public CreateProductValidator() | ||||
|         { | ||||
|             RuleFor(i => i.ProductName).NotEmpty().NotNull().OverridePropertyName(x => x.ProductName).WithName("Product Name").WithMessage("Product Name is Obligatory."); | ||||
|             RuleFor(i => i.Description).NotEmpty().NotNull().OverridePropertyName(x => x.Description).WithName("Product Description").WithMessage("Product Description is Obligatory."); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,13 @@ | ||||
| using Core.Inventory.Application.UseCases.Product.Input; | ||||
| using FluentValidation; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Validator | ||||
| { | ||||
|     public class GetAllProductsByListValidator : AbstractValidator<GetAllProductsByListRequest> | ||||
|     { | ||||
|         public GetAllProductsByListValidator() | ||||
|         { | ||||
|             RuleFor(i => i.Products).NotEmpty().NotNull().OverridePropertyName(x => x.Products).WithName("Products").WithMessage("Products are Obligatory."); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
| @@ -0,0 +1,14 @@ | ||||
| using Core.Inventory.Application.UseCases.Product.Input; | ||||
| using FluentValidation; | ||||
|  | ||||
| namespace Core.Inventory.Application.UseCases.Product.Validator | ||||
| { | ||||
|     public class UpdateProductValidator : AbstractValidator<UpdateProductRequest> | ||||
|     { | ||||
|         public UpdateProductValidator() | ||||
|         { | ||||
|             RuleFor(i => i.ProductName).NotEmpty().NotNull().OverridePropertyName(x => x.ProductName).WithName("Product Name").WithMessage("Product Name is Obligatory."); | ||||
|             RuleFor(i => i.Description).NotEmpty().NotNull().OverridePropertyName(x => x.Description).WithName("Product Description").WithMessage("Product Description is Obligatory."); | ||||
|         } | ||||
|     } | ||||
| }  | ||||
		Reference in New Issue
	
	Block a user