Add Domain project and shifted handlers to application.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
namespace FinancialApi.Domain;
|
||||
|
||||
public record Account(int Id, decimal Balance, string AccountType)
|
||||
{
|
||||
public Account ApplyPosting(decimal amount, EntryType entryType)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
throw new ArgumentException("Credit amount must be positive.");
|
||||
}
|
||||
|
||||
var newBalance = Balance;
|
||||
if (AccountType == "Revenue")
|
||||
{
|
||||
newBalance = entryType == EntryType.Credit ? newBalance + amount : newBalance - amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
newBalance = entryType == EntryType.Debit ? newBalance - amount : newBalance + amount;
|
||||
}
|
||||
|
||||
if (newBalance < 0 && AccountType == "Liability")
|
||||
{
|
||||
throw new InvalidOperationException("Insufficient funds.");
|
||||
}
|
||||
|
||||
return this with { Balance = newBalance };
|
||||
}
|
||||
|
||||
public Account Debit(decimal amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
throw new ArgumentException("Debit amount must be positive.");
|
||||
}
|
||||
|
||||
if (Balance - amount < 0)
|
||||
{
|
||||
throw new InvalidOperationException("Insufficient funds.");
|
||||
}
|
||||
|
||||
return this with { Balance = Balance - amount };
|
||||
}
|
||||
|
||||
public Account Credit(decimal amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
throw new ArgumentException("Credit amount must be positive.");
|
||||
}
|
||||
|
||||
return this with { Balance = Balance + amount };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace FinancialApi.Domain;
|
||||
|
||||
public record BalancedJournal
|
||||
{
|
||||
public JournalEntry Entry { get; }
|
||||
|
||||
private BalancedJournal(JournalEntry entry) => Entry = entry;
|
||||
|
||||
public static BalancedJournal Create(Guid id, string description, DateTimeOffset createdAt, List<JournalLine> lines)
|
||||
{
|
||||
var debits = lines.Where(l => l.Type == EntryType.Debit).Sum(l => l.Amount);
|
||||
var credits = lines.Where(l => l.Type == EntryType.Credit).Sum(l => l.Amount);
|
||||
|
||||
if (debits != credits)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"GAAP Violation: Total Debits ({debits}) must equal Total Credits ({credits})!"
|
||||
);
|
||||
}
|
||||
|
||||
return new(new JournalEntry(id, description, createdAt, lines));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace FinancialApi.Domain;
|
||||
|
||||
public enum EntryType
|
||||
{
|
||||
Debit,
|
||||
Credit
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace FinancialApi.Domain;
|
||||
|
||||
public record JournalEntry
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
public string Description { get; init; }
|
||||
public DateTimeOffset CreatedAt { get; init; }
|
||||
public List<JournalLine> Lines { get; init; } = [];
|
||||
|
||||
internal JournalEntry(Guid id, string description, DateTimeOffset createdAt, List<JournalLine> lines)
|
||||
{
|
||||
Lines = lines;
|
||||
Id = id;
|
||||
Description = description;
|
||||
CreatedAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace FinancialApi.Domain;
|
||||
|
||||
public record JournalLine(int AccountId, decimal Amount, EntryType Type);
|
||||
Reference in New Issue
Block a user