zeroframework/Services/DeviceCenter/ZeroFramework.DeviceCenter.Domain/Aggregates/OrderAggregate/Order.cs
2023-12-05 17:22:48 +08:00

83 lines
3.0 KiB
C#

using ZeroFramework.DeviceCenter.Domain.Entities;
using ZeroFramework.DeviceCenter.Domain.Events.Ordering;
using ZeroFramework.DeviceCenter.Domain.Exceptions;
namespace ZeroFramework.DeviceCenter.Domain.Aggregates.OrderAggregate
{
public class Order : BaseAggregateRoot<Guid>
{
private readonly List<OrderItem> _orderItems = [];
public OrderStatus OrderStatus { get; private set; } = OrderStatus.Submitted;
public ShippingAddress Address { get; private set; } = new ShippingAddress();
public DateTimeOffset CreationTime { get; private set; } = DateTimeOffset.Now;
public Guid BuyerId { get; private set; }
public int? PaymentMethodId { get; private set; }
public IReadOnlyCollection<OrderItem> OrderItems => _orderItems;
protected Order() { }
public Order(Guid buyerId, ShippingAddress address, int cardTypeId, string cardNumber, DateTimeOffset cardExpiration)
{
BuyerId = buyerId;
Address = address;
OrderStatus = OrderStatus.Submitted;
// Add the OrderStarterDomainEvent to the domain events collection
// to be raised/dispatched when comitting changes into the Database [ After DbContext.SaveChanges() ]
var domainEvent = new OrderStartedDomainEvent(this, buyerId, cardTypeId, cardNumber, cardExpiration);
AddDomainEvent(domainEvent);
}
public decimal Total => _orderItems.Sum(o => o.Units * o.UnitPrice);
public void SetPaymentMethodId(int id) => PaymentMethodId = id;
public void SetBuyerId(Guid id) => BuyerId = id;
public void AddOrderItem(int productId, decimal unitPrice, int units = 1)
{
var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId).SingleOrDefault();
if (existingOrderForProduct != null)
{
//if previous line exist modify it with higher discount and units..
if (unitPrice * units > sbyte.MaxValue)
{
units += 1;
}
existingOrderForProduct.AddUnits(units);
}
else
{
//add validated new order item
var orderItem = new OrderItem(productId, unitPrice, units);
_orderItems.Add(orderItem);
}
}
public void SetPaidStatus()
{
if (OrderStatus == OrderStatus.StockConfirmed)
{
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
OrderStatus = OrderStatus.Paid;
}
}
public void SetCancelledStatus()
{
if (OrderStatus == OrderStatus.Paid || OrderStatus == OrderStatus.Shipped)
{
throw new OrderingDomainException($"Is not possible to change the order status.");
}
OrderStatus = OrderStatus.Cancelled;
AddDomainEvent(new OrderCancelledDomainEvent(this));
}
}
}