001/* 002 * Copyright 2007 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.ole.coa.businessobject; 017 018import java.sql.Date; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.LinkedHashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.apache.commons.lang.StringUtils; 028import org.kuali.ole.sys.OLEPropertyConstants; 029import org.kuali.ole.sys.context.SpringContext; 030import org.kuali.rice.core.api.util.type.KualiDecimal; 031import org.kuali.rice.krad.bo.GlobalBusinessObject; 032import org.kuali.rice.krad.bo.GlobalBusinessObjectDetail; 033import org.kuali.rice.krad.bo.PersistableBusinessObject; 034import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 035import org.kuali.rice.krad.service.BusinessObjectService; 036import org.kuali.rice.krad.service.PersistenceStructureService; 037 038/** 039 * This class simply acts as a container to hold the List of Delegate Changes and the list of Account entries, for the Global 040 * Delegate Change Document. 041 */ 042public class AccountDelegateGlobal extends PersistableBusinessObjectBase implements GlobalBusinessObject { 043 044 protected String documentNumber; 045 046 protected String modelName; 047 protected String modelChartOfAccountsCode; 048 protected String modelOrganizationCode; 049 050 protected AccountDelegateModel model; 051 052 protected List<AccountGlobalDetail> accountGlobalDetails; 053 protected List<AccountDelegateGlobalDetail> delegateGlobals; 054 055 /** 056 * Constructs a DelegateGlobal.java. 057 */ 058 public AccountDelegateGlobal() { 059 super(); 060 accountGlobalDetails = new ArrayList<AccountGlobalDetail>(); 061 delegateGlobals = new ArrayList<AccountDelegateGlobalDetail>(); 062 } 063 064 /** 065 * This method adds a single AccountGlobalDetail instance to the list. If one is already present in the list with the same 066 * chartCode and accountNumber, then this new one will not be added. 067 * 068 * @param accountGlobalDetail - populated AccountGlobalDetail instance 069 */ 070 public void addAccount(AccountGlobalDetail accountGlobalDetail) { 071 072 // validate the argument 073 if (accountGlobalDetail == null) { 074 throw new IllegalArgumentException("The accountGlobalDetail instanced passed in was null."); 075 } 076 else if (StringUtils.isBlank(accountGlobalDetail.getChartOfAccountsCode())) { 077 throw new IllegalArgumentException("The chartOfAccountsCode member of the accountGlobalDetail object was not populated."); 078 } 079 else if (StringUtils.isBlank(accountGlobalDetail.getAccountNumber())) { 080 throw new IllegalArgumentException("The accountNumber member of the accountGlobalDetail object was not populated."); 081 } 082 083 // add the object if one doesnt already exist, otherwise silently do nothing 084 AccountGlobalDetail testObject = getAccount(accountGlobalDetail.getChartOfAccountsCode(), accountGlobalDetail.getAccountNumber()); 085 if (testObject == null) { 086 this.accountGlobalDetails.add(accountGlobalDetail); 087 } 088 } 089 090 /** 091 * This method retrieves the specific AccountGlobalDetail object that corresponds to your requested chartCode and accountNumber 092 * (or a null object if there is no match). 093 * 094 * @param chartCode 095 * @param accountNumber 096 * @return returns the AccountGlobalDetail instance matching the chartCode & accountNumber passed in, or Null if none match 097 */ 098 public AccountGlobalDetail getAccount(String chartCode, String accountNumber) { 099 100 // validate the argument 101 if (StringUtils.isBlank(chartCode)) { 102 throw new IllegalArgumentException("The chartCode argument was null or empty."); 103 } 104 else if (StringUtils.isBlank(accountNumber)) { 105 throw new IllegalArgumentException("The accountNumber argument was null or empty."); 106 } 107 108 // walk the list of AccountGlobalDetail objects 109 for (Iterator iter = this.accountGlobalDetails.iterator(); iter.hasNext();) { 110 AccountGlobalDetail accountGlobalDetail = (AccountGlobalDetail) iter.next(); 111 112 // if this one is a match, then quit 113 if (chartCode.equalsIgnoreCase(accountGlobalDetail.getChartOfAccountsCode()) && accountNumber.equalsIgnoreCase(accountGlobalDetail.getAccountNumber())) { 114 return accountGlobalDetail; 115 } 116 } 117 118 // we return null if one is not found 119 return null; 120 } 121 122 /** 123 * @see org.kuali.rice.krad.document.GlobalBusinessObject#getGlobalChangesToDelete() 124 */ 125 public List<PersistableBusinessObject> generateDeactivationsToPersist() { 126 BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class); 127 128 // retreive all the existing delegates for these accounts 129 List<AccountDelegate> bosToDeactivate = new ArrayList(); 130 Map<String, Object> fieldValues; 131 Collection existingDelegates; 132 for (AccountGlobalDetail accountDetail : getAccountGlobalDetails()) { 133 fieldValues = new HashMap(); 134 fieldValues.put("chartOfAccountsCode", accountDetail.getChartOfAccountsCode()); 135 fieldValues.put("accountNumber", accountDetail.getAccountNumber()); 136 fieldValues.put("active", true); 137 existingDelegates = boService.findMatching(AccountDelegate.class, fieldValues); 138 bosToDeactivate.addAll(existingDelegates); 139 } 140 141 // mark all the delegates as inactive 142 for (AccountDelegate accountDelegate : bosToDeactivate) { 143 accountDelegate.setActive(false); 144 } 145 return new ArrayList<PersistableBusinessObject>(bosToDeactivate); 146 } 147 148 /** 149 * @see org.kuali.rice.krad.document.GlobalBusinessObject#applyGlobalChanges(org.kuali.rice.krad.bo.BusinessObject) 150 */ 151 @SuppressWarnings("deprecation") 152 public List<PersistableBusinessObject> generateGlobalChangesToPersist() { 153 154 BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class); 155 List<AccountDelegate> persistables = new ArrayList(); 156 157 List<AccountDelegateGlobalDetail> changeDocuments = this.getDelegateGlobals(); 158 List<AccountGlobalDetail> accountDetails = this.getAccountGlobalDetails(); 159 160 for (AccountDelegateGlobalDetail changeDocument : changeDocuments) { 161 for (AccountGlobalDetail accountDetail : accountDetails) { 162 163 Account account = (Account) boService.findByPrimaryKey(Account.class, accountDetail.getPrimaryKeys()); 164 165 // if the account doesnt exist, fail fast, as this should never happen, 166 // the busines rules for this document should have caught this. 167 if (account == null) { 168 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."); 169 } 170 171 // attempt to load the existing Delegate from the DB, if it exists. we do this to avoid 172 // versionNumber conflicts if we tried to just insert a new record that already existed. 173 Map pkMap = new HashMap(); 174 pkMap.putAll(accountDetail.getPrimaryKeys()); // chartOfAccountsCode & accountNumber 175 pkMap.put("financialDocumentTypeCode", changeDocument.getFinancialDocumentTypeCode()); 176 pkMap.put("accountDelegateSystemId", changeDocument.getAccountDelegateUniversalId()); 177 AccountDelegate delegate = (AccountDelegate) boService.findByPrimaryKey(AccountDelegate.class, pkMap); 178 179 // if there is no existing Delegate with these primary keys, then we're creating a new one, 180 // so lets populate it with the primary keys 181 if (delegate == null) { 182 delegate = new AccountDelegate(); 183 delegate.setChartOfAccountsCode(accountDetail.getChartOfAccountsCode()); 184 delegate.setAccountNumber(accountDetail.getAccountNumber()); 185 delegate.setAccountDelegateSystemId(changeDocument.getAccountDelegateUniversalId()); 186 delegate.setFinancialDocumentTypeCode(changeDocument.getFinancialDocumentTypeCode()); 187 delegate.setActive(true); 188 } 189 else { 190 delegate.setActive(true); 191 } 192 193 // APPROVAL FROM AMOUNT 194 if (changeDocument.getApprovalFromThisAmount() != null) { 195 if (!changeDocument.getApprovalFromThisAmount().equals(KualiDecimal.ZERO)) { 196 delegate.setFinDocApprovalFromThisAmt(changeDocument.getApprovalFromThisAmount()); 197 } 198 } 199 200 // APPROVAL TO AMOUNT 201 if (changeDocument.getApprovalToThisAmount() != null) { 202 if (!changeDocument.getApprovalToThisAmount().equals(KualiDecimal.ZERO)) { 203 delegate.setFinDocApprovalToThisAmount(changeDocument.getApprovalToThisAmount()); 204 } 205 } 206 207 // PRIMARY ROUTING 208 delegate.setAccountsDelegatePrmrtIndicator(changeDocument.getAccountDelegatePrimaryRoutingIndicator()); 209 210 // START DATE 211 if (changeDocument.getAccountDelegateStartDate() != null) { 212 delegate.setAccountDelegateStartDate(new Date(changeDocument.getAccountDelegateStartDate().getTime())); 213 } 214 215 persistables.add(delegate); 216 217 } 218 } 219 220 return new ArrayList<PersistableBusinessObject>(persistables); 221 } 222 223 /** 224 * @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper() 225 */ 226 227 protected LinkedHashMap toStringMapper_RICE20_REFACTORME() { 228 229 LinkedHashMap m = new LinkedHashMap(); 230 231 m.put(OLEPropertyConstants.DOCUMENT_NUMBER, this.documentNumber); 232 return m; 233 } 234 235 /** 236 * @see org.kuali.rice.krad.document.GlobalBusinessObject#getDocumentNumber() 237 */ 238 public String getDocumentNumber() { 239 return documentNumber; 240 } 241 242 /** 243 * @see org.kuali.rice.krad.document.GlobalBusinessObject#setDocumentNumber(java.lang.String) 244 */ 245 public void setDocumentNumber(String documentNumber) { 246 this.documentNumber = documentNumber; 247 248 } 249 250 /** 251 * Gets the accountGlobalDetails attribute. 252 * 253 * @return Returns the accountGlobalDetails. 254 */ 255 public final List<AccountGlobalDetail> getAccountGlobalDetails() { 256 return accountGlobalDetails; 257 } 258 259 /** 260 * Sets the accountGlobalDetails attribute value. 261 * 262 * @param accountGlobalDetails The accountGlobalDetails to set. 263 */ 264 public final void setAccountGlobalDetails(List<AccountGlobalDetail> accountGlobalDetails) { 265 this.accountGlobalDetails = accountGlobalDetails; 266 } 267 268 /** 269 * Gets the delegateGlobals attribute. 270 * 271 * @return Returns the delegateGlobals. 272 */ 273 public final List<AccountDelegateGlobalDetail> getDelegateGlobals() { 274 return delegateGlobals; 275 } 276 277 /** 278 * Sets the delegateGlobals attribute value. 279 * 280 * @param delegateGlobals The delegateGlobals to set. 281 */ 282 public final void setDelegateGlobals(List<AccountDelegateGlobalDetail> delegateGlobals) { 283 this.delegateGlobals = delegateGlobals; 284 } 285 286 /** 287 * @see org.kuali.rice.krad.document.GlobalBusinessObject#isPersistable() 288 */ 289 public boolean isPersistable() { 290 PersistenceStructureService persistenceStructureService = SpringContext.getBean(PersistenceStructureService.class); 291 292 // fail if the PK for this object is emtpy 293 if (StringUtils.isBlank(documentNumber)) { 294 return false; 295 } 296 297 // fail if the PKs for any of the contained objects are empty 298 for (AccountDelegateGlobalDetail delegateGlobals : getDelegateGlobals()) { 299 if (!persistenceStructureService.hasPrimaryKeyFieldValues(delegateGlobals)) { 300 return false; 301 } 302 } 303 for (AccountGlobalDetail account : getAccountGlobalDetails()) { 304 if (!persistenceStructureService.hasPrimaryKeyFieldValues(account)) { 305 return false; 306 } 307 } 308 309 // otherwise, its all good 310 return true; 311 } 312 313 public String getModelName() { 314 return modelName; 315 } 316 317 public void setModelName(String loadModelName) { 318 this.modelName = loadModelName; 319 } 320 321 public String getModelChartOfAccountsCode() { 322 return modelChartOfAccountsCode; 323 } 324 325 public void setModelChartOfAccountsCode(String loadModelChartOfAccountsCode) { 326 this.modelChartOfAccountsCode = loadModelChartOfAccountsCode; 327 } 328 329 public String getModelOrganizationCode() { 330 return modelOrganizationCode; 331 } 332 333 public void setModelOrganizationCode(String loadModelOrganizationCode) { 334 this.modelOrganizationCode = loadModelOrganizationCode; 335 } 336 337 public AccountDelegateModel getModel() { 338 return model; 339 } 340 341 public void setModel(AccountDelegateModel loadModel) { 342 this.model = loadModel; 343 } 344 345 public List<? extends GlobalBusinessObjectDetail> getAllDetailObjects() { 346 ArrayList<GlobalBusinessObjectDetail> details = new ArrayList<GlobalBusinessObjectDetail>(accountGlobalDetails.size() + delegateGlobals.size()); 347 details.addAll(accountGlobalDetails); 348 details.addAll(delegateGlobals); 349 return details; 350 } 351 352 @Override 353 public void linkEditableUserFields() { 354 super.linkEditableUserFields(); 355 if (this == null) { 356 throw new IllegalArgumentException("globalDelegate parameter passed in was null"); 357 } 358 List<PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>(); 359 bos.addAll(getDelegateGlobals()); 360 SpringContext.getBean(BusinessObjectService.class).linkUserFields(bos); 361 } 362 363 /** 364 * @see org.kuali.rice.krad.bo.PersistableBusinessObjectBase#buildListOfDeletionAwareLists() 365 */ 366 @Override 367 public List<Collection<PersistableBusinessObject>> buildListOfDeletionAwareLists() { 368 List<Collection<PersistableBusinessObject>> managedLists = super.buildListOfDeletionAwareLists(); 369 370 managedLists.add( new ArrayList<PersistableBusinessObject>( getAccountGlobalDetails() ) ); 371 managedLists.add( new ArrayList<PersistableBusinessObject>( getDelegateGlobals() ) ); 372 373 return managedLists; 374 } 375}