Exemplo n.º 1
0
        /// <summary>
        /// calculates schedules according to keren shava formula (EqualPrincipal)
        /// </summary>
        private void CalculateScheduleEqualPrincipalFormula()
        {
            int interestOnlyRepayments = Calculator.currentHistory.InterestOnlyRepaymentCount;

            Calculator.currentHistory.Schedule.Clear();

            RepaymentIntervalTypes intervalType = (RepaymentIntervalTypes)Calculator.currentHistory.RepaymentIntervalTypeID;

            int            principalPayments = Calculator.currentHistory.RepaymentCount - interestOnlyRepayments;
            decimal        iPrincipal        = Math.Floor(Calculator.currentHistory.Amount / principalPayments);
            decimal        iFirstPrincipal   = Calculator.currentHistory.Amount - iPrincipal * (principalPayments - 1);
            List <decimal> discounts         = (WorkingModel.Offer != null && WorkingModel.Offer.DiscountPlan != null) ? WorkingModel.Offer.DiscountPlan : null;

            if (discounts != null)
            {
                discounts.ForEach(d => Log.Debug(d));

                int     discountCount = discounts.Count;
                decimal balance       = Calculator.currentHistory.Amount;
                Calculator.schedule = new List <NL_LoanSchedules>();

                // create Schedule
                for (int i = 1; i <= Calculator.currentHistory.RepaymentCount; i++)
                {
                    decimal principal = iPrincipal;

                    if (i <= interestOnlyRepayments)
                    {
                        principal = 0;
                    }
                    else if (i == interestOnlyRepayments + 1)
                    {
                        principal = iFirstPrincipal;
                    }

                    decimal r = Calculator.currentHistory.InterestRate;
                    if (i <= discountCount)
                    {
                        r *= (1 + discounts[i - 1]);
                    }

                    DateTime plannedDate      = Calculator.AddRepaymentIntervals(i - 1, Calculator.currentHistory.RepaymentDate, intervalType).Date;
                    DateTime prevScheduleDate = Calculator.PreviousScheduleDate(plannedDate, intervalType);

                    NL_LoanSchedules item = new NL_LoanSchedules()
                    {
                        InterestRate         = r,
                        PlannedDate          = plannedDate.Date,
                        Principal            = principal,              // intervals' principal
                        LoanScheduleStatusID = (int)NLScheduleStatuses.StillToPay,
                        Position             = i,
                        Balance  = balance,                        //local open principal, scheduled
                        Interest = Calculator.InterestBtwnDates(plannedDate, prevScheduleDate, balance)
                    };

                    balance -= principal;

                    Calculator.schedule.Add(item);

                    Calculator.currentHistory.Schedule.Add(item);
                }                 // for
            }
        }
