Esempio n. 1
0
        public OCurrency CalculateAmountToRepaySpecifiedInstallment(int pNumber, DateTime pDate,
            bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount, 
            bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment)
        {
            CreditContractOptions cCo =
                new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment,
                    pCancelFees, pManualFeesAmount, pManualCommissionAmount,
                    pDisableInterests, pManualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase);

            CreditContractRepayment cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS);

            return cCr.AmountToRepayInstallment;
        }
Esempio n. 2
0
        private EventStock GenerateRepaymentEvents(CreditContractRepayment cCr, 
                                                   DateTime payDate, 
                                                   OCurrency penaltiesEvent,
                                                   OCurrency commissionsEvent, 
                                                   OCurrency interestEvent, 
                                                   OCurrency interestPrepayment, 
                                                   OCurrency principalEvent,
                                                   int pastDueDays, 
                                                   OPaymentType paymentType, 
                                                   bool isPending, 
                                                   int instNumber,
                                                   OPaymentMethods paymentMethods)
        {
            RepaymentEvent rpEvent;
            EventStock listOfLoanEvents = new EventStock();

            #region Event identification
            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (cCr.PaidIstallments.Count > 0)
            {
                foreach (Installment paidIstallment in cCr.PaidIstallments)
                {
                    int number = paidIstallment.Number;
                    OCurrency rpeCapital = 0;
                    OCurrency rpeInterests = 0;
                    OCurrency rpeCommission = 0;
                    OCurrency rpePenalty = 0;
                    int overdueDays = paidIstallment.ExpectedDate >= payDate ? 0 : pastDueDays;

                    foreach (RepaymentEvent rpe in Events.GetLoanRepaymentEvents())
                    {
                        if (rpe.InstallmentNumber == paidIstallment.Number && !rpe.Deleted)
                        {
                            if (rpe.RepaymentType != OPaymentType.PersonTotalPayment)
                            {
                                rpeCapital += rpe.Principal;
                                rpeInterests += rpe.Interests;
                                rpePenalty += rpe.Penalties;
                            }

                            rpeCommission += rpe.Commissions;
                            if (rpe.RepaymentType == OPaymentType.PersonTotalPayment && cCr.LoanOptions.ManualCommissionAmount != 0)
                                rpeCommission -= rpe.Commissions;
                        }
                    }

                    if (rpeCapital > paidIstallment.PaidCapital)
                        rpeCapital = 0;

                    if (rpeInterests < 0)
                        rpeInterests = 0;

                    if (rpeInterests > paidIstallment.InterestsRepayment)
                    {
                        rpeInterests = 0;
                    }

                    OCurrency principalAmount = paidIstallment.CapitalRepayment -
                                                (paidIstallment.CapitalRepayment - (paidIstallment.PaidCapital - rpeCapital));

                    OCurrency interestAmount = paidIstallment.InterestsRepayment -
                                               (paidIstallment.InterestsRepayment - (paidIstallment.PaidInterests - rpeInterests));

                    principalEvent -= principalAmount;
                    interestEvent -= interestAmount;

                    if (principalAmount == 0 && interestAmount == 0 && paidIstallment.PaidCapital == 0)
                    {
                        principalAmount = principalEvent;
                        interestAmount = interestEvent;
                    }

                    if (interestAmount < 0)
                        interestAmount = 0;

                    OCurrency commissionAmount = paidIstallment.CommissionsUnpaid -
                                               (paidIstallment.CommissionsUnpaid - (paidIstallment.PaidCommissions - rpeCommission));

                    OCurrency penaltyAmount = paidIstallment.FeesUnpaid -
                                               (paidIstallment.FeesUnpaid - (paidIstallment.PaidFees - rpePenalty));
                    //just to be sure that we do not have negative in the base
                    penaltyAmount = penaltyAmount < 0 ? 0 : penaltyAmount;

                    rpEvent = CreateRepaymentEvent(number,
                                                       payDate,
                                                       penaltyAmount,
                                                       commissionAmount,
                                                       interestAmount,
                                                       interestAmount,
                                                       principalAmount,
                                                       overdueDays,
                                                       _clientType == OClientTypes.Group,
                                                       paymentType,
                                                       isPending);
                    rpEvent.PaymentMethod = paymentMethods;
                    listOfLoanEvents.Add(rpEvent);
                }
            }
            else
            {
                rpEvent = CreateRepaymentEvent(instNumber,
                                               payDate,
                                               penaltiesEvent,
                                               commissionsEvent,
                                               interestEvent,
                                               interestPrepayment,
                                               principalEvent,
                                               pastDueDays,
                                               _clientType == OClientTypes.Group,
                                               paymentType,
                                               isPending);
                rpEvent.PaymentMethod = paymentMethods;
                listOfLoanEvents.Add(rpEvent);
            }
            #endregion

            return listOfLoanEvents;
        }
