A quick app for creating Equal Total Payments using PHP

Let’s start by creating a blank page with our default HTML 5 markup. The basic markup below will contain the (X)HTML5 DocType Definition, the page’s language, character set, and a title.

<!DOCTYPE html>  
<html lang="en">  
  <head>
    <meta charset="UTF-8" />
    <title>Equal Total Payments</title>
  </head>
  <body>

  </body>
</html>  

The above is default (X)HTML 5 version of starting HTML. Being a lazy kitten, I would be happy to include a few frameworks, one of which being Bootstrap. Before anything, please make sure you add the responsive viewport meta tag to enable the responsive behaviour of the app.

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />  

As I said I am lazy, I would not download the files from the repository, instead get it from a CDN (Content Delivery Network). Saying so, let me include the CSS file alone (as we just need it for styling purposes only).

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"  
      rel="stylesheet" />

I am using the Bootstrap 3 version. Being a UX centric cat, I would like to choose my own fonts. Open Sans will be for the body text while Montserrat be for the headings.

<link rel="stylesheet"  
      href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Open+Sans:400,600"/>

Let’s start with a header. I would like the header to be dark and would like to use a simple markup for the same. So, the markup looks something similar to the below:

<header>  
  <h1>Equal Total Payments</h1>
</header>  

And with the above markup, the style I have written is:

header h1 {  
  font-family: 'Montserrat', sans-serif;
  text-align: center;
  font-size: 1.25em;
  font-weight: 300;
  margin: 0;
  padding: 0;
  font-size: 1.75em;
}

The above CSS will make the text to appear in the new Montserrat font, is light weight with a font size of 25% more than the body text, centrally aligned, without any margins. This would be looking in the view something like this:

The application mainly needs to get input from the user on the following fields:

  • Loan Amount
  • Rate of Interest
  • Repayment Period

The Loan Amount will be the principal amount lent by the customer and rate of interest will be a numerical value of the percentage of the principal amount that will be accrued annually. The Repayment Period is again an integral number (whole number). To get the above information from the user, we need to create a form. As I mentioned already, we’ll be using Bootstrap 3 to get kick started.

I would really like to have a panel covering the whole form. Let’s start writing a panel code.

<div class="panel panel-primary">  
  <div class="panel-heading">Input for Calculation</div>
  <div class="panel-body">

  </div>
</div>  

The above generates something like this:

That forms a perfect enclosure for our form, so now we can start building our form. I personally used Bootsnipp Form Generator, but you are free to hand-code or copy paste from anywhere. Be lazy. Now we need to capture these three fields for Loan Amount, Interest Rate, Loan Period, so let’s create the form. The code for the form looks something similar to the below:

<form class="form-horizontal" method="post">  
  <fieldset>
    <div class="form-group">
      <label class="col-md-3 control-label" for="loan-amount">Loan Amount</label>  
      <div class="col-md-7">
        <input id="loan-amount" name="loan-amount" type="text" placeholder="Loan Amount" class="form-control input-md" required="">
        <span class="help-block">Enter the loan amount.</span>  
      </div>
    </div>
    <div class="form-group">
      <label class="col-md-3 control-label" for="interest">Interest Rate</label>  
      <div class="col-md-7">
        <input id="interest" name="interest" type="text" placeholder="Annual Interest Rate" class="form-control input-md" required="">
        <span class="help-block">Enter the annual interest rate.</span>  
      </div>
    </div>
    <div class="form-group">
      <label class="col-md-3 control-label" for="period">Loan Period</label>  
      <div class="col-md-7">
        <input id="period" name="period" type="text" placeholder="Period in months" class="form-control input-md" required="">
        <span class="help-block">Enter the number of months of repayment.</span>  
      </div>
    </div>
    <div class="form-group">
      <div class="col-md-7">
        <button class="btn btn-primary">Calculate</button>
      </div>
    </div>
  </fieldset>
</form>  

The above form is syntactically and semantically valid. The main points for this form to work that you are supposed to make sure are as follows:

  • The form’s method is HTTP POST.
  • All the form elements should have unique ids.
  • No need of action attribute, as we are POSTing to the same page.

Making sure you follow the same approach above, you should be getting something like below:

Now, let’s start doing the backend logic. Let’s add another panel for the Calculation Results. The logic is as follows:

  • Calculate the following values:
    • Payment No
    • Payment Amount
    • Principal Amount Paid
    • Interest Amount Paid
    • Loan Outstanding Balance
  • Create another table with the contents above contents for the N number of months given. This will give you something similar to:

Let’s start with creating the above table. The first thing we need to do is to make it hide using server side, which we will do later. We should be creating another panel, but this time, the number of columns that’s going to be used will not be four but eight.

The code for the basic panel will be:

<div class="panel panel-primary">  
  <div class="panel-heading">Calculation Results</div>
  <div class="panel-body">

  </div>
</div>  

Now that the panel has been done, inside the panel-body, we will be creating the table structure to display something like this now:

The code for displaying the above structure is:

<table class="table table-bordered table-striped">  
  <thead>
    <tr>
      <th>Payment No</th>
      <th>Payment Amount</th>
      <th>Principal Amount Paid</th>
      <th>Interest Amount Paid</th>
      <th>Loan Outstanding Balance</th>
    </tr>
  </thead>
  <tbody>

  </tbody>
</table>  

