Search in sources :

Example 1 with LoanScheduleDto

use of org.mifos.dto.screen.LoanScheduleDto in project head by mifos.

the class CashFlowSummaryFormBean method validateSummaryOfCashflow.

/**
     * validateXXXX is invoked on transition from state
     */
public void validateSummaryOfCashflow(ValidationContext context) {
    MessageContext messageContext = context.getMessageContext();
    if (this.variableInstallmentsAllowed) {
        prevalidateDueDateIsNonNull(messageContext);
        prevalidateActualPaymentDateIsNonNull(messageContext);
        prevalidateTotalIsNonNull(messageContext);
        prevalidateAmountPaidIsNonNull(messageContext);
        if (!messageContext.hasErrorMessages()) {
            LoanScheduleDto recalculatedLoanSchedule = this.loanAccountController.retrieveLoanSchedule(customerId, productId, loanAccountFormBean, this, false);
            // set values on fields
            this.variableInstallments = recalculatedLoanSchedule.getInstallments();
            int installIndex = 0;
            for (LoanCreationInstallmentDto installment : this.variableInstallments) {
                this.installmentAmounts.set(installIndex, installment.getTotal());
                installIndex++;
            }
        }
        Errors inputInstallmentsErrors = loanAccountServiceFacade.validateInputInstallments(disbursementDate, minGapInDays, maxGapInDays, minInstallmentAmount, variableInstallments, customerId);
        Errors scheduleErrors = loanAccountServiceFacade.validateInstallmentSchedule(variableInstallments, minInstallmentAmount);
        if (inputInstallmentsErrors.hasErrors()) {
            for (ErrorEntry fieldError : inputInstallmentsErrors.getErrorEntries()) {
                addErrorMessageToContext(messageContext, fieldError);
            }
        }
        if (scheduleErrors.hasErrors()) {
            for (ErrorEntry fieldError : scheduleErrors.getErrorEntries()) {
                addErrorMessageToContext(messageContext, fieldError);
            }
        }
    } else {
        prevalidateTotalIsNonNull(messageContext);
        for (int index = 0; index < this.installmentAmounts.size(); index++) {
            Double newTotal = Double.valueOf("0.0");
            Number newTotalEntry = this.installmentAmounts.get(index);
            if (newTotalEntry != null) {
                newTotal = newTotalEntry.doubleValue();
            } else {
                this.installmentAmounts.set(index, newTotal);
            }
        }
    }
    if (!messageContext.hasErrorMessages()) {
        DateTime firstInstallmentDueDate = installments.get(0);
        DateTime lastInstallmentDueDate = installments.get(installments.size() - 1);
        this.loanInstallmentsDto = new LoanInstallmentsDto(this.loanInstallmentsDto.getLoanAmount(), this.loanInstallmentsDto.getTotalInstallmentAmount(), firstInstallmentDueDate.toDate(), lastInstallmentDueDate.toDate());
        Errors warnings = loanAccountServiceFacade.validateCashFlowForInstallmentsForWarnings(cashFlowDataDtos, productId);
        Errors errors = loanAccountServiceFacade.validateCashFlowForInstallments(loanInstallmentsDto, monthlyCashFlows, repaymentCapacity, cashFlowTotalBalance);
        if (warnings.hasErrors()) {
            for (ErrorEntry fieldError : warnings.getErrorEntries()) {
                addErrorMessageToContext(messageContext, fieldError);
            }
        }
        if (errors.hasErrors()) {
            for (ErrorEntry fieldError : errors.getErrorEntries()) {
                addErrorMessageToContext(messageContext, fieldError);
            }
        }
    }
    List<LoanRepaymentTransaction> loanRepaymentTransaction = new ArrayList<LoanRepaymentTransaction>();
    this.loanRepaymentPaidInstallmentsWithRunningBalance = new ArrayList<LoanRepaymentRunningBalance>();
    this.loanRepaymentFutureInstallments = new ArrayList<LoanRepaymentFutureInstallments>();
    // if any actual payment data exists, calculate
    validatePaymentsAndAmounts(messageContext, this.actualPaymentDates, this.actualPaymentAmounts);
    List<LoanInstallmentPostPayment> installmentsPostPayment = new ArrayList<LoanInstallmentPostPayment>();
    int paymentIndex = 0;
    if (!messageContext.hasErrorMessages()) {
        for (Number actualPayment : this.actualPaymentAmounts) {
            BigDecimal remainingPayment = BigDecimal.valueOf(actualPayment.doubleValue());
            LocalDate paymentDate = new LocalDate(this.actualPaymentDates.get(paymentIndex));
            loanRepaymentTransaction.add(new LoanRepaymentTransaction(paymentDate, remainingPayment));
            int installmentIndex = 0;
            while (remainingPayment.doubleValue() > BigDecimal.ZERO.doubleValue() && installmentIndex < this.actualPaymentAmounts.size()) {
                LoanCreationInstallmentDto installmentDetails = this.repaymentInstallments.get(installmentIndex);
                Double installmentTotalAmount = this.installmentAmounts.get(installmentIndex).doubleValue();
                LocalDate dueDate = new LocalDate(this.installments.get(installmentIndex));
                if (installmentsPostPayment.isEmpty() || installmentsPostPayment.size() <= installmentIndex) {
                    BigDecimal feesPaid = BigDecimal.valueOf(installmentDetails.getFees());
                    if (remainingPayment.doubleValue() >= installmentDetails.getFees()) {
                        remainingPayment = remainingPayment.subtract(feesPaid);
                    } else {
                        feesPaid = remainingPayment;
                        remainingPayment = remainingPayment.subtract(feesPaid);
                    }
                    BigDecimal interestPaid = BigDecimal.valueOf(installmentDetails.getInterest());
                    if (remainingPayment.doubleValue() >= installmentDetails.getInterest()) {
                        remainingPayment = remainingPayment.subtract(interestPaid);
                    } else {
                        interestPaid = remainingPayment;
                        remainingPayment = remainingPayment.subtract(interestPaid);
                    }
                    BigDecimal principalPaid = BigDecimal.valueOf(installmentDetails.getPrincipal());
                    if (remainingPayment.doubleValue() >= installmentDetails.getPrincipal()) {
                        remainingPayment = remainingPayment.subtract(principalPaid);
                    } else {
                        principalPaid = remainingPayment;
                        remainingPayment = remainingPayment.subtract(principalPaid);
                    }
                    BigDecimal totalInstallmentPaid = feesPaid.add(interestPaid).add(principalPaid);
                    LoanInstallmentPostPayment loanInstallmentPostPayment = new LoanInstallmentPostPayment(installmentDetails.getInstallmentNumber(), dueDate, paymentDate, feesPaid, interestPaid, principalPaid, totalInstallmentPaid, installmentTotalAmount);
                    installmentsPostPayment.add(loanInstallmentPostPayment);
                } else {
                    LoanInstallmentPostPayment paidInstallment = installmentsPostPayment.get(installmentIndex);
                    if (paidInstallment.isNotFullyPaid()) {
                        BigDecimal feesToBePaid = BigDecimal.valueOf(installmentDetails.getFees()).subtract(paidInstallment.getFeesPaid());
                        if (remainingPayment.doubleValue() >= feesToBePaid.doubleValue()) {
                            remainingPayment = remainingPayment.subtract(feesToBePaid);
                        } else {
                            feesToBePaid = remainingPayment;
                            remainingPayment = remainingPayment.subtract(feesToBePaid);
                        }
                        BigDecimal interestToBePaid = BigDecimal.valueOf(installmentDetails.getInterest()).subtract(paidInstallment.getInterestPaid());
                        if (remainingPayment.doubleValue() >= interestToBePaid.doubleValue()) {
                            remainingPayment = remainingPayment.subtract(interestToBePaid);
                        } else {
                            interestToBePaid = remainingPayment;
                            remainingPayment = remainingPayment.subtract(interestToBePaid);
                        }
                        BigDecimal principalToBePaid = BigDecimal.valueOf(installmentDetails.getPrincipal()).subtract(paidInstallment.getPrincipalPaid());
                        if (remainingPayment.doubleValue() >= principalToBePaid.doubleValue()) {
                            remainingPayment = remainingPayment.subtract(principalToBePaid);
                        } else {
                            principalToBePaid = remainingPayment;
                            remainingPayment = remainingPayment.subtract(principalToBePaid);
                        }
                        BigDecimal totalInstallmentPaid = feesToBePaid.add(interestToBePaid).add(principalToBePaid);
                        paidInstallment.setLastPaymentDate(paymentDate);
                        paidInstallment.setFeesPaid(paidInstallment.getFeesPaid().add(feesToBePaid));
                        paidInstallment.setInterestPaid(paidInstallment.getInterestPaid().add(interestToBePaid));
                        paidInstallment.setPrincipalPaid(paidInstallment.getPrincipalPaid().add(principalToBePaid));
                        paidInstallment.setTotalInstallmentPaid(paidInstallment.getTotalInstallmentPaid().add(totalInstallmentPaid));
                    }
                }
                installmentIndex++;
            }
            paymentIndex++;
        }
    }
    // remaining running balance
    BigDecimal cumulativeFeesPaid = BigDecimal.ZERO;
    BigDecimal cumulativeInterestPaid = BigDecimal.ZERO;
    BigDecimal cumulativePrincipalPaid = BigDecimal.ZERO;
    BigDecimal cumulativeTotalInstallmentPaid = BigDecimal.ZERO;
    for (LoanInstallmentPostPayment installment : installmentsPostPayment) {
        cumulativeFeesPaid = cumulativeFeesPaid.add(installment.getFeesPaid());
        cumulativeInterestPaid = cumulativeInterestPaid.add(installment.getInterestPaid());
        cumulativePrincipalPaid = cumulativePrincipalPaid.add(installment.getPrincipalPaid());
        cumulativeTotalInstallmentPaid = cumulativeTotalInstallmentPaid.add(installment.getTotalInstallmentPaid());
        if (installment.isNotFullyPaid()) {
            BigDecimal remainingFees = this.totalLoanFees.subtract(cumulativeFeesPaid);
            BigDecimal remainingInterest = this.totalLoanInterest.subtract(cumulativeInterestPaid);
            BigDecimal remainingTotalInstallment = this.loanPrincipal.add(this.totalLoanFees).add(this.totalLoanInterest).subtract(cumulativeTotalInstallmentPaid);
            BigDecimal remainingPrincipal = remainingTotalInstallment.subtract(remainingInterest).subtract(remainingFees);
            LoanCreationInstallmentDto installmentDetails = this.repaymentInstallments.get(installment.getInstallmentNumber() - 1);
            LoanCreationInstallmentDto installmentPaidDetails = new LoanCreationInstallmentDto(installment.getInstallmentNumber(), new LocalDate(installmentDetails.getDueDate()), installment.getPrincipalPaid().doubleValue(), installment.getInterestPaid().doubleValue(), installment.getFeesPaid().doubleValue(), BigDecimal.ZERO.doubleValue(), installment.getTotalInstallmentPaid().doubleValue());
            this.loanRepaymentPaidInstallmentsWithRunningBalance.add(new LoanRepaymentRunningBalance(installmentPaidDetails, installment.getTotalInstallmentPaid(), remainingPrincipal, remainingInterest, remainingFees, remainingTotalInstallment, installment.getLastPaymentDate(), this.actualPaymentTypes.get(installment.getInstallmentNumber() - 1)));
            BigDecimal outstandingInstallmentPrincipal = BigDecimal.valueOf(installmentDetails.getPrincipal()).subtract(installment.getPrincipalPaid());
            BigDecimal outstandingInstallmentInterest = BigDecimal.valueOf(installmentDetails.getInterest()).subtract(installment.getInterestPaid());
            BigDecimal outstandingInstallmentFees = BigDecimal.valueOf(installmentDetails.getFees()).subtract(installment.getFeesPaid());
            this.loanRepaymentFutureInstallments.add(new LoanRepaymentFutureInstallments(installmentDetails.getInstallmentNumber(), installmentDetails.getDueDate(), outstandingInstallmentPrincipal, outstandingInstallmentInterest, outstandingInstallmentFees, outstandingInstallmentPrincipal.add(outstandingInstallmentInterest).add(outstandingInstallmentFees)));
        } else {
            BigDecimal remainingFees = this.totalLoanFees.subtract(cumulativeFeesPaid);
            BigDecimal remainingInterest = this.totalLoanInterest.subtract(cumulativeInterestPaid);
            BigDecimal remainingTotalInstallment = this.loanPrincipal.add(this.totalLoanFees).add(this.totalLoanInterest).subtract(cumulativeTotalInstallmentPaid);
            BigDecimal remainingPrincipal = remainingTotalInstallment.subtract(remainingInterest).subtract(remainingFees);
            LoanCreationInstallmentDto installmentDetails = this.repaymentInstallments.get(installment.getInstallmentNumber() - 1);
            this.loanRepaymentPaidInstallmentsWithRunningBalance.add(new LoanRepaymentRunningBalance(installmentDetails, installment.getTotalInstallmentPaid(), remainingPrincipal, remainingInterest, remainingFees, remainingTotalInstallment, installment.getLastPaymentDate(), this.actualPaymentTypes.get(installment.getInstallmentNumber() - 1)));
        }
    }
    int lastHandledFutureInstallmentNumber = loanRepaymentPaidInstallmentsWithRunningBalance.size();
    if (!this.loanRepaymentFutureInstallments.isEmpty()) {
        lastHandledFutureInstallmentNumber = this.loanRepaymentFutureInstallments.get(this.loanRepaymentFutureInstallments.size() - 1).getInstallmentNumber();
    }
    for (LoanCreationInstallmentDto installmentDto : this.repaymentInstallments) {
        if (installmentDto.getInstallmentNumber() > lastHandledFutureInstallmentNumber) {
            this.loanRepaymentFutureInstallments.add(new LoanRepaymentFutureInstallments(installmentDto.getInstallmentNumber(), installmentDto.getDueDate(), BigDecimal.valueOf(installmentDto.getPrincipal()), BigDecimal.valueOf(installmentDto.getInterest()), BigDecimal.valueOf(installmentDto.getFees()), BigDecimal.valueOf(installmentDto.getTotal())));
        }
    }
}
Also used : LoanScheduleDto(org.mifos.dto.screen.LoanScheduleDto) ArrayList(java.util.ArrayList) LoanCreationInstallmentDto(org.mifos.dto.domain.LoanCreationInstallmentDto) LoanInstallmentsDto(org.mifos.dto.screen.LoanInstallmentsDto) ErrorEntry(org.mifos.platform.validations.ErrorEntry) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Errors(org.mifos.platform.validations.Errors) MessageContext(org.springframework.binding.message.MessageContext)

