Search in sources :

Example 41 with LoanOfferingBO

use of org.mifos.accounts.productdefinition.business.LoanOfferingBO in project head by mifos.

the class XlsLoansAccountImporter method parse.

/**
     * Parse input stream.
     * @param is input stream containing loan accounts' data
     * @return object containing successfully parsed rows and rows with errors
     */
public ParsedLoansDto parse(InputStream is) {
    //prepare objects: result, lists for rows
    ParsedLoansDto result = null;
    List<String> errors = new ArrayList<String>();
    //temporary list for new accounts numbers, currently not used
    List<String> newAccountsNumbers = new ArrayList<String>();
    List<ImportedLoanDetail> parsedLoanDetails = new ArrayList<ImportedLoanDetail>();
    // open spreadsheet
    try {
        HSSFWorkbook workbook = new HSSFWorkbook(is);
        HSSFSheet sheet = workbook.getSheetAt(0);
        // check first row of data
        HSSFRow row = sheet.getRow(XlsLoansImportTemplateConstants.FIRST_ROW_WITH_DATA.getValue());
        if (row == null) {
            throw new XlsParsingException(getMessage(XlsMessageConstants.NOT_ENOUGH_INPUT_ROW, null));
        }
        Iterator<Row> iterator = sheet.rowIterator();
        // skip to rows with data
        while (iterator.hasNext() && (iterator.next().getRowNum() < XlsLoansImportTemplateConstants.FIRST_ROW_WITH_DATA.getValue() - 1)) ;
        // parse loan account's data
        while (iterator.hasNext()) {
            row = (HSSFRow) iterator.next();
            List<Object> params = new ArrayList<Object>();
            // setup the first cell
            XlsLoansImportTemplateConstants currentCell = XlsLoansImportTemplateConstants.ACCOUNT_NUMBER;
            try {
                // account number
                String accountNumber = getCellStringValue(row, currentCell);
                // TODO: rewrite this account number validation to more universal and extract method
                if (StringUtils.isBlank(accountNumber) && isEdit) {
                    //editing and account number is missing
                    throw new XlsParsingException(getCellError(XlsMessageConstants.MISSING_ACCOUNT_NUMBER, row, currentCell.getValue(), null));
                } else //TODO: validation if account for edition exists
                if (StringUtils.isBlank(accountNumber) && !isEdit) {
                    //not editing, adding with predefined account number and account number is not good
                    accountNumber = null;
                } else //account number is good for creating new account with predefined account number...
                if (!StringUtils.isBlank(accountNumber) && !isEdit) {
                    //...but it's duplicate
                    if (!validateAccountNumber(accountNumber, newAccountsNumbers)) {
                        params.clear();
                        params.add(accountNumber);
                        throw new XlsParsingException(getCellError(XlsMessageConstants.DUPLICATE_GLOBAL_NUM_ERROR, row, currentCell.getValue(), params));
                    }
                }
                //all good, account is either predefined from xls document or null and will be generated 
                //TODO: extract methods that can be shared between loans and savings
                // customer global id
                currentCell = XlsLoansImportTemplateConstants.CUSTOMER_GLOBAL_ID;
                String customerGlobalId = getCellStringValue(row, currentCell);
                if (customerGlobalId.isEmpty()) {
                    throw new XlsParsingException(getCellError(XlsMessageConstants.CUSTOMER_NOT_BLANK, row, currentCell.getValue(), params));
                }
                CustomerBO customerBO = null;
                customerBO = validateCustomerGlobalId(customerGlobalId);
                if (customerBO == null) {
                    params.clear();
                    params.add(customerGlobalId);
                    throw new XlsParsingException(getCellError(XlsMessageConstants.CUSTOMER_NOT_FOUND, row, currentCell.getValue(), params));
                }
                // product name
                currentCell = XlsLoansImportTemplateConstants.PRODUCT_NAME;
                String productName = getCellStringValue(row, currentCell);
                LoanOfferingBO loanOfferingBO = null;
                loanOfferingBO = validateProductName(productName, customerBO, row, currentCell.getValue());
                //TODO: add support for backdated payments
                LoanCreationLoanDetailsDto lcldd = loanAccountServiceFacade.retrieveLoanDetailsForLoanAccountCreation(customerBO.getCustomerId(), loanOfferingBO.getPrdOfferingId(), false);
                // status name
                currentCell = XlsLoansImportTemplateConstants.STATUS_NAME;
                String statusName = getCellStringValue(row, currentCell);
                XlsLoanSavingsAccountStatesConstants statusConstant = null;
                statusConstant = validateStatusName(statusName, customerBO, this.isEdit, row, currentCell.getValue());
                // status reason flag
                currentCell = XlsLoansImportTemplateConstants.CANCEL_FlAG_REASON;
                String cancelReason = getCellStringValue(row, currentCell);
                XlsLoanSavingsFlagsConstants flagConstant = null;
                flagConstant = validateStatusFlagReason(cancelReason, statusName, AccountTypes.LOAN_ACCOUNT, row, currentCell.getValue());
                // loan amount
                currentCell = XlsLoansImportTemplateConstants.LOAN_AMOUNT;
                BigDecimal loanAmount = getCellDecimalValue(row, currentCell);
                validateAmount(loanAmount, loanOfferingBO, customerBO, lcldd, row, currentCell.getValue());
                // Interest rate
                currentCell = XlsLoansImportTemplateConstants.INTEREST_RATE;
                BigDecimal interestRate = getCellDecimalValue(row, currentCell);
                validateInterestRate(interestRate, loanOfferingBO, customerBO, lcldd, row, currentCell.getValue());
                // number of installments
                currentCell = XlsLoansImportTemplateConstants.NO_OF_INSTALLMENTS;
                Integer numberOfInstallments = getCellIntegerValue(row, currentCell);
                validateNumberOfInstallments(numberOfInstallments, customerBO, loanOfferingBO, lcldd, row, currentCell.getValue());
                // disbursal date
                currentCell = XlsLoansImportTemplateConstants.DISBURLSAL_DATE;
                Date disbursalDate = getCellDateValue(row, currentCell);
                validateDisbursalDate(disbursalDate, customerBO, loanOfferingBO, currentCell.getValue(), row, statusName);
                // grace period
                currentCell = XlsLoansImportTemplateConstants.GRACE_PERIOD;
                Integer gracePeriod = getCellIntegerValue(row, currentCell);
                validateGracePeriod(gracePeriod, loanOfferingBO, customerBO, numberOfInstallments, row, currentCell.getValue());
                // source of founds
                currentCell = XlsLoansImportTemplateConstants.SOURCE_OF_FOUNDS;
                List<FundDto> funds = lcldd.getFundDtos();
                String sourceOfFund = getCellStringValue(row, currentCell);
                Integer sourceOfFundId = null;
                sourceOfFundId = validateSourceOfFund(sourceOfFund, funds, row, currentCell.getValue());
                // purpose
                List<ValueListElement> purposes = lcldd.getLoanPurposes();
                currentCell = XlsLoansImportTemplateConstants.PURPOSE;
                String loanPurpose = getCellStringValue(row, currentCell);
                Integer loanPurposeId = null;
                loanPurposeId = validateLoanPurposeId(loanPurpose, purposes, row, currentCell.getValue());
                // collateral type
                currentCell = XlsLoansImportTemplateConstants.COLLATERAL_TYPE;
                Integer collateralTypeId = null;
                String collateralType = getCellStringValue(row, currentCell);
                Map<String, String> collaterals = lcldd.getCollateralOptions();
                collateralTypeId = validateCollateralType(collateralType, collaterals, row, currentCell.getValue());
                // collateral notes
                currentCell = XlsLoansImportTemplateConstants.COLLATERAL_NOTES;
                String collateralNotes = getCellStringValue(row, currentCell);
                collateralNotes = StringUtils.isBlank(collateralNotes) ? null : collateralNotes;
                // external id
                currentCell = XlsLoansImportTemplateConstants.EXTERNAL_ID;
                String externalId = getCellStringValue(row, currentCell);
                externalId = StringUtils.isBlank(externalId) ? null : externalId;
                //...will be used for editing/adding loans with predefined account numbers
                if (accountNumber != null) {
                    newAccountsNumbers.add(accountNumber);
                }
                //create final objects
                //TODO handle backdated payments
                Short flagValue = flagConstant == null ? null : flagConstant.getFlag().getValue();
                ImportedLoanDetail detail = new ImportedLoanDetail(accountNumber, customerBO.getCustomerId(), loanOfferingBO.getPrdOfferingId(), statusConstant.getState().getValue(), flagValue, loanAmount, interestRate, numberOfInstallments, disbursalDate, gracePeriod, sourceOfFundId, loanPurposeId, collateralTypeId, collateralNotes, externalId);
                parsedLoanDetails.add(detail);
            } catch (XlsParsingException xex) {
                if (xex.isMultiple()) {
                    for (String msg : xex.getMessages()) {
                        errors.add(msg);
                    }
                } else {
                    errors.add(xex.getMessage());
                }
            } catch (Exception cex) {
                errors.add(cex.getMessage());
            }
        }
    } catch (Exception ex) {
        errors.add(ex.getMessage());
    }
    result = new ParsedLoansDto(errors, parsedLoanDetails);
    return result;
}
Also used : ArrayList(java.util.ArrayList) HSSFRow(org.apache.poi.hssf.usermodel.HSSFRow) HSSFRichTextString(org.apache.poi.hssf.usermodel.HSSFRichTextString) CustomerBO(org.mifos.customers.business.CustomerBO) ParsedLoansDto(org.mifos.dto.domain.ParsedLoansDto) ImportedLoanDetail(org.mifos.dto.domain.ImportedLoanDetail) FundDto(org.mifos.accounts.fund.servicefacade.FundDto) HSSFWorkbook(org.apache.poi.hssf.usermodel.HSSFWorkbook) BigDecimal(java.math.BigDecimal) Date(java.util.Date) LocalDate(org.joda.time.LocalDate) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO) HSSFSheet(org.apache.poi.hssf.usermodel.HSSFSheet) HSSFRow(org.apache.poi.hssf.usermodel.HSSFRow) Row(org.apache.poi.ss.usermodel.Row) LoanCreationLoanDetailsDto(org.mifos.dto.screen.LoanCreationLoanDetailsDto) ValueListElement(org.mifos.dto.domain.ValueListElement)

