/* * 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.application.servicefacade; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.mifos.accounts.business.AccountBO; import org.mifos.accounts.business.AccountFeesActionDetailEntity; import org.mifos.accounts.business.AccountFeesEntity; import org.mifos.accounts.business.AccountStateMachines; import org.mifos.accounts.business.service.AccountBusinessService; import org.mifos.accounts.exceptions.AccountException; import org.mifos.accounts.fees.business.FeeBO; import org.mifos.accounts.fees.business.FeeDto; import org.mifos.accounts.fees.persistence.FeeDao; import org.mifos.accounts.loan.business.LoanBO; import org.mifos.accounts.loan.persistance.LoanDao; import org.mifos.accounts.savings.business.SavingsBO; import org.mifos.accounts.servicefacade.UserContextFactory; import org.mifos.accounts.util.helpers.AccountTypes; import org.mifos.accounts.util.helpers.WaiveEnum; import org.mifos.application.master.persistence.LegacyMasterDao; import org.mifos.application.meeting.business.MeetingBO; import org.mifos.application.meeting.business.MeetingFactory; import org.mifos.application.meeting.util.helpers.MeetingHelper; import org.mifos.application.util.helpers.EntityType; import org.mifos.config.ClientRules; import org.mifos.core.MifosRuntimeException; import org.mifos.customers.api.CustomerLevel; import org.mifos.customers.business.CustomerAccountBO; import org.mifos.customers.business.CustomerActivityEntity; import org.mifos.customers.business.CustomerBO; import org.mifos.customers.business.CustomerNoteEntity; import org.mifos.customers.business.CustomerPositionEntity; import org.mifos.customers.business.CustomerScheduleEntity; import org.mifos.customers.business.CustomerStatusEntity; import org.mifos.customers.business.PositionEntity; import org.mifos.customers.business.service.CustomerService; import org.mifos.customers.center.business.CenterBO; import org.mifos.customers.client.business.ClientBO; import org.mifos.customers.exceptions.CustomerException; import org.mifos.customers.group.business.GroupBO; import org.mifos.customers.office.business.OfficeBO; import org.mifos.customers.office.persistence.OfficeDao; import org.mifos.customers.persistence.CustomerDao; import org.mifos.customers.personnel.business.PersonnelBO; import org.mifos.customers.personnel.business.PersonnelNotesEntity; import org.mifos.customers.personnel.business.service.PersonnelBusinessService; import org.mifos.customers.personnel.persistence.PersonnelDao; import org.mifos.customers.util.helpers.CustomerStatus; import org.mifos.customers.util.helpers.CustomerStatusFlag; import org.mifos.dto.domain.AccountFeeScheduleDto; import org.mifos.dto.domain.AddressDto; import org.mifos.dto.domain.ApplicableAccountFeeDto; import org.mifos.dto.domain.AuditLogDto; import org.mifos.dto.domain.CenterCreation; import org.mifos.dto.domain.CenterCreationDetail; import org.mifos.dto.domain.CenterDisplayDto; import org.mifos.dto.domain.CenterDto; import org.mifos.dto.domain.CenterInformationDto; import org.mifos.dto.domain.CenterPerformanceHistoryDto; import org.mifos.dto.domain.CenterUpdate; import org.mifos.dto.domain.CreateAccountFeeDto; import org.mifos.dto.domain.CustomFieldDto; import org.mifos.dto.domain.CustomerAccountSummaryDto; import org.mifos.dto.domain.CustomerAddressDto; import org.mifos.dto.domain.CustomerChargesDetailsDto; import org.mifos.dto.domain.CustomerDetailDto; import org.mifos.dto.domain.CustomerDetailsDto; import org.mifos.dto.domain.CustomerDto; import org.mifos.dto.domain.CustomerMeetingDto; import org.mifos.dto.domain.CustomerNoteDto; import org.mifos.dto.domain.CustomerPositionDto; import org.mifos.dto.domain.CustomerPositionOtherDto; import org.mifos.dto.domain.CustomerScheduleDto; import org.mifos.dto.domain.MeetingDto; import org.mifos.dto.domain.PersonnelDto; import org.mifos.dto.domain.SavingsDetailDto; import org.mifos.dto.domain.SurveyDto; import org.mifos.dto.domain.UserDetailDto; import org.mifos.dto.screen.AccountFeesDto; import org.mifos.dto.screen.CenterFormCreationDto; import org.mifos.dto.screen.ClosedAccountDto; import org.mifos.dto.screen.CustomerNoteFormDto; import org.mifos.dto.screen.CustomerRecentActivityDto; import org.mifos.dto.screen.CustomerStatusDetailDto; import org.mifos.dto.screen.ListElement; import org.mifos.dto.screen.TransactionHistoryDto; import org.mifos.framework.business.util.Address; import org.mifos.framework.components.audit.business.service.AuditBusinessService; import org.mifos.framework.components.audit.util.helpers.AuditLogView; import org.mifos.framework.exceptions.ApplicationException; import org.mifos.framework.exceptions.PageExpiredException; import org.mifos.framework.exceptions.ServiceException; import org.mifos.framework.exceptions.StatesInitializationException; import org.mifos.framework.exceptions.SystemException; import org.mifos.framework.hibernate.helper.HibernateTransactionHelper; import org.mifos.framework.hibernate.helper.HibernateTransactionHelperForStaticHibernateUtil; import org.mifos.framework.util.DateTimeService; import org.mifos.framework.util.LocalizationConverter; import org.mifos.framework.util.helpers.Constants; import org.mifos.framework.util.helpers.DateUtils; import org.mifos.framework.util.helpers.Money; import org.mifos.framework.util.helpers.SessionUtils; import org.mifos.security.MifosUser; import org.mifos.security.util.ActivityMapper; import org.mifos.security.util.SecurityConstants; import org.mifos.security.util.UserContext; import org.mifos.service.BusinessRuleException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; public class CenterServiceFacadeWebTier implements CenterServiceFacade { private final OfficeDao officeDao; private final PersonnelDao personnelDao; private final CustomerDao customerDao; private final CustomerService customerService; @Autowired private FeeDao feeDao; @Autowired private LoanDao loanDao; @Autowired private PersonnelBusinessService personnelBusinessService; private HibernateTransactionHelper transactionHelper = new HibernateTransactionHelperForStaticHibernateUtil(); @Autowired LegacyMasterDao legacyMasterDao; @Autowired public CenterServiceFacadeWebTier(CustomerService customerService, OfficeDao officeDao, PersonnelDao personnelDao, CustomerDao customerDao) { this.customerService = customerService; this.officeDao = officeDao; this.personnelDao = personnelDao; this.customerDao = customerDao; } private UserContext toUserContext(MifosUser user) { return new UserContextFactory().create(user); } @Override public CenterFormCreationDto retrieveCenterFormCreationData(CenterCreation centerCreation) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); List<PersonnelDto> activeLoanOfficersForBranch = personnelDao.findActiveLoanOfficersForOffice(centerCreation); List<FeeBO> fees = customerDao.retrieveFeesApplicableToCenters(); CustomerApplicableFeesDto applicableFees = CustomerApplicableFeesDto.toDto(fees, userContext); List<ApplicableAccountFeeDto> applicableDefaultAccountFees = new ArrayList<ApplicableAccountFeeDto>(); for (FeeDto fee : applicableFees.getDefaultFees()) { applicableDefaultAccountFees.add(new ApplicableAccountFeeDto(fee.getFeeIdValue().intValue(), fee.getFeeName(), fee.getAmount(), fee.isRemoved(), fee.isWeekly(), fee.isMonthly(), fee.isPeriodic(), fee.getFeeSchedule())); } List<ApplicableAccountFeeDto> applicableDefaultAdditionalFees = new ArrayList<ApplicableAccountFeeDto>(); for (FeeDto fee : applicableFees.getAdditionalFees()) { applicableDefaultAdditionalFees.add(new ApplicableAccountFeeDto(fee.getFeeIdValue().intValue(), fee.getFeeName(), fee.getAmount(), fee.isRemoved(), fee.isWeekly(), fee.isMonthly(), fee.isPeriodic(), fee.getFeeSchedule())); } return new CenterFormCreationDto(activeLoanOfficersForBranch, applicableDefaultAdditionalFees, applicableDefaultAccountFees); } @Override public CustomerDetailsDto createNewCenter(CenterCreationDetail createCenterDetail, MeetingDto meetingDto) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); OfficeBO userOffice = this.officeDao.findOfficeById(userContext.getBranchId()); userContext.setBranchGlobalNum(userOffice.getGlobalOfficeNum()); String centerName = createCenterDetail.getDisplayName(); String externalId = createCenterDetail.getExternalId(); AddressDto addressDto = createCenterDetail.getAddressDto(); Address centerAddress = new Address(addressDto.getLine1(), addressDto.getLine2(), addressDto.getLine3(), addressDto.getCity(), addressDto.getState(), addressDto.getCountry(), addressDto.getZip(), addressDto.getPhoneNumber()); PersonnelBO loanOfficer = this.personnelDao.findPersonnelById(createCenterDetail.getLoanOfficerId()); OfficeBO centerOffice = this.officeDao.findOfficeById(createCenterDetail.getOfficeId()); List<AccountFeesEntity> feesForCustomerAccount = createAccountFeeEntities(createCenterDetail.getFeesToApply()); DateTime mfiJoiningDate = null; if (createCenterDetail.getMfiJoiningDate() != null) { mfiJoiningDate = createCenterDetail.getMfiJoiningDate().toDateMidnight().toDateTime(); } MeetingBO meeting = new MeetingFactory().create(meetingDto); meeting.setUserContext(userContext); CenterBO center = CenterBO.createNew(userContext, centerName, mfiJoiningDate, meeting, loanOfficer, centerOffice, centerAddress, externalId, new DateMidnight().toDateTime()); try { personnelDao.checkAccessPermission(userContext, center.getOfficeId(), center.getLoanOfficerId()); } catch (AccountException e) { throw new MifosRuntimeException("Access denied!", e); } this.customerService.createCenter(center, meeting, feesForCustomerAccount); return new CustomerDetailsDto(center.getCustomerId(), center.getGlobalCustNum()); } private List<AccountFeesEntity> createAccountFeeEntities(List<CreateAccountFeeDto> feesToApply) { List<AccountFeesEntity> feesForCustomerAccount = new ArrayList<AccountFeesEntity>(); for (CreateAccountFeeDto feeDto : feesToApply) { FeeBO fee = feeDao.findById(feeDto.getFeeId().shortValue()); Double feeAmount = new LocalizationConverter().getDoubleValueForCurrentLocale(feeDto.getAmount()); AccountBO nullReferenceForNow = null; AccountFeesEntity accountFee = new AccountFeesEntity(nullReferenceForNow, fee, feeAmount); feesForCustomerAccount.add(accountFee); } return feesForCustomerAccount; } @Override public CenterDto retrieveCenterDetailsForUpdate(Integer centerId) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); CustomerBO center = customerDao.findCustomerById(centerId); Short officeId = center.getOffice().getOfficeId(); String searchId = center.getSearchId(); Short loanOfficerId = extractLoanOfficerId(center); CenterCreation centerCreation = new CenterCreation(officeId, userContext.getId(), userContext.getLevelId(), userContext.getPreferredLocale()); List<PersonnelDto> activeLoanOfficersForBranch = personnelDao.findActiveLoanOfficersForOffice(centerCreation); List<CustomerDto> customerList = customerDao.findClientsThatAreNotCancelledOrClosed(searchId, officeId); List<CustomerPositionDto> customerPositionDtos = generateCustomerPositionViews(center, userContext .getLocaleId()); DateTime mfiJoiningDate = new DateTime(); String mfiJoiningDateAsString = ""; if (center.getMfiJoiningDate() != null) { mfiJoiningDate = new DateTime(center.getMfiJoiningDate()); mfiJoiningDateAsString = DateUtils.getUserLocaleDate(userContext.getPreferredLocale(), center .getMfiJoiningDate().toString()); } AddressDto address = null; if (center.getAddress() != null) { address = Address.toDto(center.getAddress()); } return new CenterDto(loanOfficerId, center.getCustomerId(), center.getGlobalCustNum(), mfiJoiningDate, mfiJoiningDateAsString, center.getExternalId(), address, customerPositionDtos, customerList, activeLoanOfficersForBranch, true); } private Short extractLoanOfficerId(CustomerBO customer) { Short loanOfficerId = null; PersonnelBO loanOfficer = customer.getPersonnel(); if (loanOfficer != null) { loanOfficerId = loanOfficer.getPersonnelId(); } return loanOfficerId; } private List<CustomerPositionDto> generateCustomerPositionViews(CustomerBO customer, Short localeId) { List<PositionEntity> customerPositions = new ArrayList<PositionEntity>(); List<PositionEntity> allCustomerPositions = legacyMasterDao.findMasterDataEntitiesWithLocale(PositionEntity.class); if (!ClientRules.getCenterHierarchyExists()) { customerPositions = populateWithNonCenterRelatedPositions(allCustomerPositions); } else { customerPositions.addAll(allCustomerPositions); } List<CustomerPositionDto> customerPositionDtos = new ArrayList<CustomerPositionDto>(); generatePositionsFromExistingCustomerPositions(customer, customerPositions, customerPositionDtos); if (customerPositionDtos.isEmpty()) { generateNewListOfPositions(customer, customerPositions, customerPositionDtos); } return customerPositionDtos; } private List<PositionEntity> populateWithNonCenterRelatedPositions(List<PositionEntity> allCustomerPositions) { List<PositionEntity> nonCenterRelatedPositions = new ArrayList<PositionEntity>(); for (PositionEntity positionEntity : allCustomerPositions) { if (!(positionEntity.getId().equals(Short.valueOf("1")) || positionEntity.getId() .equals(Short.valueOf("2")))) { nonCenterRelatedPositions.add(positionEntity); } } return nonCenterRelatedPositions; } private void generatePositionsFromExistingCustomerPositions(CustomerBO customer, List<PositionEntity> customerPositions, List<CustomerPositionDto> customerPositionDtos) { for (PositionEntity position : customerPositions) { for (CustomerPositionEntity entity : customer.getCustomerPositions()) { if (position.getId().equals(entity.getPosition().getId())) { CustomerPositionDto customerPosition; if (entity.getCustomer() != null) { customerPosition = new CustomerPositionDto(entity.getCustomer().getCustomerId(), entity .getPosition().getId(), entity.getPosition().getName()); } else { customerPosition = new CustomerPositionDto(customer.getCustomerId(), entity.getPosition() .getId(), entity.getPosition().getName()); } customerPositionDtos.add(customerPosition); } } } } private void generateNewListOfPositions(CustomerBO customer, List<PositionEntity> customerPositions, List<CustomerPositionDto> customerPositionDtos) { for (PositionEntity position : customerPositions) { CustomerPositionDto customerPosition = new CustomerPositionDto(customer.getCustomerId(), position.getId(), position.getName()); customerPositionDtos.add(customerPosition); } } @Override public void updateCenter(CenterUpdate centerUpdate) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { customerService.updateCenter(userContext, centerUpdate); } catch (ApplicationException e) { throw new BusinessRuleException(e.getKey(), e); } } @Override public CenterInformationDto getCenterInformationDto(String globalCustNum) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); CenterBO center = customerDao.findCenterBySystemId(globalCustNum); if (center == null) { throw new MifosRuntimeException("Center not found for globalCustNum" + globalCustNum); } try { personnelDao.checkAccessPermission(userContext, center.getOfficeId(), center.getLoanOfficerId()); } catch (AccountException e) { throw new MifosRuntimeException("Access denied!", e); } CenterDisplayDto centerDisplay = customerDao.getCenterDisplayDto(center.getCustomerId(), userContext); Integer centerId = center.getCustomerId(); String searchId = center.getSearchId(); Short branchId = centerDisplay.getBranchId(); CustomerAccountSummaryDto customerAccountSummary = customerDao.getCustomerAccountSummaryDto(centerId); CenterPerformanceHistoryDto centerPerformanceHistory = customerDao.getCenterPerformanceHistory(searchId, branchId); CustomerAddressDto centerAddress = customerDao.getCustomerAddressDto(center); List<CustomerDetailDto> groups = customerDao.getGroupsOtherThanClosedAndCancelledForGroup(searchId, branchId); List<CustomerNoteDto> recentCustomerNotes = customerDao.getRecentCustomerNoteDto(centerId); List<CustomerPositionOtherDto> customerPositions = customerDao.getCustomerPositionDto(centerId, userContext); List<SavingsDetailDto> savingsDetail = customerDao.getSavingsDetailDto(centerId, userContext); CustomerMeetingDto customerMeeting = customerDao.getCustomerMeetingDto(center.getCustomerMeeting(), userContext); List<AccountBO> allClosedLoanAndSavingsAccounts = customerDao.retrieveAllClosedLoanAndSavingsAccounts(centerId); List<SavingsDetailDto> closedSavingsAccounts = new ArrayList<SavingsDetailDto>(); for (AccountBO closedAccount : allClosedLoanAndSavingsAccounts){ if ( closedAccount.getAccountType().getAccountTypeId() == AccountTypes.SAVINGS_ACCOUNT.getValue().intValue()){ closedSavingsAccounts.add(new SavingsDetailDto(closedAccount.getGlobalAccountNum(), ((SavingsBO)closedAccount).getSavingsOffering().getPrdOfferingName(), closedAccount.getAccountState().getId(), closedAccount.getAccountState().getName(), ((SavingsBO)closedAccount).getSavingsBalance().toString())); } } Boolean activeSurveys = Boolean.FALSE;//new SurveysPersistence().isActiveSurveysForSurveyType(SurveyType.CENTER); List<SurveyDto> customerSurveys = new ArrayList<SurveyDto>(); List<CustomFieldDto> customFields = new ArrayList<CustomFieldDto>(); return new CenterInformationDto(centerDisplay, customerAccountSummary, centerPerformanceHistory, centerAddress, groups, recentCustomerNotes, customerPositions, savingsDetail, customerMeeting, activeSurveys, customerSurveys, customFields, closedSavingsAccounts); } @Override public void updateCustomerStatus(Integer customerId, Integer previousCustomerVersionNo, String flagIdAsString, String newStatusIdAsString, String notes) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); Short flagId = null; Short newStatusId = null; if (StringUtils.isNotBlank(flagIdAsString)) { flagId = Short.valueOf(flagIdAsString); } if (StringUtils.isNotBlank(newStatusIdAsString)) { newStatusId = Short.valueOf(newStatusIdAsString); } CustomerStatusFlag customerStatusFlag = null; if (flagId != null) { customerStatusFlag = CustomerStatusFlag.fromInt(flagId); } CustomerStatus newStatus = CustomerStatus.fromInt(newStatusId); CustomerStatusUpdate customerStatusUpdate = new CustomerStatusUpdate(customerId, previousCustomerVersionNo, customerStatusFlag, newStatus, notes); try { this.customerService.updateCustomerStatus(userContext, customerStatusUpdate); } catch (CustomerException e) { throw new BusinessRuleException(e.getKey(), e); } } @Override public void initializeCenterStates(String centerGlobalNum) { CenterBO center = this.customerDao.findCenterBySystemId(centerGlobalNum); try { List<ListElement> savingsStatesList = new ArrayList<ListElement>(); AccountStateMachines.getInstance().initializeCenterStates(); List<CustomerStatusEntity> statusList = AccountStateMachines.getInstance().getCenterStatusList(center.getCustomerStatus()); for (CustomerStatusEntity customerState : statusList) { savingsStatesList.add(new ListElement(customerState.getId().intValue(), customerState.getName())); } } catch (StatesInitializationException e) { throw new MifosRuntimeException(e); } } @Override public void initializeGroupStates(String groupGlobalNum) { GroupBO group = this.customerDao.findGroupBySystemId(groupGlobalNum); try { List<ListElement> savingsStatesList = new ArrayList<ListElement>(); AccountStateMachines.getInstance().initializeGroupStates(); List<CustomerStatusEntity> statusList = AccountStateMachines.getInstance().getGroupStatusList(group.getCustomerStatus()); for (CustomerStatusEntity customerState : statusList) { savingsStatesList.add(new ListElement(customerState.getId().intValue(), customerState.getName())); } } catch (StatesInitializationException e) { throw new MifosRuntimeException(e); } } @Override public void initializeClientStates(String clientGlobalNum) { ClientBO client = this.customerDao.findClientBySystemId(clientGlobalNum); try { List<ListElement> savingsStatesList = new ArrayList<ListElement>(); AccountStateMachines.getInstance().initializeClientStates(); List<CustomerStatusEntity> statusList = AccountStateMachines.getInstance().getClientStatusList(client.getCustomerStatus()); for (CustomerStatusEntity customerState : statusList) { savingsStatesList.add(new ListElement(customerState.getId().intValue(), customerState.getName())); } } catch (StatesInitializationException e) { throw new MifosRuntimeException(e); } } @Override public CustomerStatusDetailDto retrieveCustomerStatusDetails(Short newStatusId, Short flagIdValue, Short customerLevelId) { CustomerLevel customerLevel = CustomerLevel.getLevel(customerLevelId); CustomerStatus customerStatus = CustomerStatus.fromInt(newStatusId); CustomerStatusFlag statusFlag = null; if (customerStatus.isCustomerCancelledOrClosed()) { statusFlag = CustomerStatusFlag.getStatusFlag(flagIdValue); } String statusName = AccountStateMachines.getInstance().getCustomerStatusName(customerStatus, customerLevel); String flagName = AccountStateMachines.getInstance().getCustomerFlagName(statusFlag, customerLevel); return new CustomerStatusDetailDto(statusName, flagName); } @Override public CustomerChargesDetailsDto retrieveChargesDetails(Integer customerId) { MifosUser mifosUser = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = new UserContextFactory().create(mifosUser); CustomerBO customerBO = this.customerDao.findCustomerById(customerId); CustomerAccountBO customerAccount = customerBO.getCustomerAccount(); try { personnelDao.checkAccessPermission(userContext, customerBO.getOfficeId(), customerBO.getLoanOfficerId()); } catch (AccountException e) { throw new MifosRuntimeException("Access denied!", e); } List<AccountFeesDto> accountFeesDtos = new ArrayList<AccountFeesDto>(); if(!customerAccount.getAccountFees().isEmpty()) { for (AccountFeesEntity accountFeesEntity: customerAccount.getAccountFees()) { AccountFeesDto accountFeesDto = new AccountFeesDto(accountFeesEntity.getFees().getFeeFrequency().getFeeFrequencyType().getId(), (accountFeesEntity.getFees().getFeeFrequency().getFeePayment() != null ? accountFeesEntity.getFees().getFeeFrequency().getFeePayment().getId() : null), accountFeesEntity.getFeeStatus(), accountFeesEntity.getFees().getFeeName(), accountFeesEntity.getAccountFeeAmount().toString(), getMeetingRecurrence(accountFeesEntity.getFees().getFeeFrequency().getFeeMeetingFrequency(), userContext), accountFeesEntity.getFees().getFeeId()); accountFeesDtos.add(accountFeesDto); } } CustomerScheduleDto customerSchedule = null; CustomerScheduleEntity scheduleEntity = (CustomerScheduleEntity) customerAccount.getUpcomingInstallment(); if (scheduleEntity != null) { Set<AccountFeesActionDetailEntity> feeEntities = scheduleEntity.getAccountFeesActionDetails(); List<AccountFeeScheduleDto> feeDtos = new ArrayList<AccountFeeScheduleDto>(); for (AccountFeesActionDetailEntity feeEntity : feeEntities) { feeDtos.add(convertToDto(feeEntity)); } customerSchedule = new CustomerScheduleDto(scheduleEntity.getMiscFee().toString(), scheduleEntity.getMiscFeePaid().toString(), scheduleEntity.getMiscPenalty().toString(), scheduleEntity.getMiscPenaltyPaid().toString(), feeDtos); } return new CustomerChargesDetailsDto(customerAccount.getNextDueAmount().toString(), customerAccount.getTotalAmountInArrears().toString(), customerAccount.getTotalAmountDue().toString(), customerAccount.getUpcomingChargesDate(), customerSchedule, accountFeesDtos); } @Override public List<CustomerRecentActivityDto> retrieveRecentActivities(Integer customerId, Integer countOfActivities) { CustomerBO customerBO = this.customerDao.findCustomerById(customerId); List<CustomerActivityEntity> customerActivityDetails = customerBO.getCustomerAccount().getCustomerActivitDetails(); List<CustomerRecentActivityDto> customerActivityViewList = new ArrayList<CustomerRecentActivityDto>(); int count = 0; for (CustomerActivityEntity customerActivityEntity : customerActivityDetails) { customerActivityViewList.add(getCustomerActivityView(customerActivityEntity)); if (++count == countOfActivities) { break; } } return customerActivityViewList; } private CustomerRecentActivityDto getCustomerActivityView(CustomerActivityEntity customerActivityEntity) { CustomerRecentActivityDto customerRecentActivityDto = new CustomerRecentActivityDto(); String preferredDate = DateUtils.getUserLocaleDate(Locale.getDefault(), customerActivityEntity.getCreatedDate()); customerRecentActivityDto.setUserPrefferedDate(preferredDate); customerRecentActivityDto.setActivityDate(customerActivityEntity.getCreatedDate()); customerRecentActivityDto.setDescription(customerActivityEntity.getDescription()); Money amount = removeSign(customerActivityEntity.getAmount()); if (amount.isZero()) { customerRecentActivityDto.setAmount("-"); } else { customerRecentActivityDto.setAmount(amount.toString()); } if (customerActivityEntity.getPersonnel() != null) { customerRecentActivityDto.setPostedBy(customerActivityEntity.getPersonnel().getDisplayName()); } return customerRecentActivityDto; } private Money removeSign(Money amount) { if (amount != null && amount.isLessThanZero()) { return amount.negate(); } return amount; } @Override public CustomerNoteFormDto retrieveCustomerNote(String globalCustNum) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); CustomerBO customer = this.customerDao.findCustomerBySystemId(globalCustNum); PersonnelBO loggedInUser = this.personnelDao.findPersonnelById(userContext.getId()); Integer customerLevel = customer.getCustomerLevel().getId().intValue(); String globalNum = customer.getGlobalCustNum(); String displayName = customer.getDisplayName(); LocalDate commentDate = new LocalDate(); String commentUser = loggedInUser.getDisplayName(); return new CustomerNoteFormDto(globalNum, displayName, customerLevel, commentDate, commentUser, ""); } @Override public void createCustomerNote(CustomerNoteFormDto customerNoteForm) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); CustomerBO customer = this.customerDao.findCustomerBySystemId(customerNoteForm.getGlobalNum()); customer.updateDetails(userContext); PersonnelBO loggedInUser = this.personnelDao.findPersonnelById(userContext.getId()); CustomerNoteEntity customerNote = new CustomerNoteEntity(customerNoteForm.getComment(), new DateTimeService().getCurrentJavaSqlDate(), loggedInUser, customer); customer.addCustomerNotes(customerNote); try { this.transactionHelper.startTransaction(); this.customerDao.save(customer); this.transactionHelper.commitTransaction(); } catch (Exception e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(customer.getCustomerAccount().getAccountId().toString(), e); } finally { this.transactionHelper.closeSession(); } } @Override public List<ClosedAccountDto> retrieveAllClosedAccounts(Integer customerId) { List<ClosedAccountDto> closedAccounts = new ArrayList<ClosedAccountDto>(); List<AccountBO> allClosedAccounts = this.customerDao.retrieveAllClosedLoanAndSavingsAccounts(customerId); for (AccountBO account : allClosedAccounts) { LocalDate closedDate = new LocalDate(account.getClosedDate()); ClosedAccountDto closedAccount = new ClosedAccountDto(account.getAccountId(), account.getGlobalAccountNum(), account.getType().getValue().intValue(), account.getState().getValue().intValue(), closedDate); closedAccounts.add(closedAccount); } return closedAccounts; } @Override public List<TransactionHistoryDto> retrieveAccountTransactionHistory(String globalAccountNum) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { AccountBO account = new AccountBusinessService().findBySystemId(globalAccountNum); CustomerBO customerBO = account.getCustomer(); account.updateDetails(userContext); personnelDao.checkAccessPermission(userContext, customerBO.getOfficeId(), customerBO.getLoanOfficerId()); List<TransactionHistoryDto> transactionHistories = account.getTransactionHistoryView(); for (TransactionHistoryDto transactionHistoryDto : transactionHistories) { transactionHistoryDto.setUserPrefferedPostedDate(DateUtils.getUserLocaleDate(userContext.getPreferredLocale(), transactionHistoryDto.getPostedDate().toString())); transactionHistoryDto.setUserPrefferedTransactionDate(DateUtils.getUserLocaleDate(userContext.getPreferredLocale(), transactionHistoryDto.getTransactionDate().toString())); } return transactionHistories; } catch (ServiceException e) { throw new MifosRuntimeException(e); } catch (AccountException e) { throw new MifosRuntimeException("Access denied!", e); } } @Override public List<CustomerRecentActivityDto> retrieveAllAccountActivity(String globalCustNum) { List<CustomerRecentActivityDto> customerActivityViewList = new ArrayList<CustomerRecentActivityDto>(); CustomerBO customerBO = this.customerDao.findCustomerBySystemId(globalCustNum); List<CustomerActivityEntity> customerActivityDetails = customerBO.getCustomerAccount().getCustomerActivitDetails(); for (CustomerActivityEntity customerActivityEntity : customerActivityDetails) { customerActivityViewList.add(assembleCustomerActivityDto(customerActivityEntity, Locale.getDefault())); } return customerActivityViewList; } private CustomerRecentActivityDto assembleCustomerActivityDto(CustomerActivityEntity customerActivityEntity, Locale locale) { CustomerRecentActivityDto customerRecentActivityDto = new CustomerRecentActivityDto(); String preferredDate = DateUtils.getUserLocaleDate(locale, customerActivityEntity.getCreatedDate().toString()); customerRecentActivityDto.setActivityDate(customerActivityEntity.getCreatedDate()); customerRecentActivityDto.setUserPrefferedDate(preferredDate); customerRecentActivityDto.setDescription(customerActivityEntity.getDescription()); Money amount = removeSign(customerActivityEntity.getAmount()); if (amount.isZero()) { customerRecentActivityDto.setAmount("-"); } else { customerRecentActivityDto.setAmount(amount.toString()); } if (customerActivityEntity.getPersonnel() != null) { customerRecentActivityDto.setPostedBy(customerActivityEntity.getPersonnel().getDisplayName()); } return customerRecentActivityDto; } @Override public void waiveChargesDue(Integer accountId, Integer waiveType) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { AccountBO account = new AccountBusinessService().getAccount(accountId); account.updateDetails(userContext); PersonnelBO loggedInUser = this.personnelDao.findPersonnelById(userContext.getId()); WaiveEnum waiveEnum = WaiveEnum.fromInt(waiveType); if (account.getPersonnel() != null) { new AccountBusinessService().checkPermissionForWaiveDue(waiveEnum, account.getType(), account.getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), account.getPersonnel().getPersonnelId()); } else { new AccountBusinessService().checkPermissionForWaiveDue(waiveEnum, account.getType(), account.getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), userContext.getId()); } try { this.transactionHelper.startTransaction(); if (account instanceof LoanBO) { ((LoanBO)account).waiveAmountDue(waiveEnum); } else if (account instanceof SavingsBO) { ((SavingsBO)account).waiveNextDepositAmountDue(loggedInUser); } else { ((CustomerAccountBO)account).waiveAmountDue(); } this.customerDao.save(account); this.transactionHelper.commitTransaction(); } catch (Exception e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(account.getAccountId().toString(), e); } finally { this.transactionHelper.closeSession(); } } catch (ServiceException e) { throw new MifosRuntimeException(e); } catch (ApplicationException e) { throw new BusinessRuleException(e.getKey(), e); } } @Override public void waiveChargesOverDue(Integer accountId, Integer waiveType) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { AccountBO account = new AccountBusinessService().getAccount(accountId); account.updateDetails(userContext); WaiveEnum waiveEnum = WaiveEnum.fromInt(waiveType); if (account.getPersonnel() != null) { new AccountBusinessService().checkPermissionForWaiveDue(waiveEnum, account.getType(), account .getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), account .getPersonnel().getPersonnelId()); } else { new AccountBusinessService().checkPermissionForWaiveDue(waiveEnum, account.getType(), account .getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), userContext.getId()); } this.transactionHelper.startTransaction(); account.waiveAmountOverDue(waiveEnum); this.customerDao.save(account); this.transactionHelper.commitTransaction(); } catch (ServiceException e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } catch (ApplicationException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } finally { this.transactionHelper.closeSession(); } } @Override public void removeAccountFee(Integer accountId, Short feeId) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { AccountBO account = new AccountBusinessService().getAccount(accountId); if(account instanceof LoanBO) { List<LoanBO> individualLoans = this.loanDao.findIndividualLoans(account.getAccountId()); if(individualLoans != null && individualLoans.size() > 0) { for(LoanBO individual : individualLoans) { individual.updateDetails(userContext); individual.removeFeesAssociatedWithUpcomingAndAllKnownFutureInstallments(feeId, userContext.getId()); this.customerDao.save(individual); } } } account.updateDetails(userContext); if (account.getPersonnel() != null) { new AccountBusinessService().checkPermissionForRemoveFees(account.getType(), account.getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), account.getPersonnel().getPersonnelId()); } else { new AccountBusinessService().checkPermissionForRemoveFees(account.getType(), account.getCustomer().getLevel(), userContext, account.getOffice().getOfficeId(), userContext.getId()); } this.transactionHelper.startTransaction(); account.removeFeesAssociatedWithUpcomingAndAllKnownFutureInstallments(feeId, userContext.getId()); this.customerDao.save(account); this.transactionHelper.commitTransaction(); } catch (ServiceException e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } catch (AccountException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } catch (ApplicationException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } finally { this.transactionHelper.closeSession(); } } @Override public void revertLastChargesPayment(String globalCustNum, String adjustmentNote) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); PersonnelBO loggedInUser = this.personnelDao.findPersonnelById(userContext.getId()); CustomerBO customerBO = this.customerDao.findCustomerBySystemId(globalCustNum); customerBO.updateDetails(userContext); if (customerBO.getCustomerAccount().findMostRecentNonzeroPaymentByPaymentDate() != null) { customerBO.getCustomerAccount().updateDetails(userContext); try { if (customerBO.getPersonnel() != null) { new AccountBusinessService().checkPermissionForAdjustment(AccountTypes.CUSTOMER_ACCOUNT, customerBO .getLevel(), userContext, customerBO.getOffice().getOfficeId(), customerBO.getPersonnel() .getPersonnelId()); } else { new AccountBusinessService().checkPermissionForAdjustment(AccountTypes.CUSTOMER_ACCOUNT, customerBO .getLevel(), userContext, customerBO.getOffice().getOfficeId(), userContext.getId()); } this.transactionHelper.startTransaction(); customerBO.adjustPmnt(adjustmentNote, loggedInUser); this.customerDao.save(customerBO); this.transactionHelper.commitTransaction(); } catch (SystemException e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } catch (ApplicationException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } } } @Override public List<AuditLogDto> retrieveChangeLogs(Integer centerId) { try { List<AuditLogDto> auditLogs = new ArrayList<AuditLogDto>(); Short entityType = EntityType.CENTER.getValue(); AuditBusinessService auditBusinessService = new AuditBusinessService(); List<AuditLogView> centerAuditLogs = auditBusinessService.getAuditLogRecords(entityType, centerId); for (AuditLogView auditLogView : centerAuditLogs) { auditLogs.add(auditLogView.toDto()); } return auditLogs; } catch (ServiceException e) { throw new MifosRuntimeException(e); } } @Override public List<CustomerDetailDto> retrieveCustomersUnderUser(Short loanOfficerId) { PersonnelBO loanOfficer = this.personnelDao.findPersonnelById(loanOfficerId); List<CustomerDetailDto> customerList = new ArrayList<CustomerDetailDto>(); if (ClientRules.getCenterHierarchyExists()) { customerList = this.customerDao.findActiveCentersUnderUser(loanOfficer); } else { customerList = this.customerDao.findGroupsUnderUser(loanOfficer); } return customerList; } @Override public String retrieveOfficeName(Short officeId) { return this.officeDao.findOfficeById(officeId).getOfficeName(); } @Override public List<CustomerDetailDto> retrieveGroupForPentahoReport(Short loanOfficerId){ PersonnelBO loanOfficer = this.personnelDao.findPersonnelById(loanOfficerId); return this.customerDao.findGroupsUnderUser(loanOfficer); } @Override public UserDetailDto retrieveUsersDetails(Short userId) { return this.personnelDao.findPersonnelById(userId).toDto(); } @Override public void addNoteToPersonnel(Short personnelId, String comment) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { PersonnelBO personnel = this.personnelDao.findPersonnelById(personnelId); PersonnelBO loggedInUser = this.personnelDao.findPersonnelById(userContext.getId()); if (personnel != null) { checkPermissionForAddingNotesToPersonnel(userContext, personnel.getOffice().getOfficeId(), personnel.getPersonnelId()); } this.transactionHelper.startTransaction(); PersonnelNotesEntity personnelNote = new PersonnelNotesEntity(comment, loggedInUser, personnel); personnel.addNotes(userContext.getId(), personnelNote); this.personnelDao.save(personnel); this.transactionHelper.commitTransaction(); } catch (Exception e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } finally { this.transactionHelper.closeSession(); } } @Override public void putCenterBusinessKeyInSession(String globalCustNum, HttpServletRequest request) { CenterBO centerBO = customerDao.findCenterBySystemId(globalCustNum); try { SessionUtils.removeThenSetAttribute(Constants.BUSINESS_KEY, centerBO, request); } catch (PageExpiredException e) { throw new MifosRuntimeException(e); } } private void checkPermissionForAddingNotesToPersonnel(UserContext userContext, Short recordOfficeId, Short recordLoanOfficerId) { if (!isPermissionAllowed(userContext, recordOfficeId, recordLoanOfficerId)) { throw new BusinessRuleException(SecurityConstants.KEY_ACTIVITY_NOT_ALLOWED); } } private boolean isPermissionAllowed(UserContext userContext, Short recordOfficeId, Short recordLoanOfficerId) { return ActivityMapper.getInstance().isAddingNotesPermittedForPersonnel(userContext, recordOfficeId, recordLoanOfficerId); } private AccountFeeScheduleDto convertToDto(AccountFeesActionDetailEntity feeEntity) { return new AccountFeeScheduleDto(feeEntity.getFee().getFeeName(), feeEntity.getFeeAmount().toString(), feeEntity.getFeeAmountPaid().toString(), feeEntity.getFeeAllocated().toString()); } private String getMeetingRecurrence(MeetingBO meeting, UserContext userContext) { return meeting != null ? new MeetingHelper().getMessageWithFrequency(meeting, userContext) : null; } @Override public List<CustomerDetailDto> retrieveCustomersUnderBranch(Short branchId) { List<CustomerDetailDto> customers =null; try { customers = new ArrayList<CustomerDetailDto>(); List<PersonnelBO> officers = personnelBusinessService.getActiveLoanOfficersUnderOffice(branchId); for(PersonnelBO officer : officers) { customers.addAll(retrieveCustomersUnderUser(officer.getPersonnelId())); } } catch (ServiceException e) { } return customers; } }