Пример #1
0
        public List <Installment> CalculateInstallments(bool changeDate)
        {
            List <Installment> schedule = new List <Installment>();
            OCurrency          olb      = _contract.Amount;
            OCurrency          totalInterestsRepayment = _contract.Amount * Convert.ToDecimal(_contract.InterestRate) * (_contract.NbOfInstallments - _contract.GracePeriod.Value);
            decimal            decCr = 0;
            decimal            decIr = 0;

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment = new Installment {
                    Number = number, FeesUnpaid = 0, OLB = olb
                };

                if (changeDate)
                {
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                }
                else
                {
                    installment = _contract.GetInstallment(number - 1);
                }

                if (number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                    {
                        installment.InterestsRepayment = 0;
                    }

                    installment.CapitalRepayment   = 0;
                    installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate) + decIr, _roundingPoint);
                    decIr = _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) - installment.InterestsRepayment.Value;
                }
                else
                {
                    ExoticInstallment exoInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(number - _contract.GracePeriod.Value - 1);

                    OCurrency cr = Convert.ToDecimal(exoInstallment.PrincipalCoeff) * _contract.Amount.Value + decCr;
                    installment.CapitalRepayment = Math.Round(cr.Value, _roundingPoint);
                    decCr = cr.Value - installment.CapitalRepayment.Value;

                    OCurrency ir = totalInterestsRepayment.Value * Convert.ToDecimal(exoInstallment.InterestCoeff) + decIr;

                    installment.InterestsRepayment = Math.Round(ir.Value, _roundingPoint);
                    decIr = ir.Value - installment.InterestsRepayment.Value;
                }
                olb -= installment.CapitalRepayment.Value;

                if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue)
                {
                    installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint);
                }

                schedule.Add(installment);
            }

            return(schedule);
        }
        public List <Installment> CalculateInstallments(bool changeDate)
        {
            List <Installment> schedule = new List <Installment>();
            OCurrency          olb      = _contract.Amount;

            DateTime date          = _contract.AlignDisbursementDate;
            int      daysInTheYear = GetDaysInAYear(_contract.AlignDisbursementDate.Date.Year);

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment = new Installment {
                    Number = number, FeesUnpaid = 0
                };

                if (changeDate)
                {
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                }

                installment.OLB = Math.Round(olb.Value, _roundingPoint);

                int days = (installment.ExpectedDate - date).Days;

                if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue)
                {
                    installment.InterestsRepayment =
                        Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate) / daysInTheYear *
                                   (installment.ExpectedDate - _contract.StartDate).Days, _roundingPoint);
                }
                else
                {
                    installment.InterestsRepayment =
                        Math.Round((olb * _contract.InterestRate / daysInTheYear * days).Value,
                                   _roundingPoint, MidpointRounding.AwayFromZero);
                }

                if (number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                    {
                        installment.InterestsRepayment = 0;
                    }

                    installment.CapitalRepayment = 0;
                }
                else
                {
                    OCurrency principal = olb / (double)(_contract.NbOfInstallments - number + 1);
                    installment.CapitalRepayment = Math.Round(principal.Value, _roundingPoint);
                }

                olb -= installment.CapitalRepayment;
                date = installment.ExpectedDate;
                schedule.Add(installment);
            }
            return(schedule);
        }