Example 2 with LoanScheduleDto

use of org.mifos.dto.screen.LoanScheduleDto in project head by mifos.

the class GroupLoanAccountController method retrieveLoanSchedule.

public LoanScheduleDto retrieveLoanSchedule(int customerId, int productId, LoanAccountFormBean formBean, LoanScheduleFormBean loanScheduleFormBean, boolean resetRedoLoanAccountDetails) {
    LoanApplicationStateDto applicationState = loanAccountServiceFacade.retrieveLoanApplicationState();
    Integer accountState = applicationState.getConfiguredApplicationId();
    LocalDate disbursementDate = LoanCreationHelper.translateDisbursementDateToLocalDate(formBean);
    RecurringSchedule recurringSchedule = LoanCreationHelper.determineRecurringSchedule(formBean);
    List<CreateAccountFeeDto> accountFees = LoanCreationHelper.translateToAccountFeeDtos(formBean);
    List<CreateAccountFeeDto> additionalAccountFees = LoanCreationHelper.translateToAdditionalAccountFeeDtos(formBean);
    List<CreateAccountPenaltyDto> accountPenalties = LoanCreationHelper.translateToAccountPenaltyDtos(formBean);
    accountFees.addAll(additionalAccountFees);
    Map<String, List<CreateAccountFeeDto>> memberAccountsFees = LoanCreationHelper.translateToMemberAccountsFeeDtos(formBean);
    Map<String, List<CreateAccountFeeDto>> memberAccountsAdditionalFees = LoanCreationHelper.translateToMemberAccountsAdditionalFeeDtos(formBean);
    for (Map.Entry<String, List<CreateAccountFeeDto>> memberAccountEntry : memberAccountsAdditionalFees.entrySet()) {
        memberAccountsFees.get(memberAccountEntry.getKey()).addAll(memberAccountsAdditionalFees.get(memberAccountEntry.getKey()));
    }
    BigDecimal loanAmount = BigDecimal.valueOf(formBean.getAmount().doubleValue());
    BigDecimal minAllowedLoanAmount = BigDecimal.valueOf(formBean.getMinAllowedAmount().doubleValue());
    BigDecimal maxAllowedLoanAmount = BigDecimal.valueOf(formBean.getMaxAllowedAmount().doubleValue());
    CreateLoanAccount loanAccountDetails = prepareLoanAccount(accountState, formBean, disbursementDate, recurringSchedule, accountFees, accountPenalties, loanAmount, minAllowedLoanAmount, maxAllowedLoanAmount);
    List<CreateLoanAccount> memberAccounts = createGroupLoanMembers(accountState, formBean, disbursementDate, recurringSchedule, memberAccountsFees, accountPenalties, loanAmount, minAllowedLoanAmount, maxAllowedLoanAmount);
    BigDecimal totalLoanAmount = BigDecimal.valueOf(formBean.getAmount().doubleValue());
    CreateGroupLoanAccount createGroupLoanAccount = new CreateGroupLoanAccount(memberAccounts, totalLoanAmount, loanAccountDetails);
    GroupLoanScheduleDto groupLoanScheduleDto = groupLoanAccountServiceFacade.getGroupLoanScheduleDto(createGroupLoanAccount, memberAccounts);
    List<String> globalMemberIds = loanControllerHelper.getSelectedMemberGlobalIds(formBean);
    List<Integer> memberIds = loanControllerHelper.getSelectedMemberIdsFromFormBean(formBean);
    List<BigDecimal> memberAmounts = loanControllerHelper.getSelectedMemberAmounts(formBean);
    loanScheduleFormBean.setVariableInstallments(groupLoanScheduleDto.getInstallments());
    for (int i = 0; i < memberIds.size(); ++i) {
        Integer memberId = memberIds.get(i);
        String memberIdString = memberId.toString();
        LoanScheduleFormBean memberScheduleBean = loanScheduleFormBean.getMemberSchedules().get(memberIdString);
        if (memberScheduleBean == null) {
            memberScheduleBean = new LoanScheduleFormBean();
        }
        memberScheduleBean.setGlobalCustomerId(globalMemberIds.get(i));
        loanScheduleFormBean.getMemberSchedules().put(memberIdString, memberScheduleBean);
        LoanScheduleDto memberLoanSchedule = groupLoanScheduleDto.getMemberSchedules().get(memberId);
        loanControllerHelper.populateFormBeanFromDto(memberId, productId, formBean, memberScheduleBean, disbursementDate, memberLoanSchedule, resetRedoLoanAccountDetails);
        memberScheduleBean.setLoanPrincipal(memberAmounts.get(i));
        loanScheduleFormBean.setInstallments(memberScheduleBean.getInstallments());
    }
    loanScheduleFormBean.setActualPaymentAmounts(new ArrayList<Number>());
    return groupLoanScheduleDto;
}
Also used : LoanApplicationStateDto(org.mifos.clientportfolio.newloan.applicationservice.LoanApplicationStateDto) LocalDate(org.joda.time.LocalDate) CreateLoanAccount(org.mifos.clientportfolio.newloan.applicationservice.CreateLoanAccount) CreateAccountPenaltyDto(org.mifos.dto.domain.CreateAccountPenaltyDto) CreateGroupLoanAccount(org.mifos.clientportfolio.newloan.applicationservice.CreateGroupLoanAccount) ArrayList(java.util.ArrayList) List(java.util.List) CreateAccountFeeDto(org.mifos.dto.domain.CreateAccountFeeDto) LoanScheduleDto(org.mifos.dto.screen.LoanScheduleDto) GroupLoanScheduleDto(org.mifos.dto.screen.GroupLoanScheduleDto) BigDecimal(java.math.BigDecimal) RecurringSchedule(org.mifos.clientportfolio.loan.service.RecurringSchedule) HashMap(java.util.HashMap) Map(java.util.Map) GroupLoanScheduleDto(org.mifos.dto.screen.GroupLoanScheduleDto)

