예제 #1
0
        public void Handle(InvoiceBalanceUpdated notification)
        {
            var invoice = _Mediator.Send(new GetInvoice {
                Id = notification.InvoiceId
            });

            notification.Apply(invoice);

            const string query = @"
                UPDATE Accounting.Invoice
                SET Balance = @Balance
                WHERE Id = @Id";

            _UnitOfWork.Execute(query, invoice);

            // This assumes a liability account, I'm considering invoices to
            // be liabilities for the company that receives an invoice
            var ledgerEntry = new GeneralLedgerEntry
            {
                CreditAmount = notification.Amount > 0 ? notification.Amount : 0,
                DebitAmount  = notification.Amount < 0 ? notification.Amount : 0,
                EntryDate    = notification.EventDate,
                Id           = _GuidGenerator.Generate(),
                LineItemId   = notification.LineItemId,
                CreatedOn    = notification.EventDate,
                CreatedById  = notification.UpdatedById
            };

            const string query2 = @"
                INSERT INTO Accounting.GeneralLedger (Id, CreditAmount, DebitAmount, LineItemId, CreatedOn, CreatedById)
                VALUES (@Id, @CreditAmount, @DebitAmount, @LineItemId, @CreatedOn, @CreatedById)";

            _UnitOfWork.Execute(query2, ledgerEntry);
        }
        public async ValueTask <GeneralLedgerEntry> Get(GeneralLedgerEntryIdentifier identifier,
                                                        CancellationToken cancellationToken = default)
        {
            var optional = await _inner.GetOptional(GeneralLedgerEntry.FormatStreamIdentifier(identifier),
                                                    cancellationToken);

            return(optional.HasValue ? optional.Value : throw new GeneralLedgerEntryNotFoundException(identifier));
        }
예제 #3
0
        public void Apply(GeneralLedgerEntry generalLedgerEntry, ChartOfAccounts chartOfAccounts)
        {
            var(accountsPayable, inventoryInTransit) =
                PurchaseOrderItems.Aggregate((new Credit(new AccountNumber(2150)), new Debit(new AccountNumber(1400))),
                                             Accumulate);

            generalLedgerEntry.ApplyCredit(accountsPayable, chartOfAccounts);
            generalLedgerEntry.ApplyDebit(inventoryInTransit, chartOfAccounts);
            generalLedgerEntry.ApplyTransaction(this);
        }
예제 #4
0
            public void Apply(GeneralLedgerEntry generalLedgerEntry, AccountIsDeactivated accountIsDeactivated)
            {
                foreach (var credit in _credits)
                {
                    generalLedgerEntry.ApplyCredit(credit, accountIsDeactivated);
                }

                foreach (var debit in _debits)
                {
                    generalLedgerEntry.ApplyDebit(debit, accountIsDeactivated);
                }
            }
        public async ValueTask <GeneralLedgerEntry> Get(GeneralLedgerEntryIdentifier identifier,
                                                        CancellationToken cancellationToken = default)
        {
            var optionalGeneralLedgerEntry = await _inner.GetById(GeneralLedgerEntry.FormatStreamIdentifier(identifier),
                                                                  cancellationToken);

            if (!optionalGeneralLedgerEntry.HasValue)
            {
                throw new GeneralLedgerEntryNotFoundException(identifier);
            }

            return(optionalGeneralLedgerEntry.Value);
        }
        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 void Add(GeneralLedgerEntry generalLedgerEntry) => _inner.Add(generalLedgerEntry);
예제 #9
0
 public void Apply(GeneralLedgerEntry generalLedgerEntry, ChartOfAccounts _)
 {
     generalLedgerEntry.ApplyTransaction(this);
 }
예제 #10
0
 public void Apply(GeneralLedgerEntry generalLedgerEntry, AccountIsDeactivated accountIsDeactivated)
 {
     generalLedgerEntry.ApplyTransaction(this);
 }
예제 #11
0
 public void Apply(GeneralLedgerEntry generalLedgerEntry, ChartOfAccounts chartOfAccounts)
 {
     generalLedgerEntry.ApplyCredit(new Credit(Account, new Money(1m)), chartOfAccounts);
 }
예제 #12
0
 public void Apply(GeneralLedgerEntry entry, ChartOfAccounts chartOfAccounts)
 {
     entry.ApplyDebit(new Debit(new AccountNumber(1000), new Money(5m)), chartOfAccounts);
     entry.ApplyCredit(new Credit(new AccountNumber(3000), new Money(5m)), chartOfAccounts);
     entry.ApplyTransaction(this);
 }
예제 #13
0
 public void Apply(GeneralLedgerEntry generalLedgerEntry, AccountIsDeactivated accountIsDeactivated)
 {
     generalLedgerEntry.ApplyCredit(new Credit(Account, new Money(1m)), accountIsDeactivated);
 }