Search in sources :

Example 51 with AccountPaymentEntity

use of org.mifos.accounts.business.AccountPaymentEntity in project head by mifos.

the class EditStatusAction method load.

@TransactionDemarcate(joinToken = true)
public ActionForward load(ActionMapping mapping, ActionForm form, HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
    EditStatusActionForm actionForm = (EditStatusActionForm) form;
    actionForm.setSelectedItems(null);
    actionForm.setNotes(null);
    actionForm.setNewStatusId(null);
    actionForm.setFlagId(null);
    actionForm.setQuestionGroups(null);
    actionForm.setTransactionDate(DateUtils.makeDateAsSentFromBrowser());
    actionForm.setAllowBackDatedApprovals(AccountingRules.isBackDatedApprovalAllowed());
    request.getSession().removeAttribute(Constants.BUSINESS_KEY);
    UserContext userContext = getUserContext(request);
    Integer accountId = Integer.valueOf(actionForm.getAccountId());
    AccountBO accountBO = new AccountBusinessService().getAccount(accountId);
    java.util.Date lastPaymentDate = new java.util.Date(0);
    AccountPaymentEntity lastPayment = accountBO.findMostRecentNonzeroPaymentByPaymentDate();
    if (lastPayment != null) {
        lastPaymentDate = lastPayment.getPaymentDate();
    }
    actionForm.setLastPaymentDate(lastPaymentDate);
    if (accountBO.isLoanAccount() || accountBO.isGroupLoanAccount()) {
        // NOTE - not using dto values at present but available when ui is refactored away from jsp
        AccountStatusDto accountStatuses = this.loanAccountServiceFacade.retrieveAccountStatuses(accountId.longValue());
        LoanBO loanAccount = this.loanDao.findById(accountId);
        EditStatusActionForm editStatusActionForm = (EditStatusActionForm) form;
        editStatusActionForm.setAccountTypeId(AccountTypes.LOAN_ACCOUNT.getValue().toString());
        editStatusActionForm.setCurrentStatusId(loanAccount.getAccountState().getId().toString());
        editStatusActionForm.setGlobalAccountNum(loanAccount.getGlobalAccountNum());
        editStatusActionForm.setAccountName(loanAccount.getLoanOffering().getPrdOfferingName());
        if (loanAccount.isGroupLoanAccount() && loanAccount.getParentAccount() == null) {
            editStatusActionForm.setInput("grouploan");
        } else {
            editStatusActionForm.setInput("loan");
        }
        if (loanAccount.getAccountState().getId().equals(Short.valueOf("2"))) {
            List<AdminDocumentBO> allAdminDocuments = legacyAdminDocumentDao.getAllActiveAdminDocuments();
            List<AdminDocumentBO> loanAdminDocuments = new ArrayList();
            for (AdminDocumentBO adminDocumentBO : allAdminDocuments) {
                List<AdminDocAccStateMixBO> admindoclist = legacyAdminDocAccStateMixDao.getMixByAdminDocuments(adminDocumentBO.getAdmindocId());
                if (!loanAdminDocuments.contains(adminDocumentBO) && admindoclist.size() > 0 && admindoclist.get(0).getAccountStateID().getPrdType().getProductTypeID().equals(loanAccount.getType().getValue().shortValue())) {
                    for (AdminDocAccStateMixBO admindoc : admindoclist) {
                        if (admindoc.getAccountStateID().getId().shortValue() == loanAccount.getAccountState().getId().shortValue()) {
                            loanAdminDocuments.add(adminDocumentBO);
                        }
                    }
                }
            }
            SessionUtils.setCollectionAttribute("editAccountStatusDocumentsList", loanAdminDocuments, request);
        } else {
            SessionUtils.setCollectionAttribute("editAccountStatusDocumentsList", null, request);
        }
    }
    if (accountBO.isSavingsAccount()) {
        // NOTE - not using dto values at present but available when ui is refactored away from jsp
        AccountStatusDto accountStatuses = this.savingsServiceFacade.retrieveAccountStatuses(accountId.longValue());
        SavingsBO savingsAccount = this.savingsDao.findById(accountId.longValue());
        EditStatusActionForm editStatusActionForm = (EditStatusActionForm) form;
        editStatusActionForm.setAccountTypeId(AccountTypes.SAVINGS_ACCOUNT.getValue().toString());
        editStatusActionForm.setCurrentStatusId(savingsAccount.getAccountState().getId().toString());
        editStatusActionForm.setGlobalAccountNum(savingsAccount.getGlobalAccountNum());
        editStatusActionForm.setAccountName(savingsAccount.getSavingsOffering().getPrdOfferingName());
        editStatusActionForm.setInput("savings");
    }
    List<AccountStateEntity> accountStatuses = new AccountBusinessService().getStatusList(accountBO.getAccountState(), accountBO.getType(), userContext.getLocaleId());
    for (AccountStateEntity customerStatusEntity : accountStatuses) {
        for (AccountStateFlagEntity flag : customerStatusEntity.getFlagSet()) {
            String statusMessageText = ApplicationContextProvider.getBean(MessageLookup.class).lookup(flag.getLookUpValue().getPropertiesKey());
            flag.setStatusFlagMessageText(statusMessageText);
        }
    }
    SessionUtils.setAttribute(Constants.BUSINESS_KEY, accountBO, request);
    SessionUtils.setCollectionAttribute(SavingsConstants.STATUS_LIST, accountStatuses, request);
    return mapping.findForward(ActionForwards.load_success.toString());
}
Also used : AccountStatusDto(org.mifos.dto.domain.AccountStatusDto) EditStatusActionForm(org.mifos.accounts.struts.actionforms.EditStatusActionForm) UserContext(org.mifos.security.util.UserContext) Date(java.util.Date) LoanBO(org.mifos.accounts.loan.business.LoanBO) AccountPaymentEntity(org.mifos.accounts.business.AccountPaymentEntity) ArrayList(java.util.ArrayList) SavingsBO(org.mifos.accounts.savings.business.SavingsBO) AdminDocAccStateMixBO(org.mifos.reports.admindocuments.business.AdminDocAccStateMixBO) AccountStateEntity(org.mifos.accounts.business.AccountStateEntity) Date(java.util.Date) AccountBO(org.mifos.accounts.business.AccountBO) AccountBusinessService(org.mifos.accounts.business.service.AccountBusinessService) AccountStateFlagEntity(org.mifos.accounts.business.AccountStateFlagEntity) AdminDocumentBO(org.mifos.reports.admindocuments.business.AdminDocumentBO) MessageLookup(org.mifos.application.master.MessageLookup) TransactionDemarcate(org.mifos.framework.util.helpers.TransactionDemarcate)