Example 3 with LoanScheduleDto

use of org.mifos.dto.screen.LoanScheduleDto in project head by mifos.

the class LoanAccountController method retrieveLoanSchedule.

public LoanScheduleDto retrieveLoanSchedule(int customerId, int productId, LoanAccountFormBean formBean, BackdatedPaymentable loanScheduleFormBean, boolean resetRedoLoanAccountDetails) {
    LocalDate disbursementDate = LoanCreationHelper.translateDisbursementDateToLocalDate(formBean);
    RecurringSchedule recurringSchedule = LoanCreationHelper.determineRecurringSchedule(formBean);
    List<CreateAccountFeeDto> accountFees = LoanCreationHelper.translateToAccountFeeDtos(formBean);
    List<CreateAccountFeeDto> additionalAccountFees = LoanCreationHelper.translateToAdditionalAccountFeeDtos(formBean);
    accountFees.addAll(additionalAccountFees);
    CreateLoanSchedule createLoanAccount = new CreateLoanSchedule(customerId, productId, BigDecimal.valueOf(formBean.getAmount().doubleValue()), formBean.getInterestRate().doubleValue(), disbursementDate, formBean.getNumberOfInstallments().intValue(), formBean.getGraceDuration().intValue(), formBean.isRepaymentScheduleIndependentOfCustomerMeeting(), recurringSchedule, accountFees);
    LoanScheduleDto loanSchedule = null;
    if (formBean.isVariableInstallmentsAllowed() && !loanScheduleFormBean.getInstallments().isEmpty()) {
        loanSchedule = loanAccountServiceFacade.createLoanSchedule(createLoanAccount, loanScheduleFormBean.getInstallments(), loanScheduleFormBean.getInstallmentAmounts());
    } else {
        loanSchedule = loanAccountServiceFacade.createLoanSchedule(createLoanAccount);
    }
    loanControllerHelper.populateFormBeanFromDto(customerId, productId, formBean, loanScheduleFormBean, disbursementDate, loanSchedule, resetRedoLoanAccountDetails);
    return loanSchedule;
}
Also used : RecurringSchedule(org.mifos.clientportfolio.loan.service.RecurringSchedule) CreateLoanSchedule(org.mifos.clientportfolio.loan.service.CreateLoanSchedule) LoanScheduleDto(org.mifos.dto.screen.LoanScheduleDto) CreateAccountFeeDto(org.mifos.dto.domain.CreateAccountFeeDto) LocalDate(org.joda.time.LocalDate)

