SQL/Database Structure as Related to Accounting
Likely the best article you’ll find on accounting databases with a strong foundation in both SQL and Accounting Practice.
Integral Accounting Enterprise X – ERP for PHP & MySQL with Source Code Integral Accounting Enterprise X Integral Accounting Enterprise X is an Accounting & ERP System with full source code for the PHP & MySQL Development Environment. The system is Cross-Platform and can run on Linux, Unix, Mac, or Windows Servers. Integral Accounting Enterprise X comes with royalty free distribution. Download database create script for MySQL; Introduction. In the previous article, we discussed general financial accounting application database design concepts and defined a very basic roadmap for the whole database like: defining the business domain, basic requirements to be met, primary key usage policy, naming conventions. ScreenShots: Software Description: Microsoft SQL Server 2017 Enterprise + Enterprise Core + Standard + Web + Developer x64 + Full Crack Microsoft SQL Server is a. Mariage d%27 amour piano sheet pdf free. Accounting software for small business Windows Server 2019 Standard N69G4-B89J2-4G8F4-WWYCC-J464C Windows Server. SQL Accounting Computer software is an perfect, flexible, swift to study and likewise customized fiscal accounting Resource. It is really the best bookkeeping Software for new initiate company, expanding tiny-medium sized company into a huge Firm.
This article is fairly lengthy, but it is well worth the read. It focuses on a financial and accounting database, including the structure and the concepts. It’s almost a perfect marriage between SQL and database theory, and basic accounting practices. I welcome feedback from both sides of the aisle for the purpose of making it more understandable for both. But the real purpose of this article is to illustrate the level of service offered by Compass Point Media in developing web-based applications, including accounting databases.
This is my first blog entry – ever. And it’s also right in the middle of a huge database project which is essentially an accounting database for a conference planner. This client manages conferences which involves registrations, cancellations, and refunds to attendees and exhibitors on behalf of their client. For example, the International Firefighter’s Union (I’m making this up) wants to hold a conference in sunny Orlando, Florida. They then call my client who will set up online registration forms for attendees and exhibitors (and organize speakers and presenters). They will handle registration and cancellation, and get a commission for their management of the conference. I design the interface which allows them to track that financial data. Trust me, it’s a big project.
There are articles to get a good starting knowledge of SQL tables for holding orders, invoices, etc. on the web However, that is NOT what you’re about to read here. What you’re about to read is highly advanced, reasonably detailed and hopefully evokes your comments, feedback and I hope you learn something from it.
So let’s jump right into this; an accounting database should have two fundamental tables: accounts and transactions. Now, if you’re coming from QuickBooks (like I am), the first table would also be known as your “Chart of Accounts” which is basically a “master map” of a company’s bank accounts, expense and income categories, assets and liabilities<a href=”#fn1″>[1]</a><a name=”xfn1″ id=”xfn1″></a>. The second table may also be rightly called a journal entry table. All transactions – checks, deposits, invoices, cash sales, etc. – are essentially journal entries. Allow me to elaborate more.
Accounts (Chart of Accounts)
We’ll start with the table to store the chart of accounts. Here are the bare-bones fields required for a chart of accounts table:
finan_accounts
--------------
ID - primary key
Name - name of the account
Types_ID - type of account
Parent_ID - parent account
ID is the integer primary key of course. Name would be value such as “Subscriptions” or “Rental Income” or “Loan from Mom”, or for bank accounts let’s say “Wells Fargo 7028” – whatever you want to name the account. The Types_ID field is necessary to specify which type of account it is, and I store these 14 values in a table called finan_accounts_types (note the _types in the name extends the finan_accounts table):
finan_accounts_types valuesID | Name | Category |
---|---|---|
1 | Bank | Asset |
2 | Accounts Receivable | Asset |
3 | Other Current Asset | Asset |
4 | Fixed Asset | Asset |
5 | Other Asset | Asset |
6 | Accounts Payable | Liability |
7 | Credit Card | Liability |
8 | Other Current Liability | Liability |
9 | Long Term Liability | Liability |
10 | Equity | Equity |
11 | Income | Income |
12 | Other Income | Income |
13 | Expense | Expense |
14 | Cost of Goods Sold | Expense |
15 | Other Expense | Expense |
I know you’re gripping the edge of your seat in excitement at this point; actually these are pretty standard. The number to the left is just my index for them, and to the right you see which of the 5 basic account types they are.
Finally, finan_accounts table has a field called Parent_ID. This is a heirarchical field which allows one record to be the parent of another. Parent_ID is either NULL (meaning the account has no parent), or the value of its parent.
To make sure you see this, look at the following snapshot:
<img src=”../images/assets/chart%20of%20accounts.jpg” alt=”chart of accounts” width=”592″ height=”682″>
figure 1
Again, if you use QuickBooks, this should be very familiar to you. You see three different types of accounts: Undeposited Funds, Accts Receivable, and Income accounts. Notice the indentation of some of the accounts. You also see a heirarchy; “General Activities Income” is a child of Activities, which is a child of Conference Registration (which is a root-level item). Or “Books and Publications”, for example, is a child or sub-account of “Options”. Here is the actual data in the finan_accounts table:
finan_accounts recordsID | Name | Types_ID | Parent_ID |
---|---|---|---|
30 | Accounts Receivable | 2 | 1 |
31 | Undeposited Funds | 3 | 1 |
1 | Conference Registration | 11 | 0 |
26 | Activities | 11 | 1 |
27 | General Activities Income | 11 | 26 |
18 | Meals | 11 | 1 |
6 | Member/Day Registration | 11 | 1 |
4 | Member/Full Conference | 11 | 1 |
2 | Membership Dues | 11 | 1 |
7 | Non-member/Day Registration | 11 | 1 |
5 | Non-member/Full Conference | 11 | 1 |
8 | Options | 11 | 1 |
15 | Books and Publications | 11 | 8 |
16 | Electronics and Computer | 11 | 8 |
11 | Field Activity | 11 | 8 |
14 | Luncheon or Dinner | 11 | 8 |
The cool thing about the last field (Parent_ID) is that it can be changed to “move the account around”; just remember that the account and its parent must be the same type of account. You don’t want an income account below a bank account. Be sure that you set the unique constraint that Name and Parent_ID (taken together) must be unique.
Transactions (Journal Entries)
Now we cover the other main table. As I said before, the transactions table (finan_transactions in my database) is used to store journal entries. ALL transactions, including invoices and cash sales, are journal entries. Journal entries are the basis of <a href=”http://en.wikipedia.org/wiki/Double_entry_bookkeeping” target=”_blank”>double-entry bookkeeping</a>. The rules are simple:
1. You must transfer money between accounts existing on the chart of accounts
2. The net amount of the journal entry (summing up all debits and credits) must be zero.
Here are the minimum fields required for this table, which I call finan_transactions:
finan_transactions
------------------
ID - primary key
Idx - relative line in the transaction
Name - description of the entry
Accounts_ID - foreign key, points back to finan_accounts.ID
Amount - dollary amount of the entry
To make my point, I’m going to show you a sample Invoice from Capt. Barton (a fictitious fire chief) and then explain:
finan_transactions recordsID | Idx | Name | Accounts_ID | Amount |
---|---|---|---|---|
1 | 1 | IFU Registration | 4(Member/Full Conference) | -185 |
2 | 2 | Fireman’s Handbook | 15(Books and Publications) | -25 |
3 | 3 | Roast Beef Dinner | 18(Meals) | -5.75 |
4 | 4 | EMT Course | 27(General Activities Income) | -45 |
5 | NULL | Invoice #325 | 30(Accounts Receivable) | 260.75 |
Notice the first four entries. We call these “Line Items”; each is an item showing on the invoice. Capt. Barton has registered and is being invoiced for registration, dinner, a book and one EMT training course. The income to which each item is attributed is shown in the third column. (Each of these are found in the chart of accounts table, above. I have added the account name in parenthesis for simplicity). All records in the transaction table must point back to an account in the Chart of Accounts table.
Next, we have a fifth entry with account equalling 30 (Accounts Receivable). Notice the far right columns. The first four entries are negative, but the fifth is positive. You may be asking why the first three are negative at this point, so I’ll explain.
With this new invoice, the company is now owed 260.75 by Capt. Barton. So, Accounts Receivable must INCREASE by 260.75. Since the rule is that the sum of a journal entry equals zero, however, whatever flows into one account must flow out of other account(s). So we “deduct” from these income accounts. In reality the conference MADE 185.00 for registration when Capt. Barton registered, as well as 5.75 for selling a roast beef dinner etc., so just think of “using” these accounts as taking from them; it should make sense that way.
Now, Capt. Barton comes in on the day of the conference and pays his 260.75; this is called (seriously) a Payment. A payment would look like this:
finan_transactions recordsID | Idx | Name | Accounts_ID | Amount |
---|---|---|---|---|
6 | NULL | Payment check #99051 | 31(Undeposited Funds) | 260.75 |
7 | NULL | Payment of Invoice #325 | 30(Accounts Receivable) | -260.75 |
I will explain what happened. Before Capt. Barton wrote the check, we had an asset in the form of the money Capt. Barton owed us. After Capt. Barton writes the check, we no longer have that asset, so 30(Accounts Receivable) is reduced by 260.75. But, we have a check in the deposit box ready to go to the bank (which is much nicer). We refer to that as “Undeposited Funds”. So, Accounts Receivable DECREASES, and Undeposited Funds INCREASES. But again, the net effect is zero.
Now, I want to introduce you to some more complexity (life is complex). Suppose Capt. Barton wanted to pay for his registration and another registration with a single check. No problem; the payment would look like this:
.diagramGroup{
} </style>
finan_transactions recordsID | Idx | Name | Accounts_ID | Amount |
---|---|---|---|---|
6 | NULL | Payment of Invoice #325 | 30(Accounts Receivable) | -260.75 |
7 | NULL | Payment of Invoice #326 | 30(Accounts Receivable) | -120 |
8 | NULL | Payment check #99051 | 31(Undeposited Funds) | 480.75 |
Here, Capt. Barton has paid for his registration (#325), and for another registration (#326) which totaled 120.00 (not shown here). He writes a check for 480.75, which is *split* between these two invoices. But again, notice one thing: the total of the amounts on the right is still zero to be a journal entry. Accounts Receivable went down, and Undeposited Funds went up by the same amount.
Adding More Fields And Tables
So far, the examples above are not meant to be fully functional but just to illustrate how we apply accounting concepts in a relational database. You can be assured that what I had explained above is the heart of any accounting system. Now, let’s start adding more fields and tables to make the system functional.
Quantity, Index Number and Extension
The above line items in finan_transactions are missing a few useful fields. Suppose Capt. Barton wants THREE roast beef dinners? (Firefighters have an appetite; or he may have brought his wife). Let’s add a Quantity and Extension field so that we can handle this efficiently. So an invoice like this:
finan_transactions recordsID | Idx | Name | Accounts_ID | Amount |
---|---|---|---|---|
1 | 1 | IFU Registration | 4(Member/Full Conference) | -185 |
2 | 2 | Fireman’s Handbook | 15(Books and Publications) | -25 |
3 | 3 | Roast Beef Dinner | 18(Meals) | -5.75 |
4 | 4 | Roast Beef Dinner | 18(Meals) | -5.75 |
5 | 5 | Roast Beef Dinner | 18(Meals) | -5.75 |
6 | 6 | EMT Course | 27(General Activities Income) | -45 |
7 | NULL | Invoice #325 | 30(Accounts Receivable) | 272.25 |
Can now look like this:
finan_transactions recordsID | Idx | Name | Accounts_ID | Quantity | Price | Amount |
---|---|---|---|---|---|---|
1 | 1 | IFU Registration | 4(Member/Full Conference) | 1 | -185 | -185 |
2 | 2 | Fireman’s Handbook | 15(Books and Publications) | 1 | -25 | -25 |
3 | 3 | Roast Beef Dinner | 18(Meals) | 3 | -5.75 | -17.25 |
4 | 4 | EMT Course | 27(General Activities Income) | 1 | -45 | -45 |
5 | NULL | Invoice #325 | 30(Accounts Receivable) | 1 | 272.25 | 272.25 |
So, this is the formula used:
Remember, though, the values in the FARTHEST RIGHT COLUMN must always sum to zero.
I never really explained the Idx field so far. One more convenience is the ability to indicate what order the line items appear in. We could just assume that they appear in the order entered, but if we add special line items like subtotals (which are calculations on other previous rows) or ever need to cut and paste line items in our program, this will come in handy. The Idx field for the fifth row is NULL. This is because this is the offsetting entry for the first four; it never appears on the invoice. You’ll hear me refer to it as the “root” transaction sometimes.
Grouping Transactions – Use of a Header Table
Now, I have to be honest with you; I’ve left out a glaring shortcoming in the system. The reason I did this was to emphasize that the transactions table is the heart of the database, but you might see we have a problem: there is no way to group or relate transaction lines together, or indicate what type of transaction it is. Here are all of our transaction lines so far, that is, the invoice to Capt. Barton and his payment by check:
finan_transactions recordsID | Idx | Name | Accounts_ID | Quantity | Price | Amount |
---|---|---|---|---|---|---|
1 | 1 | IFU Registration | 4(Member/Full Conference) | 1 | -185 | -185 |
2 | 2 | Fireman’s Handbook | 15(Books and Publications) | 1 | -25 | -25 |
3 | 3 | Roast Beef Dinner | 18(Meals) | 3 | -5.75 | -17.25 |
4 | 4 | EMT Course | 27(General Activities Income) | 1 | -45 | |
5 | NULL | Invoice #325 | 30(Accounts Receivable) | 1 | 272.25 | 272.25 |
6 | NULL | Payment check #99051 | 31(Undeposited Funds) | 1 | 272.25 | 272.25 |
7 | NULL | Payment of Invoice #325 | 30(Accounts Receivable) | 1 | -272.25 | -272.25 |
This is good accounting because the sum of all activity is still zero. You and I both know that the first five lines represent an invoice, and the next two are a payment. But the database does not know that; we need a way to group the first four and last two transactions. We solve this by creating a new table, finan_headers, with the following bare-bones fields:
finan_headers
-------------
ID - Primary key
HeaderNumber - a preferably unique number but duplicates are allowed
HeaderDate - date of the transaction
Headertypes_ID - see below for possible values
Now, for the values in the Headertypes_ID field, we’ll create ANOTHER table to list types of headers:
finan_headertypes
-----------------
ID
Type
Sql Financial Accounting Cracked Download
Here are its values:
ID | Type |
---|---|
1 | Invoice |
2 | Cash Sale |
3 | Payment |
4 | Credit Memo |
5 | Refund |
6 | Check |
As you can see, these transaction types are pretty standard in accounting. With this, we are ready to group the first transaction, that is, the registration:
finan_headers recordsID | HeaderNumber | HeaderDate | Headertypes_ID |
---|---|---|---|
1 | 325 | 10/13/2007 | 1 (Invoice) |
We also add a new (foreign key) column in finan_transactions pointing back to finan_headers, and so now our registration looks like this:
finan_transactions recordsID | Headers_ID | Idx | Name | Accounts_ID | Quantity | Price | Amount |
---|---|---|---|---|---|---|---|
1 | 1 | 1 | IFU Registration | 4(Member/Full Conference) | 1 | -185 | -185 |
2 | 1 | 2 | Fireman’s Handbook | 15(Books and Publications) | 1 | -25 | -25 |
3 | 1 | 3 | Roast Beef Dinner | 18(Meals) | 3 | -5.75 | -17.25 |
4 | 1 | 4 | EMT Course | 27(General Activities Income) | 1 | -45 | |
5 | 1 | NULL | … | 30(Accounts Receivable) | 1 | 272.25 | 272.25 |
If you’re paying close attention you’ll notice that I took out the “Name” value for the last row (it said Invoice #325). The reason is that that information has a new home in the parent record in finan_headers.HeaderNumber.
Now, let’s add a header for the payment:
finan_headers recordsID | HeaderNumber | HeaderDate | Headertypes_ID |
---|---|---|---|
2 | 99051 | 10/25/2007 | 3 (Payment) |
ID | Headers_ID | Idx | Name | Accounts_ID | Quantity | Price | Amount |
---|---|---|---|---|---|---|---|
6 | 2 | NULL | Payment check #99051 | 31(Undeposited Funds) | 1 | 272.25 | 272.25 |
7 | 2 | NULL | Payment of Invoice #325 | 30(Accounts Receivable) | 1 | -272.25 | -272.25 |
So there you go, we have now grouped our transactions together and we can do so for any type of transaction for that matter.
Improving Performance
You’ll notice that there is no “total” column in finan_headers. I intend that that way because the total is not a “real” number. The “real” total is the sum of the first four line items (times -1 in order to make sense to humans). If we put a Total field in finan_headers, we’d have to update it anytime we edited the line items for that transaction – leaving it susceptible to getting out of synch.
However, there is something we can do which I think is worthwhile. Let’s add a field Accounts_ID in the header. Take a look at our registration (Invoice) and payment now:
finan_headers recordsID | Accounts_ID | HeaderNumber | HeaderDate | Headertypes_ID |
---|---|---|---|---|
1 | 30 | 325 | 10/13/2007 | 1 (Invoice) |
2 | 31 | 99051 | 10/25/2007 | 3 (Payment) |
For the registration, finan_headers.Accounts_ID matches finan_transactions.Accounts_ID in the fifth line of the transactions – this identifies the “root” account, or zero-offsetting transaction. This allows me to get the total like this:
a.ID=1 AND a.ID=b.Headers_ID AND a.Accounts_ID=b.Accounts_ID
I could also double-check my math on the entry by getting the total this way:
a.ID=1 AND a.ID=b.Headers_ID AND a.Accounts_ID!=b.Accounts_ID GROUP BY a.ID
This query would get all the OTHER transaction records (the line items) except for the “root” transaction. The two values should be the same.
Relating Payment to Invoice
Sql Financial Accounting Cracked Software
We are not quite finished yet. We have meaningful data in the transactions table that tells us which account is increasing or decreasing. We have created a headers table to group the transactions. However, there is no way to indicate what payment applies to what invoice. To do this, we could add fields in finan_transactions somewhere, but the more precise way is by creating two additional tables as follows:
So to apply Capt. Barton’s check to his registration, we enter the following
finan_rlx recordsID |
---|
1 |
finan_rlx_transactions records
Rlx_ID | Transactions_ID |
---|---|
1 | 1 |
1 | 2 |
this relates the payment to the invoice.
With these two tables and their entries, I can now understand that the payment (finan_headers.ID = 2) was applied to Capt. Barton’s Invoice (finan_headers.ID = 1). Also I can determine how much has been paid on an invoice with the following query:
This query could use some explaining (and I’m going to go into this more in my next article). First, we join the header and root transaction for the invoice (a and b). By joining c we get all Rlx_ID’s (relations) to this invoice. Joining d and e, we get the transactions which are in any other payments.
Some of the SQL queries required to join our information are simple, and some are complex. But this system is sufficient to accommodate one payment to multiple invoices, or multiple payments to a single invoice. One issue which has NOT been brought up is that payments under this system can actually be attributed to specific line items within an invoice, depending on how much the payment is broken up, however this can be accomplished.
What I have done by this tutorial, in effect, is propose an entire accounting database by the use of 7 basic tables. The fields in any table can be added to, and extension tables could extend queries to include inventory, registrant names and etc; however these 7 tables are the heart of the system. I really welcome your feedback on this! My next article will deal more with these SQL queries and getting meaningful data from the database.
<a href=”#xfn1″>[1]</a><a name=”fn1″ id=”fn1″></a> there are 5 basic categories of these accounts: Asset, Liability, Income, Expense, and Equity. You can pretty much figure out which is which with a little research, and you’ll learn this indirectly here.
By: Andy Novick | Updated: 2010-05-06 | Comments (8) | Related: More >T-SQL
Problem
When working with cash flow calculations in SQL Server one of the key concepts is the Net Present Value of a stream of payments. In a database of payment information, how can the Net Present Value of a stream of payments be calculated in a way that is easy for users to request? Just as important, once the number is calculated, is being sure that the answer is correct? How does the coder or tester know?
Solution
Net-Present-Value (NPV) calculations are used in several areas of finance such as mortgage calculation and the financing of bonds and loans. All NPV calculations answer one particular question: What is the total value today of a stream of payments. The 'Net' in NPV refers to the fact that there can be both positive and negative payments involved. From a bank's point of view a loan often consists of a negative payment, the principal of the loan, followed by a series of positive payments as the loan is paid back in installments with the possibility of a final balloon payment of outstanding principal. If the series of payments are at regular intervals, such as at the beginning of each month, then the NPV of the loan can be calculated by a formula and implemented in T-SQL as a scalar function.
The formula for the NPV of a loan looks like this:
Where -Principal represents paying the principal of the loan to the borrower, rate is the interest rate per period, and paymenti is a loan payment at the end of period i, which could be any time period as long as the information stays consistent. This article uses a monthly rate.
While this works well enough for simple loans like car loans and most mortgages, real-world commercial loans are a mixture of principal amounts dispersed at various dates during the early life of the loan followed by a stream of loan payments including a balloon payment at the end of the loan. To represent this complexity we can rely on a much simpler formula for the value of any individual payment. The Present Value (PV) of any cash flow is the value of the payment discounted by the interest rate given in this formula.
For an example, let's say that there is a payment of $10,000 due exactly 12 months from now. The yearly interest rate that we're using to evaluate the loan is 8% (0.08) so the monthly interest rate is 0.00667. If we plug in the numbers the formula is:
Sql Financial Accounting Cracked Free
Or in T-SQL:
Which gives us an answer of 9,233.57, which is to say that receiving $10,000 in 12 months is worth $9,233.57 today. The difference is referred to as the 'time value of money.' Maybe that's why J. Wellington Wimpy would always rather pay Popeye on Tuesday to get a hamburger today.
To get the NPV of the collection of cash flows as of a date, evaluate every payment for its value on that date and then sum the present values. That'll be the approach. Let's start with some test data. The following code sets up two tables: loan and loan_cash_flow. Each loan_cash_flow could be positive or negative depending on whether it was a Disbursement or a Payment, which is indicated by the disbursement_or_payment_column.
CREATE TABLE loan (loan_id CHAR(8) NOT NULL PRIMARY KEY CLUSTERED
,inception date NOT NULL
,monthly_rate decimal(28,9) NOT NULL
,name VARCHAR(100)
,cust_id VARCHAR(24) NOT NULL
)
GO
CREATE TABLE loan_cash_flow
(loan_id CHAR(8) NOT NULL
,cash_flow_date date NOT NULL
,disbursement_or_payment CHAR(1) NOT NULL
CHECK (disbursement_or_payment IN
('D', 'P'))
,amount money NOT NULL
,PRIMARY KEY CLUSTERED (loan_id, cash_flow_date
,disbursement_or_payment)
)
GO
For example data let's insert rows for one loan, the 'Big Mall' construction project. The project begins with several disbursements, presumably to finance the construction. It then starts with regular payments until the balloon payment at the end of the loan to repay the principal.
DECLARE @pmt decimal (38,2) = 2500000.0
INSERT INTO loan (loan_id, inception, monthly_rate, name, cust_id)
VALUES ('LN001', '2010-02-01', 0.006667, 'Big Mall', '0001')
GO
INSERT INTO loan_cash_flow (loan_id, cash_flow_date
, disbursement_or_payment, amount)
VALUES -- 3 Disbursements of 97 Million
('LN001', '2010-02-01', 'D', 40000000)
,('LN001', '2010-08-01', 'D', 32000000)
,('LN001', '2011-02-01', 'D', 27000000)
-- 11 monthly loan payments
,('LN001', '2012-03-01', 'P', @pmt)
,('LN001', '2012-04-01', 'P', @pmt)
,('LN001', '2012-05-01', 'P', @pmt)
,('LN001', '2012-06-01', 'P', @pmt)
,('LN001', '2012-07-01', 'P', @pmt)
,('LN001', '2012-08-01', 'P', @pmt)
,('LN001', '2012-09-01', 'P', @pmt)
,('LN001', '2012-10-01', 'P', @pmt)
,('LN001', '2012-11-01', 'P', @pmt)
,('LN001', '2012-12-01', 'P', @pmt)
,('LN001', '2013-01-01', 'P', @pmt)
-- balloon payment when construction is done
,('LN001', '2013-02-01', 'P', 97000000)
GO
To calculate the Present Value (PV) of any individual payment a scalar function is sufficient. The following function, cash_flow_present_value, does the trick by applying the present value formula given above. It's important to be careful about the number of periods to discount the payment. To make the examples more understandable the calculations are based on a monthly rate. In practice the calculation might be done on a daily rate.
CREATE FUNCTION dbo.cash_flow_present_value (
@as_of_date date = NULL -- evaluate as of this date
-- null for today
,@monthly_rate float -- ex 0.01 for 12%/yr
,@payment_date date -- Date payment scheduled
,@disbursement_or_payment CHAR(1) -- D or P
,@cash_flow_amount money
) RETURNS money
AS BEGIN
DECLARE @periods integer
SET @periods = DATEDIFF(MONTH
, ISNULL(@as_of_date, GETDATE())
, @payment_date)
RETURN CASE @disbursement_or_payment
WHEN 'D' THEN -1.0 -- disbursement
ELSE 1.0 -- payment
END
* @cash_flow_amount
/ POWER (1.0 + @monthly_rate, @periods)
END
GO
GRANT EXEC ON dbo.cash_flow_present_value TO PUBLIC
GO
To be confident in the calculation let's take a look at a present value calculation for each payment. It's not usually used this way, but it's instructive and by including the periods and discount columns that repeat portions of the functions formula it becomes easier to ensure that the calculation is correct:
Each row represents one cash flow, either a disbursement to the loan recipient or a payment back to the bank. Disbursements are negative cash flows. Since the loan is being evaluated as of its inception date, 2010-02-01, the $40,000,000 disbursed on the first day of the loan has a discount of 1.0 and thus a present value of $40,000,000. Each disbursement or payment in the future is worth less, on the day of the loan inception, by the discount from the day of payment.
When evaluating investments the present value of any individual payments isn't that important. What's most important is the total of all present values including any cash flows at day zero. So a typical use of cash_flow_present_value would be in a SUM aggregate. Here's the calculation of the net present value of the loan:
The result tells us that the Net Present Value of the loan to the bank is $3,217,640.95. That's great, now we know: LOAN APPROVED! But is that correct? How would we know?
When verifying a calculation we can always redo the calculation with pen and paper or we might want to look to another trusted source to do the calculation. When it comes to trusting calculations more than I trust my own code there are two sources that I look at. The first source you probably know, is an Excel spreadsheet. The second source may be unfamiliar, it's the Wolfram Alpha web site. Let's start by simulating the calculation in Excel.
Excel offers a NPV function that can be used to calculate the discounted value of a series of cash flows both negative, for disbursements, and positive, for payments. I've copied the cash flow data from the loan_payment table into a spreadsheet to do the calculation. The formula for calculating the NPV of the loan cash flows is in cell B1 and it's shown as text in cell C1.
When using Excel be very careful to read the documentation in order to get the calculation correct. The first argument to the NPV function is the rate expressed either as a decimal number or with a percentage sign. That's easy, use the 0.006667 monthly rate. Following the rate are a series of payments that come at the end of each period. The payments are stored in the spreadsheet range B4:B40. Since the first disbursement in our loan of $40,000,000 on 2010-02--01 is made at day zero of the evaluation, it shouldn't be included in the calculation. That's why the formula in B1 specifies a range of B5:B40. Since the payments are at the end of the period the formula gives us the correct calculation. As you can see the calculation in Excel is identical to the SQL Server calculation down to the penny. I consider the calculation verified.
Another trusted source of calculations is the Wolfram Alpha web site. Stephen Wolfram and his company Wolfram Research have been making the Mathimatica product for twenty years. In 2009 they made public the Alpha web site which is a combination of information database and search engine with the Mathamatica software and a natural language engine that understands written requests in many domains of knowledge. The key to getting what you are looking for is to express the request in a way that Alpha understands. That's not always obvious, at least to me.
Asking Alpha for the present value of a payment works well. Alpha will restate your original question in its formula language and the following picture shows the present value calculation for the balloon payment
Notice that I had to adapt the calculation to the way that Alpha expects input. The interest rate had to be stated as a yearly percentage, 8%, instead of the monthly rate of 0.0006667. The term had to be stated as years. The calculation matches the calculation made by the cash_flow_present_value function for the balloon payment on 2013-02-01 seen above.
Wolfram Alpha has a lot of potential to verify calculations, because of its inclusion of the Mathamatica capabilities. It also has other interesting capabilities including tons of data such as currency conversion rates, population statistics, historical events and astronomical information. The data is in a form that can be graphed or used in computations.
Next Steps
- Add the cash_flow_present_value function to your database
- Look for opportunities where evaluating cash flows with Net Present Value calculation is meaningful, such as in investments and projects.
- When testing code that does calculations, use a trusted program to verify that your T-SQL calculations are correct.
- Check out the Wolfram Alpha web site and ask it a few questions. Try using it to verify your next calculation.
Last Updated: 2010-05-06
Sql Financial Accounting Cracked Software
Sql Financial Accounting Cracked Version
About the author
Sql Financial Accounting Cracked Version
View all my tips