Example 52 with AccountPaymentEntity

use of org.mifos.accounts.business.AccountPaymentEntity in project head by mifos.

the class StandardAccountService method handleLoanDisbursal.

public void handleLoanDisbursal(Locale locale, LoanBO loan, PersonnelBO personnelBO, BigDecimal paymentAmount, PaymentTypeDto paymentType, LocalDate receiptLocalDate, LocalDate paymentLocalDate, String receiptId, Short paymentTypeIdForFees, Integer accountForTransferId) throws PersistenceException, AccountException {
    if ("MPESA".equals(paymentType.getName())) {
        paymentAmount = computeWithdrawnForMPESA(paymentAmount, loan);
    }
    PaymentTypeEntity paymentTypeEntity = legacyMasterDao.getPersistentObject(PaymentTypeEntity.class, paymentType.getValue());
    Money amount = new Money(loan.getCurrency(), paymentAmount);
    Date receiptDate = null;
    if (null != receiptLocalDate) {
        receiptDate = receiptLocalDate.toDateMidnight().toDate();
    }
    Date transactionDate = paymentLocalDate.toDateMidnight().toDate();
    AccountPaymentEntity disbursalPayment = new AccountPaymentEntity(loan, amount, receiptId, receiptDate, paymentTypeEntity, transactionDate);
    disbursalPayment.setCreatedByUser(personnelBO);
    Double interestRate = loan.getInterestRate();
    Date oldDisbursementDate = loan.getDisbursementDate();
    List<RepaymentScheduleInstallment> originalInstallments = loan.toRepaymentScheduleDto(locale);
    loan.disburseLoan(disbursalPayment, paymentTypeIdForFees, accountForTransferId);
    if (!loan.isVariableInstallmentsAllowed()) {
        originalInstallments = loan.toRepaymentScheduleDto(locale);
    }
    Date newDisbursementDate = loan.getDisbursementDate();
    boolean variableInstallmentsAllowed = loan.isVariableInstallmentsAllowed();
    loanBusinessService.adjustDatesForVariableInstallments(variableInstallmentsAllowed, loan.isFixedRepaymentSchedule(), originalInstallments, oldDisbursementDate, newDisbursementDate, loan.getOfficeId());
    Date today = new LocalDate().toDateMidnight().toDate();
    Date disburseDay = new LocalDate(oldDisbursementDate).toDateMidnight().toDate();
    if (!today.equals(disburseDay)) {
        loanBusinessService.applyDailyInterestRatesWhereApplicable(new LoanScheduleGenerationDto(newDisbursementDate, loan, variableInstallmentsAllowed, amount, interestRate), originalInstallments);
    }
    loanBusinessService.persistOriginalSchedule(loan);
}
Also used : PaymentTypeEntity(org.mifos.application.master.business.PaymentTypeEntity) Money(org.mifos.framework.util.helpers.Money) RepaymentScheduleInstallment(org.mifos.accounts.loan.util.helpers.RepaymentScheduleInstallment) LoanScheduleGenerationDto(org.mifos.accounts.loan.business.service.LoanScheduleGenerationDto) AccountPaymentEntity(org.mifos.accounts.business.AccountPaymentEntity) LocalDate(org.joda.time.LocalDate) Date(java.util.Date) LocalDate(org.joda.time.LocalDate)

