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  import javax.persistence.CascadeType;
27  import javax.persistence.Column;
28  import javax.persistence.Entity;
29  import javax.persistence.FetchType;
30  import javax.persistence.Id;
31  import javax.persistence.JoinColumn;
32  import javax.persistence.OneToMany;
33  import javax.persistence.OrderBy;
34  import javax.persistence.Table;
35  import javax.persistence.Transient;
36  import org.apache.commons.lang.StringUtils;
37  import org.kuali.ole.coa.businessobject.AccountDelegateGlobalDetail;
38  import org.kuali.ole.coa.businessobject.AccountGlobalDetail;
39  import org.kuali.ole.olekrad.service.OLELegacyDataAdapterHelperService;
40  import org.kuali.ole.sys.OLEPropertyConstants;
41  import org.kuali.ole.sys.context.SpringContext;
42  import org.kuali.rice.core.api.util.type.KualiDecimal;
43  import org.kuali.rice.kns.bo.GlobalBusinessObject;
44  import org.kuali.rice.kns.bo.GlobalBusinessObjectDetail;
45  import org.kuali.rice.krad.bo.PersistableBusinessObject;
46  import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
47  import org.kuali.rice.krad.service.BusinessObjectService;
48  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
49  import org.kuali.rice.krad.service.PersistenceStructureService;
50  
51  /**
52   * This class simply acts as a container to hold the List of Delegate Changes and the list of Account entries, for the Global
53   * Delegate Change Document.
54   */
55  @Entity
56  @Table(name = "CA_ACCT_DELEGATE_GBL_T")
57  public class AccountDelegateGlobal extends PersistableBusinessObjectBase  {
58  
59      @Id
60      @Column(name = "FDOC_NBR")
61      protected String documentNumber;
62  
63      @Transient
64      protected String modelName;
65  
66      @Transient
67      protected String modelChartOfAccountsCode;
68  
69      @Transient
70      protected String modelOrganizationCode;
71  
72      @Transient
73      protected AccountDelegateModel model;
74  
75      @OneToMany(targetEntity = AccountGlobalDetail.class, fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST })
76      @JoinColumn(name = "FDOC_NBR", referencedColumnName = "FDOC_NBR", insertable = false, updatable = false)
77      @OrderBy("chartOfAccountsCode, accountNumber")
78      protected List<AccountGlobalDetail> accountGlobalDetails;
79  
80      @OneToMany(targetEntity = AccountDelegateGlobalDetail.class, fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST })
81      @JoinColumn(name = "FDOC_NBR", referencedColumnName = "FDOC_NBR", insertable = false, updatable = false)
82      @OrderBy("accountDelegateUniversalId, financialDocumentTypeCode")
83      protected List<AccountDelegateGlobalDetail> delegateGlobals;
84  
85      /**
86       * Constructs a DelegateGlobal.java.
87       */
88      public AccountDelegateGlobal() {
89          super();
90          accountGlobalDetails = new ArrayList<AccountGlobalDetail>();
91          delegateGlobals = new ArrayList<AccountDelegateGlobalDetail>();
92      }
93  
94      /**
95       * This method adds a single AccountGlobalDetail instance to the list. If one is already present in the list with the same
96       * chartCode and accountNumber, then this new one will not be added.
97       *
98       * @param accountGlobalDetail - populated AccountGlobalDetail instance
99       */
100     public void addAccount(AccountGlobalDetail accountGlobalDetail) {
101 
102         // validate the argument
103         if (accountGlobalDetail == null) {
104             throw new IllegalArgumentException("The accountGlobalDetail instanced passed in was null.");
105         }
106         else if (StringUtils.isBlank(accountGlobalDetail.getChartOfAccountsCode())) {
107             throw new IllegalArgumentException("The chartOfAccountsCode member of the accountGlobalDetail object was not populated.");
108         }
109         else if (StringUtils.isBlank(accountGlobalDetail.getAccountNumber())) {
110             throw new IllegalArgumentException("The accountNumber member of the accountGlobalDetail object was not populated.");
111         }
112 
113         // add the object if one doesnt already exist, otherwise silently do nothing
114         AccountGlobalDetail testObject = getAccount(accountGlobalDetail.getChartOfAccountsCode(), accountGlobalDetail.getAccountNumber());
115         if (testObject == null) {
116             this.accountGlobalDetails.add(accountGlobalDetail);
117         }
118     }
119 
120     /**
121      * This method retrieves the specific AccountGlobalDetail object that corresponds to your requested chartCode and accountNumber
122      * (or a null object if there is no match).
123      *
124      * @param chartCode
125      * @param accountNumber
126      * @return returns the AccountGlobalDetail instance matching the chartCode & accountNumber passed in, or Null if none match
127      */
128     public AccountGlobalDetail getAccount(String chartCode, String accountNumber) {
129 
130         // validate the argument
131         if (StringUtils.isBlank(chartCode)) {
132             throw new IllegalArgumentException("The chartCode argument was null or empty.");
133         }
134         else if (StringUtils.isBlank(accountNumber)) {
135             throw new IllegalArgumentException("The accountNumber argument was null or empty.");
136         }
137 
138         // walk the list of AccountGlobalDetail objects
139         for (Iterator iter = this.accountGlobalDetails.iterator(); iter.hasNext();) {
140             AccountGlobalDetail accountGlobalDetail = (AccountGlobalDetail) iter.next();
141 
142             // if this one is a match, then quit
143             if (chartCode.equalsIgnoreCase(accountGlobalDetail.getChartOfAccountsCode()) && accountNumber.equalsIgnoreCase(accountGlobalDetail.getAccountNumber())) {
144                 return accountGlobalDetail;
145             }
146         }
147 
148         // we return null if one is not found
149         return null;
150     }
151 
152     /**
153      * @see org.kuali.rice.krad.document.GlobalBusinessObject#getGlobalChangesToDelete()
154      */
155     public List<PersistableBusinessObject> generateDeactivationsToPersist() {
156         BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
157 
158         // retreive all the existing delegates for these accounts
159         List<AccountDelegate> bosToDeactivate = new ArrayList();
160         Map<String, Object> fieldValues;
161         Collection existingDelegates;
162         for (AccountGlobalDetail accountDetail : getAccountGlobalDetails()) {
163             fieldValues = new HashMap();
164             fieldValues.put("chartOfAccountsCode", accountDetail.getChartOfAccountsCode());
165             fieldValues.put("accountNumber", accountDetail.getAccountNumber());
166             fieldValues.put("active", true);
167             existingDelegates = KRADServiceLocatorWeb.getLegacyDataAdapter().findMatching(AccountDelegate.class, fieldValues);
168             bosToDeactivate.addAll(existingDelegates);
169         }
170 
171         // mark all the delegates as inactive
172         for (AccountDelegate accountDelegate : bosToDeactivate) {
173             accountDelegate.setActive(false);
174         }
175         return new ArrayList<PersistableBusinessObject>(bosToDeactivate);
176     }
177 
178     /**
179      * @see org.kuali.rice.krad.document.GlobalBusinessObject#applyGlobalChanges(org.kuali.rice.krad.bo.BusinessObject)
180      */
181     @SuppressWarnings("deprecation")
182     public List<PersistableBusinessObject> generateGlobalChangesToPersist() {
183 
184         BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
185         List<AccountDelegate> persistables = new ArrayList();
186 
187         List<AccountDelegateGlobalDetail> changeDocuments = this.getDelegateGlobals();
188         List<AccountGlobalDetail> accountDetails = this.getAccountGlobalDetails();
189 
190         for (AccountDelegateGlobalDetail changeDocument : changeDocuments) {
191             for (AccountGlobalDetail accountDetail : accountDetails) {
192 
193                 Account account = (Account) KRADServiceLocatorWeb.getLegacyDataAdapter().findByPrimaryKey(Account.class, accountDetail.getPrimaryKeys());
194 
195                 // if the account doesnt exist, fail fast, as this should never happen,
196                 // the busines rules for this document should have caught this.
197                 if (account == null) {
198                     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.");
199                 }
200 
201                 // attempt to load the existing Delegate from the DB, if it exists. we do this to avoid
202                 // versionNumber conflicts if we tried to just insert a new record that already existed.
203                 Map pkMap = new HashMap();
204                 pkMap.putAll(accountDetail.getPrimaryKeys()); // chartOfAccountsCode & accountNumber
205                 pkMap.put("financialDocumentTypeCode", changeDocument.getFinancialDocumentTypeCode());
206                 pkMap.put("accountDelegateSystemId", changeDocument.getAccountDelegateUniversalId());
207                 AccountDelegate delegate = (AccountDelegate) KRADServiceLocatorWeb.getLegacyDataAdapter().findByPrimaryKey(AccountDelegate.class, pkMap);
208 
209                 // if there is no existing Delegate with these primary keys, then we're creating a new one,
210                 // so lets populate it with the primary keys
211                 if (delegate == null) {
212                     delegate = new AccountDelegate();
213                     delegate.setChartOfAccountsCode(accountDetail.getChartOfAccountsCode());
214                     delegate.setAccountNumber(accountDetail.getAccountNumber());
215                     delegate.setAccountDelegateSystemId(changeDocument.getAccountDelegateUniversalId());
216                     delegate.setFinancialDocumentTypeCode(changeDocument.getFinancialDocumentTypeCode());
217                     delegate.setActive(true);
218                 }
219                 else {
220                     delegate.setActive(true);
221                 }
222 
223                 // APPROVAL FROM AMOUNT
224                 if (changeDocument.getApprovalFromThisAmount() != null) {
225                     if (!changeDocument.getApprovalFromThisAmount().equals(KualiDecimal.ZERO)) {
226                         delegate.setFinDocApprovalFromThisAmt(changeDocument.getApprovalFromThisAmount());
227                     }
228                 }
229 
230                 // APPROVAL TO AMOUNT
231                 if (changeDocument.getApprovalToThisAmount() != null) {
232                     if (!changeDocument.getApprovalToThisAmount().equals(KualiDecimal.ZERO)) {
233                         delegate.setFinDocApprovalToThisAmount(changeDocument.getApprovalToThisAmount());
234                     }
235                 }
236 
237                 // PRIMARY ROUTING
238                 delegate.setAccountsDelegatePrmrtIndicator(changeDocument.getAccountDelegatePrimaryRoutingIndicator());
239 
240                 // START DATE
241                 if (changeDocument.getAccountDelegateStartDate() != null) {
242                     delegate.setAccountDelegateStartDate(new Date(changeDocument.getAccountDelegateStartDate().getTime()));
243                 }
244 
245                 persistables.add(delegate);
246 
247             }
248         }
249 
250         return new ArrayList<PersistableBusinessObject>(persistables);
251     }
252 
253     /**
254      * @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper()
255      */
256 
257     protected LinkedHashMap toStringMapper() {
258 
259         LinkedHashMap m = new LinkedHashMap();
260 
261         m.put(OLEPropertyConstants.DOCUMENT_NUMBER, this.documentNumber);
262         return m;
263     }
264 
265     /**
266      * @see org.kuali.rice.krad.document.GlobalBusinessObject#getDocumentNumber()
267      */
268     public String getDocumentNumber() {
269         return documentNumber;
270     }
271 
272     /**
273      * @see org.kuali.rice.krad.document.GlobalBusinessObject#setDocumentNumber(java.lang.String)
274      */
275     public void setDocumentNumber(String documentNumber) {
276         this.documentNumber = documentNumber;
277 
278     }
279 
280     /**
281      * Gets the accountGlobalDetails attribute.
282      *
283      * @return Returns the accountGlobalDetails.
284      */
285     public final List<AccountGlobalDetail> getAccountGlobalDetails() {
286         return accountGlobalDetails;
287     }
288 
289     /**
290      * Sets the accountGlobalDetails attribute value.
291      *
292      * @param accountGlobalDetails The accountGlobalDetails to set.
293      */
294     public final void setAccountGlobalDetails(List<AccountGlobalDetail> accountGlobalDetails) {
295         this.accountGlobalDetails = accountGlobalDetails;
296     }
297 
298     /**
299      * Gets the delegateGlobals attribute.
300      *
301      * @return Returns the delegateGlobals.
302      */
303     public final List<AccountDelegateGlobalDetail> getDelegateGlobals() {
304         return delegateGlobals;
305     }
306 
307     /**
308      * Sets the delegateGlobals attribute value.
309      *
310      * @param delegateGlobals The delegateGlobals to set.
311      */
312     public final void setDelegateGlobals(List<AccountDelegateGlobalDetail> delegateGlobals) {
313         this.delegateGlobals = delegateGlobals;
314     }
315 
316     /**
317      * @see org.kuali.rice.krad.document.GlobalBusinessObject#isPersistable()
318      */
319     public boolean isPersistable() {
320         PersistenceStructureService persistenceStructureService = SpringContext.getBean(PersistenceStructureService.class);
321 
322         // fail if the PK for this object is emtpy
323         if (StringUtils.isBlank(documentNumber)) {
324             return false;
325         }
326 
327         // fail if the PKs for any of the contained objects are empty
328         for (AccountDelegateGlobalDetail delegateGlobals : getDelegateGlobals()) {
329             if (!persistenceStructureService.hasPrimaryKeyFieldValues(delegateGlobals)) {
330                 return false;
331             }
332         }
333         for (AccountGlobalDetail account : getAccountGlobalDetails()) {
334             if (!persistenceStructureService.hasPrimaryKeyFieldValues(account)) {
335                 return false;
336             }
337         }
338 
339         // otherwise, its all good
340         return true;
341     }
342 
343     public String getModelName() {
344         return modelName;
345     }
346 
347     public void setModelName(String loadModelName) {
348         this.modelName = loadModelName;
349     }
350 
351     public String getModelChartOfAccountsCode() {
352         return modelChartOfAccountsCode;
353     }
354 
355     public void setModelChartOfAccountsCode(String loadModelChartOfAccountsCode) {
356         this.modelChartOfAccountsCode = loadModelChartOfAccountsCode;
357     }
358 
359     public String getModelOrganizationCode() {
360         return modelOrganizationCode;
361     }
362 
363     public void setModelOrganizationCode(String loadModelOrganizationCode) {
364         this.modelOrganizationCode = loadModelOrganizationCode;
365     }
366 
367     public AccountDelegateModel getModel() {
368         return model;
369     }
370 
371     public void setModel(AccountDelegateModel loadModel) {
372         this.model = loadModel;
373     }
374 
375     public List<? extends GlobalBusinessObjectDetail> getAllDetailObjects() {
376         ArrayList<GlobalBusinessObjectDetail> details = new ArrayList<GlobalBusinessObjectDetail>(accountGlobalDetails.size() + delegateGlobals.size());
377         details.addAll(accountGlobalDetails);
378         details.addAll(delegateGlobals);
379         return details;
380     }
381 
382     @Override
383     public void linkEditableUserFields() {
384         super.linkEditableUserFields();
385         if (this == null) {
386             throw new IllegalArgumentException("globalDelegate parameter passed in was null");
387         }
388         List<PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
389         bos.addAll(getDelegateGlobals());
390         new OLELegacyDataAdapterHelperService().linkUserFields(bos);
391     }
392 
393     /**
394      * @see org.kuali.rice.krad.bo.PersistableBusinessObjectBase#buildListOfDeletionAwareLists()
395      */
396     @Override
397     public List<Collection<PersistableBusinessObject>> buildListOfDeletionAwareLists() {
398         List<Collection<PersistableBusinessObject>> managedLists = super.buildListOfDeletionAwareLists();
399 
400         managedLists.add( new ArrayList<PersistableBusinessObject>( getAccountGlobalDetails() ) );
401         managedLists.add( new ArrayList<PersistableBusinessObject>( getDelegateGlobals() ) );
402 
403         return managedLists;
404     }
405 }