Example 42 with LoanOfferingBO

use of org.mifos.accounts.productdefinition.business.LoanOfferingBO in project head by mifos.

the class IndividualLoanAssembler method assembleFrom.

@Override
public IndividualLoan assembleFrom(IndividualLoanRequest individualLoan) {
    LoanOfferingBO loanProduct = this.loanProductDao.findBySystemId(individualLoan.getLoanProductId().globalIdentity());
    ClientBO client = this.customerDao.findClientBySystemId(individualLoan.getClientId().globalIdentity());
    int occurences = 12;
    DateTime lastScheduledDate = new DateTime();
    ScheduledEvent scheduledEvent = scheduledEventFactory.createScheduledEventFrom(loanProduct.getLoanOfferingMeetingValue());
    List<DateTime> loanScheduleDates = scheduledDateGeneration.generateScheduledDates(occurences, lastScheduledDate, scheduledEvent, false);
    // FIXME - assemble loanAmount from dto
    Money loanAmount = null;
    Double interestRate = Double.valueOf("10.0");
    Integer interestDays = Integer.valueOf(AccountingRules.getNumberOfInterestDays());
    return new IndividualLoanImpl();
}
Also used : IndividualLoanImpl(org.mifos.clientportfolio.newloan.domain.IndividualLoanImpl) ScheduledEvent(org.mifos.schedule.ScheduledEvent) Money(org.mifos.framework.util.helpers.Money) ClientBO(org.mifos.customers.client.business.ClientBO) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO) DateTime(org.joda.time.DateTime)

