home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 November
/
pcwk_11_98a.iso
/
Wtestowe
/
Money99
/
money99.1
/
debt
/
logic.js
< prev
next >
Wrap
Text File
|
1998-07-25
|
17KB
|
558 lines
// LOAN LIST DATA STRUCTURE
function loanRec( bal, rate, pmt )
{
this.rate = rate / 1200
this.pmt = pmt
this.payoffBal = bal // used later for temporary values during payoff calculation
this.payoffTerm = 0
this.begTerm = 0
this.totalPmt = 0
this.totalIntPmt = 0
return this
}
function loanList()
{
this.loan = new Array()
this.length = 5
this.addLoan = loanList_addLoan
this.totalPayoff = loanList_totalPayoff
this.calcPayoff = loanList_payoffTerm
this.calcTotalPmt = loanList_totalPmt
this.calcTotalIntPmt = loanList_totalIntPmt
return this
}
function loanList_addLoan( bal, rate, pmt )
{
this.loan[ this.loan.length ] = new loanRec( bal, rate, pmt )
}
// calculates remaining payoff balance
function loanList_totalPayoff()
{
total = 0
for ( var i = 0; i < this.loan.length; i++ )
{
total += this.loan[ i ].payoffBal
}
return total
}
// calculates payoff term
function loanList_payoffTerm()
{
var tmpNum;
for ( var i = 0; i < this.loan.length; i++ )
{
if (this.loan[i].payoffBal != 0) {
tmpNum = this.loan[i].pmt/(this.loan[i].payoffBal * (-this.loan[i].rate) + this.loan[i].pmt)
if(tmpNum > 0) {
this.loan[i].payoffTerm = Math.log(tmpNum) / Math.log(1+this.loan[i].rate)
this.loan[i].payoffTerm = Math.ceil(this.loan[i].payoffTerm)
}
else
this.loan[i].payoffTerm = -1 // not sufficient payment to cover the interest
}
}
}
// calculates total payments made so far
function loanList_totalPmt()
{
var total = 0
var i
for(i=0; i<this.loan.length; i++) {
total += this.loan[i].totalPmt
}
return total
}
// calculates total interest payment made so far
function loanList_totalIntPmt()
{
var total = 0
var i
for(i=0; i<this.loan.length; i++) {
total += this.loan[i].totalIntPmt
}
return total
}
// CREDIT CARD LIST DATA STRUCTURE
function ccRec( bal, rate, fees, pmt )
{
this.rate = rate / 1200
this.fees = fees
this.pmt = pmt
this.payoffBal = bal // used later for temporary values during payoff calculation
this.payoffTerm = 0
this.begTerm = 0
this.totalPmt = 0
this.totalIntPmt = 0
return this
}
function ccList()
{
this.cc = new Array()
this.length = 5
this.addCC = ccList_addCC
this.totalPayoff = ccList_totalPayoff
this.lowest = ccList_lowest
this.calcPayoff = ccList_payoffTerm
this.calcTotalPmt = ccList_totalPmt
this.calcTotalIntPmt = ccList_totalIntPmt
return this
}
function highrateOrder( a_ccRec, b_ccRec )
{
return b_ccRec.rate - a_ccRec.rate // if A should appear before B, return a negative number
}
function ccList_addCC( bal, rate, fees, pmt )
{
this.cc[ this.cc.length ] = new ccRec( bal, rate, fees, pmt )
arraySort( this.cc, highrateOrder ) // sort the array by rate from highest to lowest
}
function ccList_lowest()
{
return this.cc[ this.cc.length - 1 ]
}
// calculates remaining payoff balance
function ccList_totalPayoff()
{
var total = 0
for ( var i = 0; i < this.cc.length; i++ )
{
total += this.cc[ i ].payoffBal
}
return total
}
// calculates total payments made so far
function ccList_totalPmt()
{
var total = 0
var i
for(i=0; i<this.cc.length; i++) {
total += this.cc[i].totalPmt
}
return total
}
// calculates total interest payment made so far
function ccList_totalIntPmt()
{
var total = 0
var i
for(i=0; i<this.cc.length; i++) {
total += this.cc[i].totalIntPmt
}
return total
}
<%
// The payoff term is calculated by forcing the following residual value to be zero.
//
// Res^[n] = bal*eta^n - p*[eta^(n-1) + eta^(n-2) + ... + 1].
// where bal is the initial balance, eta is the (1+interest rate), p is the periodic
// payment amount.
//
// For a given initial balance, interest, and payment, forcing the Residual value to be
// zero yeilds an equation for the number of periods to payoff the loan.
%>
function ccList_payoffTerm()
{
var tmpNum;
for ( var i = 0; i < this.cc.length; i++ )
{
if(this.cc[i].payoffBal != 0) {
tmpNum = this.cc[i].pmt/(this.cc[i].payoffBal * (-this.cc[i].rate) + this.cc[i].pmt)
if(tmpNum > 0) {
this.cc[i].payoffTerm = Math.log(tmpNum) / Math.log(1+this.cc[i].rate)
this.cc[i].payoffTerm = Math.ceil(this.cc[i].payoffTerm)
}
else
this.cc[i].payoffTerm = -1 // not sufficient payment to cover the interest
}
}
}
// this function calculates interest payment for a given balance, interest rate, regular
// payment, and term.
function calcIntPmt(bal, rate, pmt, term)
{
var intPmt, curBal, i, realRate
curBal = bal
intPmt = 0
for(i=0; i<term; i++) {
intPmt += curBal * rate
curBal = curBal * (1 + rate) - pmt
if(curBal <= 0)
break;
}
return intPmt
}
var sto = parent;
var irate = sto.rateLoan
var tempRate = irate / 1200
var payment = sto.pmtLoan
var term = sto.termLoan
var fees = sto.feesLoan
var tempTaxRate = sto.taxLoan / 100
// FIRST, CALCULATE THE TOTAL AMOUNT OWED.
var ccl = new ccList()
ccl.addCC( sto.bal1, sto.rate1, sto.fees1, sto.pmt1 )
ccl.addCC( sto.bal2, sto.rate2, sto.fees2, sto.pmt2 )
ccl.addCC( sto.bal3, sto.rate3, sto.fees3, sto.pmt3 )
ccl.addCC( sto.bal4, sto.rate4, sto.fees4, sto.pmt4 )
ccl.addCC( sto.balOther1, sto.rateOther1, sto.feesOther1, sto.pmtOther1 )
var ll = new loanList()
ll.addLoan( sto.balAuto1, sto.rateAuto1, sto.pmtAuto1 )
ll.addLoan( sto.balAuto2, sto.rateAuto2, sto.pmtAuto2 )
ll.addLoan( sto.balBoat, sto.rateBoat, sto.pmtBoat )
ll.addLoan( sto.balPersonal, sto.ratePersonal, sto.pmtPersonal )
ll.addLoan( sto.balOther2, sto.rateOther2, sto.pmtOther2 )
// credit card balances
var currentTotal = ccl.totalPayoff()
ccl.calcPayoff()
// loan balances
currentTotal += ll.totalPayoff()
ll.calcPayoff()
var totalPmtMonthly = sto.pmt1 + sto.pmt2 + sto.pmt3 + sto.pmt4 + sto.pmtOther1 +
sto.pmtAuto1 + sto.pmtAuto2 + sto.pmtBoat + sto.pmtPersonal +
sto.pmtOther2
// SECOND, SPLIT UP THE TASK DEPENDING ON WHETHER CALCULATING TERM OR PAYMENT.
var totalNewPayments = 0
var totalNewInterest = 0
var totalNewTaxes = 0
if ( sto.cmethod == 0 ) // how long would it take to...
{
// WE KNOW THE PAYMENT; GET THE TERM OF THE LOAN, PLUS TOTAL INTEREST AND TAXES
var tempTotal = currentTotal
var term = 0
while ( tempTotal > 0 )
{
term++
var thisInterest = tempTotal * tempRate
var thisTax
if (sto.loanType == 0)
thisTax = thisInterest * tempTaxRate
else
thisTax = 0
totalNewInterest += thisInterest
totalNewTaxes += thisTax
if((thisTax+payment) > thisInterest)
tempTotal += thisInterest - thisTax - payment
else {
payment = 0
break;
}
}
totalNewPayments = payment * term
}
else // how much must I pay to...
{
// WE KNOW THE TERM; GET THE PAYMENT
var rate = 1 + tempRate
var tempTotal = 0
var n = -1
while ( n < (term - 1) )
{
n++
tempTotal += Math.pow( rate, n )
}
var payment = currentTotal * Math.pow(rate, term) / tempTotal
// THEN CALCULATE INTEREST AND TAXES
tempTotal = currentTotal
totalNewInterest = 0
totalNewTaxes = 0
for ( var n = 0; n < term; n++ )
{
var thisInterest = tempTotal * tempRate
var thisTax = ( sto.loanType == 0 ) ? (thisInterest * tempTaxRate) : 0
totalNewInterest = totalNewInterest + thisInterest
totalNewTaxes = totalNewTaxes + thisTax
tempTotal = tempTotal + thisInterest - thisTax - payment
}
totalNewPayments = (payment * term) + fees
}
loanMonths = term
var numDebts = ccl.cc.length + ll.loan.length
var totalLength = 0
var prevTerm, prevPmt
var loanTerm, crdTerm, loanIndex, crdIndex
while(numDebts > 0) {
// find the shortest payoff term from both credit card and conventional loans
loanTerm = crdTerm = 10000
loanIndex = crdIndex = 10000
for(var i=0; i<ccl.cc.length; i++) {
var crd = ccl.cc[i]
if((crd.payoffTerm>0) && (crd.payoffTerm!=0) && (crd.payoffTerm < crdTerm)) {
crdTerm = crd.payoffTerm
crdIndex = i
}
}
if(crdIndex == 10000) {
for(var i=0; i<ll.loan.length; i++) {
var loan = ll.loan[i]
if((loan.payoffTerm>0) && (loan.payoffTerm!=0) && (loan.payoffTerm < loanTerm)) {
loanTerm = loan.payoffTerm
loanIndex = i
}
}
}
// leave if nothing is to be done
if((loanTerm==10000) && (crdTerm==10000))
break;
// set the payoffTerm to be zero to indicate the credit card or loan is paid off
if(crdTerm != 10000) {
prevTerm = ccl.cc[crdIndex].payoffTerm
prevPmt = ccl.cc[crdIndex].pmt
ccl.cc[crdIndex].totalIntPmt += calcIntPmt(ccl.cc[crdIndex].payoffBal,
ccl.cc[crdIndex].rate, prevPmt, prevTerm)
ccl.cc[crdIndex].totalPmt += ccl.cc[crdIndex].payoffBal + ccl.cc[crdIndex].totalIntPmt
ccl.cc[crdIndex].payoffTerm = 0
totalLength += prevTerm
}
else {
prevTerm = ll.loan[loanIndex].payoffTerm
prevPmt = ll.loan[loanIndex].pmt
ll.loan[loanIndex].totalIntPmt += calcIntPmt(ll.loan[loanIndex].payoffBal,
ll.loan[loanIndex].rate, prevPmt, prevTerm)
ll.loan[loanIndex].totalPmt += ll.loan[loanIndex].payoffBal + ll.loan[loanIndex].totalIntPmt
ll.loan[loanIndex].payoffTerm = 0
totalLength += prevTerm
}
// get the shortest payoff term and let its payment to cover the highest interest
// loan from this point and on. Note the "other loan" index is offset by the
// length of the credit card. The reason being that is to be in sync. with the
// second period payment that's coming.
var maxIndex = ccl.cc.length + ll.loan.length
for(var i=0; i<maxIndex; i++) {
if(i < ccl.cc.length) {
if(ccl.cc[i].payoffBal != 0) { // assume the rates are sorted already
// calc payments made so far
if(i != crdIndex) {
var curTerm = prevTerm - ccl.cc[i].begTerm
var eta = 1 + ccl.cc[i].rate
var etan = Math.pow(eta, curTerm)
var tmpBal = ccl.cc[i].payoffBal*etan - ccl.cc[i].pmt*((1-etan)/(1-eta))
if(tmpBal > 0) { // make sure the following loan still needs to be paid
ccl.cc[i].payoffBal = tmpBal
ccl.cc[i].totalIntPmt += calcIntPmt(ccl.cc[i].payoffBal, ccl.cc[i].rate,
ccl.cc[i].pmt, curTerm)
ccl.cc[i].totalPmt += ccl.cc[i].pmt * curTerm
ccl.cc[i].pmt = prevPmt + ccl.cc[i].pmt
ccl.cc[i].begTerm = prevTerm
if(crdIndex != 10000)
ccl.cc[crdIndex].payoffBal = 0
ccl.calcPayoff() // recalculate payoff term
break;
}
else { // this is a case when straight forward payoff is made.
ccl.cc[i].totalIntPmt += calcIntPmt(ccl.cc[i].payoffBal, ccl.cc[i].rate,
ccl.cc[i].pmt, curTerm)
ccl.cc[i].totalPmt += ccl.cc[i].payoffBal + ccl.cc[i].totalIntPmt
ccl.cc[i].payoffTerm = 0
continue
}
}
else {
ccl.cc[crdIndex].payoffBal = 0
continue
}
}
}
else {
j = i - ccl.cc.length
if(ll.loan[j].payoffBal != 0) {
// calc payments made so far
if(j != loanIndex) {
var curTerm = prevTerm - ll.loan[j].begTerm
var eta = 1 + ll.loan[j].rate
var etan = Math.pow(eta, curTerm)
var tmpBal = ll.loan[j].payoffBal*etan - ll.loan[j].pmt*((1-etan)/(1-eta))
if(tmpBal > 0) {
ll.loan[j].payoffBal = tmpBal
ll.loan[j].totalIntPmt += calcIntPmt(ll.loan[j].payoffBal, ll.loan[j].rate,
ll.loan[j].pmt, curTerm)
ll.loan[j].totalPmt += ll.loan[j].pmt * curTerm
ll.loan[j].pmt = prevPmt + ll.loan[j].pmt
ll.loan[j].begTerm = prevTerm
if(loanIndex != 10000)
ll.loan[loanIndex].payoffBal = 0
ll.calcPayoff() // recalculate payoff term
break;
}
else {
ll.loan[j].totalIntPmt += calcIntPmt(ll.loan[j].payoffBal, ll.loan[j].rate,
ll.loan[j].pmt, curTerm)
ll.loan[j].totalPmt += ll.loan[j].payoffBal + ll.loan[j].totalIntPmt
ll.loan[j].payoffTerm = 0
continue
}
}
else {
ll.loan[loanIndex].payoffBal = 0
continue
}
}
}
}
numDebts--;
}
termBalance = ccl.totalPayoff() + ll.totalPayoff()
// FINALLY, FILL THE FIELDS ON THE LAST PAGE.
var totalOldCrdPmt=0
var totalOldLoanPmt=0
var totalOldCrdBal=0
var totalOldLoanBal=0
// if total payoff balance is not zero, but the payment is zero --> a not
// sufficient payment condition
totalOldCrdPmt = ccl.calcTotalPmt()
for(var i=0; i<ccl.cc.length; i++)
totalOldCrdBal += ccl.cc[i].payoffBal
if((totalOldCrdBal>0) && (totalOldCrdPmt==0))
payment = 0 // flag a not sufficient payment error condition
totalOldLoanPmt = ll.calcTotalPmt()
for(var i=0; i<ll.loan.length; i++)
totalOldLoanBal += ll.loan[i].payoffBal
if((totalOldLoanBal>0) && (totalOldLoanPmt==0))
payment = 0 // flag a not sufficient payment error condition
var totalOldPayments = totalOldCrdPmt + totalOldLoanPmt
var totalOldInterest = ccl.calcTotalIntPmt() + ll.calcTotalIntPmt()
var totalOldFees = 0
for(var i=0; i<ccl.cc.length; i++)
totalOldFees += ccl.cc[i].fees
var loanType = ( sto.loanType == 0 ) ? 'home equity' : 'personal'
var loanRate = irate
var loanPmt = numToDollars( Math.round(payment) )
var payoffLenBefore = Math.round( totalLength )
var payoffLenAfter = loanMonths
var paymentBefore = intToDollarStr( Math.round( totalOldPayments - totalOldInterest) )
var paymentAfter = intToDollarStr( Math.round( totalOldPayments - totalOldInterest ) )
var interestBefore = intToDollarStr( Math.round( totalOldInterest ) )
var interestAfter = intToDollarStr( Math.round( totalNewInterest ) )
var feesBefore = intToDollarStr(totalOldFees)
var feesAfter = intToDollarStr(fees)
var taxesBefore = intToDollarStr( 0 )
var taxesAfter = intToDollarStr( Math.round( totalNewTaxes ) )
var totalBefore = intToDollarStr( Math.round( totalOldPayments + totalOldFees) )
var totalAfter = intToDollarStr( Math.round( (totalOldPayments - totalOldInterest) + totalNewInterest + fees - totalNewTaxes ) )
//logic transferred from pg_5.asp to logic.js
var resultStr = '';
if(payment != 0) {
if(totalBefore < totalAfter) {
if (sto.cmethod == 0){
resultStr = "If you consolidate your debts into one " + loanType + " loan (with"
+ " an interest rate of " + loanRate + "% and a monthly contribution of "
+ loanPmt + "), it will take you " + loanMonths + " months to pay off all your debts.";
}
else{
resultStr = "If you consolidate your debts into one " + loanType + " loan (with"
+ " an interest rate of " + loanRate + "% and making payments for "
+ loanMonths + " months) you need to pay " + loanPmt + " per month to pay off all your debts.";
}
}
else {
var saved = dollarStrToInt(totalBefore) - dollarStrToInt(totalAfter)
if (sto.cmethod == 0){
resultStr = "If you consolidate your debts into one " + loanType + " loan (with"
+ " an interest rate of " + loanRate + "% and a monthly contribution of "
+ loanPmt + "), it will take you " + loanMonths + " months to pay off all your debts. "
+ "You will save $" + saved + " consolidating your debt.";
}
else{
resultStr = "If you consolidate your debts into one " + loanType + " loan (with"
+ " an interest rate of " + loanRate + "% and making payments for "
+ loanMonths + " months) you need to pay " + loanPmt + " per month to pay off all your debts."
+ "You will save $" + saved + " consolidating your debt.";
}
}
}
else {
resultStr ="There is not enough payment made to either the consolidated or unconsolidated loan to cover the "
+ "interest itself. Please increase the payment amount and recalcuate.";
}
//calculation for Summary Page
var ansStr = '';
if(payment != 0) {
if (sto.cmethod == 0){
ansStr = "If you consolidate your debts into one " + loanType + " loan,"
+ " <b>paying " + numToDollars(payment) + " a month,</b> it will take you"
+ " <b>" + numToUnits(payoffLenAfter, 'months') + "</b> and cost " + totalAfter
+ " to pay off all your debts. Paying " + numToDollars(totalPmtMonthly) + " a month on your current loans,"
+ " it will take you " + numToUnits(payoffLenBefore, 'months') + " and"
+ " cost " + totalBefore + " to pay off all your debts.";
}
else{
ansStr = "If you consolidate your debts into one " + loanType + " loan,"
+ " you must pay <b>" + numToDollars(payment) + " a month</b> to pay off all you loan"
+ " in " + numToUnits(payoffLenAfter, 'months') + ", it will cost you " + totalAfter
+ ". Paying " + numToDollars(totalPmtMonthly) + " a month on your current loans,"
+ " it will take you " + numToUnits(payoffLenBefore, 'months') + " and"
+ " cost " + totalBefore + " to pay off all your debts.";
}
}
else {
ansStr ="There is not enough payment made to either the consolidated"
+ " or unconsolidated loan to cover the interest itself."
+ " Please increase the payment amount and recalcuate.";
}