The Code for the Mortgage Calculator

The Model

                
// Loan Model

namespace MortgageCalculatorMVC.Models
{
    public class Loan
    {
        public decimal Amount { get; set; }
        public decimal Rate { get; set; }
        public int Term { get; set; }
        public int Yearly { get; set; }
        public decimal Payment { get; set; }
        public decimal TotalInterest { get; set; }
        public decimal TotalCost { get; set; }
        public List<LoanPayment> Payments { get; set; } = new List<LoanPayment>();
    }
}

// Loan Payments Model

namespace MortgageCalculatorMVC.Models
{
    public class LoanPayment
    {
        public int Month { get; set; }

        [DisplayFormat(DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
        public decimal Payment { get; set; }

        [DisplayFormat(DataFormatString = "{0:C0}")]
        public decimal MonthlyPrincipal { get; set; }
        public decimal MonthlyInterest { get; set; }
        public decimal TotalInterest { get; set; }
        public decimal Balance { get; set; }
    }
}
                
            

The View



<div class="container mt-0 p-0">
    <div class="row row-cols-1 row-cols-md-2">
    <div class="col">
    <form asp-controller="Home" asp-action="App" method="post" class="row row-cols-1 gy-2 gx-3 bg-gray py-3 pt-1 pb-3">
    <div class="col">
    <label asp-for="Amount">Loan Amount</label><span id="fAmount" class="ms-3 pb-1"></span>
    <input id="loanAmount" asp-for="Amount" value="@Model.Amount" type="number" class="form-control" aria-label="Loan Amount">
        </div>
    <div class="col">
    <div class="row">
    <label>Term</label>
    <div class="col-md-6">
    <label asp-for="Term">Monthly</label>
    <input id="monthly" asp-for="Term" value="@Model.Term" type="number" class="form-control" aria-label="Monthly">
                </div>
    <div class="col-md-6">
    <label>Yearly</label>
    <input id="yearly" asp-for="Yearly" value="@Model.Yearly" type="number" step="any" class="form-control" aria-label="Yearly">
                </div>
            </div>
        </div>
    <div class="col">
    <label asp-for="Rate">Fixed Interest Rate</label>
    <input id="rate" asp-for="Rate" value="@Model.Rate" step="0.1" type="number" class="form-control" aria-label="Rate">
        </div>
    <div class="row m-0 p-0">
    <div class="col-md-6 mt-2">
    <label style="display: none;">Extra Monthly Payments</label>
    <input style="display: none;" id="extraPayment" type="number" value="0" class="form-control" aria-label="Extra Payments">
            </div>
    <div class="col-md-3 d-flex justify-content-start justify-content-md-end mt-3">
    <button type="submit" id="btnSubmit" class="btn btn-outline-success btn-lg">Calculate</button>
            </div>
    <div class="col-md-3 d-flex justify-content-start justify-content-md-end mt-3">
    <button type="button" id="btnReset" class="btn btn-outline-success btn-lg">Reset</button>
            </div>
        </div>
    </form>
</div>
    <div class="col">
    <form id="formHeader" class="row row-cols-1 gy-2 gx-3">
    <div class="col-12 text-center">
    <p><i>Your Monthly Payments</i></p>
        </div>
    <div class="col-12 text-center mb-2">
    <div><span id="monthlyPayment" class="fw-bold fs-1">@Model.Payment.ToString("C")</span></div>
        </div>
    <div class="col-6">
    <span>Total Principal:</span>
        </div>
    <div class="col-6">
    <span id="totalPrincipal">@Model.Amount.ToString("C")</span>
        </div>
    <div class="col-6">
    <span>Total Interest</span>
        </div>
    <div class="col-6">
    <span id="totalInterest">@Model.TotalInterest.ToString("C")</span>
        </div>
    <div class="col-6">
    <span>Total Cost</span>
        </div>
    <div class="col-6">
    <span id="totalCost" class="fw-bold">@Model.TotalCost.ToString("C")</span>
        </div>
    </form>
    <div class="mt-5">
        Note: This does not include PMI, Property Taxes, Home Insurance, HOA and other fees.
        For a detailed cost analysis, visit the <a href="https://usmortgagecalculator.org/" target="_blank">US Mortgage Calculator</a>.
    </div>
</div>
</div>
    <div class="chart">
<!-- <canvas id="myChart"></canvas> -->
</div>
    <hr>
        @if (Model.Payments.Count > 0)
        {
        <div class="col-12">
        <table class="table table-striped table-sm">
        <thead class="theadbg text-light">
        <tr>
        <th>Month</th>
        <th>Payment</th>
        <th>Principal</th>
        <th>Interest</th>
        <th>Accrued Interest</th>
        <th>Balance</th>
            </tr>
            </thead>
        <tbody id="results">
                @foreach (var item in Model.Payments)
            {
            <tr>
            <td>@item.Month</td>
            <td>@item.Payment.ToString("C")</td>
            <td>@item.MonthlyPrincipal.ToString("C")</td>
            <td>@item.MonthlyInterest.ToString("C")</td>
            <td>@item.TotalInterest.ToString("C")</td>
            <td>@item.Balance.ToString("C")</td>
            </tr>
            }
            </tbody>
        </table>
    </div> 
                }
</div>
                
            

The Controller

                
[HttpGet]
public IActionResult App() 
{
    Loan loan = new();
    loan.Payment = 0.0m;
    loan.TotalInterest= 0.0m;
    loan.TotalCost= 0.0m;
    loan.Rate = 1.0m;
    loan.Amount = 150000m;
    loan.Term = 60;
    loan.Yearly = 5;

    return View(loan);
}

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult App(Loan loan)
{
    var loanHelper = new LoanHelper();
    Loan newLoan = loanHelper.GetPayments(loan);

    return View(newLoan);
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
    return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
                
            

The Helper Class

                
namespace MortgageCalculatorMVC.Helpers
{
    public class LoanHelper
    {
        public Loan GetPayments(Loan loan)
        {
            //Calculate my Monthly Payment
            loan.Payment = CalcPayment(loan.Amount, loan.Rate, loan.Term);

            // Create a loop from 1 to the term
            var balance = loan.Amount;
            var totalInterest = 0.0m;
            var monthlyInterest = 0.0m;
            var monthlyPrincipal = 0.0m;
            var monthlyRate = CalcMonthlyRate(loan.Rate);

            //loop over each month until i reach the term of the loan
            for (int month = 1; month <= loan.Term; month++)
            {
                monthlyInterest = CalcMonthlyInterest(balance, monthlyRate);
                totalInterest += monthlyInterest;
                monthlyPrincipal = loan.Payment - monthlyInterest;
                balance -= monthlyPrincipal;

                LoanPayment loanPayment = new();

                loanPayment.Month = month;
                loanPayment.Payment = loan.Payment;
                loanPayment.MonthlyPrincipal = monthlyPrincipal;
                loanPayment.MonthlyInterest = monthlyInterest;
                loanPayment.TotalInterest = totalInterest;
                loanPayment.Balance = balance;

                //push the object into the Loan Model
                loan.Payments.Add(loanPayment);

            }

            loan.TotalInterest = totalInterest;
            loan.TotalCost = loan.Amount + totalInterest;
            loan.Yearly = (loan.Term / 12);
            //return the loan to the view
            return loan;


        }

        private decimal CalcPayment(decimal amount, decimal rate, int term)
        {
            var monthlyRate = CalcMonthlyRate(rate);
            var rateD = Convert.ToDouble(rate);
            var amountD = Convert.ToDouble(amount);

            var paymentD = (amountD * (rateD/1200)) / (1 - Math.Pow(1 + rateD / 1200, -term));


            return Convert.ToDecimal(paymentD);
        }


        private decimal CalcMonthlyRate(decimal rate)
        {
            return rate / 1200;
        }

        private decimal CalcMonthlyInterest(decimal balance, decimal monthlyRate)
        {
            return balance * monthlyRate;
        }

    }
}
                
            

This code is structured using the MVC model.

The Model

The model represents the database. It defines the database table as well as the columns. The perameters are set in the class, and translated into SQL on the server side.

The View

The view is a web page that displays the data and is the interface between the user and the applicaiton. It uses a combination of HTML, CSS, Javasctipt and C# to display the web page.

The Controller

When the view, or web page is interacted with by the user, the controller is consulted to determine the action to be taken. In this case, the user enters data in a form, and when the button is clicked, the controller executes the appropriate action determined by the code. It communicates between the model and the view. The controller also exectues any commands on the back end database as dictated by the code. In this example, the controller recieves the data entered in the form, executes the function to process the data entered, communicates with the database to make the designated changes, then sends the result back to the view and displays it.

The Helper Class

The helper class separates the logic from the controller. This practice keeps the code cleaner and more maintainable, and implements the principal of "Separation of Concerns". The controller is the go-between for the view and models, and should be used to call all the necessary methods to run the app. Although th logic can be included in the conroller, it is a best practice to separate the logic from the controller where appropriate.

Please contact me if you have any questions and/or would like to discuss my skill set and qualifications.