Esempio n. 3
0
        public OCurrency CalculateMaximumAmountForEscapedMember(int pNumber, DateTime pDate,
            bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount,
            bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment, OCurrency pLoanShareAmount)
        {
            var cCo = new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment,
                                                                  pCancelFees, pManualFeesAmount, pManualCommissionAmount,
                                                                  pDisableInterests, pManualInterests,
                                                                  Product.AnticipatedTotalRepaymentPenaltiesBase, Product.IsExotic);

            var cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS);

            return cCr.MaximumAmountForEscapedMember;
        }
Esempio n. 4
0
        /// <summary>
        /// This method manages all the repayment cases implemented in OCTOPUS
        /// </summary>
        /// <param name="pNumber">pNumber of the installment paid</param>
        /// <param name="pDate">pDate of the payment</param>
        /// <param name="pAmountPaid">amount paid by the client which can be lower, equal or greater than the expected amount for an installment</param>
        /// <param name="cancelFees">when true, cancel anticipated payment Commission</param>
        /// <param name="manualFeesAmount">manual amount of commission (when anticipated payment commission are cancelled)</param>
        /// <returns>A RepaymentEvent or null if : 
        /// - repayment amount lower than 0
        /// - repayment amount greater than olb + interestsToPay + commission
        /// - installment already repaid
        /// - bad loan and past due days greater than 180
        /// </returns>
        /// <param name="manualCommissionAmount"></param>
        /// <param name="disableInterests"></param>
        /// <param name="manualInterests"></param>
        /// <param name="keepExpectedInstallment"></param>
        /// <param name="paymentMethod"></param>
        /// <param name="comment"></param>
        /// <param name="pending"></param>
        public RepaymentEvent Repay(int pNumber, DateTime pDate, OCurrency pAmountPaid,
            bool cancelFees, OCurrency manualFeesAmount, OCurrency manualCommissionAmount,
            bool disableInterests, OCurrency manualInterests, bool keepExpectedInstallment,
            OPaymentMethods paymentMethod, string comment, bool pending)
        {
            OCurrency anticipatePayment = CalculateAnticipateInteresAmountForClosure(pDate, OPaymentType.PartialPayment)
                + CalculateTotalNonRepaymentPenalties(pDate);

            if (anticipatePayment >= pAmountPaid || (anticipatePayment == 0 && GetInstallment(pNumber - 1).ExpectedDate <= pDate))
            {
                keepExpectedInstallment = true;
            }

            var cCo = new CreditContractOptions(Product.LoanType,
                                                keepExpectedInstallment,
                                                cancelFees,
                                                manualFeesAmount,
                                                manualCommissionAmount,
                                                disableInterests,
                                                manualInterests,
                                                Product.AnticipatedTotalRepaymentPenaltiesBase,
                                                Product.IsExotic);

            var cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS);

            if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) > 0)
            {
                return null;
            }

            OCurrency principalEvent = 0;
            OCurrency interestEvent = 0;
            OCurrency interestPrepayment = 0;
            OCurrency penaltiesEvent = 0;
            OCurrency commissionsEvent = 0;
            OCurrency manualInterestEvent = cCo.ManualInterestsAmount;

            int pastDueDays = CalculatePastDueSinceLastRepayment(pDate);

            OPaymentType paymentType = OPaymentType.StandardPayment;

            foreach (Installment installment in InstallmentList)
            {
                if (!installment.IsRepaid && installment.Number == pNumber && !keepExpectedInstallment)
                {
                    paymentType = OPaymentType.PartialPayment;
                }
            }

            //we have total repayment for a person
            if(EscapedMember != null)
            {
                paymentType = OPaymentType.PartialPayment;
                keepExpectedInstallment = false;
                cCo.KeepExpectedInstallments = false;
            }

            if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) == 0 && !keepExpectedInstallment)
            {
                paymentType = OPaymentType.TotalPayment;
            }

            cCr.Repay(pAmountPaid, ref penaltiesEvent, ref commissionsEvent, ref interestEvent,
                      ref interestPrepayment, ref principalEvent, ref manualInterestEvent, paymentType);

            //this part of code to correct calculation of principal
            OCurrency principalAmount = principalEvent;
            foreach (RepaymentEvent rPayment in Events.GetRepaymentEvents())
            {
                if (!rPayment.Deleted)
                    principalAmount += rPayment.Principal;

                if (principalAmount > Amount)
                {
                    principalEvent -= Math.Round(principalAmount.Value, 2) - Amount;
                }
            }

            // when we keep initial schedule and total payment
            if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) == 0 && (pNumber != InstallmentList.Count) && AllInstallmentsRepaid)
            {
                paymentType = OPaymentType.TotalPayment;
            }

            //////////////////////////////////////////////////////////////
            RepaymentEvent rPe = CreateRepaymentEvent(pNumber, pDate, penaltiesEvent, commissionsEvent, interestEvent,
                                                      interestPrepayment, principalEvent, pastDueDays,
                                                      _clientType == OClientTypes.Group, paymentType, pending);

            if (AllInstallmentsRepaid && !pending)
            {
                if (ContractStatus != OContractStatus.WrittenOff)
                {
                    _closed = true;
                    ContractStatus = OContractStatus.Closed;
                    CloseDate = pDate;
                }

                // check if Client has other 'active' loans if so, mark him as active client
                if (Project != null)
                    foreach (var loan in Project.Credits)
                        Project.Client.Active = loan.ContractStatus == OContractStatus.Active;
            }

            //Event identification
            Events.Add(GenerateRepaymentEvents(cCr, pDate, penaltiesEvent, commissionsEvent, interestEvent,
                                                   interestPrepayment, principalEvent, pastDueDays, paymentType,
                                                   pending, pNumber, paymentMethod));

            //principal amount correction in case of shit which is taken place when we do big prepayment
            //please remove it when all shity contracts will be closed
            OCurrency paidPrincipal = 0;
            foreach (RepaymentEvent repaymentEvent in Events.GetLoanRepaymentEvents())
            {
                if(repaymentEvent.Deleted == false)
                {
                    paidPrincipal += repaymentEvent.Principal;
                }

                if(paidPrincipal >  Amount)
                {
                    repaymentEvent.Principal += Amount - paidPrincipal;
                }
            }
            //////////////////////////////////////////////////////////////////////////////////////////////

            _installmentList.Sort((x, y) => x.ExpectedDate.CompareTo(y.ExpectedDate));

            foreach (Installment installment in InstallmentList)
            {
                //setup paid date for installments
                if (installment.IsRepaid && installment.Number > pNumber)
                {
                    installment.PaidDate = pDate;
                    installment.PaymentMethod = paymentMethod;
                    installment.Comment = comment;
                    installment.IsPending = pending;
                }
                else if (installment.Number == pNumber)
                {
                    installment.PaidDate = pDate;
                    installment.PaymentMethod = paymentMethod;
                    installment.Comment = comment;
                    installment.IsPending = pending;
                }

                installment.OLB = CalculateExpectedOlb(installment.Number, keepExpectedInstallment);
            }
            EscapedMember = null;
            return rPe;
        }
Esempio n. 5
0
        public OCurrency CalculateMaximumAmountAuthorizedToRepay(int pNumber, DateTime pDate, 
            bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount, 
            bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment, bool pIsForExoticProduct)
        {
            Loan fakeLoan = Copy();
            if (_generalSettings.AccountingProcesses == OAccountingProcesses.Accrual && !pKeepExpectedInstallment)
            {
                fakeLoan.CreateLoanInterestAccruingEvent(pDate);
            }

            CreditContractOptions cCo = new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment,
                pCancelFees, pManualFeesAmount, pManualCommissionAmount,
                pDisableInterests, pManualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase, pIsForExoticProduct);

            CreditContractRepayment cCr = new CreditContractRepayment(fakeLoan, cCo, pDate, pNumber, _user, _generalSettings, _nwdS);

            return cCr.MaximumAmountAuthorizeToRepay;
        }