Exemplo n.º 2
0
        }         // constructor

        /// <exception cref="OverflowException">Condition. </exception>
        public virtual void Execute()
        {
            // not accepted rollover
            if (Calculator.acceptedRollover.Rollover == null)
            {
                Log.Alert("RolloverRescheduling: no accepted rollover");
                return;
            }

            // not accepted rollover
            if (!Calculator.acceptedRollover.Rollover.IsAccepted || !Calculator.acceptedRollover.Rollover.CustomerActionTime.HasValue)
            {
                Log.Alert("RolloverRescheduling: rollover not accepted (paid). {0}", Calculator.acceptedRollover.Rollover);
                return;
            }

            // rollover proceeseed
            if (Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date == Calculator.currentHistory.EventTime.Date || Calculator.acceptedRolloverProcessed)
            {
                Log.Debug("RolloverRescheduling: History ({0}) for rollover {1:d}, rolloverID {2} already exists", Calculator.currentHistory.LoanHistoryID, Calculator.acceptedRollover.Rollover.CustomerActionTime.Value, Calculator.acceptedRollover.Rollover.LoanRolloverID);
                return;
            }

            var rolloverPayment = Calculator.events.FirstOrDefault(p => p.Payment != null && p.Payment.PaymentTime.Date.Equals(Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date) && p.Payment.PaymentDestination.Equals(NLPaymentDestinations.Rollover.ToString()));

            // rollover not paid
            if (rolloverPayment == null)
            {
                Log.Alert("RolloverRescheduling: rollover payment not found. {0}", Calculator.acceptedRollover.Rollover);
                return;
            }

            DateTime acceptionTime = Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date;

            NL_LoanHistory lastHistory = WorkingModel.Loan.LastHistory();

            // 1. create new history
            NL_LoanHistory newHistory = new NL_LoanHistory {
                LoanID                  = lastHistory.LoanID,
                LoanLegalID             = lastHistory.LoanLegalID,
                AgreementModel          = lastHistory.AgreementModel,
                Agreements              = lastHistory.Agreements,
                InterestRate            = lastHistory.InterestRate,
                RepaymentIntervalTypeID = lastHistory.RepaymentIntervalTypeID,
                UserID                  = WorkingModel.CustomerID,
                Description             = "accept rollover",
                Amount                  = Calculator.currentOpenPrincipal,
                EventTime               = acceptionTime
            };

            RepaymentIntervalTypes intervalType = (RepaymentIntervalTypes)lastHistory.RepaymentIntervalTypeID;

            int removedItems = 0;

            newHistory.RepaymentDate = DateTime.MinValue;

            // 2. mark removed schedules + add new schedules
            foreach (NL_LoanSchedules s in Calculator.schedule.Where(s => s.PlannedDate >= acceptionTime))
            {
                s.SetStatusOnRescheduling();
                s.ClosedTime = acceptionTime;

                removedItems++;

                DateTime plannedDate = Calculator.AddRepaymentIntervals(1, s.PlannedDate, intervalType);

                if (newHistory.RepaymentDate.Equals(DateTime.MinValue))
                {
                    newHistory.RepaymentDate = plannedDate;
                }

                // add new schedule instead of removed
                NL_LoanSchedules newSchedule = new NL_LoanSchedules()
                {
                    LoanScheduleID       = 0,
                    LoanScheduleStatusID = (int)NLScheduleStatuses.StillToPay,
                    Position             = s.Position,
                    PlannedDate          = plannedDate,
                    Principal            = s.Principal,          // (s.Principal - s.PrincipalPaid),
                    InterestRate         = s.InterestRate,
                    TwoDaysDueMailSent   = false,                //s.TwoDaysDueMailSent,
                    FiveDaysDueMailSent  = false,                //s.FiveDaysDueMailSent
                };

                Log.Debug("schedule {0} replaced by {1}", s, newSchedule);

                newHistory.Schedule.Add(newSchedule);
            }

            newHistory.RepaymentCount = removedItems;

            WorkingModel.Loan.Histories.Add(newHistory);

            //List<NL_LoanFees> replacedDistributedFees = new List<NL_LoanFees>();

            bool distributedFees = false;

            // 3. mark removed distributed fees + add new distributed fees
            foreach (NL_LoanFees fee in Calculator.distributedFeesList.Where(f => f.AssignTime.Date >= acceptionTime))
            {
                fee.DisabledTime    = acceptionTime;
                fee.Notes           = "disabled on rollover";
                fee.DeletedByUserID = WorkingModel.UserID ?? 1;

                distributedFees = true;

                //NL_LoanFees newFee = new NL_LoanFees() {
                //	LoanFeeID = 0,
                //	Amount = fee.Amount,
                //	AssignTime = Calculator.AddRepaymentIntervals(1, fee.AssignTime, intervalType),
                //	LoanID = WorkingModel.Loan.LoanID,
                //	LoanFeeTypeID = fee.LoanFeeTypeID,
                //	AssignedByUserID = fee.AssignedByUserID,
                //	CreatedTime = acceptionTime,
                //	Notes = fee.Notes
                //};

                //Log.Debug("fee {0} replaced by {1}", fee, newFee);

                //replacedDistributedFees.Add(newFee);
            }

            //Calculator.distributedFeesList.AddRange(replacedDistributedFees);
            //WorkingModel.Loan.Fees.AddRange(replacedDistributedFees);

            if (distributedFees)
            {
                // offer-fees
                NL_OfferFees offerFees = WorkingModel.Offer.OfferFees.FirstOrDefault();

                if (offerFees != null && offerFees.DistributedPartPercent != null && (decimal)offerFees.DistributedPartPercent == 1)
                {
                    var     feeCalculator          = new SetupFeeCalculator(offerFees.Percent, null);
                    decimal servicingFeeAmount     = feeCalculator.Calculate(newHistory.Amount).Total;
                    decimal servicingFeePaidAmount = WorkingModel.Loan.Fees.Where(f => f.LoanFeeTypeID == (int)NLFeeTypes.ServicingFee).Sum(f => f.PaidAmount);

                    Log.Debug("servicingFeeAmount: {0}, servicingFeePaidAmount: {1}", servicingFeeAmount, servicingFeePaidAmount);                     // new "spreaded" amount

                    Calculator.AttachDistributedFeesToLoanBySchedule(WorkingModel, (servicingFeeAmount - servicingFeePaidAmount), acceptionTime);
                }
            }

            // TODO could be reseted at all??????????????
            // reset paid amount for deleted/closed schedules and disabled distributed fees
            foreach (NL_Payments p in WorkingModel.Loan.Payments)
            {
                foreach (NL_LoanSchedulePayments sp in p.SchedulePayments)
                {
                    foreach (NL_LoanSchedules s in Calculator.schedule.Where(s => s.IsDeleted()))
                    {
                        if (s.LoanScheduleID == sp.LoanScheduleID)
                        {
                            sp.ResetInterestPaid  = sp.PrincipalPaid;
                            sp.ResetPrincipalPaid = sp.PrincipalPaid;

                            sp.PrincipalPaid = 0;
                            sp.InterestPaid  = 0;
                        }
                    }
                }

                foreach (NL_LoanFeePayments fp in p.FeePayments)
                {
                    foreach (NL_LoanFees f in Calculator.distributedFeesList.Where(f => f.DisabledTime.Equals(acceptionTime)))
                    {
                        if (f.LoanFeeID == fp.LoanFeeID)
                        {
                            fp.ResetAmount = fp.Amount;
                            fp.Amount      = 0;

                            f.PaidAmount -= (decimal)fp.ResetAmount;
                        }
                    }
                }
            }

            Calculator.acceptedRolloverProcessed = true;
        }