/*
* 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.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.mifos.config.GeneralConfig;
import org.mifos.core.MifosRuntimeException;
import org.mifos.customers.persistence.CustomerPersistence;
import org.mifos.framework.hibernate.helper.StaticHibernateUtil;
/**
* Loads Collection Sheet data into Hibernate session cache.
*
* This minimises the number of read requests required to process the Collection Sheet.
*/
public class SaveCollectionSheetSessionCache {
private final CustomerPersistence customerPersistence = new CustomerPersistence();
// lists of non-zero accounts
private List<Integer> customerAccounts = new ArrayList<Integer>();
private List<Integer> loanAccounts = new ArrayList<Integer>();
private List<Integer> savingsAccounts = new ArrayList<Integer>();
private List<Integer> allAccounts = new ArrayList<Integer>();
private Boolean worthCaching = false;
private Boolean worthCachingRepayments = false;
private Boolean worthCachingDisbursals = false;
private Boolean worthCachingACCollections = false;
private Boolean worthCachingSavings = false;
private Long prefetchTotalTime = null;
private Long prefetchCustomerHierarchyTotalTime = null;
private Integer prefetchCustomerHierarchyCount = null;
private Long prefetchAccountDataTotalTime = null;
private Integer prefetchAccountDataCount = null;
private Long prefetchLoanSchedulesTotalTime = null;
private Integer prefetchLoanSchedulesCount = null;
private Long prefetchAccountFeeDetailsTotalTime = null;
private Integer prefetchAccountFeeDetailsCount = null;
private Long prefetchCustomerSchedulesTotalTime = null;
private Integer prefetchCustomerSchedulesCount = null;
public void loadSessionCacheWithCollectionSheetData(final SaveCollectionSheetDto saveCollectionSheet,
Short branchId, String searchId) {
Long prefetchTotalTimeStart = System.currentTimeMillis();
Long sTime;
Boolean allowDataPrefetching = GeneralConfig.getAllowDataPrefetchingWhenSavingCollectionSheets();
if (allowDataPrefetching) {
List<Object> prefetchObjectList = null;
analyseSaveCollectionSheet(saveCollectionSheet);
if (worthCaching) {
sTime = System.currentTimeMillis();
prefetchObjectList = submitSavePreFetch("prefetchCustomerHierarchy", branchId, searchId, null);
prefetchCustomerHierarchyTotalTime = System.currentTimeMillis() - sTime;
prefetchCustomerHierarchyCount = prefetchObjectList.size();
makeNonZeroAccountLists(saveCollectionSheet.getSaveCollectionSheetCustomers());
if (allAccounts.size() > 0) {
sTime = System.currentTimeMillis();
prefetchObjectList = submitSavePreFetch("prefetchAccountData", branchId, searchId, allAccounts);
prefetchAccountDataTotalTime = System.currentTimeMillis() - sTime;
prefetchAccountDataCount = prefetchObjectList.size();
}
if (worthCachingRepayments || worthCachingDisbursals) {
sTime = System.currentTimeMillis();
prefetchObjectList = submitSavePreFetch("prefetchLoanSchedules", branchId, searchId, loanAccounts);
prefetchLoanSchedulesTotalTime = System.currentTimeMillis() - sTime;
prefetchLoanSchedulesCount = prefetchObjectList.size();
}
if (worthCachingRepayments || worthCachingDisbursals || worthCachingACCollections) {
sTime = System.currentTimeMillis();
prefetchObjectList = submitSavePreFetch("prefetchAccountFeeDetails", branchId, searchId,
allAccounts);
prefetchAccountFeeDetailsTotalTime = System.currentTimeMillis() - sTime;
prefetchAccountFeeDetailsCount = prefetchObjectList.size();
}
if (worthCachingACCollections) {
sTime = System.currentTimeMillis();
prefetchObjectList = submitSavePreFetch("prefetchCustomerSchedules", branchId, searchId,
customerAccounts);
prefetchCustomerSchedulesTotalTime = System.currentTimeMillis() - sTime;
prefetchCustomerSchedulesCount = prefetchObjectList.size();
}
prefetchTotalTime = System.currentTimeMillis() - prefetchTotalTimeStart;
}
}
}
@SuppressWarnings("unchecked")
private List<Object> submitSavePreFetch(final String queryName, final Short branchId, final String searchId,
final List<Integer> accountIds) {
Session session = StaticHibernateUtil.getSessionTL();
Query query = session.getNamedQuery(queryName);
query.setParameter("BRANCH_ID", branchId);
query.setParameter("SEARCH_ID", searchId);
query.setParameter("SEARCH_ID2", searchId + ".%");
if (accountIds != null) {
// query should fall over if empty list passed through
if (accountIds.size() == 0) {
throw new MifosRuntimeException("Empty Account Id List for Query: " + queryName);
}
query.setParameterList("ACCOUNT_IDS", accountIds);
}
return query.list();
}
private void analyseSaveCollectionSheet(SaveCollectionSheetDto saveCollectionSheet) {
if (saveCollectionSheet.countOneLevelUnder() + saveCollectionSheet.countTwoLevelsUnder() > 2) {
worthCaching = true;
if (saveCollectionSheet.countCustomerAccounts() > 2) {
worthCachingACCollections = true;
}
if (saveCollectionSheet.countLoanDisbursements() > 2) {
worthCachingDisbursals = true;
}
if (saveCollectionSheet.countLoanRepayments() > 2) {
worthCachingRepayments = true;
}
}
}
private void makeNonZeroAccountLists(List<SaveCollectionSheetCustomerDto> saveCollectionSheetCustomers) {
if (saveCollectionSheetCustomers != null && saveCollectionSheetCustomers.size() > 0) {
for (SaveCollectionSheetCustomerDto saveCollectionSheetCustomer : saveCollectionSheetCustomers) {
SaveCollectionSheetCustomerAccountDto saveCollectionSheetCustomerAccount = saveCollectionSheetCustomer
.getSaveCollectionSheetCustomerAccount();
if (null != saveCollectionSheetCustomerAccount) {
if (saveCollectionSheetCustomerAccount.getTotalCustomerAccountCollectionFee().compareTo(
BigDecimal.ZERO) > 0) {
customerAccounts.add(saveCollectionSheetCustomerAccount.getAccountId());
}
}
List<SaveCollectionSheetCustomerLoanDto> saveCollectionSheetCustomerLoans = saveCollectionSheetCustomer
.getSaveCollectionSheetCustomerLoans();
if (null != saveCollectionSheetCustomerLoans && saveCollectionSheetCustomerLoans.size() > 0) {
for (SaveCollectionSheetCustomerLoanDto saveCollectionSheetCustomerLoan : saveCollectionSheetCustomerLoans) {
if ((saveCollectionSheetCustomerLoan.getTotalDisbursement().compareTo(BigDecimal.ZERO) > 0)
|| (saveCollectionSheetCustomerLoan.getTotalLoanPayment().compareTo(BigDecimal.ZERO) > 0)) {
loanAccounts.add(saveCollectionSheetCustomerLoan.getAccountId());
}
}
}
List<SaveCollectionSheetCustomerSavingDto> saveCollectionSheetCustomerSavings = saveCollectionSheetCustomer
.getSaveCollectionSheetCustomerSavings();
if (null != saveCollectionSheetCustomerSavings && saveCollectionSheetCustomerSavings.size() > 0) {
for (SaveCollectionSheetCustomerSavingDto saveCollectionSheetCustomerSaving : saveCollectionSheetCustomerSavings) {
if ((saveCollectionSheetCustomerSaving.getTotalWithdrawal().compareTo(BigDecimal.ZERO) > 0)
|| (saveCollectionSheetCustomerSaving.getTotalDeposit().compareTo(BigDecimal.ZERO) > 0)) {
savingsAccounts.add(saveCollectionSheetCustomerSaving.getAccountId());
}
}
}
}
}
allAccounts.addAll(customerAccounts);
allAccounts.addAll(loanAccounts);
allAccounts.addAll(savingsAccounts);
}
public Long getPrefetchTotalTime() {
return this.prefetchTotalTime;
}
public Long getPrefetchCustomerHierarchyTotalTime() {
return this.prefetchCustomerHierarchyTotalTime;
}
public Integer getPrefetchCustomerHierarchyCount() {
return this.prefetchCustomerHierarchyCount;
}
public Long getPrefetchAccountDataTotalTime() {
return this.prefetchAccountDataTotalTime;
}
public Integer getPrefetchAccountDataCount() {
return this.prefetchAccountDataCount;
}
public Long getPrefetchLoanSchedulesTotalTime() {
return this.prefetchLoanSchedulesTotalTime;
}
public Integer getPrefetchLoanSchedulesCount() {
return this.prefetchLoanSchedulesCount;
}
public Long getPrefetchAccountFeeDetailsTotalTime() {
return this.prefetchAccountFeeDetailsTotalTime;
}
public Integer getPrefetchAccountFeeDetailsCount() {
return this.prefetchAccountFeeDetailsCount;
}
public Long getPrefetchCustomerSchedulesTotalTime() {
return this.prefetchCustomerSchedulesTotalTime;
}
public Integer getPrefetchCustomerSchedulesCount() {
return this.prefetchCustomerSchedulesCount;
}
}