94 lines
2.5 KiB
C#
94 lines
2.5 KiB
C#
namespace BudgetApp.Domain.Models;
|
|
|
|
/// <summary>
|
|
/// Value object representing a monetary amount.
|
|
/// Immutable and ensures non-negative amounts.
|
|
/// </summary>
|
|
public class Money : IEquatable<Money>
|
|
{
|
|
public decimal Amount { get; }
|
|
public string Currency { get; }
|
|
|
|
public Money(decimal amount, string currency = "USD")
|
|
{
|
|
if (amount < 0)
|
|
throw new ArgumentException("Amount cannot be negative.", nameof(amount));
|
|
|
|
if (string.IsNullOrWhiteSpace(currency))
|
|
throw new ArgumentException("Currency cannot be null or empty.", nameof(currency));
|
|
|
|
Amount = amount;
|
|
Currency = currency;
|
|
}
|
|
|
|
public Money Add(Money other)
|
|
{
|
|
if (other == null)
|
|
throw new ArgumentNullException(nameof(other));
|
|
|
|
if (Currency != other.Currency)
|
|
throw new InvalidOperationException($"Cannot add money with different currencies: {Currency} and {other.Currency}");
|
|
|
|
return new Money(Amount + other.Amount, Currency);
|
|
}
|
|
|
|
public Money Subtract(Money other)
|
|
{
|
|
if (other == null)
|
|
throw new ArgumentNullException(nameof(other));
|
|
|
|
if (Currency != other.Currency)
|
|
throw new InvalidOperationException($"Cannot subtract money with different currencies: {Currency} and {other.Currency}");
|
|
|
|
var result = Amount - other.Amount;
|
|
if (result < 0)
|
|
throw new InvalidOperationException("Result cannot be negative.");
|
|
|
|
return new Money(result, Currency);
|
|
}
|
|
|
|
public bool Equals(Money? other)
|
|
{
|
|
if (other == null) return false;
|
|
return Amount == other.Amount && Currency == other.Currency;
|
|
}
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
return Equals(obj as Money);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return HashCode.Combine(Amount, Currency);
|
|
}
|
|
|
|
public static bool operator ==(Money? left, Money? right)
|
|
{
|
|
if (ReferenceEquals(left, right)) return true;
|
|
if (left is null || right is null) return false;
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(Money? left, Money? right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
|
|
public static Money operator +(Money left, Money right)
|
|
{
|
|
return left.Add(right);
|
|
}
|
|
|
|
public static Money operator -(Money left, Money right)
|
|
{
|
|
return left.Subtract(right);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Amount:F2} {Currency}";
|
|
}
|
|
}
|
|
|