-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
88acee8
commit 0543ff8
Showing
38 changed files
with
905 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file added
BIN
+9.78 KB
src/api gateways/DevStore.Bff.Compras/Controllers/ShoppingCartController.cs
Binary file not shown.
Binary file modified
BIN
-200 Bytes
(93%)
src/api gateways/DevStore.Bff.Compras/DevStore.Bff.Compras.csproj
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+660 Bytes
src/api gateways/DevStore.Bff.Compras/Models/ShoppingCartItemDto.cs
Binary file not shown.
Binary file added
BIN
+5.55 KB
src/api gateways/DevStore.Bff.Compras/Services/ShoppingCartService.cs
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
170 changes: 170 additions & 0 deletions
170
src/services/DevStore.ShoppingCart.API/Controllers/ShoppingCartController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
using DevStore.ShoppingCart.API.Model; | ||
using DevStore.WebAPI.Core.Controllers; | ||
using DevStore.WebAPI.Core.Usuario; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.EntityFrameworkCore; | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
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<ShoppingCartClient> GetShoppingCart() | ||
{ | ||
return await GetShoppingCartClient() ?? new ShoppingCartClient(); | ||
} | ||
|
||
[HttpPost("")] | ||
public async Task<IActionResult> AddItem(CartItem item) | ||
{ | ||
var carrinho = await GetShoppingCartClient(); | ||
|
||
if (carrinho == null) | ||
ManageNewCart(item); | ||
else | ||
ManageCart(carrinho, item); | ||
|
||
if (!OperacaoValida()) return CustomResponse(); | ||
|
||
await Persist(); | ||
return CustomResponse(); | ||
} | ||
|
||
[HttpPut("{productId}")] | ||
public async Task<IActionResult> UpdateItem(Guid productId, CartItem item) | ||
{ | ||
var carrinho = await GetShoppingCartClient(); | ||
var itemCarrinho = await GetValidItem(productId, carrinho, item); | ||
if (itemCarrinho == null) return CustomResponse(); | ||
|
||
carrinho.UpdateUnit(itemCarrinho, item.Quantity); | ||
|
||
ValidateShoppingCart(carrinho); | ||
if (!OperacaoValida()) return CustomResponse(); | ||
|
||
_context.CartItems.Update(itemCarrinho); | ||
_context.ShoppingCartClient.Update(carrinho); | ||
|
||
await Persist(); | ||
return CustomResponse(); | ||
} | ||
|
||
[HttpDelete("{productId}")] | ||
public async Task<IActionResult> RemoveItem(Guid productId) | ||
{ | ||
var cart = await GetShoppingCartClient(); | ||
|
||
var item = await GetValidItem(productId, cart); | ||
if (item == null) return CustomResponse(); | ||
|
||
ValidateShoppingCart(cart); | ||
if (!OperacaoValida()) return CustomResponse(); | ||
|
||
cart.RemoveItem(item); | ||
|
||
_context.CartItems.Remove(item); | ||
_context.ShoppingCartClient.Update(cart); | ||
|
||
await Persist(); | ||
return CustomResponse(); | ||
} | ||
|
||
[HttpPost] | ||
[Route("apply-voucher")] | ||
public async Task<IActionResult> ApplyVoucher(Voucher voucher) | ||
{ | ||
var cart = await GetShoppingCartClient(); | ||
|
||
cart.ApplyVoucher(voucher); | ||
|
||
_context.ShoppingCartClient.Update(cart); | ||
|
||
await Persist(); | ||
return CustomResponse(); | ||
} | ||
|
||
private async Task<ShoppingCartClient> GetShoppingCartClient() | ||
{ | ||
return await _context.ShoppingCartClient | ||
.Include(c => c.Items) | ||
.FirstOrDefaultAsync(c => c.ClientId == _user.ObterUserId()); | ||
} | ||
private void ManageNewCart(CartItem item) | ||
{ | ||
var cart = new ShoppingCartClient(_user.ObterUserId()); | ||
cart.AddItem(item); | ||
|
||
ValidateShoppingCart(cart); | ||
_context.ShoppingCartClient.Add(cart); | ||
} | ||
private void ManageCart(ShoppingCartClient 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.ShoppingCartClient.Update(cart); | ||
} | ||
private async Task<CartItem> GetValidItem(Guid productId, ShoppingCartClient cart, CartItem item = null) | ||
{ | ||
if (item != null && productId != item.ProductId) | ||
{ | ||
AdicionarErroProcessamento("Current item is not the same sent item"); | ||
return null; | ||
} | ||
|
||
if (cart == null) | ||
{ | ||
AdicionarErroProcessamento("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)) | ||
{ | ||
AdicionarErroProcessamento("The item is not in cart"); | ||
return null; | ||
} | ||
|
||
return cartItem; | ||
} | ||
private async Task Persist() | ||
{ | ||
var result = await _context.SaveChangesAsync(); | ||
if (result <= 0) AdicionarErroProcessamento("Error saving data"); | ||
} | ||
private bool ValidateShoppingCart(ShoppingCartClient carrinho) | ||
{ | ||
if (carrinho.IsValid()) return true; | ||
|
||
carrinho.ValidationResult.Errors.ToList().ForEach(e => AdicionarErroProcessamento(e.ErrorMessage)); | ||
return false; | ||
} | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
src/services/DevStore.ShoppingCart.API/Data/ShoppingCartContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using DevStore.ShoppingCart.API.Model; | ||
using FluentValidation.Results; | ||
using Microsoft.EntityFrameworkCore; | ||
using System.Linq; | ||
|
||
namespace DevStore.ShoppingCart.API.Data | ||
{ | ||
public sealed class ShoppingCartContext : DbContext | ||
{ | ||
public ShoppingCartContext(DbContextOptions<ShoppingCartContext> options) | ||
: base(options) | ||
{ | ||
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; | ||
ChangeTracker.AutoDetectChangesEnabled = false; | ||
} | ||
|
||
public DbSet<CartItem> CartItems { get; set; } | ||
public DbSet<ShoppingCartClient> ShoppingCartClient { get; set; } | ||
|
||
protected override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | ||
foreach (var property in modelBuilder.Model.GetEntityTypes().SelectMany( | ||
e => e.GetProperties().Where(p => p.ClrType == typeof(string)))) | ||
property.SetColumnType("varchar(100)"); | ||
|
||
modelBuilder.Ignore<ValidationResult>(); | ||
|
||
modelBuilder.Entity<ShoppingCartClient>() | ||
.HasIndex(c => c.ClientId) | ||
.HasName("IDX_Cliente"); | ||
|
||
modelBuilder.Entity<ShoppingCartClient>() | ||
.Ignore(c => c.Voucher) | ||
.OwnsOne(c => c.Voucher, v => | ||
{ | ||
v.Property(vc => vc.Code) | ||
.HasColumnType("varchar(50)"); | ||
v.Property(vc => vc.DiscountType); | ||
v.Property(vc => vc.Percentage); | ||
v.Property(vc => vc.Discount); | ||
}); | ||
|
||
modelBuilder.Entity<ShoppingCartClient>() | ||
.HasMany(c => c.Items) | ||
.WithOne(i => i.ShoppingCartClient) | ||
.HasForeignKey(c => c.ShoppingCartId); | ||
|
||
foreach (var relationship in modelBuilder.Model.GetEntityTypes() | ||
.SelectMany(e => e.GetForeignKeys())) relationship.DeleteBehavior = DeleteBehavior.Cascade; | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
129 changes: 129 additions & 0 deletions
129
src/services/DevStore.ShoppingCart.API/Migrations/20210806055427_Initial.Designer.cs
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.