private GeneralLedger() { _untransferredEntryIdentifiers = new List <GeneralLedgerEntryIdentifier>(); _entryIdentifiers = new List <GeneralLedgerEntryIdentifier>(); _trialBalance = TrialBalance.None; _closingOn = default; _profitAndLoss = null !; Register <GeneralLedgerOpened>(e => _period = Period.Open(e.OpenedOn)); Register <AccountingPeriodClosing>(e => { _periodClosing = true; _period = Period.Parse(e.Period); _profitAndLoss = new ProfitAndLoss(_period); _entryIdentifiers.AddRange(Array.ConvertAll(e.GeneralLedgerEntryIds, identifier => new GeneralLedgerEntryIdentifier(identifier))); _untransferredEntryIdentifiers.AddRange(_entryIdentifiers); _closingOn = e.ClosingOn; _closingGeneralLedgerEntryIdentifier = new GeneralLedgerEntryIdentifier(e.ClosingGeneralLedgerEntryId); }); Register <AccountingPeriodClosed>(e => { _untransferredEntryIdentifiers.Clear(); _entryIdentifiers.Clear(); foreach (var(accountNumber, amount) in e.Balance) { _trialBalance.Apply(new AccountNumber(accountNumber), new Money(amount)); } _period = Period.Parse(e.Period).Next(); _periodClosing = false; }); }
public void EqualityOperator(Guid value) { var sut = new GeneralLedgerEntryIdentifier(value); var copy = new GeneralLedgerEntryIdentifier(value); Assert.True(sut == copy); }
public void Equality(Guid value) { var sut = new GeneralLedgerEntryIdentifier(value); var copy = new GeneralLedgerEntryIdentifier(value); Assert.Equal(sut, copy); }
public GeneralLedgerEntry GetClosingEntry(AccountIsDeactivated accountIsDeactivated, EquityAccount retainedEarningsAccount, LocalDateTime closedOn, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier) { var entry = new GeneralLedgerEntry(closingGeneralLedgerEntryIdentifier, new GeneralLedgerEntryNumber("jec", int.Parse(_accountingPeriod.ToString())), _accountingPeriod, closedOn); foreach (var account in _current.Where(x => x.Balance != Money.Zero) .OrderBy(x => x.AccountNumber.ToInt32())) { switch (account) { case IncomeAccount: { if (account.Balance > Money.Zero) { entry.ApplyDebit(new(account.AccountNumber, account.Balance), IgnoreInactiveAccount); } else { entry.ApplyCredit(new(account.AccountNumber, -account.Balance), IgnoreInactiveAccount); } continue; } case ExpenseAccount: if (account.Balance > Money.Zero) { entry.ApplyCredit(new(account.AccountNumber, account.Balance), IgnoreInactiveAccount); } else { entry.ApplyDebit(new(account.AccountNumber, -account.Balance), IgnoreInactiveAccount); } continue; default: continue; } } var retainedEarnings = entry.Debits.Select(x => x.Amount).Sum() - entry.Credits.Select(x => x.Amount).Sum(); if (retainedEarnings < Money.Zero) { entry.ApplyDebit(new(retainedEarningsAccount.AccountNumber, -retainedEarnings), accountIsDeactivated); } else if (retainedEarnings > Money.Zero) { entry.ApplyCredit(new(retainedEarningsAccount.AccountNumber, retainedEarnings), accountIsDeactivated); } entry.Post(); return(entry); }
public GeneralLedgerEntry GetClosingEntry(ChartOfAccounts chartOfAccounts, AccountNumber retainedEarningsAccountNumber, DateTimeOffset closedOn, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier) { var entry = new GeneralLedgerEntry(closingGeneralLedgerEntryIdentifier, new GeneralLedgerEntryNumber("jec", int.Parse(_period.ToString())), _period, closedOn); foreach (var(accountNumber, amount) in _income) { if (amount == Money.Zero) { continue; } if (amount > Money.Zero) { entry.ApplyCredit(new Credit(accountNumber, amount), chartOfAccounts); } else { entry.ApplyDebit(new Debit(accountNumber, -amount), chartOfAccounts); } } foreach (var(accountNumber, amount) in _expenses) { if (amount == Money.Zero) { continue; } if (amount < Money.Zero) { entry.ApplyCredit(new Credit(accountNumber, amount), chartOfAccounts); } else { entry.ApplyDebit(new Debit(accountNumber, -amount), chartOfAccounts); } } var retainedEarnings = entry.Debits.Select(x => x.Amount).Sum() - entry.Credits.Select(x => x.Amount).Sum(); if (retainedEarnings < Money.Zero) { entry.ApplyDebit(new Debit(retainedEarningsAccountNumber, -retainedEarnings), chartOfAccounts); } else if (retainedEarnings > Money.Zero) { entry.ApplyCredit(new Credit(retainedEarningsAccountNumber, retainedEarnings), chartOfAccounts); } entry.Post(); return(entry); }
internal GeneralLedgerEntry(GeneralLedgerEntryIdentifier identifier, GeneralLedgerEntryNumber number, Period period, DateTimeOffset createdOn) : this() { Apply(new GeneralLedgerEntryCreated { GeneralLedgerEntryId = identifier.ToGuid(), Number = number.ToString(), CreatedOn = createdOn, Period = period.ToString() }); }
internal GeneralLedgerEntry(GeneralLedgerEntryIdentifier identifier, GeneralLedgerEntryNumber number, AccountingPeriod accountingPeriod, LocalDateTime createdOn) : this() { if (!accountingPeriod.Contains(createdOn.Date)) { throw new GeneralLedgerEntryNotInPeriodException(number, createdOn, accountingPeriod); } Apply(new GeneralLedgerEntryCreated { GeneralLedgerEntryId = identifier.ToGuid(), Number = number.ToString(), CreatedOn = Time.Format.LocalDateTime(createdOn), Period = accountingPeriod.ToString() }); }
private GeneralLedgerEntry() { _credits = new List <Credit>(); _debits = new List <Debit>(); Register <GeneralLedgerEntryCreated>(e => { _identifier = new GeneralLedgerEntryIdentifier(e.GeneralLedgerEntryId); _period = Period.Parse(e.Period); }); Register <CreditApplied>(e => _credits.Add(new Credit(new AccountNumber(e.AccountNumber), new Money(e.Amount)))); Register <DebitApplied>(e => _debits.Add(new Debit(new AccountNumber(e.AccountNumber), new Money(e.Amount)))); Register <GeneralLedgerEntryPosted>(_ => _posted = true); }
internal GeneralLedgerEntry(GeneralLedgerEntryIdentifier identifier, GeneralLedgerEntryNumber number, Period period, DateTimeOffset createdOn) : this() { if (!period.Contains(createdOn)) { throw new GeneralLedgerEntryNotInPeriodException(number, createdOn, period); } Apply(new GeneralLedgerEntryCreated { GeneralLedgerEntryId = identifier.ToGuid(), Number = number.ToString(), CreatedOn = createdOn, Period = period.ToString() }); }
public AccountingPeriodClosingProcess( ChartOfAccounts chartOfAccounts, AccountingPeriod accountingPeriod, LocalDateTime closingOn, GeneralLedgerEntryIdentifier[] generalLedgerEntryIdentifiers, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier, EquityAccount retainedEarningsAccount, AccountIsDeactivated accountIsDeactivated) { _accountingPeriod = accountingPeriod; _closingOn = closingOn; _closingGeneralLedgerEntryIdentifier = closingGeneralLedgerEntryIdentifier; _retainedEarningsAccount = retainedEarningsAccount; _accountIsDeactivated = accountIsDeactivated; _generalLedgerEntryIdentifiers = new HashSet <GeneralLedgerEntryIdentifier>(generalLedgerEntryIdentifiers); TrialBalance = new TrialBalance(chartOfAccounts); ProfitAndLoss = new ProfitAndLoss(accountingPeriod, chartOfAccounts); }
public void BeginClosingPeriod(AccountNumber retainedEarningsAccountNumber, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier, GeneralLedgerEntryIdentifier[] generalLedgerEntryIdentifiers, DateTimeOffset closingOn) { if (_periodClosing) { throw new PeriodClosingInProcessException(_period); } _period.MustNotBeAfter(closingOn); Apply(new AccountingPeriodClosing { Period = _period.ToString(), GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers, id => id.ToGuid()), ClosingOn = closingOn, RetainedEarningsAccountNumber = retainedEarningsAccountNumber.ToInt32(), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }); }
public void InequalityOperator(GeneralLedgerEntryIdentifier left, GeneralLedgerEntryIdentifier right) { Assert.True(left != right); }
public static string FormatStreamIdentifier(GeneralLedgerEntryIdentifier identifier) => $"generalLedgerEntry-{identifier}";
public GeneralLedgerEntryNotFoundException(GeneralLedgerEntryIdentifier generalLedgerEntryIdentifier) : base($"General Ledger Entry {generalLedgerEntryIdentifier} was not found.") { }
public GeneralLedgerEntryWasNotPostedException(GeneralLedgerEntryIdentifier generalLedgerEntryIdentifier) : base("The general ledger entry was not posted.") { GeneralLedgerEntryIdentifier = generalLedgerEntryIdentifier; }
public void ToStringReturnsExpectedResult(Guid value) { var sut = new GeneralLedgerEntryIdentifier(value); Assert.Equal(value.ToString("n"), sut.ToString()); }
public GeneralLedgerEntryNotInBalanceException(GeneralLedgerEntryIdentifier generalLedgerEntryIdentifier) : base("The general ledger entry was not in balance.") { GeneralLedgerEntryIdentifier = generalLedgerEntryIdentifier; }
public GeneralLedgerEntry Create(GeneralLedgerEntryIdentifier identifier, GeneralLedgerEntryNumber number, DateTimeOffset createdOn) => _periodClosing ? Create(identifier, number, createdOn, _period.Next()) : Create(identifier, number, createdOn, _period.Contains(createdOn) ? _period : _period.Next());
private static GeneralLedgerEntry Create(GeneralLedgerEntryIdentifier identifier, GeneralLedgerEntryNumber number, DateTimeOffset createdOn, Period period) => new GeneralLedgerEntry(identifier, number, period, createdOn);