Example 43 with LoanOfferingBO

use of org.mifos.accounts.productdefinition.business.LoanOfferingBO in project head by mifos.

the class LoanAccountAction method manage.

@TransactionDemarcate(joinToken = true)
public ActionForward manage(final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, @SuppressWarnings("unused") final HttpServletResponse response) throws Exception {
    LoanAccountActionForm loanActionForm = (LoanAccountActionForm) form;
    String globalAccountNum = request.getParameter(GLOBAL_ACCOUNT_NUM);
    CustomerBO customer = getCustomerFromRequest(request);
    if (isGlimEnabled() || isNewGlimEnabled()) {
        populateGlimAttributes(request, loanActionForm, globalAccountNum, customer);
    }
    String recurMonth = customer.getCustomerMeeting().getMeeting().getMeetingDetails().getRecurAfter().toString();
    handleRepaymentsIndependentOfMeetingIfConfigured(request, loanActionForm, recurMonth);
    LoanBO loanBO = new LoanDaoHibernate(new GenericDaoHibernate()).findByGlobalAccountNum(globalAccountNum);
    UserContext userContext = getUserContext(request);
    loanBO.setUserContext(userContext);
    SessionUtils.setAttribute(PROPOSED_DISBURSAL_DATE, loanBO.getDisbursementDate(), request);
    SessionUtils.removeAttribute(LOANOFFERING, request);
    LoanOfferingBO loanOffering = getLoanOffering(loanBO.getLoanOffering().getPrdOfferingId(), userContext.getLocaleId());
    loanActionForm.setInstallmentRange(loanBO.getMaxMinNoOfInstall());
    loanActionForm.setLoanAmountRange(loanBO.getMaxMinLoanAmount());
    MaxMinInterestRate interestRateRange = loanBO.getMaxMinInterestRate();
    loanActionForm.setMaxInterestRate(interestRateRange.getMaxLoanAmount());
    loanActionForm.setMinInterestRate(interestRateRange.getMinLoanAmount());
    loanActionForm.setExternalId(loanBO.getExternalId());
    if (null != loanBO.getFund()) {
        loanActionForm.setLoanOfferingFund(loanBO.getFund().getFundId().toString());
    }
    if (configService.isRepaymentIndepOfMeetingEnabled()) {
        MeetingDetailsEntity meetingDetail = loanBO.getLoanMeeting().getMeetingDetails();
        loanActionForm.setMonthDay("");
        loanActionForm.setMonthWeek("0");
        loanActionForm.setMonthRank("0");
        if (meetingDetail.getRecurrenceTypeEnum() == RecurrenceType.MONTHLY) {
            setMonthlySchedule(loanActionForm, meetingDetail);
        } else {
            setWeeklySchedule(loanActionForm, meetingDetail);
        }
    }
    setSessionAtributeForGLIM(request, loanBO);
    SessionUtils.setAttribute(LOANOFFERING, loanOffering, request);
    // Retrieve and set into the session all collateral types from the
    // lookup_value_locale table associated with the current user context
    // locale
    SessionUtils.setCollectionAttribute(MasterConstants.COLLATERAL_TYPES, legacyMasterDao.getLookUpEntity(MasterConstants.COLLATERAL_TYPES).getCustomValueListElements(), request);
    SessionUtils.setCollectionAttribute(MasterConstants.BUSINESS_ACTIVITIES, legacyMasterDao.findValueListElements(MasterConstants.LOAN_PURPOSES), request);
    SessionUtils.setCollectionAttribute(CUSTOM_FIELDS, new ArrayList<CustomFieldDefinitionEntity>(), request);
    SessionUtils.setAttribute(RECURRENCEID, loanBO.getLoanMeeting().getMeetingDetails().getRecurrenceTypeEnum().getValue(), request);
    SessionUtils.setAttribute(RECURRENCENAME, loanBO.getLoanMeeting().getMeetingDetails().getRecurrenceType().getRecurrenceName(), request);
    SessionUtils.setCollectionAttribute(LOANFUNDS, getFunds(loanOffering), request);
    setRequestAttributesForEditPage(request, loanBO);
    InformationOrderServiceFacade informationOrderServiceFacade = ApplicationContextProvider.getBean(InformationOrderServiceFacade.class);
    SessionUtils.setCollectionAttribute("detailsInformationOrder", informationOrderServiceFacade.getInformationOrder("CreateLoan"), request);
    setFormAttributes(loanBO, form, request);
    return mapping.findForward(ActionForwards.manage_success.toString());
}
Also used : GenericDaoHibernate(org.mifos.accounts.savings.persistence.GenericDaoHibernate) UserContext(org.mifos.security.util.UserContext) LoanBO(org.mifos.accounts.loan.business.LoanBO) MaxMinInterestRate(org.mifos.accounts.loan.business.MaxMinInterestRate) CustomFieldDefinitionEntity(org.mifos.application.master.business.CustomFieldDefinitionEntity) LoanAccountActionForm(org.mifos.accounts.loan.struts.actionforms.LoanAccountActionForm) InformationOrderServiceFacade(org.mifos.platform.questionnaire.service.InformationOrderServiceFacade) LoanDaoHibernate(org.mifos.accounts.loan.persistance.LoanDaoHibernate) MeetingDetailsEntity(org.mifos.application.meeting.business.MeetingDetailsEntity) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO) CustomerBO(org.mifos.customers.business.CustomerBO) TransactionDemarcate(org.mifos.framework.util.helpers.TransactionDemarcate)