The good way of creating tabular data is to use both <thead> and <tbody>. We use the table <thead> to add the header of the table while the contents will go inside <tbody>. Now that we have created the base structure, let’s hide it from the view until the results are populated. This means, we shouldn’t show the table until a POST request has been made to the server. Let’s wrap the <table> code between the following:

<?php if (count($_POST) == 3) { ?>

<?php } ?>  

The reason why I give count as 3 is that we are capturing three values from the user. The other problem I had was to deal with displaying the captured values again in the result screen, but shouldn’t be a problem (throw an error) when requesting the page for the first time.

<input id="loan-amount" name="loan-amount" type="text" placeholder="Loan Amount" class="form-control input-md" required="" value="<?php echo @$_POST["loan-amount"]; ?>" />  
<input id="interest" name="interest" type="text" placeholder="Annual Interest Rate" class="form-control input-md" required="" value="<?php echo @$_POST["interest"]; ?>" />  
<input id="period" name="period" type="text" placeholder="Period in months" class="form-control input-md" required="" value="<?php echo @$_POST["period"]; ?>" />  

Here, I have used @$_POST because, the @ keyword suppresses the errors caused by the variable not set or present at the run time. When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.

Note: The @-operator works only on expressions. A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth.

Now that we have done with the capturing of input from the user, let’s try to build our logic. The initial equated payment for the N months stays the same. The formula is given as follows:

(Rn * A) / [1 - (1 +Rn)-N ]

The above formula can be written in PHP using the following method:

$payment = ($rate * $amount) * round(pow((1 + $rate), $months), 5) / (round(pow((1 + $rate), $months), 5) - 1);

We use the following functions:

  • PHP round - Returns the rounded value to specified precision (number of digits after the decimal point) and the value of precision can also be negative or zero (default).
  • PHP pow - Exponential expression, returns base raised to the power of exp.

With the above expression we have calculated the equated payments. Now, for every loop, we will be calculating the following values:

  • Payment No
  • Payment Amount
  • Principal Amount Paid
  • Interest Amount Paid
  • Loan Outstanding Balance

The first value of Payment No is just the index of the loop. If we run a for loop like this:

for ($i = 1; $i <= $months; $i++) {  
}

We can easily assign it to the $i value. For the ease of calculation, I have started the for loop from 1 till the number of months given by the user. The Payment Amount is going to be the same throughout and we have also calculated it. So, the current code for both of them will be like:

<td><?php echo $i; ?></td>  
<td><?php echo number_format($payment, 2); ?></td>  

The PHP function number_format will round off the number to the nearest specified number of decimals and returns the string of it. Note, the resultant will not be an integral value. After these two columns are filled, the next one we’ll be calculating is going to be the monthly Principal Amount that’s been paid every month.

To calculate the Principal Amount Paid, the formula will be:

Payment / (1+Rn)(1+N-n)

To calculate the above formula programmatically using PHP, we’ll be using the below expression. Note that we will also be rounding off to the nearest seven decimals for making sure we don’t go out of bounds.

$pp = $payment / (round(pow((1+$rate), (1+$months-$i)), 7));

That’s the current month’s Principal Amount Paid. The next thing we need to calculate is the interest that’s incurred every month. This is going to be the difference between the Equated Monthly Payment and the Principal Amount Paid. The simple expression in PHP for that is:

$int = $payment - $pp;

Finally, we’ll be calculating the Loan Outstanding Balance. This is simpler because this is going to be the interest amount divided by the rate of interest without the Principal Amount Paid.

$lob = ($int / $rate) - $pp;

Getting all the above details, now let’s construct our row.

<tr>  
  <td><?php echo $i; ?></td>
  <td><?php echo number_format($payment, 2); ?></td>
  <td><?php echo number_format($pp, 2); ?></td>
  <td><?php echo number_format($int, 2); ?></td>
  <td><?php echo number_format(abs($lob), 2); ?></td>
</tr>  

The above snippet should be totally looped for the N months and we should make sure the end of the row is zero to be paid in Loan Outstanding Balance. The full code now will be:

<tbody>  
<?php  
  // Get the input values.
  $amount = $_POST["loan-amount"];
  $rate = $_POST["interest"] / 1000;
  $months = $_POST["period"];
  // The equated payment amount will be the same throughout of each period.
  // The formula is given as follows:
  // (Rn * A) / [1 - (1 +Rn)power-N ]
  $payment = ($rate * $amount) * round(pow((1 + $rate), $months), 5) / (round(pow((1 + $rate), $months), 5) - 1);
  // echo "Payment is ", number_format($payment, 2), " &pound;<br />";
  for ($i = 1; $i <= $months; $i++) {
    // To calculate the principal amount 1:
    // Payment1 / pow((1+Rn),(1+N-n))
    $pp = $payment / (round(pow((1+$rate), (1+$months-$i)), 7));
    // To calculate the Interest paid:
    // Payment1 - PP1
    $int = $payment - $pp;
    // To calculate the LOB
    // (INT1/ Rn) – PP1
    $lob = ($int / $rate) - $pp;
    ?>
  <tr>
    <td><?php echo $i; ?></td>
    <td><?php echo number_format($payment, 2); ?></td>
    <td><?php echo number_format($pp, 2); ?></td>
    <td><?php echo number_format($int, 2); ?></td>
    <td><?php echo number_format(abs($lob), 2); ?></td>
  </tr>
<?php } ?>  
</tbody>  

The above code includes the whole contents of <tbody>. The output you would be getting, if you implemented everything correctly will be:

Hope this was useful to everyone reading this. Back with another awesomeness. Until then, have a nice week!