/*
* 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.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.ObjectUtils;
import org.hibernate.HibernateException;
import org.joda.time.LocalDate;
import org.mifos.accounts.business.AccountBO;
import org.mifos.accounts.business.AccountPaymentEntity;
import org.mifos.accounts.loan.business.LoanBO;
import org.mifos.accounts.loan.persistance.ClientAttendanceDao;
import org.mifos.accounts.loan.persistance.LegacyLoanDao;
import org.mifos.accounts.persistence.LegacyAccountDao;
import org.mifos.accounts.savings.business.SavingsBO;
import org.mifos.accounts.savings.persistence.SavingsDao;
import org.mifos.application.collectionsheet.persistence.CollectionSheetDao;
import org.mifos.config.ClientRules;
import org.mifos.core.MifosRuntimeException;
import org.mifos.customers.api.CustomerLevel;
import org.mifos.customers.client.business.ClientAttendanceBO;
import org.mifos.customers.persistence.CustomerPersistence;
import org.mifos.framework.hibernate.helper.StaticHibernateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* implementation of CollectionSheetService
*
*/
public class CollectionSheetServiceImpl implements CollectionSheetService {
private static final Logger logger = LoggerFactory.getLogger(CollectionSheetServiceImpl.class);
private final ClientAttendanceDao clientAttendanceDao;
@Autowired
private LegacyLoanDao legacyLoanDao;
@Autowired
private LegacyAccountDao legacyAccountDao;
private final SavingsDao savingsDao;
private final CollectionSheetDao collectionSheetDao;
@Autowired
private SaveCollectionSheetAssembler saveCollectionSheetAssembler;
@Autowired
public CollectionSheetServiceImpl(final ClientAttendanceDao clientAttendanceDao,
final SavingsDao savingsDao, final CollectionSheetDao collectionSheetDao) {
this.clientAttendanceDao = clientAttendanceDao;
this.savingsDao = savingsDao;
this.collectionSheetDao = collectionSheetDao;
}
public CollectionSheetServiceImpl(final ClientAttendanceDao clientAttendanceDao,
final LegacyLoanDao legacyLoanDao, final LegacyAccountDao legacyAccountDao,
final SavingsDao savingsDao, final CollectionSheetDao collectionSheetDao) {
this.clientAttendanceDao = clientAttendanceDao;
this.legacyLoanDao = legacyLoanDao;
this.legacyAccountDao = legacyAccountDao;
this.savingsDao = savingsDao;
this.collectionSheetDao = collectionSheetDao;
}
/**
* The method saves a collection sheet.
*
* @throws SaveCollectionSheetException
* */
@Override
public CollectionSheetErrorsDto saveCollectionSheet(final SaveCollectionSheetDto saveCollectionSheet)
throws SaveCollectionSheetException {
Long totalTime;
Long totalTimeStart = System.currentTimeMillis();
Long readTime;
Long saveTime = null;
Long saveTimeStart;
Integer topCustomerId = saveCollectionSheet.getSaveCollectionSheetCustomers().get(0).getCustomerId();
CollectionSheetCustomerDto collectionSheetTopCustomer = new CustomerPersistence()
.findCustomerWithNoAssocationsLoaded(topCustomerId);
if (collectionSheetTopCustomer == null) {
List<InvalidSaveCollectionSheetReason> invalidSaveCollectionSheetReasons = new ArrayList<InvalidSaveCollectionSheetReason>();
List<String> invalidSaveCollectionSheetReasonsExtended = new ArrayList<String>();
invalidSaveCollectionSheetReasons.add(InvalidSaveCollectionSheetReason.INVALID_TOP_CUSTOMER);
invalidSaveCollectionSheetReasonsExtended.add(InvalidSaveCollectionSheetReason.INVALID_TOP_CUSTOMER
.toString()
+ ": Customer Id: " + topCustomerId);
throw new SaveCollectionSheetException(invalidSaveCollectionSheetReasons,
invalidSaveCollectionSheetReasonsExtended);
}
Short branchId = collectionSheetTopCustomer.getBranchId();
String searchId = collectionSheetTopCustomer.getSearchId();
// session caching: prefetch collection sheet data
// done prior to structure validation because it loads
// the customers and accounts to be validated into the session
SaveCollectionSheetSessionCache saveCollectionSheetSessionCache = new SaveCollectionSheetSessionCache();
saveCollectionSheetSessionCache
.loadSessionCacheWithCollectionSheetData(saveCollectionSheet, branchId, searchId);
try {
new SaveCollectionSheetStructureValidator().execute(saveCollectionSheet);
} catch (SaveCollectionSheetException e) {
System.out.println(e.printInvalidSaveCollectionSheetReasons());
throw e;
}
/*
* With preprocessing complete...
*
* only errors and warnings from the business model remain
*/
final List<String> failedSavingsDepositAccountNums = new ArrayList<String>();
final List<String> failedSavingsWithdrawalNums = new ArrayList<String>();
final List<String> failedLoanDisbursementAccountNumbers = new ArrayList<String>();
final List<String> failedLoanRepaymentAccountNumbers = new ArrayList<String>();
final List<String> failedCustomerAccountPaymentNums = new ArrayList<String>();
final List<ClientAttendanceBO> clientAttendances = saveCollectionSheetAssembler
.clientAttendanceAssemblerfromDto(saveCollectionSheet.getSaveCollectionSheetCustomers(),
saveCollectionSheet.getTransactionDate(), branchId, searchId);
final AccountPaymentEntity payment = saveCollectionSheetAssembler.accountPaymentAssemblerFromDto(
saveCollectionSheet.getTransactionDate(), saveCollectionSheet.getPaymentType(), saveCollectionSheet
.getReceiptId(), saveCollectionSheet.getReceiptDate(), saveCollectionSheet.getUserId());
final List<SavingsBO> savingsAccounts = saveCollectionSheetAssembler.savingsAccountAssemblerFromDto(
saveCollectionSheet.getSaveCollectionSheetCustomers(), payment, failedSavingsDepositAccountNums,
failedSavingsWithdrawalNums);
Short paymentTypeId = (payment.getPaymentType() == null || payment.getPaymentType().getId() == null) ? null : payment.getPaymentType().getId();
final List<LoanBO> loanAccounts = saveCollectionSheetAssembler.loanAccountAssemblerFromDto(saveCollectionSheet
.getSaveCollectionSheetCustomers(), payment, failedLoanDisbursementAccountNumbers,
failedLoanRepaymentAccountNumbers, paymentTypeId);
final List<AccountBO> customerAccounts = saveCollectionSheetAssembler.customerAccountAssemblerFromDto(
saveCollectionSheet.getSaveCollectionSheetCustomers(), payment, failedCustomerAccountPaymentNums);
boolean databaseErrorOccurred = false;
Throwable databaseError = null;
readTime = System.currentTimeMillis() - totalTimeStart;
try {
saveTimeStart = System.currentTimeMillis();
persistCollectionSheet(clientAttendances, loanAccounts, customerAccounts, savingsAccounts);
saveTime = System.currentTimeMillis() - saveTimeStart;
} catch (HibernateException e) {
logger.error("database error saving collection sheet", e);
databaseErrorOccurred = true;
databaseError = e;
}
totalTime = System.currentTimeMillis() - totalTimeStart;
printTiming(saveCollectionSheet.printSummary(), totalTime, saveTime, readTime, saveCollectionSheetSessionCache);
return new CollectionSheetErrorsDto(failedSavingsDepositAccountNums, failedSavingsWithdrawalNums,
failedLoanDisbursementAccountNumbers, failedLoanRepaymentAccountNumbers,
failedCustomerAccountPaymentNums, databaseErrorOccurred, databaseError);
}
private void printTiming(String printSummary, Long totalTime, Long saveTime, Long readTime,
SaveCollectionSheetSessionCache saveCollectionSheetSessionCache) {
final StringBuilder builder = new StringBuilder();
final String comma = ", ";
builder.append(printSummary);
builder.append(comma);
builder.append("Collection Sheet Timing:");
builder.append(comma);
builder.append(totalTime);
builder.append(comma);
builder.append(saveTime);
builder.append(comma);
builder.append(readTime);
builder.append(comma);
builder.append("Cache Use Timing:");
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchCustomerHierarchyTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchCustomerHierarchyCount());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchAccountDataTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchAccountDataCount());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchLoanSchedulesTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchLoanSchedulesCount());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchAccountFeeDetailsTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchAccountFeeDetailsCount());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchCustomerSchedulesTotalTime());
builder.append(comma);
builder.append(saveCollectionSheetSessionCache.getPrefetchCustomerSchedulesCount());
doLog(builder.toString());
}
private void persistCollectionSheet(final List<ClientAttendanceBO> clientAttendances,
final List<LoanBO> loanAccounts, final List<AccountBO> customerAccountList,
final List<SavingsBO> savingAccounts) {
try {
StaticHibernateUtil.startTransaction();
clientAttendanceDao.save(clientAttendances);
legacyLoanDao.save(loanAccounts);
legacyAccountDao.save(customerAccountList);
savingsDao.save(savingAccounts);
StaticHibernateUtil.commitTransaction();
} catch (HibernateException e) {
StaticHibernateUtil.rollbackTransaction();
throw e;
} finally {
StaticHibernateUtil.closeSession();
}
}
@Override
public CollectionSheetDto retrieveCollectionSheet(final Integer customerId, final LocalDate transactionDate) {
if (customerId == null) {
throw new IllegalArgumentException("Invalid Null Customer Id");
}
if (transactionDate == null) {
throw new IllegalArgumentException("Invalid Null Transaction Date: ");
}
final List<CollectionSheetCustomerDto> customerHierarchy = collectionSheetDao.findCustomerHierarchy(customerId,
transactionDate);
if (customerHierarchy == null || customerHierarchy.size() == 0) {
throw new IllegalArgumentException("Invalid Customer Id: " + customerId);
}
final Short branchId = customerHierarchy.get(0).getBranchId();
final String searchId = customerHierarchy.get(0).getSearchId() + ".%";
final CustomerHierarchyParams customerHierarchyParams = new CustomerHierarchyParams(customerId, branchId,
searchId, transactionDate);
String searchIdForLoanRepayments = "";
if (ClientRules.getCenterHierarchyExists()) {
searchIdForLoanRepayments = searchId;
} else {
searchIdForLoanRepayments = customerHierarchy.get(0).getSearchId() + "%";
}
final Map<Integer, List<CollectionSheetCustomerLoanDto>> allLoanRepaymentsGroupedByCustomerId = collectionSheetDao
.findAllLoanRepaymentsForCustomerHierarchy(branchId, searchIdForLoanRepayments, transactionDate, customerId);
final Map<Integer, Map<Integer, List<CollectionSheetLoanFeeDto>>> allLoanFeesGroupedByCustomerIdAndAccountId = collectionSheetDao
.findOutstandingFeesForLoansOnCustomerHierarchy(branchId, searchId, transactionDate, customerId);
final Map<Integer, List<CollectionSheetCustomerAccountCollectionDto>> allAccountCollectionsByCustomerId = collectionSheetDao
.findAccountCollectionsOnCustomerAccount(branchId, searchId, transactionDate, customerId);
final Map<Integer, List<CollectionSheetCustomerAccountCollectionDto>> feesAssociatedWithAccountCollectionsByCustomerId = collectionSheetDao
.findOutstandingFeesForCustomerAccountOnCustomerHierarchy(branchId, searchId, transactionDate,
customerId);
final Map<Integer, List<CollectionSheetCustomerLoanDto>> allLoanDisbursements = collectionSheetDao
.findLoanDisbursementsForCustomerHierarchy(branchId, searchId, transactionDate, customerId);
// Retrieve Each Savings Account
final List<CollectionSheetCustomerSavingsAccountDto> savingsAccounts = collectionSheetDao
.findAllSavingAccountsForCustomerHierarchy(customerHierarchyParams);
Map<Integer, List<CollectionSheetCustomerSavingDto>> allSavingsDepositsGroupedByCustomerId = new HashMap<Integer, List<CollectionSheetCustomerSavingDto>>();
Map<Integer, List<CollectionSheetCustomerSavingDto>> allSavingsAccountsToBePaidByIndividualClientsGroupedByCustomerId = new HashMap<Integer, List<CollectionSheetCustomerSavingDto>>();
// No need to look for unpaid Savings Account transactions if no Savings Accounts
if (savingsAccounts != null && savingsAccounts.size() > 0) {
allSavingsDepositsGroupedByCustomerId = collectionSheetDao
.findSavingsDepositsforCustomerHierarchy(customerHierarchyParams);
// only need to look for unpaid installments for the CLIENTS underneath center or group individual savings
// account if those accounts exist
if (containsIndividualAccount(savingsAccounts)) {
allSavingsAccountsToBePaidByIndividualClientsGroupedByCustomerId = collectionSheetDao
.findAllSavingsAccountsPayableByIndividualClientsForCustomerHierarchy(customerHierarchyParams);
}
}
//
final List<CollectionSheetCustomerDto> populatedCollectionSheetCustomer = new ArrayList<CollectionSheetCustomerDto>();
for (CollectionSheetCustomerDto collectionSheetCustomer : customerHierarchy) {
final Integer customerInHierarchyId = collectionSheetCustomer.getCustomerId();
final List<CollectionSheetCustomerLoanDto> associatedLoanRepayments = allLoanRepaymentsGroupedByCustomerId
.get(customerInHierarchyId);
final Map<Integer, List<CollectionSheetLoanFeeDto>> outstandingFeesOnLoanRepayments = allLoanFeesGroupedByCustomerIdAndAccountId
.get(customerInHierarchyId);
final List<CollectionSheetCustomerLoanDto> associatedLoanDisbursements = allLoanDisbursements
.get(customerInHierarchyId);
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollections = allAccountCollectionsByCustomerId
.get(customerInHierarchyId);
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollectionFees = feesAssociatedWithAccountCollectionsByCustomerId
.get(customerInHierarchyId);
final CollectionSheetCustomerAccountDto customerAccount = sumAssociatedCustomerAccountCollectionFees(
customerAccountCollections, customerAccountCollectionFees);
// process savings accounts
List<CollectionSheetCustomerSavingDto> associatedSavingAccounts = ensureAllSavingsAccountsRepresented(
allSavingsDepositsGroupedByCustomerId.get(customerInHierarchyId), savingsAccounts,
customerInHierarchyId);
List<CollectionSheetCustomerSavingDto> associatedIndividualSavingsAccounts = ensureAllClientIndividualSavingsAccountsRepresented(
allSavingsAccountsToBePaidByIndividualClientsGroupedByCustomerId.get(customerInHierarchyId),
getIndividualSavingsAccounts(savingsAccounts), collectionSheetCustomer);
//
populatedCollectionSheetCustomer.add(createNullSafeCollectionSheetCustomer(collectionSheetCustomer,
associatedLoanRepayments, outstandingFeesOnLoanRepayments, associatedLoanDisbursements,
associatedSavingAccounts, associatedIndividualSavingsAccounts, customerAccount));
}
return new CollectionSheetDto(populatedCollectionSheetCustomer, transactionDate);
}
/*
* Each savings account should be represented in the collection sheet. The previous retrievals only bring back
* savings accounts that have unpaid installments. The following code adds a zero entry for any savings accounts not
* there. This is because it is possible to deposit or withdraw without an outstanding unpaid installment.
*/
private List<CollectionSheetCustomerSavingDto> ensureAllSavingsAccountsRepresented(
List<CollectionSheetCustomerSavingDto> associatedSavingAccountsWithUnpaidInstallments,
final List<CollectionSheetCustomerSavingsAccountDto> savingsAccounts, final Integer customerId) {
if (savingsAccounts == null || savingsAccounts.size() == 0) {
return null;
}
List<CollectionSheetCustomerSavingDto> combinedSavingsAccountsList = new ArrayList<CollectionSheetCustomerSavingDto>();
if (associatedSavingAccountsWithUnpaidInstallments != null) {
combinedSavingsAccountsList.addAll(associatedSavingAccountsWithUnpaidInstallments);
}
for (CollectionSheetCustomerSavingsAccountDto savingsAccount : savingsAccounts) {
if (savingsAccount.getCustomerId().compareTo(customerId) == 0) {
// matches on customer, now account not already in list then add it
if (!isAccountInCombinedSavingsAccountsList(
combinedSavingsAccountsList, savingsAccount.getAccountId())) {
CollectionSheetCustomerSavingDto zeroValueSavingsAccount = new CollectionSheetCustomerSavingDto();
zeroValueSavingsAccount.setCustomerId(savingsAccount.getCustomerId());
zeroValueSavingsAccount.setAccountId(savingsAccount.getAccountId());
zeroValueSavingsAccount.setProductId(savingsAccount.getProductId());
zeroValueSavingsAccount.setProductShortName(savingsAccount.getProductShortName());
zeroValueSavingsAccount.setRecommendedAmountUnitId(savingsAccount.getRecommendedAmountUnitId());
zeroValueSavingsAccount.setCurrencyId(savingsAccount.getCurrencyId());
zeroValueSavingsAccount.setDepositDue(BigDecimal.ZERO);
zeroValueSavingsAccount.setDepositPaid(BigDecimal.ZERO);
combinedSavingsAccountsList.add(zeroValueSavingsAccount);
}
}
}
return combinedSavingsAccountsList;
}
/*
* Each client individual savings account should be represented in the collection sheet. The previous retrievals
* only bring back client individual savings accounts that have unpaid installments. The following code adds a zero
* entry for any client individual savings accounts not there. This is because it is possible to deposit or withdraw
* without an outstanding unpaid installment.
*/
private List<CollectionSheetCustomerSavingDto> ensureAllClientIndividualSavingsAccountsRepresented(
List<CollectionSheetCustomerSavingDto> clientIndividualSavingAccountsWithUnpaidInstallments,
final List<CollectionSheetCustomerSavingsAccountDto> clientIndividualSavingsAccounts,
CollectionSheetCustomerDto customer) {
if (clientIndividualSavingsAccounts == null) {
return null;
}
// Only clients have client individual savings accounts (the account actually belongs to a "group individual" or
// a "center" savings account.
if (customer.getLevelId().compareTo(CustomerLevel.CLIENT.getValue()) != 0) {
if (clientIndividualSavingAccountsWithUnpaidInstallments != null) {
throw new MifosRuntimeException("Customer Id: " + customer.getCustomerId()
+ " is not a client... but has client individual savings");
}
return null;
}
List<CollectionSheetCustomerSavingDto> combinedSavingsAccountsList = new ArrayList<CollectionSheetCustomerSavingDto>();
if (clientIndividualSavingAccountsWithUnpaidInstallments != null) {
combinedSavingsAccountsList.addAll(clientIndividualSavingAccountsWithUnpaidInstallments);
}
for (CollectionSheetCustomerSavingsAccountDto individualSavingsAccount : clientIndividualSavingsAccounts) {
//
if ((individualSavingsAccount.getCustomerLevelId().compareTo(CustomerLevel.CENTER.getValue()) == 0)
|| (individualSavingsAccount.getCustomerId().compareTo(customer.getParentCustomerId())) == 0) {
if(!isAccountInCombinedSavingsAccountsList(
combinedSavingsAccountsList, individualSavingsAccount.getAccountId())) {
CollectionSheetCustomerSavingDto zeroValueSavingsAccount = new CollectionSheetCustomerSavingDto();
zeroValueSavingsAccount.setCustomerId(individualSavingsAccount.getCustomerId());
zeroValueSavingsAccount.setAccountId(individualSavingsAccount.getAccountId());
zeroValueSavingsAccount.setProductId(individualSavingsAccount.getProductId());
zeroValueSavingsAccount.setProductShortName(individualSavingsAccount.getProductShortName());
zeroValueSavingsAccount.setRecommendedAmountUnitId(individualSavingsAccount
.getRecommendedAmountUnitId());
zeroValueSavingsAccount.setCurrencyId(individualSavingsAccount.getCurrencyId());
zeroValueSavingsAccount.setDepositDue(BigDecimal.ZERO);
zeroValueSavingsAccount.setDepositPaid(BigDecimal.ZERO);
combinedSavingsAccountsList.add(zeroValueSavingsAccount);
}
}
}
return combinedSavingsAccountsList;
}
/*
* Method returns null if accountId parameter is found
*/
private Boolean isAccountInCombinedSavingsAccountsList(
List<CollectionSheetCustomerSavingDto> combinedSavingsAccountsList, Integer accountId) {
for (Integer i = 0; i < combinedSavingsAccountsList.size(); i++) {
if (combinedSavingsAccountsList.get(i).getAccountId().compareTo(accountId) == 0) {
return true;
}
}
return false;
}
private Boolean containsIndividualAccount(List<CollectionSheetCustomerSavingsAccountDto> savingsAccounts) {
for (CollectionSheetCustomerSavingsAccountDto savingsAccount : savingsAccounts) {
if (isIndividualSavingsAccount(savingsAccount.getCustomerLevelId(), savingsAccount
.getRecommendedAmountUnitId())) {
return true;
}
}
return false;
}
private List<CollectionSheetCustomerSavingsAccountDto> getIndividualSavingsAccounts(
List<CollectionSheetCustomerSavingsAccountDto> savingsAccounts) {
if (savingsAccounts != null && savingsAccounts.size() > 0) {
List<CollectionSheetCustomerSavingsAccountDto> individualSavingsAccounts = new ArrayList<CollectionSheetCustomerSavingsAccountDto>();
for (CollectionSheetCustomerSavingsAccountDto savingsAccount : savingsAccounts) {
if (isIndividualSavingsAccount(savingsAccount.getCustomerLevelId(), savingsAccount
.getRecommendedAmountUnitId())) {
individualSavingsAccounts.add(savingsAccount);
}
}
if (individualSavingsAccounts.size() > 0) {
return individualSavingsAccounts;
}
}
return null;
}
private Boolean isIndividualSavingsAccount(Short customerLevelId, Short recommendedAmountUnitId) {
if (customerLevelId.compareTo(CustomerLevel.CENTER.getValue()) == 0) {
return true;
}
if ((customerLevelId.compareTo(CustomerLevel.GROUP.getValue()) == 0) && (recommendedAmountUnitId != null)
&& (recommendedAmountUnitId.compareTo(Short.valueOf("1")) == 0)) {
return true;
}
return false;
}
private CollectionSheetCustomerAccountDto sumAssociatedCustomerAccountCollectionFees(
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollections,
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollectionFees) {
final CollectionSheetCustomerAccountDto totalCollection = sumAccountCollections(customerAccountCollections);
final CollectionSheetCustomerAccountDto totalCollectionFee = sumAccountCollectionFees(customerAccountCollectionFees);
final int accountId = Math.max(totalCollection.getAccountId(), totalCollectionFee.getAccountId());
final int currencyId = Math.max(totalCollection.getCurrencyId(), totalCollectionFee.getCurrencyId());
return new CollectionSheetCustomerAccountDto(accountId, (short) currencyId, totalCollection
.getTotalCustomerAccountCollectionFee()
+ totalCollectionFee.getTotalCustomerAccountCollectionFee());
}
private CollectionSheetCustomerAccountDto sumAccountCollectionFees(
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollectionFees) {
Double totalFee = Double.valueOf("0.0");
if (customerAccountCollectionFees == null) {
return new CollectionSheetCustomerAccountDto(-1, Short.valueOf("1"), totalFee);
}
if (customerAccountCollectionFees.size() > 1) {
throw new IllegalStateException("Multiple currency");
}
return new CollectionSheetCustomerAccountDto(customerAccountCollectionFees.get(0).getAccountId(),
customerAccountCollectionFees.get(0).getCurrencyId(), customerAccountCollectionFees.get(0)
.getTotalFeeAmountDue());
}
private CollectionSheetCustomerAccountDto sumAccountCollections(
final List<CollectionSheetCustomerAccountCollectionDto> customerAccountCollections) {
Double totalFee = Double.valueOf("0.0");
if (customerAccountCollections == null) {
return new CollectionSheetCustomerAccountDto(-1, Short.valueOf("-1"), totalFee);
}
if (customerAccountCollections.size() > 1) {
throw new IllegalStateException("Multiple currency");
}
return new CollectionSheetCustomerAccountDto(customerAccountCollections.get(0).getAccountId(),
customerAccountCollections.get(0).getCurrencyId(), customerAccountCollections.get(0)
.getAccountCollectionPayment());
}
@SuppressWarnings("unchecked")
private CollectionSheetCustomerDto createNullSafeCollectionSheetCustomer(
final CollectionSheetCustomerDto collectionSheetCustomer,
final List<CollectionSheetCustomerLoanDto> associatedLoanRepayments,
final Map<Integer, List<CollectionSheetLoanFeeDto>> outstandingFeesOnLoanRepayments,
final List<CollectionSheetCustomerLoanDto> allLoanDisbursements,
final List<CollectionSheetCustomerSavingDto> associatedSavingAccount,
final List<CollectionSheetCustomerSavingDto> associatedIndividualSavingsAccounts,
final CollectionSheetCustomerAccountDto customerAccount) {
final List<CollectionSheetCustomerSavingDto> savingAccounts = (List<CollectionSheetCustomerSavingDto>) ObjectUtils
.defaultIfNull(associatedSavingAccount, new ArrayList<CollectionSheetCustomerSavingDto>());
final List<CollectionSheetCustomerSavingDto> individualSavingAccounts = (List<CollectionSheetCustomerSavingDto>) ObjectUtils
.defaultIfNull(associatedIndividualSavingsAccounts, new ArrayList<CollectionSheetCustomerSavingDto>());
if (outstandingFeesOnLoanRepayments == null) {
List<CollectionSheetCustomerLoanDto> loanRepaymentsAndDisbursements = new ArrayList<CollectionSheetCustomerLoanDto>();
if (associatedLoanRepayments != null) {
loanRepaymentsAndDisbursements.addAll(associatedLoanRepayments);
}
if (allLoanDisbursements != null) {
loanRepaymentsAndDisbursements.addAll(allLoanDisbursements);
}
return new CollectionSheetCustomerDto(collectionSheetCustomer, loanRepaymentsAndDisbursements,
savingAccounts, individualSavingAccounts, customerAccount);
}
final List<CollectionSheetCustomerLoanDto> loanRepaymentsAndDisbursementsWithFees = new ArrayList<CollectionSheetCustomerLoanDto>();
if (associatedLoanRepayments != null) {
for (CollectionSheetCustomerLoanDto collectionSheetCustomerLoan : associatedLoanRepayments) {
final List<CollectionSheetLoanFeeDto> loanFeesAgainstAccountOfCustomer = outstandingFeesOnLoanRepayments
.get(collectionSheetCustomerLoan.getAccountId());
loanRepaymentsAndDisbursementsWithFees.add(populateCollectionSheetCustomerLoan(
collectionSheetCustomerLoan, loanFeesAgainstAccountOfCustomer));
}
}
if (allLoanDisbursements != null) {
loanRepaymentsAndDisbursementsWithFees.addAll(allLoanDisbursements);
}
return new CollectionSheetCustomerDto(collectionSheetCustomer, loanRepaymentsAndDisbursementsWithFees,
savingAccounts, individualSavingAccounts, customerAccount);
}
private CollectionSheetCustomerLoanDto populateCollectionSheetCustomerLoan(
final CollectionSheetCustomerLoanDto loan, final List<CollectionSheetLoanFeeDto> loanFees) {
if (loanFees == null || loanFees.isEmpty()) {
return loan;
}
if (loanFees.size() > 1) {
throw new IllegalStateException("Multiple summed fees exist against loan account [" + loan.getAccountId()
+ "]. This most likey due to multiple currencies existing which is not supported.");
}
loan.setTotalAccountFees(loanFees.get(0).getTotalFeeAmountDue());
return loan;
}
private void doLog(String str) {
logger.info(str);
}
}