home *** CD-ROM | disk | FTP | other *** search
- /*
- ** FINANCE
- **
- ** HTTP Wrapper for the Financial Tools
- **
- ** Confidential Property of Tod Sambar
- ** (c) Copyright Tod Sambar 1996
- ** All rights reserved.
- **
- **
- ** Public Functions:
- **
- ** finance_init
- **
- **
- ** History:
- ** Chg# Date Description Resp
- ** ---- ------- ------------------------------------------------------- ----
- ** 6SEP96 Created sambar
- */
-
- #include <stdio.h>
- #include <memory.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <finance.h>
-
- /*
- ** Finance RPC Commands
- */
- typedef struct finance__rpcs
- {
- SA_CHAR *name;
- SA_RPCPARAM *params;
- SA_INT numparams;
- SA_INT auth;
- SA_VOID *func;
- SA_CHAR *descr;
- } FINANCE__RPCS;
-
- static SA_RPCPARAM amorcalcp [] =
- {
- { "price", 1, "The price of the property." },
- { "months", 1, "The number of month of sthe load." },
- { "rate", 1, "The rate of the loan." },
- { "month", 1, "The starting month of the loan." },
- { "year", 1, "The starting year of the loan." }
- };
- static SA_RPCPARAM fvmdcalcp [] =
- {
- { "amount", 1, "The regular amount of deposit." },
- { "deposits", 1, "The number of deposits per year." },
- { "months", 1, "The total number of months." },
- { "rate", 1, "The normal interest rate." }
- };
- static SA_RPCPARAM fvpscalcp [] =
- {
- { "sum", 1, "The present sum to be calculated." },
- { "rate", 1, "The annual interest rate." },
- { "periods", 1, "The number of periods per year." },
- { "periods", 1, "The number of periods to maturity." }
- };
- static SA_RPCPARAM mortcalcp [] =
- {
- { "price", 1, "The sale price of the home." },
- { "down", 1, "The down payment amount." },
- { "years", 1, "The number of years to pay off the mortgage." },
- { "rate", 1, "The interest rate." }
- };
- static SA_RPCPARAM ratecalcp [] =
- {
- { "price", 1, "The principal value of the loan." },
- { "terms", 1, "The number of terms per year." },
- { "periods", 1, "The number of periods of the loan." },
- { "payment", 1, "The amount of each payment." }
- };
-
- static FINANCE__RPCS finance_rpcs [] =
- {
- { "amorcalc", amorcalcp, sizeof(amorcalcp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)finance_amorcalc,
- "Amortization schedule calculation." },
- { "fvmdcalc", fvmdcalcp, sizeof(fvmdcalcp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)finance_fvmdcalc,
- "Future value of monthly deposit calculator." },
- { "fvpscalc", fvpscalcp, sizeof(fvpscalcp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)finance_fvpscalc,
- "Future value of present sum calculator." },
- { "mortcalc", mortcalcp, sizeof(mortcalcp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)finance_mortcalc,
- "Mortgage calculator." },
- { "ratecalc", ratecalcp, sizeof(ratecalcp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)finance_ratecalc,
- "Interest rate calculator." }
- };
-
- /*
- ** FINANCE_INIT
- **
- ** Initialize the Financial Tools calculators.
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_init(sactx)
- SA_CTX *sactx;
- {
- int i;
-
- /* Register the Finance RPCs with the application */
- for (i = 0; i < sizeof(finance_rpcs) / sizeof(FINANCE__RPCS); i++)
- {
- if (sa_cmd_init(sactx, finance_rpcs[i].name,
- finance_rpcs[i].params, finance_rpcs[i].numparams,
- finance_rpcs[i].auth, finance_rpcs[i].descr,
- (SA_RPCFUNC)finance_rpcs[i].func) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR, "Unable to initialize Finance RPCs");
- return (SA_FAIL);
- }
- }
-
- sa_log2(sactx, SA_LOG_TRACE, "Finance Library Initialized");
-
- return (SA_SUCCEED);
- }
-
- /*
- ** FINANCE_FVPSCALC
- **
- ** Future value of present sum calculator.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_fvpscalc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT i;
- SA_INT periods;
- SA_INT numperiods;
- SA_INT datalen;
- double pressum;
- double rate;
- double tmp1;
- double tmp2;
- double fvps;
- SA_CHAR *data;
- SA_CHAR buffer[256];
-
-
- /* Get the present sum */
- if ((sa_param(sactx, saparams, "sum", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- pressum = atof(data);
-
- /* Get the annual interest rate */
- if ((sa_param(sactx, saparams, "rate", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- rate = atof(data);
-
- /* Get the number of periods per year */
- if ((sa_param(sactx, saparams, "periods", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- periods = atoi(data);
-
- /* Get the number of periods to maturity */
- if ((sa_param(sactx, saparams, "numperiods", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- numperiods = atoi(data);
-
- if ((pressum <= 0) || (rate <= 0) || (periods <= 0) || (numperiods <= 0))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- tmp1 = 1.0 + ((rate / (float)periods) / 100);
- tmp2 = tmp1;
- if (numperiods != 1)
- {
- for (i = 1; i < numperiods - 1; i++)
- {
- tmp1 = tmp1 * tmp2;
- }
- }
-
- fvps = pressum * tmp1;
-
- if (sa_send_macro(saconn, "FINANCE_FVPSCALC") != SA_SUCCEED)
- return (SA_FAIL);
-
- sprintf(buffer, "$%11.2f\n", fvps);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_send_macro(saconn, "FINANCE_FOOTER") != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** FINANCE_AMORCALC
- **
- ** Amortization schedule calculator.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_amorcalc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT i;
- SA_INT months;
- SA_INT start;
- SA_INT year;
- SA_INT datalen;
- double price;
- double rate;
- double payment;
- double tmp1;
- double tmp2;
- double at;
- double ay;
- SA_CHAR *data;
- SA_CHAR buffer[256];
-
- /* Get the principle amount */
- if ((sa_param(sactx, saparams, "price", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- price = atof(data);
-
- /* Get the number of months in the loan */
- if ((sa_param(sactx, saparams, "months", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- months = atoi(data);
-
- /* Get the interest rate */
- if ((sa_param(sactx, saparams, "rate", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- rate = atof(data);
-
- /* Get the starting month */
- if ((sa_param(sactx, saparams, "month", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- start = atoi(data);
-
- /* Get the starting year */
- if ((sa_param(sactx, saparams, "year", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- year = atoi(data);
-
- if ((price <= 0) || (months <= 0) || (rate <= 0) || (start <= 0) ||
- (year <= 0))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- if (sa_send_macro(saconn, "FINANCE_AMORCALC") != SA_SUCCEED)
- return (SA_FAIL);
-
- start--;
- year--;
-
- tmp1 = rate / 1200.0;
- tmp2 = 1.0 - (1.0 / pow((float)(tmp1+1), (float)months));
- payment = price * tmp1 / tmp2;
-
- at = ay = 0.0;
- for (i = 0; i < months; i++)
- {
- if (start >= 12)
- {
- year++;
- at += ay;
- sprintf(buffer,
- "<I>Total Interest for paid during %ld:</I> $%11.2f<BR>\n",
- year, ay);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- ay = 0.0;
- start = 0;
- }
-
- ay = ay + (price * tmp1);
- price = price - (payment - (price * tmp1));
-
- if (price > 0.0)
- start++;
- else
- break;
- }
-
- if (start > 0)
- {
- at += ay;
- sprintf(buffer, "<I>Total Interest paid during %ld:</I> $%11.2f<BR>\n",
- year, ay);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
- }
-
- sprintf(buffer,
- "<BR><B><I>Total Interest paid during loan:</B></I> $%11.2f<BR>\n",
- at);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_send_macro(saconn, "FINANCE_FOOTER") != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** FINANCE_RATECALC
- **
- ** Interest rate calculator.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_ratecalc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT i;
- SA_INT terms;
- SA_INT periods;
- SA_INT datalen;
- double price;
- double payment;
- double tmp1;
- double tmp2;
- double rate;
- SA_CHAR *data;
- SA_CHAR buffer[256];
-
- /* Get the principal value of the loan */
- if ((sa_param(sactx, saparams, "price", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- price = atof(data);
-
- /* Get the number of terms per year */
- if ((sa_param(sactx, saparams, "terms", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- terms = atoi(data);
-
- /* Get the number of periods of the load */
- if ((sa_param(sactx, saparams, "periods", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- periods = atoi(data);
-
- /* Get the amount of each payment */
- if ((sa_param(sactx, saparams, "payment", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- payment = atof(data);
-
- if ((price <= 0) || (terms <= 0) || (periods <= 0) || (payment <= 0))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- tmp1 = 0.008;
- i = 0;
- while (i < 1000000)
- {
- tmp2 = payment / price * pow((float)(tmp1+1), (float)(periods-1)) /
- pow((float)(tmp1+1), (float)periods);
- if (tmp1 - tmp2 < 0.000001 && tmp1 - tmp2 > -0.000001)
- i = 1000000;
- else
- tmp1 = tmp2;
-
- i++;
- }
-
- rate = tmp2 * terms * 100;
-
- if (sa_send_macro(saconn, "FINANCE_MORTCALC") != SA_SUCCEED)
- return (SA_FAIL);
-
- sprintf(buffer, "%11.4f%%\n", rate);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_send_macro(saconn, "FINANCE_FOOTER") != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** FINANCE_MORTCALC
- **
- ** Mortgage calculator.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_mortcalc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT years;
- SA_INT datalen;
- double price;
- double down;
- double rate;
- double tmp1;
- double mort;
- SA_CHAR *data;
- SA_CHAR buffer[256];
-
- /* Get the sale price of the house */
- if ((sa_param(sactx, saparams, "price", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- price = atof(data);
-
- /* Get the down payment amount */
- if ((sa_param(sactx, saparams, "down", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- down = atof(data);
-
- /* Get the number of years to pay off the mortgage */
- if ((sa_param(sactx, saparams, "years", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- years = atoi(data);
-
- /* Get the interest rate */
- if ((sa_param(sactx, saparams, "rate", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- rate = atof(data);
-
- if ((price <= 0) || (down <= 0) || (years <= 0) || (rate <= 0) ||
- (down > price))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- tmp1 = rate / (12 * 100);
- mort = (price - down) * (tmp1 / (1 - pow(1 + tmp1, - (years * 12))));
-
- if (sa_send_macro(saconn, "FINANCE_MORTCALC") != SA_SUCCEED)
- return (SA_FAIL);
-
- sprintf(buffer, "$%11.2f\n", mort);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_send_macro(saconn, "FINANCE_FOOTER") != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** FINANCE_FVMDCALC
- **
- ** Future value of monthly deposit calculator.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- finance_fvmdcalc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT deposits;
- SA_INT months;
- SA_INT years;
- SA_INT datalen;
- double amount;
- double rate;
- double tmp1;
- double tmp2;
- double fvmd;
- SA_CHAR *data;
- SA_CHAR buffer[256];
-
- /* Get the regular amount of deposit */
- if ((sa_param(sactx, saparams, "amount", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- amount = atof(data);
-
- /* Get the number of deposits per year */
- if ((sa_param(sactx, saparams, "deposits", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- deposits = atoi(data);
-
- /* Get the total months */
- if ((sa_param(sactx, saparams, "months", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- months = atoi(data);
-
- /* Get the nominal interest rate */
- if ((sa_param(sactx, saparams, "rate", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 32))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- rate = atof(data);
-
- if ((amount <= 0) || (rate <= 0) || (deposits <= 0) || (months <= 0))
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- years = months / 12;
- tmp1 = rate / (float)deposits / 100.0;
- tmp2 = pow((float)(1+tmp1), (float)(deposits * years));
- tmp2--;
- tmp2 /= tmp1;
- fvmd = amount * tmp2;
-
- if (sa_send_macro(saconn, "FINANCE_FVMDCALC") != SA_SUCCEED)
- return (SA_FAIL);
-
- sprintf(buffer, "$%11.2f\n", fvmd);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_send_macro(saconn, "FINANCE_FOOTER") != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-