Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Created December 6, 2023 20:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcomartin/b59c614e1ab8d2fbd8588c4e8583abeb to your computer and use it in GitHub Desktop.
Save dcomartin/b59c614e1ab8d2fbd8588c4e8583abeb to your computer and use it in GitHub Desktop.
public class Product : MyEntity
{
[Required]
[StringLength(ProductInvariants.NameMaxLength)]
public string Name { get; private set; }
[Required]
[StringLength(ProductInvariants.DescriptionMaxLength)]
public string Description { get; private set; }
[Required]
public Money Price { get; private set; }
[Required]
public Mass Mass { get; private set; }
public int NumberInStock { get; private set; }
// EF
private Product()
{
Name = null!;
Description = null!;
Mass = null!;
Price = null!;
}
public Product(string name, string description, Money price, Mass mass)
{
UpdateName(name);
UpdateDescription(description);
CheckMass(mass?.Value ?? throw new ArgumentNullException(nameof(mass)));
CheckPrice(price?.Amount ?? throw new ArgumentNullException(nameof(price)));
Mass = mass;
Price = price;
NumberInStock = 0;
}
public void UpdateMass(float value)
{
CheckMass(value);
Mass = new Mass(value, Mass?.Unit ?? ProductInvariants.DefaultMassUnit);
}
public void UpdatePrice(decimal amount)
{
CheckPrice(amount);
Price = new Money(amount, Price?.Currency ?? ProductInvariants.DefaultPriceCurrency);
}
[MemberNotNull(nameof(Name))]
public void UpdateName(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Name cannot be empty.");
if (value.Length > ProductInvariants.NameMaxLength)
throw new ArgumentException($"Length of value ({value.Length}) exceeds maximum name length ({ProductInvariants.NameMaxLength}).");
Name = value;
}
[MemberNotNull(nameof(Description))]
public void UpdateDescription(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Description cannot be empty.");
if (value.Length > ProductInvariants.DescriptionMaxLength)
throw new ArgumentException($"Length of value ({value.Length}) exceeds maximum description length ({ProductInvariants.NameMaxLength}).");
Description = value;
}
/// <summary>
/// Adjust product stock based on a transaction occurred.
/// </summary>
internal void RecordTransaction(TransactionLine transactionLine)
{
if (transactionLine.Quantity < 1)
throw new ArgumentException("Product quantity in transaction must be 1 or greater.");
switch (transactionLine.Transaction.TransactionType)
{
case TransactionType.Sales:
if (transactionLine.Quantity > NumberInStock)
throw new InsufficientStockException(this, transactionLine.Quantity, NumberInStock);
NumberInStock -= transactionLine.Quantity;
break;
case TransactionType.Procurement:
NumberInStock += transactionLine.Quantity;
break;
default:
throw new InvalidEnumArgumentException($"Unexpected {nameof(TransactionType)}: '{transactionLine.Transaction.TransactionType}'.");
}
}
private static void CheckMass(float value)
{
if (value < ProductInvariants.MassMinimum)
throw new ArgumentException($"Value '{value}' is smaller than the minimum required mass of {ProductInvariants.MassMinimum}.");
}
private static void CheckPrice(decimal amount)
{
if (amount < ProductInvariants.PriceMinimum)
throw new ArgumentException($"Amount '{amount}' is smaller than the minimum required price of {ProductInvariants.MassMinimum}.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment