public void CalculateMonthlyPaymentPremiums(int instalmentCount) { _instalmentCount = instalmentCount; if (instalmentCount == 12 /* a year */) { // No deposit at Renewal _deposit = 0.0; } else { // Standard deposit calculation _deposit = NumericalOperation.PennyTruncate(TotalPremium * (_depositPercentage / NumericalOperation.PercentageDivisor)) + _depositFixed; } double remainingPrinciple = TotalPremium - _deposit; _totalCalculatedLoan = NumericalOperation.PennyRound(remainingPrinciple * (1.0 + _interestPercentage / NumericalOperation.PercentageDivisor)); // Round the monthly payment // Note that due to the necessary rounding to a penny the total of all the payments may not equal exactly the calculated loan _monthlyPayment = NumericalOperation.PennyRound(_totalCalculatedLoan / instalmentCount); // The actual amount paid double monthlyPaymentTotal = _monthlyPayment * instalmentCount; // Check the difference between the total of the payments and the loan calculation _totalPaymentDifferenceFromCalculatedLoan = monthlyPaymentTotal - _totalCalculatedLoan; // Adjust the payments according to the deposit double nonDepositFraction = 1.0 - _deposit / TotalPremium; PrimaryCoverSection.CalculateMonthlyPayment(instalmentCount, _interestPercentage, nonDepositFraction); SetAdditionalCoverSectionPayments(instalmentCount, nonDepositFraction); // Generate total annual payment values double totalAdditionalCoverSectionAnnualPayment = TotalAdditionalCoverSectionMonthlyPayments * instalmentCount; double totalPrimaryCoverSectionAnnualPayment = PrimaryCoverSection.MonthlyPayment * instalmentCount; // Calculate the difference between the total of the penny rounded payments and what the total should really be double multiplePaymentCorrection = monthlyPaymentTotal - (totalPrimaryCoverSectionAnnualPayment + totalAdditionalCoverSectionAnnualPayment); // Put into the Deposit the difference between the total of the individual payments and what the total should have been _multiplePaymentCorrection = multiplePaymentCorrection; } // CalculateMonthlyPaymentPremiums
public void CalculateMonthlyPaymentPremiums(bool depositRequired, int installmentCount) { // Simple Endsleigh style payment validation if (depositRequired) { // New Business if (installmentCount != 11) { throw new ArgumentException(String.Format("Cases where a deposit is required must be New Business and have 11 payments")); } } // New Business else { // Renewals if (installmentCount != 12) { throw new ArgumentException(String.Format("Cases where a deposit is NOT required must be Renewals and have 12 payments")); } } // Renewals _installmentCount = installmentCount; if (depositRequired) { // Standard deposit calculation for New Business double depositTotal = NumericalOperation.PennyTruncate(TotalPremium * (_depositPercentage / NumericalOperation.PercentageDivisor)) + _depositFixedAmount; foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentPlanDepositDetails(installmentCount, depositTotal, TotalPremium); } PrimaryPaymentCoverSection.InstallmentCount = installmentCount; // Use the remainder as the Primary Cover Section Deposit PrimaryPaymentCoverSection.UncorrectedDeposit = depositTotal - TotalAdditionalCoverSectionDeposits; PrimaryPaymentCoverSection.DepositCorrection = 0.0; } // Standard deposit calculation for New Business else { // No deposit at Renewal foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentPlanDepositDetails(installmentCount, 0.0, TotalPremium); } PrimaryPaymentCoverSection.InstallmentCount = installmentCount; PrimaryPaymentCoverSection.UncorrectedDeposit = 0.0; PrimaryPaymentCoverSection.DepositCorrection = 0.0; } double loanPrincipal = TotalPremium - Deposit; _totalCalculatedLoan = NumericalOperation.PennyRound(loanPrincipal * (1.0 + _interestPercentage / NumericalOperation.PercentageDivisor)); // Round the monthly payment // Note that due to the necessary rounding to a penny the total of all the payments may not equal exactly the calculated loan _monthlyPayment = NumericalOperation.PennyRound(_totalCalculatedLoan / installmentCount); // The actual amount paid double monthlyPaymentTotal = _monthlyPayment * installmentCount; // Retain the difference between the total of the payments and the loan calculation _totalPaymentDifferenceFromCalculatedLoan = _totalCalculatedLoan - monthlyPaymentTotal; if (depositRequired) { // When there is a non-zero deposit correct the total payment // to equal the calculated loan by changing the value of the deposit PrimaryPaymentCoverSection.DepositCorrection = _totalPaymentDifferenceFromCalculatedLoan; } // Distribute the payments across the Cover Sections according to the premium for each Cover Section foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentDetails(_monthlyPayment, TotalPremium); } // Use the remainder as the Primary Cover Section Monthly Payment PrimaryPaymentCoverSection.UncorrectedMonthlyPayment = _monthlyPayment - TotalAdditionalCoverSectionMonthlyPayments; // Calculate the difference between the total of the penny rounded or truncated payments and what the total payments should be really // This should be very close to zero double multiplePaymentDifference = monthlyPaymentTotal - TotalAnnualPayment; _multiplePaymentDifference = multiplePaymentDifference; } // CalculateMonthlyPaymentPremiums