Example 53 with AccountPaymentEntity

use of org.mifos.accounts.business.AccountPaymentEntity in project head by mifos.

the class StandardAccountService method lookupPayments.

@Override
public List<AccountPaymentParametersDto> lookupPayments(AccountReferenceDto accountRef) throws PersistenceException {
    final int accountId = accountRef.getAccountId();
    final AccountBO account = this.legacyAccountDao.getAccount(accountId);
    List<AccountPaymentParametersDto> paymentDtos = new ArrayList<AccountPaymentParametersDto>();
    for (AccountPaymentEntity paymentEntity : account.getAccountPayments()) {
        paymentDtos.add(makePaymentDto(paymentEntity));
    }
    return paymentDtos;
}
Also used : AccountBO(org.mifos.accounts.business.AccountBO) CustomerAccountBO(org.mifos.customers.business.CustomerAccountBO) ArrayList(java.util.ArrayList) AccountPaymentEntity(org.mifos.accounts.business.AccountPaymentEntity) AccountPaymentParametersDto(org.mifos.dto.domain.AccountPaymentParametersDto)

Example 54 with AccountPaymentEntity

use of org.mifos.accounts.business.AccountPaymentEntity in project head by mifos.

the class StandardAccountService method makeImportedPayments.

/**
     * method created for undo transaction import ability MIFOS-5702
     * returns Id of transaction  
     * */
