Last active
August 4, 2023 12:52
-
-
Save arleypadua/f96a8b0fc6ed6b358a7afd6d5de5a1ed to your computer and use it in GitHub Desktop.
Rich Domain Model
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
public class Order | |
{ | |
private Order() { } | |
public string OrderId { get; private set; } | |
public string CustomerId { get; private set; } | |
public decimal Discount { get; private set; } | |
public bool Paid { get; private set; } | |
public DateTime? PaymentTime { get; private set; } | |
public DateTime CreationTime { get; private set; } | |
private List<OrderItem> _items; // The original source is private and can only be modified by this class. | |
public IEnumerable<OrderItem> Items => _items.AsReadOnly(); // Exposes a readonly copy of order items | |
public static Order New(string orderId, string customerId, DateTime? creationTime = null) | |
{ | |
if (string.IsNullOrWhiteSpace(orderId)) throw new ArgumentNullException(nameof(orderId)); | |
if (string.IsNullOrWhiteSpace(customerId)) throw new ArgumentNullException(nameof(customerId)); | |
return new Order | |
{ | |
OrderId = orderId, | |
CustomerId = customerId, | |
CreationTime = creationTime ?? DateTime.UtcNow, | |
_items = new List<OrderItem>() | |
}; | |
} | |
public decimal TotalDiscountOnItems => Items.Sum(i => i.Discount); | |
public decimal GrossTotal => Items.Sum(i => i.Quantity * i.Price); | |
public decimal OrderTotal => GrossTotal - TotalDiscountOnItems - Discount; | |
public void AddItem(OrderItem item) | |
{ | |
if (Paid) throw new InvalidOperationException("The order is paid already."); | |
if (_items.Count > 5) throw new InvalidOperationException("Cannot add more than 5 items in an order."); | |
if (TotalDiscountOnItems + item.Discount > GrossTotal) throw new ArgumentException("Discount on item cannot exceed the order total."); | |
_items.Add(item); | |
} | |
public void AddOrderDiscount(decimal discount) | |
{ | |
if (Paid) throw new InvalidOperationException("The order is already paid."); | |
if (OrderTotal - discount < 0) throw new ArgumentException("Discount cannot exceed the order total.", nameof(discount)); | |
Discount = discount; | |
} | |
public void PayOrder() | |
{ | |
if (Paid) return; | |
Paid = true; | |
PaymentTime = DateTime.UtcNow; | |
} | |
} |
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
public class OrderItem | |
{ | |
private OrderItem() { } | |
public static OrderItem New(string productId, int quantity, decimal price, decimal discount = 0) | |
{ | |
if (string.IsNullOrWhiteSpace(productId)) throw new ArgumentNullException(nameof(productId)); | |
if (quantity <= 0) throw new ArgumentOutOfRangeException(nameof(quantity)); | |
if (price <= 0) throw new ArgumentOutOfRangeException(nameof(price)); | |
if (discount <= 0) throw new ArgumentOutOfRangeException(nameof(discount)); | |
if (discount > price * quantity) throw new ArgumentException("The discount cannot be more than the total of the order item.", nameof(discount)); | |
return new OrderItem | |
{ | |
ProductId = productId, | |
Quantity = quantity, | |
Price = price, | |
Discount = discount | |
}; | |
} | |
public string ProductId { get; private set; } | |
public int Quantity { get; private set; } | |
public decimal Price { get; private set; } | |
public decimal Discount { get; private set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment