1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.coa.service.impl;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.kuali.ole.coa.businessobject.Account;
29  import org.kuali.ole.coa.service.AccountPersistenceStructureService;
30  import org.kuali.ole.sys.OLEPropertyConstants;
31  import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
32  import org.kuali.rice.krad.bo.PersistableBusinessObject;
33  import org.kuali.rice.krad.service.impl.PersistenceStructureServiceImpl;
34  import org.kuali.rice.krad.util.KRADConstants;
35  import org.springframework.beans.factory.InitializingBean;
36  
37  public class AccountPersistenceStructureServiceImpl extends PersistenceStructureServiceImpl implements AccountPersistenceStructureService, InitializingBean {
38      
39      protected List<AccountReferencePersistenceExemption> accountReferencePersistenceExemptions;
40      protected Map<Class<?>, List<AccountReferencePersistenceExemption>> accountReferencePersistenceExemptionsMap;
41                  
42      
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68      
69      public boolean isAccountRelatedClass(Class clazz) {
70          List<String> pks = listPrimaryKeyFieldNames(clazz);
71          
72          if (pks.contains(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE) && pks.contains(OLEPropertyConstants.ACCOUNT_NUMBER )) {
73              return true;
74          }
75          else {
76              return false;
77          }
78      }
79      
80      private MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
81  
82      public void setMaintenanceDocumentDictionaryService(MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService) {
83          this.maintenanceDocumentDictionaryService = maintenanceDocumentDictionaryService;
84      }
85  
86      @SuppressWarnings("rawtypes")
87      public Map<String, Class> listCollectionAccountFields(PersistableBusinessObject bo) {
88          Map<String, Class> accountFields = new HashMap<String, Class>(); 
89          Iterator<Map.Entry<String, Class>> collObjs = listCollectionObjectTypes(bo).entrySet().iterator();
90          
91          while (collObjs.hasNext()) {
92              Map.Entry<String, Class> entry = (Map.Entry<String, Class>)collObjs.next();
93              String accountCollName = entry.getKey();
94              Class accountCollType = entry.getValue();
95              
96              
97              if (isAccountRelatedClass(accountCollType)) {
98                  
99                  String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(bo.getClass());
100                 if (maintenanceDocumentDictionaryService.getMaintainableCollection(docTypeName, accountCollName) == null)
101                     continue;
102                 
103                 
104                 accountFields.put(accountCollName, accountCollType);                
105             }
106         }
107         
108         return accountFields;
109     }
110     
111     @SuppressWarnings("rawtypes")
112     public Set<String> listCollectionChartOfAccountsCodeNames(PersistableBusinessObject bo) {
113         Set<String> coaCodeNames = new HashSet<String>();
114         String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(bo.getClass());
115         Iterator<Map.Entry<String, Class>> collObjs = listCollectionObjectTypes(bo).entrySet().iterator();
116         
117         while (collObjs.hasNext()) {
118             Map.Entry<String, Class> entry = (Map.Entry<String, Class>)collObjs.next();
119             String accountCollName = entry.getKey();
120             Class accountCollType = entry.getValue();
121             
122             
123             if (isAccountRelatedClass(accountCollType)) {
124                 
125                 if (maintenanceDocumentDictionaryService.getMaintainableCollection(docTypeName, accountCollName) == null)
126                     continue;
127 
128                 
129                 String coaCodeName = KRADConstants.ADD_PREFIX + "." + accountCollName + "." + OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE;
130                 coaCodeNames.add(coaCodeName);
131             }
132         }
133 
134         return coaCodeNames;
135     }
136     
137     @SuppressWarnings("rawtypes")
138     public Map<String, Class> listReferenceAccountFields(PersistableBusinessObject bo) {
139         Map<String, Class> accountFields = new HashMap<String, Class>();       
140         Iterator<Map.Entry<String, Class>> refObjs = listReferenceObjectFields(bo).entrySet().iterator();
141         
142         while (refObjs.hasNext()) {
143             Map.Entry<String, Class> entry = (Map.Entry<String, Class>)refObjs.next();
144             String accountName = entry.getKey();
145             Class accountType = entry.getValue();
146             
147             
148             if (isAccountRelatedClass(accountType)) {
149                 String coaCodeName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
150                 String acctNumName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.ACCOUNT_NUMBER);
151                 
152                 
153                 
154                 
155                 
156                 
157                 if (StringUtils.isEmpty(coaCodeName) || StringUtils.isEmpty(acctNumName)) 
158                     continue;
159                 
160                 
161                 
162                 
163                 
164                 List<String> pks = listPrimaryKeyFieldNames(bo.getClass());
165                 if (bo instanceof Account && pks.contains(coaCodeName) && pks.contains(acctNumName )) 
166                     continue;                
167                 
168                 
169                 String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(bo.getClass());
170                 if (maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, coaCodeName) == null ||
171                     maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, acctNumName) == null)
172                     continue;
173                 
174                 
175                 accountFields.put(accountName, accountType);                
176             }
177         }
178         
179         return accountFields;
180     }
181     
182     @SuppressWarnings("rawtypes")
183     public Map<String, String> listChartCodeAccountNumberPairs(PersistableBusinessObject bo) {
184         Map<String, String> chartAccountPairs = new HashMap<String, String>();       
185         Iterator<Map.Entry<String, Class>> refObjs = listReferenceObjectFields(bo).entrySet().iterator();
186         
187         while (refObjs.hasNext()) {
188             Map.Entry<String, Class> entry = (Map.Entry<String, Class>)refObjs.next();
189             String accountName = entry.getKey();
190             Class accountType = entry.getValue();
191             
192             
193             if (isAccountRelatedClass(accountType)) {
194                 String coaCodeName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
195                 String acctNumName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.ACCOUNT_NUMBER);
196                 
197                 
198                 
199                 
200                 
201                 
202                 if (StringUtils.isEmpty(coaCodeName) || StringUtils.isEmpty(acctNumName)) 
203                     continue;
204                 
205                 
206                 
207                 
208                 
209                 List<String> pks = listPrimaryKeyFieldNames(bo.getClass());
210                 if (bo instanceof Account && pks.contains(coaCodeName) && pks.contains(acctNumName )) 
211                     continue;                
212                                 
213                 
214                 if (isExemptedFromAccountsCannotCrossChartsRules(bo.getClass(), coaCodeName, acctNumName)) {
215                     continue;
216                 }
217                                 
218                 
219                 String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(bo.getClass());
220                 if (maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, coaCodeName) == null ||
221                     maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, acctNumName) == null)
222                     continue;
223                 
224                 
225                 chartAccountPairs.put(coaCodeName, acctNumName);                
226             }
227         }
228         
229         return chartAccountPairs;
230     }
231     
232     @SuppressWarnings("rawtypes")
233     public Map<String, String> listAccountNumberChartCodePairs(PersistableBusinessObject bo) {
234         Map<String, String> accountChartPairs = new HashMap<String, String>(); 
235         Iterator<Map.Entry<String, Class>> refObjs = listReferenceObjectFields(bo).entrySet().iterator();
236         
237         while (refObjs.hasNext()) {
238             Map.Entry<String, Class> entry = (Map.Entry<String, Class>)refObjs.next();
239             String accountName = entry.getKey();
240             Class accountType = entry.getValue();
241             
242             
243             if (isAccountRelatedClass(accountType)) {
244                 String coaCodeName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
245                 String acctNumName = getForeignKeyFieldName(bo.getClass(), accountName, OLEPropertyConstants.ACCOUNT_NUMBER);
246                 
247                 
248                 
249                 
250                 
251                 
252                 if (StringUtils.isEmpty(coaCodeName) || StringUtils.isEmpty(acctNumName)) 
253                     continue;
254                 
255                 
256                 
257                 
258                 
259                 List<String> pks = listPrimaryKeyFieldNames(bo.getClass());
260                 if (bo instanceof Account && pks.contains(coaCodeName) && pks.contains(acctNumName )) 
261                     continue;                
262                 
263                 
264                 if (isExemptedFromAccountsCannotCrossChartsRules(bo.getClass(), coaCodeName, acctNumName)) {
265                     continue;
266                 }
267 
268                 
269                 String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(bo.getClass());
270                 if (maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, coaCodeName) == null ||
271                     maintenanceDocumentDictionaryService.getMaintainableField(docTypeName, acctNumName) == null)
272                     continue;
273                 
274                 
275                 accountChartPairs.put(acctNumName, coaCodeName);
276             }
277         }
278         
279         return accountChartPairs;
280     }
281 
282     public Set<String> listChartOfAccountsCodeNames(PersistableBusinessObject bo) {;
283         return listChartCodeAccountNumberPairs(bo).keySet();        
284     }
285 
286     public Set<String> listAccountNumberNames(PersistableBusinessObject bo) {
287         return listAccountNumberChartCodePairs(bo).keySet();     
288     }
289     
290     public String getChartOfAccountsCodeName(PersistableBusinessObject bo, String accountNumberName) {
291         return listAccountNumberChartCodePairs(bo).get(accountNumberName);        
292     }
293     
294     public String getAccountNumberName(PersistableBusinessObject bo, String chartOfAccountsCodeName) {
295         return listChartCodeAccountNumberPairs(bo).get(chartOfAccountsCodeName);        
296     }
297     
298     
299 
300 
301 
302 
303 
304     @SuppressWarnings("rawtypes")
305     @Override
306     public Map<String, Class> listReferenceObjectFields(PersistableBusinessObject bo) {
307         if ( isPersistable(bo.getClass() ) ) {
308             return super.listReferenceObjectFields(bo);
309         }
310         return Collections.emptyMap();
311     }
312     
313     
314 
315 
316 
317 
318 
319 
320 
321     public boolean isExemptedFromAccountsCannotCrossChartsRules(Class<?> relationshipOwningClass, String chartOfAccountsCodePropertyName, String accountNumberPropertyName) {
322         final List<AccountReferencePersistenceExemption> exemptionList = accountReferencePersistenceExemptionsMap.get(relationshipOwningClass);
323         if (exemptionList != null) {
324             for (AccountReferencePersistenceExemption exemption : exemptionList) {
325                 if (exemption.matches(chartOfAccountsCodePropertyName, accountNumberPropertyName)) {
326                     return true;
327                 }
328             }
329         }
330         return false;
331     }
332 
333     
334 
335 
336 
337     public void setAccountReferencePersistenceExemptions(List<AccountReferencePersistenceExemption> accountReferencePersistenceExemptions) {
338         this.accountReferencePersistenceExemptions = accountReferencePersistenceExemptions;
339     }
340 
341     
342 
343 
344 
345     @Override
346     public void afterPropertiesSet() throws Exception {
347         accountReferencePersistenceExemptionsMap = new HashMap<Class<?>, List<AccountReferencePersistenceExemption>>();
348         if (accountReferencePersistenceExemptions != null) {
349             for (AccountReferencePersistenceExemption exemption : accountReferencePersistenceExemptions) {
350                 List<AccountReferencePersistenceExemption> exemptionList = accountReferencePersistenceExemptionsMap.get(exemption.getParentBusinessObjectClass());
351                 if (exemptionList == null) {
352                     exemptionList = new ArrayList<AccountReferencePersistenceExemption>();
353                 }
354                 exemptionList.add(exemption);
355                 accountReferencePersistenceExemptionsMap.put(exemption.getParentBusinessObjectClass(), exemptionList);
356             }
357         }
358     }
359     
360 }