Example 4 with LoanScheduleDto

use of org.mifos.dto.screen.LoanScheduleDto in project head by mifos.

the class GroupLoanAccountServiceFacadeWebTier method getGroupLoanScheduleDto.

@Override
public GroupLoanScheduleDto getGroupLoanScheduleDto(CreateGroupLoanAccount loanAccountInfo, List<CreateLoanAccount> memberDetails) {
    DateTime creationDate = new DateTime();
    // 0. verify member details for GLIM group accounts
    for (CreateLoanAccount groupMemberAccount : memberDetails) {
        ClientBO member = this.customerDao.findClientById(groupMemberAccount.getCustomerId());
        if (creationDate.isBefore(new DateTime(member.getCreatedDate()))) {
            throw new BusinessRuleException("errors.cannotCreateLoan.because.clientsAreCreatedInFuture");
        }
    }
    // 1. assemble loan details
    MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserContext userContext = toUserContext(user);
    OfficeBO userOffice = this.officeDao.findOfficeById(user.getBranchId());
    PersonnelBO createdBy = this.personnelDao.findPersonnelById(userContext.getId());
    CustomerBO customer = this.customerDao.findCustomerById(loanAccountInfo.getGroupLoanAccountDetails().getCustomerId());
    if (customer.isGroup()) {
        customer = this.customerDao.findGroupBySystemId(customer.getGlobalCustNum());
    }
    // assemble
    LoanAccountDetail loanAccountDetail = assembleLoanAccountDetail(loanAccountInfo);
    List<AccountFeesEntity> accountFeeEntities = assembleAccountFees(loanAccountInfo.getGroupLoanAccountDetails().getAccountFees());
    List<AccountPenaltiesEntity> accountPenaltyEntities = assembleAccountPenalties(loanAccountInfo.getGroupLoanAccountDetails().getAccountPenalties());
    LoanProductOverridenDetail overridenDetail = new LoanProductOverridenDetail(loanAccountDetail.getLoanAmount(), loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), loanAccountInfo.getGroupLoanAccountDetails().getInterestRate(), loanAccountInfo.getGroupLoanAccountDetails().getNumberOfInstallments(), loanAccountInfo.getGroupLoanAccountDetails().getGraceDuration(), accountFeeEntities, accountPenaltyEntities);
    Integer interestDays = Integer.valueOf(AccountingRules.getNumberOfInterestDays().intValue());
    boolean loanScheduleIndependentOfCustomerMeetingEnabled = loanAccountInfo.getGroupLoanAccountDetails().isRepaymentScheduleIndependentOfCustomerMeeting();
    LoanScheduleConfiguration configuration = new LoanScheduleConfiguration(loanScheduleIndependentOfCustomerMeetingEnabled, interestDays);
    MeetingBO repaymentDayMeeting = null;
    if (loanScheduleIndependentOfCustomerMeetingEnabled) {
        repaymentDayMeeting = this.createNewMeetingForRepaymentDay(loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), loanAccountInfo.getGroupLoanAccountDetails(), loanAccountDetail.getCustomer());
    } else {
        MeetingDto customerMeetingDto = customer.getCustomerMeetingValue().toDto();
        repaymentDayMeeting = new MeetingFactory().create(customerMeetingDto);
        Short recurAfter = loanAccountDetail.getLoanProduct().getLoanOfferingMeeting().getMeeting().getRecurAfter();
        repaymentDayMeeting.getMeetingDetails().setRecurAfter(recurAfter);
    }
    List<DateTime> loanScheduleDates = new ArrayList<DateTime>();
    LoanSchedule loanSchedule = assembleLoanSchedule(loanAccountDetail.getCustomer(), loanAccountDetail.getLoanProduct(), overridenDetail, configuration, repaymentDayMeeting, userOffice, loanScheduleDates, loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), new ArrayList<Number>());
    // 2. create loan
    InstallmentRange installmentRange = new MaxMinNoOfInstall(loanAccountInfo.getGroupLoanAccountDetails().getMinAllowedNumberOfInstallments().shortValue(), loanAccountInfo.getGroupLoanAccountDetails().getMaxAllowedNumberOfInstallments().shortValue(), null);
    AmountRange amountRange = new MaxMinLoanAmount(loanAccountInfo.getGroupLoanAccountDetails().getMaxAllowedLoanAmount().doubleValue(), loanAccountInfo.getGroupLoanAccountDetails().getMinAllowedLoanAmount().doubleValue(), null);
    creationDate = loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate().toDateMidnight().toDateTime();
    CreationDetail creationDetail = new CreationDetail(creationDate, Integer.valueOf(user.getUserId()));
    LoanBO loan = LoanBO.openGroupLoanAccount(loanAccountDetail.getLoanProduct(), loanAccountDetail.getCustomer(), repaymentDayMeeting, loanSchedule, loanAccountDetail.getAccountState(), loanAccountDetail.getFund(), overridenDetail, configuration, installmentRange, amountRange, creationDetail, createdBy);
    loan.setBusinessActivityId(loanAccountInfo.getGroupLoanAccountDetails().getLoanPurposeId());
    loan.setExternalId(loanAccountInfo.getGroupLoanAccountDetails().getExternalId());
    loan.setCollateralNote(loanAccountInfo.getGroupLoanAccountDetails().getCollateralNotes());
    loan.setCollateralTypeId(loanAccountInfo.getGroupLoanAccountDetails().getCollateralTypeId());
    loan.markAsCreatedWithBackdatedPayments();
    //set up predefined loan account for importing loans
    if (loanAccountInfo.getGroupLoanAccountDetails().getPredefinedAccountNumber() != null) {
        loan.setGlobalAccountNum(loanAccountInfo.getGroupLoanAccountDetails().getPredefinedAccountNumber());
    }
    // for GLIM loans only
    List<CreateLoanAccount> individualMembersOfGroupLoan = new ArrayList<CreateLoanAccount>();
    List<BigDecimal> radio = new ArrayList<BigDecimal>(loan.getNoOfInstallments());
    List<LoanProductOverridenDetail> memberOverridenDetails = new ArrayList<LoanProductOverridenDetail>();
    List<LoanSchedule> memberLoanSchedules = new ArrayList<LoanSchedule>();
    List<ClientBO> clients = new ArrayList<ClientBO>();
    for (CreateLoanAccount groupMemberAccount : memberDetails) {
        ClientBO member = this.customerDao.findClientById(groupMemberAccount.getCustomerId());
        Money loanAmount = new Money(loanAccountDetail.getLoanProduct().getCurrency(), groupMemberAccount.getLoanAmount());
        List<CreateAccountPenaltyDto> defaultAccountPenalties = new ArrayList<CreateAccountPenaltyDto>();
        radio.add(loanAmount.divide(loan.getLoanAmount()));
        int memberCount = memberDetails.size();
        for (CreateAccountPenaltyDto createAccountPenaltyDto : loanAccountInfo.getGroupLoanAccountDetails().getAccountPenalties()) {
            Integer penaltyId = createAccountPenaltyDto.getPenaltyId();
            String amount = createAccountPenaltyDto.getAmount();
            PenaltyBO penaltyBO = this.penaltyDao.findPenaltyById(penaltyId.shortValue());
            if (penaltyBO instanceof AmountPenaltyBO) {
                amount = String.valueOf(Double.valueOf(createAccountPenaltyDto.getAmount()) / memberCount);
            }
            defaultAccountPenalties.add(new CreateAccountPenaltyDto(penaltyId, amount));
        }
        List<AccountFeesEntity> feeEntities = assembleAccountFees(groupMemberAccount.getAccountFees());
        List<AccountPenaltiesEntity> penaltyEntities = assembleAccountPenalties(defaultAccountPenalties);
        LoanProductOverridenDetail memberOverridenDetail = new LoanProductOverridenDetail(loanAmount, feeEntities, overridenDetail, penaltyEntities);
        LoanSchedule memberSchedule = assembleLoanSchedule(member, loanAccountDetail.getLoanProduct(), memberOverridenDetail, configuration, repaymentDayMeeting, userOffice, new ArrayList<DateTime>(), loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), new ArrayList<Number>());
        memberOverridenDetails.add(memberOverridenDetail);
        memberLoanSchedules.add(memberSchedule);
        clients.add(member);
        individualMembersOfGroupLoan.add(groupMemberAccount);
    }
    //for original schedule persisting
    List<LoanBO> memberLoans = new ArrayList<LoanBO>();
    int index = 0;
    for (CreateLoanAccount groupMemberAccount : individualMembersOfGroupLoan) {
        LoanBO memberLoan = LoanBO.openGroupLoanForAccount(loan, loanAccountDetail.getLoanProduct(), clients.get(index), repaymentDayMeeting, memberLoanSchedules.get(index), memberOverridenDetails.get(index), configuration, installmentRange, amountRange, creationDetail, createdBy, Boolean.TRUE);
        if (groupMemberAccount.getLoanPurposeId() > 0) {
            memberLoan.setBusinessActivityId(groupMemberAccount.getLoanPurposeId());
        }
        memberLoan.markAsCreatedWithBackdatedPayments();
        memberLoans.add(memberLoan);
        index++;
    }
    // update loan schedule for Group Loan Account
    loanSchedule = this.loanScheduleService.generateGroupLoanSchedule(loanAccountDetail.getLoanProduct(), repaymentDayMeeting, loanSchedule, memberLoanSchedules, loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), overridenDetail, configuration, userOffice.getOfficeId(), loanAccountDetail.getCustomer(), accountFeeEntities);
    fixMemberAndParentInstallmentDetails(loan, memberLoans);
    // translate schedules to dto form
    Map<Integer, LoanScheduleEntity> parentScheduleEntities = loan.getLoanScheduleEntityMap();
    List<LoanCreationInstallmentDto> parentInstallments = new ArrayList<LoanCreationInstallmentDto>();
    Map<Integer, List<LoanCreationInstallmentDto>> memberInstallments = new HashMap<Integer, List<LoanCreationInstallmentDto>>();
    for (CreateLoanAccount member : memberDetails) {
        memberInstallments.put(member.getCustomerId(), new ArrayList<LoanCreationInstallmentDto>());
    }
    Short digitsAfterDecimal = AccountingRules.getDigitsAfterDecimal();
    for (Integer installmentId : parentScheduleEntities.keySet()) {
        LoanScheduleEntity loanScheduleEntity = parentScheduleEntities.get(installmentId);
        parentInstallments.add(loanScheduleEntity.toLoanCreationInstallmentDto(digitsAfterDecimal));
        for (LoanBO memberLoan : memberLoans) {
            LoanScheduleEntity memberLoanScheduleEntity = memberLoan.getLoanScheduleEntityMap().get(installmentId);
            memberInstallments.get(memberLoan.getCustomer().getCustomerId()).add(memberLoanScheduleEntity.toLoanCreationInstallmentDto(digitsAfterDecimal));
        }
    }
    GroupLoanScheduleDto groupScheduleDto = new GroupLoanScheduleDto(customer.getDisplayName(), Double.valueOf(loan.getLoanAmount().getAmountDoubleValue()), loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), loan.getGraceType().getValue().intValue(), parentInstallments);
    groupScheduleDto.setMemberSchedules(new HashMap<Integer, LoanScheduleDto>());
    for (LoanBO memberLoan : memberLoans) {
        Integer id = memberLoan.getCustomer().getCustomerId();
        LoanScheduleDto memberScheduleDto = new LoanScheduleDto(memberLoan.getCustomer().getDisplayName(), Double.valueOf(memberLoan.getLoanAmount().getAmountDoubleValue()), loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), loan.getGraceType().getValue().intValue(), memberInstallments.get(id));
        groupScheduleDto.getMemberSchedules().put(id, memberScheduleDto);
    }
    return groupScheduleDto;
}
Also used : HashMap(java.util.HashMap) MeetingBO(org.mifos.application.meeting.business.MeetingBO) ClientBO(org.mifos.customers.client.business.ClientBO) ArrayList(java.util.ArrayList) MeetingFactory(org.mifos.application.meeting.business.MeetingFactory) DateTime(org.joda.time.DateTime) CreateLoanAccount(org.mifos.clientportfolio.newloan.applicationservice.CreateLoanAccount) OfficeBO(org.mifos.customers.office.business.OfficeBO) PersonnelBO(org.mifos.customers.personnel.business.PersonnelBO) ArrayList(java.util.ArrayList) List(java.util.List) AccountFeesEntity(org.mifos.accounts.business.AccountFeesEntity) PenaltyBO(org.mifos.accounts.penalties.business.PenaltyBO) AmountPenaltyBO(org.mifos.accounts.penalties.business.AmountPenaltyBO) LoanSchedule(org.mifos.clientportfolio.newloan.domain.LoanSchedule) LoanBO(org.mifos.accounts.loan.business.LoanBO) LoanScheduleDto(org.mifos.dto.screen.LoanScheduleDto) GroupLoanScheduleDto(org.mifos.dto.screen.GroupLoanScheduleDto) LoanAccountDetail(org.mifos.clientportfolio.newloan.domain.LoanAccountDetail) MaxMinLoanAmount(org.mifos.accounts.loan.business.MaxMinLoanAmount) LoanProductOverridenDetail(org.mifos.clientportfolio.newloan.domain.LoanProductOverridenDetail) LoanScheduleEntity(org.mifos.accounts.loan.business.LoanScheduleEntity) AccountPenaltiesEntity(org.mifos.accounts.business.AccountPenaltiesEntity) LoanScheduleConfiguration(org.mifos.clientportfolio.newloan.domain.LoanScheduleConfiguration) Money(org.mifos.framework.util.helpers.Money) BusinessRuleException(org.mifos.service.BusinessRuleException) CreateAccountPenaltyDto(org.mifos.dto.domain.CreateAccountPenaltyDto) InstallmentRange(org.mifos.accounts.productdefinition.business.InstallmentRange) AmountRange(org.mifos.accounts.productdefinition.business.AmountRange) CustomerBO(org.mifos.customers.business.CustomerBO) UserContext(org.mifos.security.util.UserContext) MifosUser(org.mifos.security.MifosUser) CreationDetail(org.mifos.clientportfolio.newloan.domain.CreationDetail) LoanCreationInstallmentDto(org.mifos.dto.domain.LoanCreationInstallmentDto) BigDecimal(java.math.BigDecimal) MeetingDto(org.mifos.dto.domain.MeetingDto) MaxMinNoOfInstall(org.mifos.accounts.loan.business.MaxMinNoOfInstall) AmountPenaltyBO(org.mifos.accounts.penalties.business.AmountPenaltyBO) GroupLoanScheduleDto(org.mifos.dto.screen.GroupLoanScheduleDto)