public AccountBO makeImportedPayments(AccountPaymentParametersDto accountPaymentParametersDto, Integer savingsPaymentId) throws PersistenceException, AccountException {
    final int accountId = accountPaymentParametersDto.getAccountId();
    final AccountBO account = this.legacyAccountDao.getAccount(accountId);
    MifosUser mifosUser = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserContext userContext = new UserContextFactory().create(mifosUser);
    try {
        personnelDao.checkAccessPermission(userContext, account.getOfficeId(), account.getCustomer().getLoanOfficerId());
    } catch (AccountException e) {
        throw new MifosRuntimeException(SecurityConstants.KEY_ACTIVITY_NOT_ALLOWED, e);
    }
    monthClosingServiceFacade.validateTransactionDate(accountPaymentParametersDto.getPaymentDate().toDateMidnight().toDate());
    /**
         * Handle member payment if parent payment data not provided.
         * Situation may occur when payment is executed directly on group member account (e.g. from transaction import).
         * Loan Group Member payments should be posted after parent payment.
         */
    if (account.isGroupLoanAccountMember()) {
        AccountPaymentParametersDto parentPaymentParametersDto = this.createParentLoanPaymentData(account, accountPaymentParametersDto);
        return makeImportedPayments(parentPaymentParametersDto, savingsPaymentId);
    }
    PersonnelBO loggedInUser = ApplicationContextProvider.getBean(LegacyPersonnelDao.class).findPersonnelById(accountPaymentParametersDto.getUserMakingPayment().getUserId());
    List<InvalidPaymentReason> validationErrors = validatePayment(accountPaymentParametersDto);
    if (!(account instanceof CustomerAccountBO) && validationErrors.contains(InvalidPaymentReason.INVALID_DATE)) {
        throw new AccountException("errors.invalidTxndate");
    }
    Money overpaymentAmount = null;
    Money amount = new Money(account.getCurrency(), accountPaymentParametersDto.getPaymentAmount());
    if (account instanceof LoanBO && accountPaymentParametersDto.getPaymentOptions().contains(AccountPaymentParametersDto.PaymentOptions.ALLOW_OVERPAYMENTS) && amount.isGreaterThan(((LoanBO) account).getTotalRepayableAmount())) {
        overpaymentAmount = amount.subtract(((LoanBO) account).getTotalRepayableAmount());
        amount = ((LoanBO) account).getTotalRepayableAmount();
    }
    Date receiptDate = null;
    if (accountPaymentParametersDto.getReceiptDate() != null) {
        receiptDate = accountPaymentParametersDto.getReceiptDate().toDateMidnight().toDate();
    }
    PaymentData paymentData = account.createPaymentData(amount, accountPaymentParametersDto.getPaymentDate().toDateMidnight().toDate(), accountPaymentParametersDto.getReceiptId(), receiptDate, accountPaymentParametersDto.getPaymentType().getValue(), loggedInUser);
    if (savingsPaymentId != null) {
        AccountPaymentEntity withdrawal = legacyAccountDao.findPaymentById(savingsPaymentId);
        paymentData.setOtherTransferPayment(withdrawal);
    }
    if (accountPaymentParametersDto.getCustomer() != null) {
        paymentData.setCustomer(customerDao.findCustomerById(accountPaymentParametersDto.getCustomer().getCustomerId()));
    }
    paymentData.setComment(accountPaymentParametersDto.getComment());
    paymentData.setOverpaymentAmount(overpaymentAmount);
    if (accountPaymentParametersDto.getPaymentOptions().contains(PaymentOptions.ALLOW_OVERPAYMENTS)) {
        paymentData.setAllowOverpayment(true);
    }
    AccountPaymentEntity paymentEntity = account.applyPayment(paymentData);
    handleParentGroupLoanPayment(account, accountPaymentParametersDto, savingsPaymentId, paymentEntity);
    this.legacyAccountDao.createOrUpdate(account);
    /*
         * Return null when only overpayment is being apply
         */
    if (amount.isZero() && overpaymentAmount != null && overpaymentAmount.isGreaterThanZero()) {
        return null;
    }
    return account;
}
Also used : CustomerAccountBO(org.mifos.customers.business.CustomerAccountBO) PaymentData(org.mifos.accounts.util.helpers.PaymentData) UserContext(org.mifos.security.util.UserContext) LoanBO(org.mifos.accounts.loan.business.LoanBO) AccountPaymentEntity(org.mifos.accounts.business.AccountPaymentEntity) MifosUser(org.mifos.security.MifosUser) UserContextFactory(org.mifos.accounts.servicefacade.UserContextFactory) LegacyPersonnelDao(org.mifos.customers.personnel.persistence.LegacyPersonnelDao) AccountPaymentParametersDto(org.mifos.dto.domain.AccountPaymentParametersDto) Date(java.util.Date) LocalDate(org.joda.time.LocalDate) AccountBO(org.mifos.accounts.business.AccountBO) CustomerAccountBO(org.mifos.customers.business.CustomerAccountBO) Money(org.mifos.framework.util.helpers.Money) AccountException(org.mifos.accounts.exceptions.AccountException) PersonnelBO(org.mifos.customers.personnel.business.PersonnelBO) MifosRuntimeException(org.mifos.core.MifosRuntimeException)

Example 55 with AccountPaymentEntity

use of org.mifos.accounts.business.AccountPaymentEntity in project head by mifos.

the class GroupLoanAccountServiceFacadeWebTier method createGroupLoanAccount.