Example 44 with LoanOfferingBO

use of org.mifos.accounts.productdefinition.business.LoanOfferingBO in project head by mifos.

the class LoanAccountActionForm method checkValidationForPreviewBefore.

private void checkValidationForPreviewBefore(ActionErrors errors, HttpServletRequest request) throws ApplicationException {
    LoanOfferingBO loanOffering = (LoanOfferingBO) SessionUtils.getAttribute(LoanConstants.LOANOFFERING, request);
    if (!((configService.isNewGlimEnabled() || configService.isGlimEnabled()) && getCustomer(request).isGroup())) {
        checkForMinMax(errors, loanAmount, amountRange, this.getLocalizedMessage("loan.amount"));
    }
    checkForMinMax(errors, interestRate, maxInterestRate, minInterestRate, this.getLocalizedMessage("loan.interestRate"));
    checkForMinMax(errors, noOfInstallments, installmentRange, this.getLocalizedMessage("loan.noOfInstallments"));
    if (StringUtils.isBlank(getDisbursementDate())) {
        addError(errors, "Proposed/Actual disbursal date", "errors.validandmandatory", this.getLocalizedMessage("loan.disbursalDate"));
    }
    // Check for invalid data format
    try {
        DateUtils.getLocaleDate(Locale.ENGLISH, getDisbursementDate());
    } catch (InvalidDateException ide) {
        addError(errors, "Proposed/Actual disbursal date", LoanExceptionConstants.ERROR_INVALID_DISBURSEMENT_DATE_FORMAT, this.getLocalizedMessage("loan.disbursalDate"));
    }
    if (isInterestDedAtDisbValue()) {
        setGracePeriodDuration("0");
    }
    if (((!isInterestDedAtDisbValue()) && StringUtils.isBlank(getGracePeriodDuration())) || (getDoubleValue(getGracePeriodDuration()) != null && getDoubleValue(getNoOfInstallments()) != null && getDoubleValue(getGracePeriodDuration()) >= getDoubleValue(getNoOfInstallments()))) {
        String gracePeriodForRepayments = this.getLocalizedMessage("loan.grace_period");
        String noInst = StringUtils.isBlank(getNoOfInstallments()) ? getStringValue(installmentRange.getMaxNoOfInstall()) : getNoOfInstallments();
        addError(errors, LoanConstants.GRACEPERIODDURATION, LoanConstants.GRACEPERIODERROR, gracePeriodForRepayments, noInst);
    }
}
Also used : InvalidDateException(org.mifos.application.admin.servicefacade.InvalidDateException) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO)

