@ -1,15 +0,0 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands | |||
{ | |||
using MediatR; | |||
public class CancelOrderRequest | |||
: IAsyncRequest<bool> | |||
{ | |||
public int OrderId { get; private set; } | |||
public CancelOrderRequest(int orderId) | |||
{ | |||
OrderId = orderId; | |||
} | |||
} | |||
} |
@ -1,15 +0,0 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands | |||
{ | |||
using MediatR; | |||
using System; | |||
using System.Threading.Tasks; | |||
public class CancelOrderRequestHandler | |||
: IAsyncRequestHandler<CancelOrderRequest, bool> | |||
{ | |||
public Task<bool> Handle(CancelOrderRequest message) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@ -1,15 +1,110 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands | |||
{ | |||
using Domain.Repositories; | |||
using MediatR; | |||
using System.Linq; | |||
using System; | |||
using System.Threading.Tasks; | |||
using Domain; | |||
public class NewOrderRequestHandler | |||
: IAsyncRequestHandler<NewOrderRequest, bool> | |||
{ | |||
public Task<bool> Handle(NewOrderRequest message) | |||
private readonly IBuyerRepository _buyerRepository; | |||
private readonly IOrderRepository _orderRepository; | |||
public NewOrderRequestHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository) | |||
{ | |||
if (buyerRepository == null) | |||
{ | |||
throw new ArgumentNullException(nameof(buyerRepository)); | |||
} | |||
if (orderRepository == null) | |||
{ | |||
throw new ArgumentNullException(nameof(orderRepository)); | |||
} | |||
_buyerRepository = buyerRepository; | |||
_orderRepository = orderRepository; | |||
} | |||
public async Task<bool> Handle(NewOrderRequest message) | |||
{ | |||
//find buyer/payment or add a new one | |||
var buyer = await _buyerRepository.FindAsync(message.Buyer); | |||
if (buyer == null) | |||
{ | |||
buyer = CreateBuyer(message); | |||
} | |||
var payment = GetExistingPaymentOrAddANewOne(buyer, message); | |||
await _buyerRepository.UnitOfWork.SaveChangesAsync(); | |||
//create order | |||
var order = CreateOrder(buyer.Id, payment.Id, 0); | |||
order.SetAddress( new Address() | |||
{ | |||
City = message.City, | |||
State = message.State, | |||
Street = message.Street, | |||
ZipCode = message.ZipCode | |||
}); | |||
_orderRepository.Add(order); | |||
var result = await _orderRepository.UnitOfWork.SaveChangesAsync(); | |||
return result > 0; | |||
} | |||
Payment GetExistingPaymentOrAddANewOne(Buyer buyer, NewOrderRequest message) | |||
{ | |||
Payment payment = PaymentAlreadyExist(buyer, message); | |||
if (payment == null) | |||
{ | |||
payment = CreatePayment(message); | |||
buyer.Payments.Add(payment); | |||
} | |||
return payment; | |||
} | |||
Payment PaymentAlreadyExist(Domain.Buyer buyer, NewOrderRequest message) | |||
{ | |||
return buyer.Payments | |||
.SingleOrDefault(p => | |||
{ | |||
return p.CardHolderName == message.CardHolderName | |||
&& | |||
p.CardNumber == message.CardNumber | |||
&& | |||
p.Expiration == message.CardExpiration | |||
&& | |||
p.SecurityNumber == message.CardSecurityNumber; | |||
}); | |||
} | |||
Buyer CreateBuyer(NewOrderRequest message) | |||
{ | |||
return _buyerRepository.Add( | |||
new Buyer(message.Buyer)); | |||
} | |||
Order CreateOrder(int buyerId, int paymentId, int addressId) | |||
{ | |||
return new Order(buyerId, paymentId); | |||
} | |||
Payment CreatePayment(NewOrderRequest message) | |||
{ | |||
throw new NotImplementedException(); | |||
return new Payment(message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration, message.CardTypeId); | |||
} | |||
} | |||
} |
@ -0,0 +1,34 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Decorators | |||
{ | |||
using Extensions.Logging; | |||
using MediatR; | |||
using System.Threading.Tasks; | |||
public class LogDecorator<TRequest, TResponse> | |||
: IAsyncRequestHandler<TRequest, TResponse> | |||
where TRequest : IAsyncRequest<TResponse> | |||
{ | |||
private readonly IAsyncRequestHandler<TRequest, TResponse> _inner; | |||
private readonly ILogger<LogDecorator<TRequest, TResponse>> _logger; | |||
public LogDecorator( | |||
IAsyncRequestHandler<TRequest, TResponse> inner, | |||
ILogger<LogDecorator<TRequest, TResponse>> logger) | |||
{ | |||
_inner = inner; | |||
_logger = logger; | |||
} | |||
public async Task<TResponse> Handle(TRequest message) | |||
{ | |||
_logger.LogInformation($"Executing command {_inner.GetType().FullName}"); | |||
var response = await _inner.Handle(message); | |||
_logger.LogInformation($"Succedded executed command {_inner.GetType().FullName}"); | |||
return response; | |||
} | |||
} | |||
} |
@ -1,12 +1,27 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain | |||
{ | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||
using System; | |||
using System.Collections.Generic; | |||
public class Buyer | |||
:Entity,IAggregateRoot | |||
{ | |||
public string FullName { get; private set; } | |||
public HashSet<Payment> Payments { get; private set; } | |||
protected Buyer() { } | |||
public Buyer(string fullName) | |||
{ | |||
if (String.IsNullOrWhiteSpace(fullName)) | |||
{ | |||
throw new ArgumentNullException(nameof(fullName)); | |||
} | |||
this.FullName = fullName; | |||
this.Payments = new HashSet<Payment>(); | |||
} | |||
} | |||
} |
@ -0,0 +1,13 @@ | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||
using System.Threading.Tasks; | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories | |||
{ | |||
public interface IBuyerRepository | |||
:IRepository | |||
{ | |||
Buyer Add(Buyer buyer); | |||
Task<Buyer> FindAsync(string name); | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories | |||
{ | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; | |||
public interface IOrderRepository | |||
:IRepository | |||
{ | |||
Order Add(Order order); | |||
} | |||
} |
@ -1,10 +1,11 @@ | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork | |||
{ | |||
public interface IUnitOfWork : IDisposable | |||
{ | |||
Task<int> CommitAsync(); | |||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); | |||
} | |||
} |
@ -0,0 +1,51 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories | |||
{ | |||
using Domain.SeedWork; | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories; | |||
using System; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
public class BuyerRepository | |||
: IBuyerRepository | |||
{ | |||
private readonly OrderingContext _context; | |||
public BuyerRepository(OrderingContext context) | |||
{ | |||
if (context == null) | |||
{ | |||
throw new ArgumentNullException(nameof(context)); | |||
} | |||
_context = context; | |||
} | |||
public IUnitOfWork UnitOfWork | |||
{ | |||
get | |||
{ | |||
return _context; | |||
} | |||
} | |||
public Buyer Add(Buyer buyer) | |||
{ | |||
return _context.Buyers | |||
.Add(buyer) | |||
.Entity; | |||
} | |||
public async Task<Buyer> FindAsync(string name) | |||
{ | |||
var buyer = await _context.Buyers | |||
.Include(b => b.Payments) | |||
.Where(b => b.FullName == name) | |||
.SingleOrDefaultAsync(); | |||
return buyer; | |||
} | |||
} | |||
} |
@ -0,0 +1,36 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories | |||
{ | |||
using Domain; | |||
using Domain.SeedWork; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories; | |||
using System; | |||
public class OrderRepository | |||
: IOrderRepository | |||
{ | |||
private readonly OrderingContext _context; | |||
public IUnitOfWork UnitOfWork | |||
{ | |||
get | |||
{ | |||
return _context; | |||
} | |||
} | |||
public OrderRepository(OrderingContext context) | |||
{ | |||
if (context == null) | |||
{ | |||
throw new ArgumentNullException(nameof(context)); | |||
} | |||
_context = context; | |||
} | |||
public Order Add(Order order) | |||
{ | |||
return _context.Orders.Add(order) | |||
.Entity; | |||
} | |||
} | |||
} |