IEnableMuch: Amortization Calculator

This is the computation routine for a real estate app I made a real estate app long time ago(2003, made in VB6), what it don't compute then is how long you will pay something based on your budget. A new feature Author: Michael Buen

by meetravi

HTML

<body ng-controller="RealEstateController" ng-app="RealEstateApp">


    <div style='float: left' class='input'>
    <fieldset>
        <legend>Selling</legend>
        
        <div><label for='TotalContractPrice'>Total Contract Price</label></div>
        <div>
        <input 
        id='TotalContractPrice' 
        ng-model='TotalContractPrice' 
        ng-change='ComputeFromTotalContractPrice()'
        ng-disabled='DeterminePaymentTerms'/>
        </div>

        <div><label for='DownPaymentPercent'>Downpayment %</label></div>
        <div><input 
        id='DownpaymentPercent' ng-model='DownPaymentPercent' ng-change='ComputeFromDownPaymentPercent()' 
        ng-disabled='DeterminePaymentTerms'
        percent/></div>
        
        <div><label for='DownPayment'>Downpayment</label></div>
        <div><input id='DownPayment' ng-model='DownPayment' ng-change='ComputeFromDownPayment()' ng-disabled='DeterminePaymentTerms' type='number'/></div>
        
        <div><label for='InstallmentPrincipal'>Installment Principal</label></div>
        <div><input id='InstallmentPrincipal' ng-model='InstallmentPrincipal' ng-change='ComputeFromInstallmentPrincipal()' ng-disabled='DeterminePaymentTerms'/></div>
        
    </fieldset>



    <fieldset>

        <legend>Payment Terms</legend>
    
        <div><label for='NumberOfYearsToPay'>Number of years to pay</label></div>
        <div><input ng-disabled='DeterminePaymentTerms' id='NumberOfYearsToPay' ng-model='NumberOfYearsToPay' ng-change='ComputeFromYears()' type='number'/></div>
    
        
        <div><label for='NumberOfMonthsToPay'>Number of months to pay</label></div>
        <div><input ng-disabled='DeterminePaymentTerms' id='NumberOfMonthsToPay' ng-model='NumberOfMonthsToPay' ng-change='ComputeFromMonths()' type='number'/></div>
        
        <div><label for='PaymentModeInMonths'>Payment Mode(1 = Monthly, 3 = Quarterly, ..., 12 = Yearly)</label></div>
        <div><input...

CSS

fieldset { font-size: 13px; font-family : 'Calibri'}
div.input { width: 380px; }
div.amort { width: auto; }
table, th, td { font-size: 13px; font-family : 'Calibri'; }


input {
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 5px;
}


fieldset {
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
}

table.table {
    margin: 20px;
    color: 666;
    font-size: 12px;
    -moz-border-radius: 3px;
    -moz-box-shadow: 0 1px 2px #d1d1d1;
    -webkit-border-radius: 3px;
    -webkit-box-shadow: 0 1px 2px #d1d1d1;
    background: #eaebec;
    border: #ccc 1px solid;
    border-radius: 3px;
    box-shadow: 0 1px 2px #d1d1d1;
    font-family: Arial, Helvetica, sans-serif;
    text-shadow: 1px 1px 0px #fff;
}

table.table tr.even td {
    background: #f6f6f6;
    background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6));
    background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6);
}

table.table th {
    padding: 21px 25px 22px 25px;
    border-bottom: 1px solid #e0e0e0; border-top: 1px solid #fafafa;
    background: #ededed;
    background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb));
    background: -moz-linear-gradient(top, #ededed, #ebebeb);
}

table.table th:first-child {
    padding-left: 20px;
    text-align: left
}

table.table a:visited {
    color: #999999;
    font-weight: bold;
    text-decoration: none
}

table.table a:active,
table.table a:hover {
    color: #bd5a35;
    text-decoration: underline
}

table.table a:link {
    color: #666;
    font-weight: bold;
    text-decoration: none
}

table.table tr {
    padding-left: 20px;
    text-align: center
}

table.table tr:first-child th:first-child {
    -moz-border-radius-topleft: 3px;
    -webkit-border-top-left-radius: 3px;
    border-top-left-radius: 3px;
}

table.table tr:first-child th:last-child {
    -moz-border-radius-topright: 3px;
    -webkit-border-top-right-radius: 3px;
   ...

JavaScript

var myApp = angular.module('RealEstateApp', []);

myApp.directive("percent", function($filter){
    var p = function(viewValue){
        var m = viewValue.match(/^(\d+)\/(\d+)/);
        if (m != null)
          return $filter('number')(parseInt(m[1])/parseInt(m[2]), 4);
        return $filter('number')(parseFloat(viewValue)/100, 4);
    };

    var f = function(modelValue){
        return $filter('number')(parseFloat(modelValue)*100, 2);
    };
    
    return {
        require: 'ngModel',
        link: function(scope, ele, attr, ctrl){
            ctrl.$parsers.unshift(p);
            ctrl.$formatters.unshift(f);
        }
    };
});

myApp.controller('RealEstateController',['$scope', function($scope) {
 // ------- MODELS --------
    
    // Month number, amortization date, interest, principal, principal balance
    $scope.Amortizations = [];
        
    $scope.TotalContractPrice = 4000000;
    $scope.DownPaymentPercent = .2; 
    $scope.DownPayment = 0;
    $scope.InstallmentPrincipal = 0;
    
    $scope.TotalInterest = 0;
    $scope.TotalPrincipal = 0;
    $scope.TotalAmortization = 0;
    
    
    
    $scope.NumberOfYearsToPay = 5;
    $scope.NumberOfMonthsToPay = 0;
    $scope.PaymentModeInMonths = 1; // monthly
    


    $scope.InterestRatePerAnnum = 0.21;
    $scope.PeriodicInterestRate = 0;
    $scope.AmortizationFactor = 0;
    $scope.AmortizationAmount = 0;
    $scope.AmortizationStartDate = new Date('May 5, 2000');
    
    // determine payment terms based on budget
    $scope.DeterminePaymentTerms = false; 
    $scope.Budget = 0;
    
    
    $scope.AdvancedPayments = [
        { MonthNumber: null, Payment: null }
    ];
    
    
    // ------- CONTROLLER's ACTIONS -----------
    
    $scope.ComputeYears = function() {
        $scope.NumberOfYearsToPay = $scope.NumberOfMonthsToPay / 12;
    }
    
    $scope.ComputeFromTotalContractPrice = function() {
        $scope.ComputeDownPayment();
        $scope.ComputeInstallmentPrincipal();
       ...