View Javadoc
1   /*
2    * Copyright 2007 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.coa.businessobject;
17  
18  import java.sql.Date;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.LinkedHashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.kuali.ole.sys.OLEPropertyConstants;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.rice.core.api.util.type.KualiDecimal;
31  import org.kuali.rice.krad.bo.GlobalBusinessObject;
32  import org.kuali.rice.krad.bo.GlobalBusinessObjectDetail;
33  import org.kuali.rice.krad.bo.PersistableBusinessObject;
34  import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
35  import org.kuali.rice.krad.service.BusinessObjectService;
36  import org.kuali.rice.krad.service.PersistenceStructureService;
37  
38  /**
39   * This class simply acts as a container to hold the List of Delegate Changes and the list of Account entries, for the Global
40   * Delegate Change Document.
41   */
42  public class AccountDelegateGlobal extends PersistableBusinessObjectBase implements GlobalBusinessObject {
43  
44      protected String documentNumber;
45  
46      protected String modelName;
47      protected String modelChartOfAccountsCode;
48      protected String modelOrganizationCode;
49  
50      protected AccountDelegateModel model;
51  
52      protected List<AccountGlobalDetail> accountGlobalDetails;
53      protected List<AccountDelegateGlobalDetail> delegateGlobals;
54  
55      /**
56       * Constructs a DelegateGlobal.java.
57       */
58      public AccountDelegateGlobal() {
59          super();
60          accountGlobalDetails = new ArrayList<AccountGlobalDetail>();
61          delegateGlobals = new ArrayList<AccountDelegateGlobalDetail>();
62      }
63  
64      /**
65       * This method adds a single AccountGlobalDetail instance to the list. If one is already present in the list with the same
66       * chartCode and accountNumber, then this new one will not be added.
67       * 
68       * @param accountGlobalDetail - populated AccountGlobalDetail instance
69       */
70      public void addAccount(AccountGlobalDetail accountGlobalDetail) {
71  
72          // validate the argument
73          if (accountGlobalDetail == null) {
74              throw new IllegalArgumentException("The accountGlobalDetail instanced passed in was null.");
75          }
76          else if (StringUtils.isBlank(accountGlobalDetail.getChartOfAccountsCode())) {
77              throw new IllegalArgumentException("The chartOfAccountsCode member of the accountGlobalDetail object was not populated.");
78          }
79          else if (StringUtils.isBlank(accountGlobalDetail.getAccountNumber())) {
80              throw new IllegalArgumentException("The accountNumber member of the accountGlobalDetail object was not populated.");
81          }
82  
83          // add the object if one doesnt already exist, otherwise silently do nothing
84          AccountGlobalDetail testObject = getAccount(accountGlobalDetail.getChartOfAccountsCode(), accountGlobalDetail.getAccountNumber());
85          if (testObject == null) {
86              this.accountGlobalDetails.add(accountGlobalDetail);
87          }
88      }
89  
90      /**
91       * This method retrieves the specific AccountGlobalDetail object that corresponds to your requested chartCode and accountNumber
92       * (or a null object if there is no match).
93       * 
94       * @param chartCode
95       * @param accountNumber
96       * @return returns the AccountGlobalDetail instance matching the chartCode & accountNumber passed in, or Null if none match
97       */
98      public AccountGlobalDetail getAccount(String chartCode, String accountNumber) {
99  
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 }