diff --git a/src/services/DevStore.ShoppingCart.API/Configuration/ApiConfig.cs b/src/services/DevStore.ShoppingCart.API/Configuration/ApiConfig.cs index a8dc68f..257c566 100644 --- a/src/services/DevStore.ShoppingCart.API/Configuration/ApiConfig.cs +++ b/src/services/DevStore.ShoppingCart.API/Configuration/ApiConfig.cs @@ -1,12 +1,6 @@ -using DevStore.ShoppingCart.API.Data; -using DevStore.ShoppingCart.API.Services.gRPC; +using DevStore.ShoppingCart.API.Services.gRPC; using DevStore.WebAPI.Core.Identity; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; namespace DevStore.ShoppingCart.API.Configuration { diff --git a/src/services/DevStore.ShoppingCart.API/Configuration/DbMigrationHelpers.cs b/src/services/DevStore.ShoppingCart.API/Configuration/DbMigrationHelpers.cs index 594c2c3..3fed258 100644 --- a/src/services/DevStore.ShoppingCart.API/Configuration/DbMigrationHelpers.cs +++ b/src/services/DevStore.ShoppingCart.API/Configuration/DbMigrationHelpers.cs @@ -1,10 +1,4 @@ -using System; -using System.Threading.Tasks; -using DevStore.ShoppingCart.API.Data; -using DevStore.WebAPI.Core.Configuration; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; +using DevStore.WebAPI.Core.Configuration; namespace DevStore.ShoppingCart.API.Configuration { diff --git a/src/services/DevStore.ShoppingCart.API/Configuration/DependencyInjectionConfig.cs b/src/services/DevStore.ShoppingCart.API/Configuration/DependencyInjectionConfig.cs index fe13559..5cda6a1 100644 --- a/src/services/DevStore.ShoppingCart.API/Configuration/DependencyInjectionConfig.cs +++ b/src/services/DevStore.ShoppingCart.API/Configuration/DependencyInjectionConfig.cs @@ -1,7 +1,4 @@ -using DevStore.ShoppingCart.API.Data; -using DevStore.WebAPI.Core.User; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; +using DevStore.WebAPI.Core.User; namespace DevStore.ShoppingCart.API.Configuration { diff --git a/src/services/DevStore.ShoppingCart.API/Configuration/MessageBusConfig.cs b/src/services/DevStore.ShoppingCart.API/Configuration/MessageBusConfig.cs index b6c4c05..dab9e11 100644 --- a/src/services/DevStore.ShoppingCart.API/Configuration/MessageBusConfig.cs +++ b/src/services/DevStore.ShoppingCart.API/Configuration/MessageBusConfig.cs @@ -1,8 +1,6 @@ using DevStore.Core.Utils; using DevStore.MessageBus; using DevStore.ShoppingCart.API.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; namespace DevStore.ShoppingCart.API.Configuration { diff --git a/src/services/DevStore.ShoppingCart.API/Configuration/SwaggerConfig.cs b/src/services/DevStore.ShoppingCart.API/Configuration/SwaggerConfig.cs index 3c30e58..07af652 100644 --- a/src/services/DevStore.ShoppingCart.API/Configuration/SwaggerConfig.cs +++ b/src/services/DevStore.ShoppingCart.API/Configuration/SwaggerConfig.cs @@ -1,7 +1,4 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.OpenApi.Models; -using System; +using Microsoft.OpenApi.Models; namespace DevStore.ShoppingCart.API.Configuration { diff --git a/src/services/DevStore.ShoppingCart.API/Controllers/ShoppingCartController.cs b/src/services/DevStore.ShoppingCart.API/Controllers/ShoppingCartController.cs deleted file mode 100644 index 522cd0a..0000000 --- a/src/services/DevStore.ShoppingCart.API/Controllers/ShoppingCartController.cs +++ /dev/null @@ -1,170 +0,0 @@ -using DevStore.ShoppingCart.API.Model; -using DevStore.WebAPI.Core.Controllers; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using System; -using System.Linq; -using System.Threading.Tasks; -using DevStore.WebAPI.Core.User; - -namespace DevStore.ShoppingCart.API.Controllers -{ - [Authorize, Route("shopping-cart")] - public class ShoppingCartController : MainController - { - private readonly IAspNetUser _user; - private readonly Data.ShoppingCartContext _context; - - public ShoppingCartController(IAspNetUser user, Data.ShoppingCartContext context) - { - _user = user; - _context = context; - } - - [HttpGet("")] - public async Task GetShoppingCart() - { - return await GetShoppingCartClient() ?? new CustomerShoppingCart(); - } - - [HttpPost("")] - public async Task AddItem(CartItem item) - { - var shoppingCart = await GetShoppingCartClient(); - - if (shoppingCart == null) - ManageNewCart(item); - else - ManageCart(shoppingCart, item); - - if (!ValidOperation()) return CustomResponse(); - - await Persist(); - return CustomResponse(); - } - - [HttpPut("{productId}")] - public async Task UpdateItem(Guid productId, CartItem item) - { - var shoppingCart = await GetShoppingCartClient(); - var shoppingCartItem = await GetValidItem(productId, shoppingCart, item); - if (shoppingCartItem == null) return CustomResponse(); - - shoppingCart.UpdateUnit(shoppingCartItem, item.Quantity); - - ValidateShoppingCart(shoppingCart); - if (!ValidOperation()) return CustomResponse(); - - _context.CartItems.Update(shoppingCartItem); - _context.CustomerShoppingCart.Update(shoppingCart); - - await Persist(); - return CustomResponse(); - } - - [HttpDelete("{productId}")] - public async Task RemoveItem(Guid productId) - { - var cart = await GetShoppingCartClient(); - - var item = await GetValidItem(productId, cart); - if (item == null) return CustomResponse(); - - ValidateShoppingCart(cart); - if (!ValidOperation()) return CustomResponse(); - - cart.RemoveItem(item); - - _context.CartItems.Remove(item); - _context.CustomerShoppingCart.Update(cart); - - await Persist(); - return CustomResponse(); - } - - [HttpPost] - [Route("apply-voucher")] - public async Task ApplyVoucher(Voucher voucher) - { - var cart = await GetShoppingCartClient(); - - cart.ApplyVoucher(voucher); - - _context.CustomerShoppingCart.Update(cart); - - await Persist(); - return CustomResponse(); - } - - private async Task GetShoppingCartClient() - { - return await _context.CustomerShoppingCart - .Include(c => c.Items) - .FirstOrDefaultAsync(c => c.CustomerId == _user.GetUserId()); - } - private void ManageNewCart(CartItem item) - { - var cart = new CustomerShoppingCart(_user.GetUserId()); - cart.AddItem(item); - - ValidateShoppingCart(cart); - _context.CustomerShoppingCart.Add(cart); - } - private void ManageCart(CustomerShoppingCart cart, CartItem item) - { - var savedItem = cart.HasItem(item); - - cart.AddItem(item); - ValidateShoppingCart(cart); - - if (savedItem) - { - _context.CartItems.Update(cart.GetProductById(item.ProductId)); - } - else - { - _context.CartItems.Add(item); - } - - _context.CustomerShoppingCart.Update(cart); - } - private async Task GetValidItem(Guid productId, CustomerShoppingCart cart, CartItem item = null) - { - if (item != null && productId != item.ProductId) - { - AddErrorToStack("Current item is not the same sent item"); - return null; - } - - if (cart == null) - { - AddErrorToStack("Shopping cart not found"); - return null; - } - - var cartItem = await _context.CartItems - .FirstOrDefaultAsync(i => i.ShoppingCartId == cart.Id && i.ProductId == productId); - - if (cartItem == null || !cart.HasItem(cartItem)) - { - AddErrorToStack("The item is not in cart"); - return null; - } - - return cartItem; - } - private async Task Persist() - { - var result = await _context.SaveChangesAsync(); - if (result <= 0) AddErrorToStack("Error saving data"); - } - private bool ValidateShoppingCart(CustomerShoppingCart shoppingCart) - { - if (shoppingCart.IsValid()) return true; - - shoppingCart.ValidationResult.Errors.ToList().ForEach(e => AddErrorToStack(e.ErrorMessage)); - return false; - } - } -} diff --git a/src/services/DevStore.ShoppingCart.API/Data/ShoppingCartContext.cs b/src/services/DevStore.ShoppingCart.API/Data/ShoppingCartContext.cs index 1a42a57..436714d 100644 --- a/src/services/DevStore.ShoppingCart.API/Data/ShoppingCartContext.cs +++ b/src/services/DevStore.ShoppingCart.API/Data/ShoppingCartContext.cs @@ -1,7 +1,6 @@ using DevStore.ShoppingCart.API.Model; using FluentValidation.Results; using Microsoft.EntityFrameworkCore; -using System.Linq; namespace DevStore.ShoppingCart.API.Data { diff --git a/src/services/DevStore.ShoppingCart.API/DevStore.ShoppingCart.API.csproj b/src/services/DevStore.ShoppingCart.API/DevStore.ShoppingCart.API.csproj index ae32627..f632f5c 100644 --- a/src/services/DevStore.ShoppingCart.API/DevStore.ShoppingCart.API.csproj +++ b/src/services/DevStore.ShoppingCart.API/DevStore.ShoppingCart.API.csproj @@ -1,29 +1,30 @@  - - net5.0 - 14093821-325c-4620-86a1-2b4a9d955c4f - Linux - ..\..\.. - + + net6.0 + enable + 14093821-325c-4620-86a1-2b4a9d955c4f + Linux + ..\..\.. + - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - - + + + + diff --git a/src/services/DevStore.ShoppingCart.API/Migrations/20210908035300_Initial.cs b/src/services/DevStore.ShoppingCart.API/Migrations/20210908035300_Initial.cs index 2abb4cd..89eac02 100644 --- a/src/services/DevStore.ShoppingCart.API/Migrations/20210908035300_Initial.cs +++ b/src/services/DevStore.ShoppingCart.API/Migrations/20210908035300_Initial.cs @@ -1,5 +1,4 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; namespace DevStore.ShoppingCart.API.Migrations { diff --git a/src/services/DevStore.ShoppingCart.API/Model/CartItem.cs b/src/services/DevStore.ShoppingCart.API/Model/CartItem.cs index 1d75df1..98562ca 100644 --- a/src/services/DevStore.ShoppingCart.API/Model/CartItem.cs +++ b/src/services/DevStore.ShoppingCart.API/Model/CartItem.cs @@ -1,5 +1,4 @@ using FluentValidation; -using System; using System.Text.Json.Serialization; namespace DevStore.ShoppingCart.API.Model diff --git a/src/services/DevStore.ShoppingCart.API/Model/CustomerShoppingCart.cs b/src/services/DevStore.ShoppingCart.API/Model/CustomerShoppingCart.cs index e99c265..a4daf5d 100644 --- a/src/services/DevStore.ShoppingCart.API/Model/CustomerShoppingCart.cs +++ b/src/services/DevStore.ShoppingCart.API/Model/CustomerShoppingCart.cs @@ -1,8 +1,5 @@ using FluentValidation; using FluentValidation.Results; -using System; -using System.Collections.Generic; -using System.Linq; namespace DevStore.ShoppingCart.API.Model { diff --git a/src/services/DevStore.ShoppingCart.API/Program.cs b/src/services/DevStore.ShoppingCart.API/Program.cs index 30683a8..2cd6f99 100644 --- a/src/services/DevStore.ShoppingCart.API/Program.cs +++ b/src/services/DevStore.ShoppingCart.API/Program.cs @@ -1,27 +1,253 @@ -using System.Threading.Tasks; using DevStore.ShoppingCart.API.Configuration; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; +using DevStore.ShoppingCart.API.Data; +using DevStore.ShoppingCart.API.Model; +using DevStore.WebAPI.Core.Identity; +using DevStore.WebAPI.Core.User; +using Microsoft.AspNetCore.Authorization; +using Microsoft.EntityFrameworkCore; -namespace DevStore.ShoppingCart.API +#region Builder Configuration + +var builder = WebApplication.CreateBuilder(args); + +builder.Configuration + .SetBasePath(builder.Environment.ContentRootPath) + .AddJsonFile("appsettings.json", true, true) + .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", true, true) + .AddEnvironmentVariables(); + +builder.Configuration.AddUserSecrets(); + +#endregion + +#region Configure Services + +builder.Services.AddApiConfiguration(builder.Configuration); + +builder.Services.AddJwtConfiguration(builder.Configuration); + +builder.Services.AddSwaggerConfiguration(); + +builder.Services.RegisterServices(); + +builder.Services.AddMessageBusConfiguration(builder.Configuration); + +var app = builder.Build(); + +#endregion + +#region Configure Pipeline + +var context = app.Services.GetRequiredService(); +var user = app.Services.GetRequiredService(); +var Errors = new List(); + +app.UseSwaggerConfiguration(); + +app.UseApiConfiguration(app.Environment); + +MapActions(app); + +app.Run(); + +#endregion + +#region Actions + +void MapActions(WebApplication app) { - public class Program - { - public static void Main(string[] args) + app.MapGet("/shopping-cart", [Authorize] async () => + await GetShoppingCartClient() ?? new CustomerShoppingCart()) + .WithName("GetShoppingCart") + .WithTags("ShoppingCart"); + + app.MapPost("/fornecedor", [Authorize] async ( + CartItem item) => { - var host = CreateHostBuilder(args).Build(); + var shoppingCart = await GetShoppingCartClient(); + + if (shoppingCart == null) + ManageNewCart(item); + else + ManageCart(shoppingCart, item); + + if (Errors.Any()) return CustomResponse(); + + await Persist(); + return CustomResponse(); + }) + .ProducesValidationProblem() + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status400BadRequest) + .WithName("AddItem") + .WithTags("ShoppingCart"); + + app.MapPut("/fornecedor/{productId}", [Authorize] async ( + Guid productId, + CartItem item) => + { + var shoppingCart = await GetShoppingCartClient(); + var shoppingCartItem = await GetValidItem(productId, shoppingCart, item); + if (shoppingCartItem == null) return CustomResponse(); + + shoppingCart.UpdateUnit(shoppingCartItem, item.Quantity); + + ValidateShoppingCart(shoppingCart); + if (Errors.Any()) return CustomResponse(); + + context.CartItems.Update(shoppingCartItem); + context.CustomerShoppingCart.Update(shoppingCart); + + await Persist(); + return CustomResponse(); + }) + .ProducesValidationProblem() + .Produces(StatusCodes.Status204NoContent) + .Produces(StatusCodes.Status400BadRequest) + .WithName("UpdateItem") + .WithTags("ShoppingCart"); + + app.MapDelete("/fornecedor/{productId}", [Authorize] async ( + Guid productId) => + { + var cart = await GetShoppingCartClient(); + + var item = await GetValidItem(productId, cart); + if (item == null) return CustomResponse(); + + ValidateShoppingCart(cart); + if (Errors.Any()) return CustomResponse(); + + cart.RemoveItem(item); + + context.CartItems.Remove(item); + context.CustomerShoppingCart.Update(cart); + + await Persist(); + return CustomResponse(); + }) + .ProducesValidationProblem() + .Produces(StatusCodes.Status204NoContent) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status404NotFound) + .WithName("RemoveItem") + .WithTags("ShoppingCart"); + + app.MapPost("/fornecedor/apply-voucher", [Authorize] async ( + Voucher voucher) => + { + var cart = await GetShoppingCartClient(); + + cart.ApplyVoucher(voucher); + + context.CustomerShoppingCart.Update(cart); + + await Persist(); + return CustomResponse(); + }) + .ProducesValidationProblem() + .Produces(StatusCodes.Status204NoContent) + .Produces(StatusCodes.Status400BadRequest) + .WithName("ApplyVoucher") + .WithTags("ShoppingCart"); +} - Task.WaitAll(DbMigrationHelpers.EnsureSeedData(host.Services.CreateScope())); +#endregion - host.Run(); - } +#region Action Methods - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); +async Task GetShoppingCartClient() +{ + return await context.CustomerShoppingCart + .Include(c => c.Items) + .FirstOrDefaultAsync(c => c.CustomerId == user.GetUserId()); +} + +void ManageNewCart(CartItem item) +{ + var cart = new CustomerShoppingCart(user.GetUserId()); + cart.AddItem(item); + + ValidateShoppingCart(cart); + context.CustomerShoppingCart.Add(cart); +} + +void ManageCart(CustomerShoppingCart cart, CartItem item) +{ + var savedItem = cart.HasItem(item); + + cart.AddItem(item); + ValidateShoppingCart(cart); + + if (savedItem) + { + context.CartItems.Update(cart.GetProductById(item.ProductId)); } + else + { + context.CartItems.Add(item); + } + + context.CustomerShoppingCart.Update(cart); } + +async Task GetValidItem(Guid productId, CustomerShoppingCart cart, CartItem item = null) +{ + if (item != null && productId != item.ProductId) + { + AddErrorToStack("Current item is not the same sent item"); + return null; + } + + if (cart == null) + { + AddErrorToStack("Shopping cart not found"); + return null; + } + + var cartItem = await context.CartItems + .FirstOrDefaultAsync(i => i.ShoppingCartId == cart.Id && i.ProductId == productId); + + if (cartItem == null || !cart.HasItem(cartItem)) + { + AddErrorToStack("The item is not in cart"); + return null; + } + + return cartItem; +} + +async Task Persist() +{ + var result = await context.SaveChangesAsync(); + if (result <= 0) AddErrorToStack("Error saving data"); +} + +bool ValidateShoppingCart(CustomerShoppingCart shoppingCart) +{ + if (shoppingCart.IsValid()) return true; + + shoppingCart.ValidationResult.Errors.ToList().ForEach(e => AddErrorToStack(e.ErrorMessage)); + return false; +} + +void AddErrorToStack(string error) +{ + Errors.Add(error); +} + +IResult CustomResponse(object result = null) +{ + if (!Errors.Any()) + { + return Results.Ok(result); + } + + return Results.BadRequest(Results.ValidationProblem( + new Dictionary + { + { "Messages", Errors.ToArray() } + })); +} + +#endregion \ No newline at end of file diff --git a/src/services/DevStore.ShoppingCart.API/Services/ShoppingCartIntegrationHandler.cs b/src/services/DevStore.ShoppingCart.API/Services/ShoppingCartIntegrationHandler.cs index 97c3732..9233e27 100644 --- a/src/services/DevStore.ShoppingCart.API/Services/ShoppingCartIntegrationHandler.cs +++ b/src/services/DevStore.ShoppingCart.API/Services/ShoppingCartIntegrationHandler.cs @@ -1,11 +1,6 @@ using DevStore.Core.Messages.Integration; using DevStore.MessageBus; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System; -using System.Threading; -using System.Threading.Tasks; namespace DevStore.ShoppingCart.API.Services { diff --git a/src/services/DevStore.ShoppingCart.API/Services/gRPC/ShoppingCartGrpcService.cs b/src/services/DevStore.ShoppingCart.API/Services/gRPC/ShoppingCartGrpcService.cs index 5d96a69..c7b2c23 100644 --- a/src/services/DevStore.ShoppingCart.API/Services/gRPC/ShoppingCartGrpcService.cs +++ b/src/services/DevStore.ShoppingCart.API/Services/gRPC/ShoppingCartGrpcService.cs @@ -2,8 +2,6 @@ using Grpc.Core; using Microsoft.AspNetCore.Authorization; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; using DevStore.WebAPI.Core.User; namespace DevStore.ShoppingCart.API.Services.gRPC diff --git a/src/services/DevStore.ShoppingCart.API/Startup.cs b/src/services/DevStore.ShoppingCart.API/Startup.cs deleted file mode 100644 index 98624ca..0000000 --- a/src/services/DevStore.ShoppingCart.API/Startup.cs +++ /dev/null @@ -1,51 +0,0 @@ -using DevStore.ShoppingCart.API.Configuration; -using DevStore.WebAPI.Core.Identity; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; - -namespace DevStore.ShoppingCart.API -{ - public class Startup - { - public IConfiguration Configuration { get; } - - public Startup(IHostEnvironment hostEnvironment) - { - var builder = new ConfigurationBuilder() - .SetBasePath(hostEnvironment.ContentRootPath) - .AddJsonFile("appsettings.json", true, true) - .AddJsonFile($"appsettings.{hostEnvironment.EnvironmentName}.json", true, true) - .AddEnvironmentVariables(); - - if (hostEnvironment.IsDevelopment()) - { - builder.AddUserSecrets(); - } - - Configuration = builder.Build(); - } - - public void ConfigureServices(IServiceCollection services) - { - services.AddApiConfiguration(Configuration); - - services.AddJwtConfiguration(Configuration); - - services.AddSwaggerConfiguration(); - - services.RegisterServices(); - - services.AddMessageBusConfiguration(Configuration); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseSwaggerConfiguration(); - - app.UseApiConfiguration(env); - } - } -} diff --git a/src/services/DevStore.ShoppingCart.API/appsettings.Development.json b/src/services/DevStore.ShoppingCart.API/appsettings.Development.json index 9b4f7f6..abb9dc5 100644 --- a/src/services/DevStore.ShoppingCart.API/appsettings.Development.json +++ b/src/services/DevStore.ShoppingCart.API/appsettings.Development.json @@ -7,7 +7,6 @@ } }, "ConnectionStrings": { - //"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ShoppingCart;Trusted_Connection=True;MultipleActiveResultSets=true" "DefaultConnection": "Server=.;Initial Catalog=DSShoppingCart;Persist Security Info=False;User ID=sa;Password=@Password1;MultipleActiveResultSets=False;Connection Timeout=30;" }, "MessageQueueConnection": {