2026-01-03 10:29:03 -06:00

69 lines
2.1 KiB
C#

namespace BudgetApp.Domain.Models;
/// <summary>
/// Abstract base class for all budget types.
/// Represents a container for money with a balance that cannot be negative.
/// </summary>
public abstract class Budget
{
public Guid Id { get; protected set; }
public string Name { get; protected set; }
public Money Balance { get; protected set; }
protected Budget(Guid id, string name, Money initialBalance)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException("Name cannot be null or empty.", nameof(name));
if (initialBalance == null)
throw new ArgumentNullException(nameof(initialBalance));
Id = id;
Name = name;
Balance = initialBalance;
ValidateBalance();
}
/// <summary>
/// Adds money to the budget balance.
/// </summary>
public void AddMoney(Money amount)
{
if (amount == null)
throw new ArgumentNullException(nameof(amount));
if (Balance.Currency != amount.Currency)
throw new InvalidOperationException($"Cannot add money with different currency: {Balance.Currency} and {amount.Currency}");
Balance = Balance.Add(amount);
ValidateBalance();
}
/// <summary>
/// Removes money from the budget balance.
/// Ensures balance never becomes negative.
/// </summary>
public void RemoveMoney(Money amount)
{
if (amount == null)
throw new ArgumentNullException(nameof(amount));
if (Balance.Currency != amount.Currency)
throw new InvalidOperationException($"Cannot remove money with different currency: {Balance.Currency} and {amount.Currency}");
var newBalance = Balance.Subtract(amount);
Balance = newBalance;
ValidateBalance();
}
/// <summary>
/// Validates that the balance is never negative.
/// </summary>
protected void ValidateBalance()
{
if (Balance.Amount < 0)
throw new InvalidOperationException($"Budget balance cannot be negative. Current balance: {Balance}");
}
}