public async ValueTask Handle(AccountingPeriodClosing @event, CancellationToken cancellationToken) { var generalLedgerEntryIdentifiers = Array.ConvertAll(@event.GeneralLedgerEntryIds, id => new GeneralLedgerEntryIdentifier(id)); var chartOfAccounts = await _chartOfAccounts.Get(cancellationToken); var accountingPeriodClosingProcess = new AccountingPeriodClosingProcess( chartOfAccounts, AccountingPeriod.Parse(@event.Period), Time.Parse.LocalDateTime(@event.ClosingOn), generalLedgerEntryIdentifiers, new GeneralLedgerEntryIdentifier(@event.ClosingGeneralLedgerEntryId), (EquityAccount)chartOfAccounts[new AccountNumber(@event.RetainedEarningsAccountNumber)], _accountIsDeactivated); foreach (var id in @event.GeneralLedgerEntryIds) { var generalLedgerEntry = await _generalLedgerEntries.Get(new GeneralLedgerEntryIdentifier(id), cancellationToken); accountingPeriodClosingProcess.TransferEntry(generalLedgerEntry); } var generalLedger = await _generalLedger.Get(cancellationToken); generalLedger.CompleteClosingPeriod(generalLedgerEntryIdentifiers, accountingPeriodClosingProcess.Complete(), accountingPeriodClosingProcess.TrialBalance); }
public async ValueTask Handle(AccountingPeriodClosing @event, CancellationToken cancellationToken) { var retainedEarningsAccountNumber = new AccountNumber(@event.RetainedEarningsAccountNumber); AccountType.OfAccountNumber(retainedEarningsAccountNumber).MustBe(AccountType.Equity); var generalLedger = await _generalLedger.Get(cancellationToken); foreach (var id in @event.GeneralLedgerEntryIds) { var generalLedgerEntry = await _generalLedgerEntries.Get(new GeneralLedgerEntryIdentifier(id), cancellationToken); generalLedger.TransferEntry(generalLedgerEntry); } var chartOfAccounts = await _chartOfAccounts.Get(cancellationToken); generalLedger.CompleteClosingPeriod(chartOfAccounts, retainedEarningsAccountNumber); }
public Task unposted_entry_throws(LocalDate openedOn, GeneralLedgerEntryNumber generalLedgerEntryNumber, EquityAccount retainedEarnings, GeneralLedgerEntryIdentifier generalLedgerEntryIdentifier, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier) { var period = AccountingPeriod.Open(openedOn); var closingOn = openedOn.AtMidnight(); var accountingPeriodClosing = new AccountingPeriodClosing { Period = period.ToString(), ClosingOn = Time.Format.LocalDateTime(closingOn), RetainedEarningsAccountNumber = retainedEarnings.AccountNumber.ToInt32(), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), GeneralLedgerEntryIds = new[] { generalLedgerEntryIdentifier.ToGuid() } }; return(new Scenario() .Given(GeneralLedger.Identifier, new GeneralLedgerOpened { OpenedOn = Time.Format.LocalDate(openedOn) }, accountingPeriodClosing) .Given(ChartOfAccounts.Identifier, new AccountDefined { AccountName = retainedEarnings.AccountName.ToString(), AccountNumber = retainedEarnings.AccountNumber.ToInt32() }) .Given(GeneralLedgerEntry.FormatStreamIdentifier(generalLedgerEntryIdentifier), new GeneralLedgerEntryCreated { GeneralLedgerEntryId = generalLedgerEntryIdentifier.ToGuid(), Number = generalLedgerEntryNumber.ToString(), Period = period.ToString(), CreatedOn = Time.Format.LocalDateTime(openedOn.AtMidnight()) }) .When(accountingPeriodClosing) .Throws(new GeneralLedgerEntryWasNotPostedException(generalLedgerEntryIdentifier)) .Assert(_handler, _facts)); }
public Task period_closing_started(LocalDate openedOn, EquityAccount retainedEarnings, AssetAccount cashAccount, IncomeAccount incomeAccount, ExpenseAccount expenseAccount, GeneralLedgerEntryIdentifier[] generalLedgerEntryIdentifiers, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier, Money income, Money expense) { var period = AccountingPeriod.Open(openedOn); var closingOn = openedOn.AtMidnight(); var accountingPeriodClosing = new AccountingPeriodClosing { Period = period.ToString(), ClosingOn = Time.Format.LocalDateTime(closingOn), RetainedEarningsAccountNumber = retainedEarnings.AccountNumber.ToInt32(), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers, identifier => identifier.ToGuid()) }; var net = income - expense; var generalLedgerEntryFacts = generalLedgerEntryIdentifiers.SelectMany( (identifier, index) => Array.ConvertAll(new object[] { new GeneralLedgerEntryCreated { Number = $"sale-{index}", Period = period.ToString(), CreatedOn = Time.Format.LocalDate(openedOn), GeneralLedgerEntryId = identifier.ToGuid() }, new CreditApplied { Amount = income.ToDecimal(), AccountNumber = incomeAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() }, new DebitApplied { Amount = expense.ToDecimal(), AccountNumber = expenseAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() }, net > Money.Zero ? new DebitApplied { Amount = net.ToDecimal(), AccountNumber = cashAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() } : new CreditApplied { Amount = -net.ToDecimal(), AccountNumber = cashAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() }, new GeneralLedgerEntryPosted { Period = period.ToString(), GeneralLedgerEntryId = identifier.ToGuid() }, }, e => new Fact(GeneralLedgerEntry.FormatStreamIdentifier(identifier), e))) .ToArray(); return(new Scenario() .Given(ChartOfAccounts.Identifier, new AccountDefined { AccountName = cashAccount.AccountName.ToString(), AccountNumber = cashAccount.AccountNumber.ToInt32() }, new AccountDefined { AccountName = incomeAccount.AccountName.ToString(), AccountNumber = incomeAccount.AccountNumber.ToInt32() }, new AccountDefined { AccountName = expenseAccount.AccountName.ToString(), AccountNumber = expenseAccount.AccountNumber.ToInt32() }, new AccountDefined { AccountName = retainedEarnings.AccountName.ToString(), AccountNumber = retainedEarnings.AccountNumber.ToInt32() }) .Given(GeneralLedger.Identifier, new GeneralLedgerOpened { OpenedOn = Time.Format.LocalDate(openedOn) }, accountingPeriodClosing) .Given(generalLedgerEntryFacts) .When(accountingPeriodClosing) .Then(GeneralLedger.Identifier, new GeneralLedgerEntryCreated { CreatedOn = Time.Format.LocalDateTime(closingOn), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), Number = $"jec-{period}", Period = period.ToString() }, new DebitApplied { Amount = income.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = incomeAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new CreditApplied { Amount = expense.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = expenseAccount.AccountNumber.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, net < Money.Zero ? new DebitApplied { Amount = -net.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = retainedEarnings.AccountNumber.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() } : new CreditApplied { Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = retainedEarnings.AccountNumber.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new GeneralLedgerEntryPosted { Period = period.ToString(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new AccountingPeriodClosed { Period = period.ToString(), GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers, identifier => identifier.ToGuid()), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), Balance = new[] { new BalanceLineItem { AccountNumber = cashAccount.AccountNumber.ToInt32(), Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length }, new BalanceLineItem { AccountNumber = retainedEarnings.AccountNumber.ToInt32(), Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length }, new BalanceLineItem { AccountNumber = incomeAccount.AccountNumber.ToInt32(), Amount = Money.Zero.ToDecimal() }, new BalanceLineItem { AccountNumber = expenseAccount.AccountNumber.ToInt32(), Amount = Money.Zero.ToDecimal() } } }) .Assert(_handler, _facts)); }
public Task period_closing_started(DateTimeOffset openedOn, GeneralLedgerEntryIdentifier[] generalLedgerEntryIdentifiers, GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier, Money amount) { var period = Period.Open(openedOn); var cashAccountNumber = new AccountNumber(new Random().Next(1000, 1999)); var incomeAccountNumber = new AccountNumber(new Random().Next(4000, 4999)); var closingOn = new DateTimeOffset(new DateTime(period.Year, period.Month, 2)); var accountingPeriodClosing = new AccountingPeriodClosing { Period = period.ToString(), ClosingOn = closingOn, RetainedEarningsAccountNumber = _retainedEarnings.ToInt32(), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers, identifier => identifier.ToGuid()) }; var generalLedgerEntryFacts = generalLedgerEntryIdentifiers.SelectMany( (identifier, index) => Array.ConvertAll(new object[] { new GeneralLedgerEntryCreated { Number = $"sale-{index}", Period = period.ToString(), CreatedOn = openedOn, GeneralLedgerEntryId = identifier.ToGuid() }, new DebitApplied { Amount = amount.ToDecimal(), AccountNumber = cashAccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() }, new CreditApplied { Amount = amount.ToDecimal(), AccountNumber = incomeAccountNumber.ToInt32(), GeneralLedgerEntryId = identifier.ToGuid() }, new GeneralLedgerEntryPosted { Period = period.ToString(), GeneralLedgerEntryId = identifier.ToGuid() }, }, e => new Fact($"generalLedgerEntry-{identifier}", e))) .ToArray(); return(new Scenario() .Given("chartOfAccounts", new AccountDefined { AccountName = "Cash on Hand", AccountNumber = cashAccountNumber.ToInt32() }, new AccountDefined { AccountName = "Income", AccountNumber = incomeAccountNumber.ToInt32() }, new AccountDefined { AccountName = "Retained Earnings", AccountNumber = _retainedEarnings.ToInt32() }) .Given("generalLedger", new GeneralLedgerOpened { OpenedOn = openedOn }, accountingPeriodClosing) .Given(generalLedgerEntryFacts) .When(accountingPeriodClosing) .Then("generalLedger", new GeneralLedgerEntryCreated { CreatedOn = closingOn, GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), Number = $"jec-{period}", Period = period.ToString() }, new DebitApplied { Amount = amount.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = incomeAccountNumber.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new CreditApplied { Amount = amount.ToDecimal() * generalLedgerEntryIdentifiers.Length, AccountNumber = _retainedEarnings.ToInt32(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new GeneralLedgerEntryPosted { Period = period.ToString(), GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid() }, new AccountingPeriodClosed { Period = period.ToString(), GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers, identifier => identifier.ToGuid()), ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(), Balance = new Dictionary <int, decimal> { [cashAccountNumber.ToInt32()] = amount.ToDecimal() * generalLedgerEntryIdentifiers.Length, [incomeAccountNumber.ToInt32()] = Money.Zero.ToDecimal(), [_retainedEarnings.ToInt32()] = -(amount.ToDecimal() * generalLedgerEntryIdentifiers.Length) } }) .Assert(_handler, _facts)); }