Example 5 with LoanScheduleDto

use of org.mifos.dto.screen.LoanScheduleDto in project head by mifos.

the class LoanAccountServiceFacadeWebTier method createLoanSchedule.

@Override
public LoanScheduleDto createLoanSchedule(CreateLoanSchedule createLoanSchedule, List<DateTime> loanScheduleDates, List<Number> totalInstallmentAmounts) {
    MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserContext userContext = toUserContext(user);
    // assemble into domain entities
    LoanOfferingBO loanProduct = this.loanProductDao.findById(createLoanSchedule.getProductId());
    CustomerBO customer = this.customerDao.findCustomerById(createLoanSchedule.getCustomerId());
    Money loanAmountDisbursed = new Money(loanProduct.getCurrency(), createLoanSchedule.getLoanAmount());
    List<AccountFeesEntity> accountFeeEntities = assembleAccountFees(createLoanSchedule.getAccountFeeEntities());
    LoanProductOverridenDetail overridenDetail = new LoanProductOverridenDetail(loanAmountDisbursed, createLoanSchedule.getDisbursementDate(), createLoanSchedule.getInterestRate(), createLoanSchedule.getNumberOfInstallments(), createLoanSchedule.getGraceDuration(), accountFeeEntities, new ArrayList<AccountPenaltiesEntity>());
    Integer interestDays = Integer.valueOf(AccountingRules.getNumberOfInterestDays().intValue());
    boolean loanScheduleIndependentOfCustomerMeetingEnabled = createLoanSchedule.isRepaymentIndependentOfCustomerMeetingSchedule();
    MeetingBO loanMeeting = customer.getCustomerMeetingValue();
    if (loanScheduleIndependentOfCustomerMeetingEnabled) {
        loanMeeting = this.createNewMeetingForRepaymentDay(createLoanSchedule.getDisbursementDate(), createLoanSchedule, customer);
        if (loanProduct.isVariableInstallmentsAllowed()) {
            loanMeeting.setMeetingStartDate(createLoanSchedule.getDisbursementDate().toDateMidnight().toDate());
        }
    }
    LoanScheduleConfiguration configuration = new LoanScheduleConfiguration(loanScheduleIndependentOfCustomerMeetingEnabled, interestDays);
    LoanSchedule loanSchedule = this.loanScheduleService.generate(loanProduct, customer, loanMeeting, overridenDetail, configuration, accountFeeEntities, createLoanSchedule.getDisbursementDate(), loanScheduleDates, totalInstallmentAmounts);
    // translate to DTO form
    List<LoanCreationInstallmentDto> installments = new ArrayList<LoanCreationInstallmentDto>();
    Short digitsAfterDecimal = AccountingRules.getDigitsAfterDecimal();
    for (LoanScheduleEntity loanScheduleEntity : loanSchedule.getRoundedLoanSchedules()) {
        Integer installmentNumber = loanScheduleEntity.getInstallmentId().intValue();
        LocalDate dueDate = new LocalDate(loanScheduleEntity.getActionDate());
        String principal = loanScheduleEntity.getPrincipal().toString(digitsAfterDecimal);
        String interest = loanScheduleEntity.getInterest().toString(digitsAfterDecimal);
        String fees = loanScheduleEntity.getTotalFees().toString(digitsAfterDecimal);
        String penalty = "0.0";
        String total = loanScheduleEntity.getPrincipal().add(loanScheduleEntity.getInterest()).add(loanScheduleEntity.getTotalFees()).toString(digitsAfterDecimal);
        LoanCreationInstallmentDto installment = new LoanCreationInstallmentDto(installmentNumber, dueDate, Double.valueOf(principal), Double.valueOf(interest), Double.valueOf(fees), Double.valueOf(penalty), Double.valueOf(total));
        installments.add(installment);
    }
    return new LoanScheduleDto(customer.getDisplayName(), Double.valueOf(createLoanSchedule.getLoanAmount().doubleValue()), createLoanSchedule.getDisbursementDate(), loanProduct.getGraceType().getValue().intValue(), installments);
}
Also used : LoanScheduleEntity(org.mifos.accounts.loan.business.LoanScheduleEntity) OriginalLoanScheduleEntity(org.mifos.accounts.loan.business.OriginalLoanScheduleEntity) AccountPenaltiesEntity(org.mifos.accounts.business.AccountPenaltiesEntity) CreateLoanSchedule(org.mifos.clientportfolio.loan.service.CreateLoanSchedule) LoanSchedule(org.mifos.clientportfolio.newloan.domain.LoanSchedule) UserContext(org.mifos.security.util.UserContext) MeetingBO(org.mifos.application.meeting.business.MeetingBO) ArrayList(java.util.ArrayList) LoanScheduleDto(org.mifos.dto.screen.LoanScheduleDto) MifosUser(org.mifos.security.MifosUser) LoanCreationInstallmentDto(org.mifos.dto.domain.LoanCreationInstallmentDto) LoanProductOverridenDetail(org.mifos.clientportfolio.newloan.domain.LoanProductOverridenDetail) LocalDate(org.joda.time.LocalDate) LoanScheduleConfiguration(org.mifos.clientportfolio.newloan.domain.LoanScheduleConfiguration) Money(org.mifos.framework.util.helpers.Money) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO) CustomerBO(org.mifos.customers.business.CustomerBO) AccountFeesEntity(org.mifos.accounts.business.AccountFeesEntity)

