/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.coa.businessobject;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.krad.bo.GlobalBusinessObject;
import org.kuali.rice.krad.bo.GlobalBusinessObjectDetail;
import org.kuali.rice.krad.bo.PersistableBusinessObject;
import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.PersistenceStructureService;
/**
* This class simply acts as a container to hold the List of Delegate Changes and the list of Account entries, for the Global
* Delegate Change Document.
*/
public class AccountDelegateGlobal extends PersistableBusinessObjectBase implements GlobalBusinessObject {
protected String documentNumber;
protected String modelName;
protected String modelChartOfAccountsCode;
protected String modelOrganizationCode;
protected AccountDelegateModel model;
protected List<AccountGlobalDetail> accountGlobalDetails;
protected List<AccountDelegateGlobalDetail> delegateGlobals;
/**
* Constructs a DelegateGlobal.java.
*/
public AccountDelegateGlobal() {
super();
accountGlobalDetails = new ArrayList<AccountGlobalDetail>();
delegateGlobals = new ArrayList<AccountDelegateGlobalDetail>();
}
/**
* This method adds a single AccountGlobalDetail instance to the list. If one is already present in the list with the same
* chartCode and accountNumber, then this new one will not be added.
*
* @param accountGlobalDetail - populated AccountGlobalDetail instance
*/
public void addAccount(AccountGlobalDetail accountGlobalDetail) {
// validate the argument
if (accountGlobalDetail == null) {
throw new IllegalArgumentException("The accountGlobalDetail instanced passed in was null.");
}
else if (StringUtils.isBlank(accountGlobalDetail.getChartOfAccountsCode())) {
throw new IllegalArgumentException("The chartOfAccountsCode member of the accountGlobalDetail object was not populated.");
}
else if (StringUtils.isBlank(accountGlobalDetail.getAccountNumber())) {
throw new IllegalArgumentException("The accountNumber member of the accountGlobalDetail object was not populated.");
}
// add the object if one doesnt already exist, otherwise silently do nothing
AccountGlobalDetail testObject = getAccount(accountGlobalDetail.getChartOfAccountsCode(), accountGlobalDetail.getAccountNumber());
if (testObject == null) {
this.accountGlobalDetails.add(accountGlobalDetail);
}
}
/**
* This method retrieves the specific AccountGlobalDetail object that corresponds to your requested chartCode and accountNumber
* (or a null object if there is no match).
*
* @param chartCode
* @param accountNumber
* @return returns the AccountGlobalDetail instance matching the chartCode & accountNumber passed in, or Null if none match
*/
public AccountGlobalDetail getAccount(String chartCode, String accountNumber) {
// validate the argument
if (StringUtils.isBlank(chartCode)) {
throw new IllegalArgumentException("The chartCode argument was null or empty.");
}
else if (StringUtils.isBlank(accountNumber)) {
throw new IllegalArgumentException("The accountNumber argument was null or empty.");
}
// walk the list of AccountGlobalDetail objects
for (Iterator iter = this.accountGlobalDetails.iterator(); iter.hasNext();) {
AccountGlobalDetail accountGlobalDetail = (AccountGlobalDetail) iter.next();
// if this one is a match, then quit
if (chartCode.equalsIgnoreCase(accountGlobalDetail.getChartOfAccountsCode()) && accountNumber.equalsIgnoreCase(accountGlobalDetail.getAccountNumber())) {
return accountGlobalDetail;
}
}
// we return null if one is not found
return null;
}
/**
* @see org.kuali.rice.krad.document.GlobalBusinessObject#getGlobalChangesToDelete()
*/
@Override
public List<PersistableBusinessObject> generateDeactivationsToPersist() {
BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
// retreive all the existing delegates for these accounts
List<AccountDelegate> bosToDeactivate = new ArrayList();
Map<String, Object> fieldValues;
Collection existingDelegates;
for (AccountGlobalDetail accountDetail : getAccountGlobalDetails()) {
fieldValues = new HashMap();
fieldValues.put("chartOfAccountsCode", accountDetail.getChartOfAccountsCode());
fieldValues.put("accountNumber", accountDetail.getAccountNumber());
fieldValues.put("active", true);
existingDelegates = boService.findMatching(AccountDelegate.class, fieldValues);
bosToDeactivate.addAll(existingDelegates);
}
// mark all the delegates as inactive
for (AccountDelegate accountDelegate : bosToDeactivate) {
accountDelegate.setActive(false);
}
return new ArrayList<PersistableBusinessObject>(bosToDeactivate);
}
/**
* @see org.kuali.rice.krad.document.GlobalBusinessObject#applyGlobalChanges(org.kuali.rice.krad.bo.BusinessObject)
*/
@Override
@SuppressWarnings("deprecation")
public List<PersistableBusinessObject> generateGlobalChangesToPersist() {
BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
List<AccountDelegate> persistables = new ArrayList();
List<AccountDelegateGlobalDetail> changeDocuments = this.getDelegateGlobals();
List<AccountGlobalDetail> accountDetails = this.getAccountGlobalDetails();
for (AccountDelegateGlobalDetail changeDocument : changeDocuments) {
for (AccountGlobalDetail accountDetail : accountDetails) {
Account account = boService.findByPrimaryKey(Account.class, accountDetail.getPrimaryKeys());
// if the account doesnt exist, fail fast, as this should never happen,
// the busines rules for this document should have caught this.
if (account == null) {
throw new RuntimeException("Account [" + accountDetail.getChartOfAccountsCode() + "-" + accountDetail.getAccountNumber() + "] was not present in the database. " + "This should never happen under normal circumstances, as an invalid account should have " + "been caught by the Business Rules infrastructure.");
}
// attempt to load the existing Delegate from the DB, if it exists. we do this to avoid
// versionNumber conflicts if we tried to just insert a new record that already existed.
Map pkMap = new HashMap();
pkMap.putAll(accountDetail.getPrimaryKeys()); // chartOfAccountsCode & accountNumber
pkMap.put("financialDocumentTypeCode", changeDocument.getFinancialDocumentTypeCode());
pkMap.put("accountDelegateSystemId", changeDocument.getAccountDelegateUniversalId());
AccountDelegate delegate = boService.findByPrimaryKey(AccountDelegate.class, pkMap);
// if there is no existing Delegate with these primary keys, then we're creating a new one,
// so lets populate it with the primary keys
if (delegate == null) {
delegate = new AccountDelegate();
delegate.setChartOfAccountsCode(accountDetail.getChartOfAccountsCode());
delegate.setAccountNumber(accountDetail.getAccountNumber());
delegate.setAccountDelegateSystemId(changeDocument.getAccountDelegateUniversalId());
delegate.setFinancialDocumentTypeCode(changeDocument.getFinancialDocumentTypeCode());
delegate.setActive(true);
}
else {
delegate.setActive(true);
}
// APPROVAL FROM AMOUNT
delegate.setFinDocApprovalFromThisAmt(changeDocument.getApprovalFromThisAmount());
// APPROVAL TO AMOUNT
delegate.setFinDocApprovalToThisAmount(changeDocument.getApprovalToThisAmount());
// PRIMARY ROUTING
delegate.setAccountsDelegatePrmrtIndicator(changeDocument.getAccountDelegatePrimaryRoutingIndicator());
// START DATE
if (changeDocument.getAccountDelegateStartDate() != null) {
delegate.setAccountDelegateStartDate(new Date(changeDocument.getAccountDelegateStartDate().getTime()));
}
persistables.add(delegate);
}
}
return new ArrayList<PersistableBusinessObject>(persistables);
}
/**
* @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper()
*/
protected LinkedHashMap toStringMapper_RICE20_REFACTORME() {
LinkedHashMap m = new LinkedHashMap();
m.put(KFSPropertyConstants.DOCUMENT_NUMBER, this.documentNumber);
return m;
}
/**
* @see org.kuali.rice.krad.document.GlobalBusinessObject#getDocumentNumber()
*/
@Override
public String getDocumentNumber() {
return documentNumber;
}
/**
* @see org.kuali.rice.krad.document.GlobalBusinessObject#setDocumentNumber(java.lang.String)
*/
@Override
public void setDocumentNumber(String documentNumber) {
this.documentNumber = documentNumber;
}
/**
* Gets the accountGlobalDetails attribute.
*
* @return Returns the accountGlobalDetails.
*/
public final List<AccountGlobalDetail> getAccountGlobalDetails() {
return accountGlobalDetails;
}
/**
* Sets the accountGlobalDetails attribute value.
*
* @param accountGlobalDetails The accountGlobalDetails to set.
*/
public final void setAccountGlobalDetails(List<AccountGlobalDetail> accountGlobalDetails) {
this.accountGlobalDetails = accountGlobalDetails;
}
/**
* Gets the delegateGlobals attribute.
*
* @return Returns the delegateGlobals.
*/
public final List<AccountDelegateGlobalDetail> getDelegateGlobals() {
return delegateGlobals;
}
/**
* Sets the delegateGlobals attribute value.
*
* @param delegateGlobals The delegateGlobals to set.
*/
public final void setDelegateGlobals(List<AccountDelegateGlobalDetail> delegateGlobals) {
this.delegateGlobals = delegateGlobals;
}
/**
* @see org.kuali.rice.krad.document.GlobalBusinessObject#isPersistable()
*/
@Override
public boolean isPersistable() {
PersistenceStructureService persistenceStructureService = SpringContext.getBean(PersistenceStructureService.class);
// fail if the PK for this object is emtpy
if (StringUtils.isBlank(documentNumber)) {
return false;
}
// fail if the PKs for any of the contained objects are empty
for (AccountDelegateGlobalDetail delegateGlobals : getDelegateGlobals()) {
if (!persistenceStructureService.hasPrimaryKeyFieldValues(delegateGlobals)) {
return false;
}
}
for (AccountGlobalDetail account : getAccountGlobalDetails()) {
if (!persistenceStructureService.hasPrimaryKeyFieldValues(account)) {
return false;
}
}
// otherwise, its all good
return true;
}
public String getModelName() {
return modelName;
}
public void setModelName(String loadModelName) {
this.modelName = loadModelName;
}
public String getModelChartOfAccountsCode() {
return modelChartOfAccountsCode;
}
public void setModelChartOfAccountsCode(String loadModelChartOfAccountsCode) {
this.modelChartOfAccountsCode = loadModelChartOfAccountsCode;
}
public String getModelOrganizationCode() {
return modelOrganizationCode;
}
public void setModelOrganizationCode(String loadModelOrganizationCode) {
this.modelOrganizationCode = loadModelOrganizationCode;
}
public AccountDelegateModel getModel() {
return model;
}
public void setModel(AccountDelegateModel loadModel) {
this.model = loadModel;
}
@Override
public List<? extends GlobalBusinessObjectDetail> getAllDetailObjects() {
ArrayList<GlobalBusinessObjectDetail> details = new ArrayList<GlobalBusinessObjectDetail>(accountGlobalDetails.size() + delegateGlobals.size());
details.addAll(accountGlobalDetails);
details.addAll(delegateGlobals);
return details;
}
@Override
public void linkEditableUserFields() {
super.linkEditableUserFields();
if (this == null) {
throw new IllegalArgumentException("globalDelegate parameter passed in was null");
}
List<PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
bos.addAll(getDelegateGlobals());
SpringContext.getBean(BusinessObjectService.class).linkUserFields(bos);
}
/**
* @see org.kuali.rice.krad.bo.PersistableBusinessObjectBase#buildListOfDeletionAwareLists()
*/
@Override
public List<Collection<PersistableBusinessObject>> buildListOfDeletionAwareLists() {
List<Collection<PersistableBusinessObject>> managedLists = super.buildListOfDeletionAwareLists();
managedLists.add( new ArrayList<PersistableBusinessObject>( getAccountGlobalDetails() ) );
managedLists.add( new ArrayList<PersistableBusinessObject>( getDelegateGlobals() ) );
return managedLists;
}
}