/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.accounts.fees.business.service; import org.mifos.accounts.fees.business.AmountFeeBO; import org.mifos.accounts.fees.business.CategoryTypeEntity; import org.mifos.accounts.fees.business.FeeBO; import org.mifos.accounts.fees.business.FeeFormulaEntity; import org.mifos.accounts.fees.business.FeeFrequencyTypeEntity; import org.mifos.accounts.fees.business.FeePaymentEntity; import org.mifos.accounts.fees.business.FeeStatusEntity; import org.mifos.accounts.fees.business.RateFeeBO; import org.mifos.accounts.fees.exceptions.FeeException; import org.mifos.accounts.fees.persistence.FeeDao; import org.mifos.accounts.fees.servicefacade.FeeCreateRequest; import org.mifos.accounts.fees.util.helpers.FeeChangeType; import org.mifos.accounts.fees.util.helpers.FeeStatus; import org.mifos.accounts.fees.util.helpers.RateAmountFlag; import org.mifos.accounts.financial.business.GLCodeEntity; import org.mifos.accounts.financial.business.service.GeneralLedgerDao; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.meeting.business.MeetingBO; import org.mifos.application.meeting.exceptions.MeetingException; import org.mifos.application.meeting.util.helpers.MeetingType; import org.mifos.application.meeting.util.helpers.RecurrenceType; import org.mifos.config.AccountingRules; import org.mifos.core.MifosRuntimeException; import org.mifos.dto.domain.FeeUpdateRequest; import org.mifos.framework.exceptions.ApplicationException; import org.mifos.framework.hibernate.helper.HibernateTransactionHelper; import org.mifos.framework.util.DateTimeService; import org.mifos.framework.util.helpers.Money; import org.mifos.security.util.UserContext; import org.mifos.service.BusinessRuleException; import org.springframework.beans.factory.annotation.Autowired; public class FeeServiceImpl implements FeeService { private final FeeDao feeDao; private final GeneralLedgerDao generalLedgerDao; private final HibernateTransactionHelper hibernateTransactionHelper; @Autowired public FeeServiceImpl(FeeDao feeDao, GeneralLedgerDao generalLedgerDao, HibernateTransactionHelper hibernateTransactionHelper) { this.feeDao = feeDao; this.generalLedgerDao = generalLedgerDao; this.hibernateTransactionHelper = hibernateTransactionHelper; } @Override public FeeBO create(FeeCreateRequest feeCreateRequest, UserContext userContext) throws ApplicationException { FeeFrequencyTypeEntity feeFrequencyType = this.feeDao.findFeeFrequencyEntityByType(feeCreateRequest.getFeeFrequencyType()); CategoryTypeEntity feeCategoryType = this.feeDao.findFeeCategoryTypeEntityByType(feeCreateRequest.getCategoryType()); GLCodeEntity glCodeEntity = this.generalLedgerDao.findGlCodeById(feeCreateRequest.getGlCode()); FeeBO feeBO = null; if (feeFrequencyType.isOneTime()) { feeBO = createOneTimeFee(feeCreateRequest, feeFrequencyType, feeCategoryType, glCodeEntity, userContext); } else { feeBO = createPeriodicFee(feeCreateRequest, feeFrequencyType, feeCategoryType, glCodeEntity, userContext); } try { hibernateTransactionHelper.startTransaction(); this.feeDao.save(feeBO); hibernateTransactionHelper.commitTransaction(); } catch (Exception e) { hibernateTransactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } finally { hibernateTransactionHelper.closeSession(); } return feeBO; } private FeeBO createPeriodicFee(FeeCreateRequest feeCreateRequest, FeeFrequencyTypeEntity feeFrequencyType, CategoryTypeEntity feeCategoryType, GLCodeEntity glCodeEntity, UserContext userContext) throws FeeException, MeetingException { MeetingBO feeMeeting = feeCreateRequest.getFeeRecurrenceType().equals(RecurrenceType.MONTHLY) ? new MeetingBO(feeCreateRequest.getFeeRecurrenceType(), feeCreateRequest.getMonthRecurAfter(), new DateTimeService() .getCurrentJavaDateTime(), MeetingType.PERIODIC_FEE) : new MeetingBO(feeCreateRequest.getFeeRecurrenceType(), feeCreateRequest.getWeekRecurAfter(), new DateTimeService().getCurrentJavaDateTime(), MeetingType.PERIODIC_FEE); FeeBO feeBO = null; if (feeCreateRequest.isRateFee()) { FeeFormulaEntity feeFormulaEntity = this.feeDao.findFeeFormulaEntityByType(feeCreateRequest.getFeeFormula()); feeBO = new RateFeeBO(userContext, feeCreateRequest.getFeeName(), feeCategoryType, feeFrequencyType, glCodeEntity, feeCreateRequest.getRate(), feeFormulaEntity, feeCreateRequest.isCustomerDefaultFee(), feeMeeting); } else { Money feeMoney = new Money(getCurrency(feeCreateRequest.getCurrencyId()), feeCreateRequest.getAmount()); feeBO = new AmountFeeBO(userContext, feeCreateRequest.getFeeName(), feeCategoryType, feeFrequencyType, glCodeEntity, feeMoney, feeCreateRequest.isCustomerDefaultFee(), feeMeeting); } return feeBO; } private FeeBO createOneTimeFee(FeeCreateRequest feeCreateRequest, FeeFrequencyTypeEntity feeFrequencyType, CategoryTypeEntity feeCategoryType, GLCodeEntity glCodeEntity, UserContext userContext) throws FeeException { FeePaymentEntity feePaymentEntity = this.feeDao.findFeePaymentEntityByType(feeCreateRequest.getFeePaymentType()); FeeBO feeBO = null; if (feeCreateRequest.isRateFee()) { FeeFormulaEntity feeFormulaEntity = this.feeDao.findFeeFormulaEntityByType(feeCreateRequest.getFeeFormula()); feeBO = new RateFeeBO(userContext, feeCreateRequest.getFeeName(), feeCategoryType, feeFrequencyType, glCodeEntity, feeCreateRequest.getRate(), feeFormulaEntity, feeCreateRequest.isCustomerDefaultFee(), feePaymentEntity); } else { Money feeMoney = new Money(getCurrency(feeCreateRequest.getCurrencyId()), feeCreateRequest.getAmount()); feeBO = new AmountFeeBO(userContext, feeCreateRequest.getFeeName(), feeCategoryType, feeFrequencyType, glCodeEntity, feeMoney, feeCreateRequest.isCustomerDefaultFee(), feePaymentEntity); } return feeBO; } private MifosCurrency getCurrency(Short currencyId) { MifosCurrency currency; if (currencyId == null) { // Currency is passed from Form only for Loan (Amount) Fees in multi-currency settings currency = Money.getDefaultCurrency(); } else { currency = AccountingRules.getCurrencyByCurrencyId(currencyId); } return currency; } @Override public void update(FeeUpdateRequest feeUpdateRequest, UserContext userContext) throws ApplicationException { FeeBO feeBo = this.feeDao.findById(feeUpdateRequest.getFeeId()); feeBo.updateDetails(userContext); FeeChangeType feeChangeType; FeeStatus feeStatus = null; if (feeUpdateRequest.getFeeStatusValue() != null) { feeStatus = FeeStatus.getFeeStatus(feeUpdateRequest.getFeeStatusValue()); } FeeStatusEntity feeStatusEntity = new FeeStatusEntity(feeStatus); if (feeBo.getFeeType().equals(RateAmountFlag.AMOUNT)) { AmountFeeBO amountFee = ((AmountFeeBO) feeBo); feeChangeType = amountFee.calculateNewFeeChangeType(new Money(getCurrency(feeUpdateRequest.getCurrencyId()), feeUpdateRequest.getAmount()), feeStatusEntity); amountFee.setFeeAmount(new Money(getCurrency(feeUpdateRequest.getCurrencyId()), feeUpdateRequest.getAmount())); } else { RateFeeBO rateFee = ((RateFeeBO) feeBo); feeChangeType = rateFee.calculateNewFeeChangeType(feeUpdateRequest.getRateValue(), feeStatusEntity); rateFee.setRate(feeUpdateRequest.getRateValue()); } try { hibernateTransactionHelper.startTransaction(); feeBo.updateStatus(feeStatus); feeBo.updateFeeChangeType(feeChangeType); this.feeDao.save(feeBo); hibernateTransactionHelper.commitTransaction(); } catch (ApplicationException e) { hibernateTransactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } catch (Exception e) { hibernateTransactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } finally { hibernateTransactionHelper.closeSession(); } } @Override public void remove(FeeBO fee, boolean isInProducts, boolean isFeeInUsedLoan, boolean remove) { try { hibernateTransactionHelper.startTransaction(); this.feeDao.remove(fee, isInProducts, isFeeInUsedLoan, remove); hibernateTransactionHelper.commitTransaction(); } catch (MifosRuntimeException e) { throw new MifosRuntimeException(e.getMessage()); } catch (Exception e) { hibernateTransactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } finally { hibernateTransactionHelper.closeSession(); } } }