Пример #3
0
        private DateTime[] _Reschedule_AdjustDates(ReschedulingOptions ro)
        {
            DateTime[] retval  = new DateTime[2];
            DateTime   oldDate = DateTime.MinValue;
            DateTime   newDate = DateTime.MinValue;
            bool       first   = false;
            int        number  = 0;

            for (int i = 0; i < _contract.InstallmentList.Count; i++)
            {
                Installment installment = _contract.GetInstallment(i);
                if (installment.IsRepaid)
                {
                    continue;
                }
                if (!first)
                {
                    first   = true;
                    oldDate = installment.ExpectedDate;
                    newDate = installment.ExpectedDate;
                    if (0 == ro.RepaymentDateOffset)
                    {
                        break;
                    }

                    newDate = newDate.AddDays(ro.RepaymentDateOffset);

                    DateTime actualNewDate = _nwdS.GetTheNearestValidDate(newDate,
                                                                          _generalSettings.IsIncrementalDuringDayOff,
                                                                          _generalSettings.DoNotSkipNonWorkingDays, true);
                    installment.ExpectedDate = actualNewDate;
                }
                installment.ExpectedDate = _contract.CalculateInstallmentDate(newDate, number);
                number++;
            }
            retval[0] = oldDate;
            retval[1] = newDate;
            return(retval);
        }
        public void TestCalculateInstallmentDateWhenWeekEndDay2IsSunday()
        {
            LoanProduct package = new LoanProduct
            {
                InstallmentType = new InstallmentType(1, "Monthly", 0, 1),
                LoanType        = OLoanTypes.DecliningFixedInstallments,
                ChargeInterestWithinGracePeriod = true,
                Currency = new Currency {
                    Id = 1
                }
            };
            Loan myContract = new Loan(package, 1000, 0.03m, 6, 0, new DateTime(2006, 6, 30), new User(), ApplicationSettings.GetInstance(""), NonWorkingDateSingleton.GetInstance(""), ProvisionTable.GetInstance(new User()), ChartOfAccounts.GetInstance(new User()));

            Assert.AreEqual(new DateTime(2006, 7, 31), myContract.CalculateInstallmentDate(myContract.StartDate, 1));
        }
Пример #5
0
        public List <Installment> CalculateInstallments(bool changeDate)
        {
            List <Installment> schedule = new List <Installment>();
            OCurrency          olb      = _contract.Amount;

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment = new Installment {
                    Number = number, FeesUnpaid = 0
                };

                if (changeDate)
                {
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                }

                decimal olbValue = olb.Value;
                installment.OLB = Math.Round(olbValue, _roundingPoint);
                decimal interestRepayment = (olbValue * _contract.InterestRate);
                installment.InterestsRepayment = Math.Round(interestRepayment, _roundingPoint);

                if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue)
                {
                    installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint);
                }

                if (number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                    {
                        installment.InterestsRepayment = 0;
                    }

                    installment.CapitalRepayment = 0;
                }
                else
                {
                    OCurrency principal = olb / (double)(_contract.NbOfInstallments - number + 1);
                    installment.CapitalRepayment = Math.Round(principal.Value, _roundingPoint);
                }

                olb -= installment.CapitalRepayment;

                schedule.Add(installment);
            }
            return(schedule);
        }
Пример #6
0
        private void TrancheExtendMaturity(int newInstallments, DateTime pFirstInstallmentDate)
        {
            if (newInstallments > 0)
            {
                List <Installment> listInstallment = new List <Installment>();
                listInstallment.AddRange(_currentLoan.InstallmentList);

                foreach (Installment _installment in _currentLoan.InstallmentList)
                {
                    if (!_installment.IsRepaid)
                    {
                        listInstallment.Remove(_installment);
                    }
                }

                int lastNumber = listInstallment.Count;
                _trancheEvent.StartedFromInstallment = lastNumber;

                for (int i = 1; i <= newInstallments; i++)
                {
                    DateTime    expectedDate = _currentLoan.CalculateInstallmentDate(pFirstInstallmentDate, i);
                    Installment installment  = new Installment
                    {
                        Number             = lastNumber + i,
                        CapitalRepayment   = 0,
                        PaidCapital        = 0,
                        CommissionsUnpaid  = 0,
                        FeesUnpaid         = 0,
                        InterestsRepayment = 1,
                        PaidInterests      = 0,
                        ExpectedDate       = expectedDate
                    };

                    listInstallment.Add(installment);
                }
                _currentLoan.InstallmentList = listInstallment;

                _currentLoan.NbOfInstallments = _currentLoan.InstallmentList.Count;
            }
        }