private LoanCreationResultDto createGroupLoanAccount(CreateGroupLoanAccount loanAccountInfo, Map<Integer, List<LoanPaymentDto>> backdatedLoanPayments, List<QuestionGroupDetail> questionGroups, LoanAccountCashFlow loanAccountCashFlow, List<DateTime> loanScheduleInstallmentDates, List<Number> totalInstallmentAmounts, List<CreateLoanAccount> memberDetails, boolean isBackdatedLoan) {
    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>(loanScheduleInstallmentDates);
    LoanSchedule loanSchedule = assembleLoanSchedule(loanAccountDetail.getCustomer(), loanAccountDetail.getLoanProduct(), overridenDetail, configuration, repaymentDayMeeting, userOffice, loanScheduleDates, loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate(), totalInstallmentAmounts);
    // 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);
    if (isBackdatedLoan) {
        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());
    if (isBackdatedLoan) {
        loan.markAsCreatedWithBackdatedPayments();
    }
    //set up predefined loan account for importing loans
    if (loanAccountInfo.getGroupLoanAccountDetails().getPredefinedAccountNumber() != null) {
        loan.setGlobalAccountNum(loanAccountInfo.getGroupLoanAccountDetails().getPredefinedAccountNumber());
    }
    try {
        personnelDao.checkAccessPermission(userContext, loan.getOfficeId(), loan.getCustomer().getLoanOfficerId());
    } catch (AccountException e) {
        throw new MifosRuntimeException("Access denied!", e);
    }
    try {
        transactionHelper.startTransaction();
        this.loanDao.save(loan);
        transactionHelper.flushSession();
        //no predefined account number, generate one instead
        if (loanAccountInfo.getGroupLoanAccountDetails().getPredefinedAccountNumber() == null) {
            try {
                loan.setGlobalAccountNum(loan.generateId(userOffice.getGlobalOfficeNum()));
            } catch (AccountException e) {
                throw new BusinessRuleException(e.getMessage());
            }
            this.loanDao.save(loan);
            transactionHelper.flushSession();
        }
        //set up status flag
        AccountStateFlagEntity flagEntity = null;
        if (loanAccountInfo.getGroupLoanAccountDetails().getFlagId() != null) {
            try {
                flagEntity = legacyMasterDao.getPersistentObject(AccountStateFlagEntity.class, loanAccountInfo.getGroupLoanAccountDetails().getFlagId());
                loan.setUserContext(userContext);
                loan.setFlag(flagEntity);
                loan.setClosedDate(new DateTimeService().getCurrentJavaDateTime());
                loan.setUserContext(userContext);
            } catch (PersistenceException e) {
                throw new BusinessRuleException(e.getMessage());
            }
            this.loanDao.save(loan);
            transactionHelper.flushSession();
        }
        // 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());
            }
            if (!backdatedLoanPayments.isEmpty()) {
                memberLoan.markAsCreatedWithBackdatedPayments();
            }
            this.loanDao.save(memberLoan);
            transactionHelper.flushSession();
            try {
                memberLoan.setGlobalAccountNum(memberLoan.generateId(userOffice.getGlobalOfficeNum()));
            } catch (AccountException e) {
                throw new BusinessRuleException(e.getMessage());
            }
            this.loanDao.save(memberLoan);
            transactionHelper.flushSession();
            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);
        for (LoanBO memberLoan : memberLoans) {
            memberLoan.updateLoanSummary();
            loanDao.save(memberLoan);
        }
        this.loanDao.save(loan);
        transactionHelper.flushSession();
        // save question groups
        if (!questionGroups.isEmpty()) {
            Integer eventSourceId = questionnaireServiceFacade.getEventSourceId("Create", "Loan");
            QuestionGroupDetails questionGroupDetails = new QuestionGroupDetails(Integer.valueOf(user.getUserId()).shortValue(), loan.getAccountId(), eventSourceId, questionGroups);
            questionnaireServiceFacade.saveResponses(questionGroupDetails);
            transactionHelper.flushSession();
        }
        if (loanAccountCashFlow != null && !loanAccountCashFlow.getMonthlyCashFlow().isEmpty()) {
            List<MonthlyCashFlowDetail> monthlyCashFlowDetails = new ArrayList<MonthlyCashFlowDetail>();
            for (MonthlyCashFlowDto monthlyCashFlow : loanAccountCashFlow.getMonthlyCashFlow()) {
                MonthlyCashFlowDetail monthlyCashFlowDetail = new MonthlyCashFlowDetail(monthlyCashFlow.getMonthDate(), monthlyCashFlow.getRevenue(), monthlyCashFlow.getExpenses(), monthlyCashFlow.getNotes());
                monthlyCashFlowDetails.add(monthlyCashFlowDetail);
            }
            org.mifos.platform.cashflow.service.CashFlowDetail cashFlowDetail = new org.mifos.platform.cashflow.service.CashFlowDetail(monthlyCashFlowDetails);
            cashFlowDetail.setTotalCapital(loanAccountCashFlow.getTotalCapital());
            cashFlowDetail.setTotalLiability(loanAccountCashFlow.getTotalLiability());
            cashFlowService.save(cashFlowDetail);
            transactionHelper.flushSession();
        }
        if (isBackdatedLoan) {
            // 3. auto approve loan
            String comment = "Automatic Status Update (Redo Loan)";
            LocalDate approvalDate = loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate();
            loan.approve(createdBy, comment, approvalDate);
            for (LoanBO memberLoan : memberLoans) {
                memberLoan.approve(createdBy, comment, approvalDate);
            }
            // 4. disburse loan
            String receiptNumber = null;
            Date receiptDate = null;
            PaymentTypeEntity paymentType = new PaymentTypeEntity(PaymentTypes.CASH.getValue());
            if (loanAccountInfo.getGroupLoanAccountDetails().getDisbursalPaymentTypeId() != null) {
                paymentType = new PaymentTypeEntity(loanAccountInfo.getGroupLoanAccountDetails().getDisbursalPaymentTypeId());
            }
            Date paymentDate = loanAccountInfo.getGroupLoanAccountDetails().getDisbursementDate().toDateMidnight().toDate();
            AccountPaymentEntity disbursalPayment = new AccountPaymentEntity(loan, loan.getLoanAmount(), receiptNumber, receiptDate, paymentType, paymentDate);
            disbursalPayment.setCreatedByUser(createdBy);
            this.loanBusinessService.persistOriginalSchedule(loan);
            for (LoanBO memberLoan : memberLoans) {
                this.loanBusinessService.persistOriginalSchedule(memberLoan);
            }
            // refactoring of loan disbursal
            if (customer.isDisbursalPreventedDueToAnyExistingActiveLoansForTheSameProduct(loan.getLoanOffering())) {
                throw new BusinessRuleException("errors.cannotDisburseLoan.because.otherLoansAreActive");
            }
            try {
                loan.updateCustomer(customer);
                new ProductMixValidator().checkIfProductsOfferingCanCoexist(loan);
            } catch (ServiceException e1) {
                throw new AccountException(e1.getMessage());
            }
            loan.disburse(createdBy, disbursalPayment);
            for (LoanBO memberLoan : memberLoans) {
                memberLoan.disburse(createdBy, disbursalPayment);
            }
            customer.updatePerformanceHistoryOnDisbursement(loan, loan.getLoanAmount());
            // end of refactoring of loan disbural
            this.loanDao.save(loan);
            transactionHelper.flushSession();
            // 5. apply each payment
            for (LoanBO memberLoan : memberLoans) {
                Integer id = memberLoan.getCustomer().getCustomerId();
                List<LoanPaymentDto> payments = backdatedLoanPayments.get(id);
                for (LoanPaymentDto loanPayment : payments) {
                    Money amountPaidToDate = new Money(loan.getCurrency(), loanPayment.getAmount());
                    PaymentData paymentData = new PaymentData(amountPaidToDate, createdBy, loanPayment.getPaymentTypeId(), loanPayment.getPaymentDate().toDateMidnight().toDate());
                    memberLoan.applyPayment(paymentData);
                    loan.applyPayment(paymentData);
                    this.loanDao.save(memberLoan);
                    this.loanDao.save(loan);
                }
            }
        }
        transactionHelper.commitTransaction();
        return new LoanCreationResultDto(false, loan.getAccountId(), loan.getGlobalAccountNum());
    } catch (BusinessRuleException e) {
        this.transactionHelper.rollbackTransaction();
        throw new BusinessRuleException(e.getMessageKey(), e);
    } catch (Exception e) {
        this.transactionHelper.rollbackTransaction();
        throw new MifosRuntimeException(e);
    } finally {
        this.transactionHelper.closeSession();
    }
}
Also used : MonthlyCashFlowDto(org.mifos.dto.domain.MonthlyCashFlowDto) MonthlyCashFlowDetail(org.mifos.platform.cashflow.service.MonthlyCashFlowDetail) 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) LocalDate(org.joda.time.LocalDate) 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) LoanPaymentDto(org.mifos.dto.domain.LoanPaymentDto) AccountFeesEntity(org.mifos.accounts.business.AccountFeesEntity) DateTimeService(org.mifos.framework.util.DateTimeService) PaymentData(org.mifos.accounts.util.helpers.PaymentData) PenaltyBO(org.mifos.accounts.penalties.business.PenaltyBO) AmountPenaltyBO(org.mifos.accounts.penalties.business.AmountPenaltyBO) LoanSchedule(org.mifos.clientportfolio.newloan.domain.LoanSchedule) QuestionGroupDetails(org.mifos.platform.questionnaire.service.QuestionGroupDetails) LoanBO(org.mifos.accounts.loan.business.LoanBO) LoanAccountDetail(org.mifos.clientportfolio.newloan.domain.LoanAccountDetail) MaxMinLoanAmount(org.mifos.accounts.loan.business.MaxMinLoanAmount) LoanProductOverridenDetail(org.mifos.clientportfolio.newloan.domain.LoanProductOverridenDetail) PaymentTypeEntity(org.mifos.application.master.business.PaymentTypeEntity) AccountException(org.mifos.accounts.exceptions.AccountException) ServiceException(org.mifos.framework.exceptions.ServiceException) PersistenceException(org.mifos.framework.exceptions.PersistenceException) AccountPenaltiesEntity(org.mifos.accounts.business.AccountPenaltiesEntity) AccountPaymentEntity(org.mifos.accounts.business.AccountPaymentEntity) LoanScheduleConfiguration(org.mifos.clientportfolio.newloan.domain.LoanScheduleConfiguration) Money(org.mifos.framework.util.helpers.Money) BusinessRuleException(org.mifos.service.BusinessRuleException) AccountStateFlagEntity(org.mifos.accounts.business.AccountStateFlagEntity) 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) BigDecimal(java.math.BigDecimal) MonthlyCashFlowDetail(org.mifos.platform.cashflow.service.MonthlyCashFlowDetail) Date(java.util.Date) LocalDate(org.joda.time.LocalDate) MifosRuntimeException(org.mifos.core.MifosRuntimeException) AccountException(org.mifos.accounts.exceptions.AccountException) BusinessRuleException(org.mifos.service.BusinessRuleException) PersistenceException(org.mifos.framework.exceptions.PersistenceException) ServiceException(org.mifos.framework.exceptions.ServiceException) MeetingException(org.mifos.application.meeting.exceptions.MeetingException) MeetingDto(org.mifos.dto.domain.MeetingDto) ProductMixValidator(org.mifos.accounts.loan.struts.action.validate.ProductMixValidator) MaxMinNoOfInstall(org.mifos.accounts.loan.business.MaxMinNoOfInstall) AmountPenaltyBO(org.mifos.accounts.penalties.business.AmountPenaltyBO) LoanCreationResultDto(org.mifos.dto.screen.LoanCreationResultDto) MifosRuntimeException(org.mifos.core.MifosRuntimeException)