Aggregations

LoanScheduleDto (org.mifos.dto.screen.LoanScheduleDto)7 ArrayList (java.util.ArrayList)6 LocalDate (org.joda.time.LocalDate)6 LoanCreationInstallmentDto (org.mifos.dto.domain.LoanCreationInstallmentDto)5 BigDecimal (java.math.BigDecimal)4 AccountFeesEntity (org.mifos.accounts.business.AccountFeesEntity)3 AccountPenaltiesEntity (org.mifos.accounts.business.AccountPenaltiesEntity)3 LoanScheduleEntity (org.mifos.accounts.loan.business.LoanScheduleEntity)3 MeetingBO (org.mifos.application.meeting.business.MeetingBO)3 CreateLoanSchedule (org.mifos.clientportfolio.loan.service.CreateLoanSchedule)3 LoanProductOverridenDetail (org.mifos.clientportfolio.newloan.domain.LoanProductOverridenDetail)3 LoanSchedule (org.mifos.clientportfolio.newloan.domain.LoanSchedule)3 LoanScheduleConfiguration (org.mifos.clientportfolio.newloan.domain.LoanScheduleConfiguration)3 CustomerBO (org.mifos.customers.business.CustomerBO)3 Money (org.mifos.framework.util.helpers.Money)3 MifosUser (org.mifos.security.MifosUser)3 UserContext (org.mifos.security.util.UserContext)3 HashMap (java.util.HashMap)2 List (java.util.List)2 DateTime (org.joda.time.DateTime)2