Пример #7
0
        public List <Installment> CalculateInstallments(bool changeDate)
        {
            List <Installment> schedule    = new List <Installment>();
            OCurrency          olb         = _contract.Amount;
            OCurrency          totalAmount = _contract.Amount;

            OCurrency totalInterest = _contract.GracePeriod.HasValue &&
                                      !_contract.Product.ChargeInterestWithinGracePeriod
                                          ? Math.Round(
                _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) *
                (_contract.NbOfInstallments - _contract.GracePeriod.Value),
                _roundingPoint, MidpointRounding.AwayFromZero)
                                          : Math.Round(
                _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) *
                _contract.NbOfInstallments, _roundingPoint,
                MidpointRounding.AwayFromZero);

            int nbOfInstallmentWithoutGracePeriod = _contract.GracePeriod.HasValue
                                                        ? _contract.NbOfInstallments - _contract.GracePeriod.Value
                                                        : _contract.NbOfInstallments;

            OCurrency sumOfPrincipal = 0;
            OCurrency sumOfInterest  = 0;

            OCurrency interestBase = _contract.Product.ChargeInterestWithinGracePeriod
                                         ? Math.Round(
                (totalInterest.Value - sumOfInterest.Value) /
                (nbOfInstallmentWithoutGracePeriod + _contract.GracePeriod.Value),
                _roundingPoint, MidpointRounding.AwayFromZero)
                                         : Math.Round(
                (totalInterest.Value - sumOfInterest.Value) /
                (nbOfInstallmentWithoutGracePeriod),
                _roundingPoint, MidpointRounding.AwayFromZero);

            OCurrency principalBase = Math.Round(
                (totalAmount.Value - sumOfPrincipal.Value) /
                (nbOfInstallmentWithoutGracePeriod),
                _roundingPoint, MidpointRounding.AwayFromZero);

            int installmentNumberWithoutGracePeriodForCapital  = 0;
            int installmentNumberWithoutGracePeriodForInterest = 0;

            if (!_contract.Rescheduled)
            {
                for (int number = 1; number <= _contract.NbOfInstallments; number++)
                {
                    Installment installment = new Installment {
                        Number = number, FeesUnpaid = 0
                    };

                    if (changeDate)
                    {
                        installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                    }

                    installment.OLB = olb;

                    OCurrency interest = Math.Round(
                        (totalInterest.Value - sumOfInterest.Value) /
                        (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest),
                        _roundingPoint, MidpointRounding.AwayFromZero);

                    OCurrency principal = Math.Round(
                        (totalAmount.Value - sumOfPrincipal.Value) /
                        (nbOfInstallmentWithoutGracePeriod - installmentNumberWithoutGracePeriodForCapital),
                        _roundingPoint, MidpointRounding.AwayFromZero);

                    if (_contract.Product.RoundingType == ORoundingType.End ||
                        _contract.Product.RoundingType == ORoundingType.Begin)
                    {
                        interest  = interestBase;
                        principal = principalBase;
                    }

                    if (_contract.GracePeriod.HasValue && number <= _contract.GracePeriod)
                    {
                        installment.CapitalRepayment = 0;

                        if (_contract.Product.ChargeInterestWithinGracePeriod)
                        {
                            installment.InterestsRepayment = interest;

                            sumOfInterest += installment.InterestsRepayment;
                            installmentNumberWithoutGracePeriodForInterest++;
                        }
                        else
                        {
                            installment.InterestsRepayment = 0;
                            installmentNumberWithoutGracePeriodForInterest++;
                        }
                    }
                    else
                    {
                        installment.CapitalRepayment = principal;

                        sumOfPrincipal += installment.CapitalRepayment;
                        installmentNumberWithoutGracePeriodForCapital++;

                        installment.InterestsRepayment = interest;

                        sumOfInterest += installment.InterestsRepayment;
                        installmentNumberWithoutGracePeriodForInterest++;
                    }

                    if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue)
                    {
                        installment.InterestsRepayment =
                            Math.Round(
                                installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment *
                                (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint,
                                MidpointRounding.AwayFromZero);
                    }

                    olb -= installment.CapitalRepayment.Value;

                    schedule.Add(installment);
                }
            }

            if (_contract.Product.RoundingType == ORoundingType.End)
            {
                schedule[_contract.NbOfInstallments - 1].InterestsRepayment += totalInterest - sumOfInterest;
                schedule[_contract.NbOfInstallments - 1].CapitalRepayment   += totalAmount - sumOfPrincipal;
            }

            if (_contract.Product.RoundingType == ORoundingType.Begin)
            {
                schedule[0].CapitalRepayment += totalInterest - sumOfInterest;
                schedule[0].CapitalRepayment += totalAmount - sumOfPrincipal;
            }

            return(schedule);
        }
        public List <Installment> CalculateInstallments(bool pChangeDate)
        {
            List <Installment> schedule = new List <Installment>();
            OCurrency          olb      = _startAmount;
            OCurrency          VPM      = 0;

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment;

                if (pChangeDate)
                {
                    installment = new Installment {
                        Number = number
                    };
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate,
                                                                                  installment.Number);
                }
                else
                {
                    installment = _contract.GetInstallment(number - 1);
                }

                installment.FeesUnpaid         = 0;
                installment.InterestsRepayment = Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate),
                                                            _roundingPoint, MidpointRounding.AwayFromZero);

                if (installment.Number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                    {
                        installment.InterestsRepayment = 0;
                    }

                    installment.CapitalRepayment = 0;
                }
                else
                {
                    OCurrency installmentVpm = Math.Round(_contract.VPM(olb, _numberOfInstallmentsToPay - installment.Number + 1).Value,
                                                          _roundingPoint, MidpointRounding.AwayFromZero);

                    if ((_contract.Product.RoundingType == ORoundingType.End ||
                         _contract.Product.RoundingType == ORoundingType.Begin) && VPM == 0)
                    {
                        VPM = installmentVpm;
                    }
                    else if (_contract.Product.RoundingType == ORoundingType.Approximate)
                    {
                        VPM = installmentVpm;
                    }

                    OCurrency capital =
                        Math.Round((VPM.Value - Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate), _roundingPoint)),
                                   _roundingPoint, MidpointRounding.AwayFromZero);

                    installment.CapitalRepayment = capital;

                    //to count the difference in case End and Beging rounding type
                    OCurrency installemtDiff = VPM - (installment.CapitalRepayment + installment.InterestsRepayment);

                    if (installemtDiff != 0)
                    {
                        installment.CapitalRepayment += installemtDiff;
                    }

                    olb -= capital + installemtDiff;
                    ///////////////////////////////////////////////////////////////
                }

                if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue)
                {
                    installment.InterestsRepayment =
                        Math.Round(
                            installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment *
                            (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint,
                            MidpointRounding.AwayFromZero);
                }

                if (pChangeDate)
                {
                    schedule.Add(installment);
                }
            }

            if (_contract.Product.RoundingType == ORoundingType.End && olb != 0)
            {
                schedule[_contract.NbOfInstallments - 1].CapitalRepayment += olb;
            }

            if (_contract.Product.RoundingType == ORoundingType.Begin && olb != 0)
            {
                schedule[0].CapitalRepayment += olb;
            }

            olb = _startAmount;
            OCurrency capetalRepayment = 0;

            //OLB Calculation
            foreach (Installment installment in schedule)
            {
                olb             -= capetalRepayment;
                installment.OLB  = olb;
                capetalRepayment = installment.CapitalRepayment;
            }

            return(schedule);
        }