Example 45 with LoanOfferingBO

use of org.mifos.accounts.productdefinition.business.LoanOfferingBO in project head by mifos.

the class LoanBOTestUtils method getLoanAccount.

private LoanBO getLoanAccount(final AccountState state, final Date startDate) {
    MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
    CenterBO center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting);
    GroupBO group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center);
    LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting);
    final int disbursalType = 3;
    return TestObjectFactory.createLoanAccountWithDisbursement("99999999999", group, state, startDate, loanOffering, disbursalType);
}
Also used : MeetingBO(org.mifos.application.meeting.business.MeetingBO) LoanOfferingBO(org.mifos.accounts.productdefinition.business.LoanOfferingBO) CenterBO(org.mifos.customers.center.business.CenterBO) GroupBO(org.mifos.customers.group.business.GroupBO)

Aggregations

LoanOfferingBO (org.mifos.accounts.productdefinition.business.LoanOfferingBO)135 MeetingBO (org.mifos.application.meeting.business.MeetingBO)44 Date (java.util.Date)37 Test (org.junit.Test)37 ArrayList (java.util.ArrayList)26 Date (java.sql.Date)21 LoanBO (org.mifos.accounts.loan.business.LoanBO)18 LocalDate (org.joda.time.LocalDate)17 CustomerBO (org.mifos.customers.business.CustomerBO)12 LoanProductBuilder (org.mifos.domain.builders.LoanProductBuilder)11 UserContext (org.mifos.security.util.UserContext)9 ClientBuilder (org.mifos.domain.builders.ClientBuilder)8 Money (org.mifos.framework.util.helpers.Money)8 MifosUser (org.mifos.security.MifosUser)8 BusinessRuleException (org.mifos.service.BusinessRuleException)8 ProductCategoryBO (org.mifos.accounts.productdefinition.business.ProductCategoryBO)7 MifosRuntimeException (org.mifos.core.MifosRuntimeException)7 BigDecimal (java.math.BigDecimal)6 AccountException (org.mifos.accounts.exceptions.AccountException)6 FeeBO (org.mifos.accounts.fees.business.FeeBO)6