Ejemplo n.º 1
0
        /// <summary>
        /// Calculates the principal portion of a specific payment on a loan.
        /// </summary>
        /// <param name="rate">The periodic interest rate (applied every period). This must be greater than or equal to zero.</param>
        /// <param name="numberOfPeriods">The total number of periods.</param>
        /// <param name="currentBalance">The current balance of the loan. This must be greater than or equal to zero and not contain fractional pennies.</param>
        /// <param name="period">The period for which to calculate the principal portion. This must be in the range <c>[1,<paramref name="numberOfPeriods"/>]</c> and defaults to <c>1</c>.</param>
        /// <param name="futureBalance">The future balance of the loan. This must be greater than or equal to zero and not contain fractional pennies.</param>
        /// <param name="payAtBeginningOfPeriod">Set to <c>true</c> to indicate payments are made at the beginning of the period; by default, payments are made at the end of the period.</param>
        /// <returns>The principal portion of the specific payment.</returns>
        /// <exception cref="InvalidOperationException">The principal portion of the payment could not be calculated.</exception>
        public static decimal PrincipalPayment(decimal rate, uint numberOfPeriods, decimal currentBalance, int period = 1, decimal futureBalance = decimal.Zero, bool payAtBeginningOfPeriod = false)
        {
            Contract.Requires <ArgumentOutOfRangeException>(rate >= 0, "Rate may not be less than zero.");
            VerifyMoneyArgument(currentBalance, "currentBalance");
            VerifyMoneyArgument(futureBalance, "futureBalance");

            var result = -Exact.PrincipalPayment(rate, numberOfPeriods, currentBalance, period, futureBalance, payAtBeginningOfPeriod);

            if (result < decimal.Zero)
            {
                var e = new InvalidOperationException("The principal portion of the payment could not be calculated.");
                e.Data["rate"]                   = rate;
                e.Data["numberOfPeriods"]        = numberOfPeriods;
                e.Data["currentBalance"]         = currentBalance;
                e.Data["period"]                 = period;
                e.Data["futureBalance"]          = futureBalance;
                e.Data["payAtBeginningOfPeriod"] = payAtBeginningOfPeriod;
                e.Data["result"]                 = result;
                throw e;
            }

            try
            {
                return(checked (Math.Ceiling(result * 100) / 100));
            }
            catch (OverflowException ex)
            {
                var e = new InvalidOperationException("The principal portion of the payment could not be calculated.", ex);
                e.Data["rate"]                   = rate;
                e.Data["numberOfPeriods"]        = numberOfPeriods;
                e.Data["currentBalance"]         = currentBalance;
                e.Data["period"]                 = period;
                e.Data["futureBalance"]          = futureBalance;
                e.Data["payAtBeginningOfPeriod"] = payAtBeginningOfPeriod;
                e.Data["result"]                 = result;
                throw e;
            }
        }