Aggregations

AccountPaymentEntity (org.mifos.accounts.business.AccountPaymentEntity)113 Money (org.mifos.framework.util.helpers.Money)56 Date (java.util.Date)43 LocalDate (org.joda.time.LocalDate)41 Test (org.junit.Test)36 PersonnelBO (org.mifos.customers.personnel.business.PersonnelBO)34 AccountException (org.mifos.accounts.exceptions.AccountException)30 PaymentTypeEntity (org.mifos.application.master.business.PaymentTypeEntity)24 SavingsBO (org.mifos.accounts.savings.business.SavingsBO)23 UserContext (org.mifos.security.util.UserContext)23 ArrayList (java.util.ArrayList)22 AccountTrxnEntity (org.mifos.accounts.business.AccountTrxnEntity)22 MifosRuntimeException (org.mifos.core.MifosRuntimeException)19 PaymentData (org.mifos.accounts.util.helpers.PaymentData)18 CustomerBO (org.mifos.customers.business.CustomerBO)18 AccountBO (org.mifos.accounts.business.AccountBO)16 PersistenceException (org.mifos.framework.exceptions.PersistenceException)16 BigDecimal (java.math.BigDecimal)14 LoanBO (org.mifos.accounts.loan.business.LoanBO)14 Date (java.sql.Date)13