1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.fp.document.validation.impl;
17  
18  import java.util.List;
19  
20  import org.kuali.ole.fp.businessobject.CapitalAssetAccountsGroupDetails;
21  import org.kuali.ole.fp.businessobject.CapitalAssetInformation;
22  import org.kuali.ole.fp.document.CapitalAssetEditable;
23  import org.kuali.ole.integration.cab.CapitalAssetBuilderModuleService;
24  import org.kuali.ole.sys.OLEConstants;
25  import org.kuali.ole.sys.OLEKeyConstants;
26  import org.kuali.ole.sys.OLEPropertyConstants;
27  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
28  import org.kuali.ole.sys.businessobject.TargetAccountingLine;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.ole.sys.document.AccountingDocument;
31  import org.kuali.ole.sys.document.validation.GenericValidation;
32  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
33  import org.kuali.rice.core.api.util.type.KualiDecimal;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  import org.kuali.rice.krad.util.MessageMap;
36  import org.kuali.rice.krad.util.ObjectUtils;
37  
38  
39  
40  
41  public class CapitalAssetInformationValidation extends GenericValidation {
42      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CapitalAssetInformationValidation.class);
43  
44      private CapitalAssetBuilderModuleService capitalAssetBuilderModuleService = SpringContext.getBean(CapitalAssetBuilderModuleService.class);
45      private AccountingDocument accountingDocumentForValidation;
46  
47      
48  
49  
50      public boolean validate(AttributedDocumentEvent event) {
51          boolean valid = true ;
52          
53          
54          valid &= accountingLinesDisributedToCapitalAssets(accountingDocumentForValidation);
55  
56          if (valid) {
57              
58              valid &= capitalAssetsAccountLinesMatchToAccountingLines(accountingDocumentForValidation);
59          }
60  
61          if (valid) {
62              
63              valid &= amountsForCapitalAssetsAndAccountLinesMatch(accountingDocumentForValidation);
64          }
65  
66          if (valid) {
67              
68              valid &= amountsForCapitalAssetsAndDistributedAccountLinesMatch(accountingDocumentForValidation);
69          }
70          
71          if (valid) {
72              
73              valid &= hasValidCapitalAssetInformation(accountingDocumentForValidation);
74          }
75          
76          return valid;
77      }
78  
79      
80  
81  
82  
83  
84  
85  
86  
87  
88      protected boolean accountingLinesDisributedToCapitalAssets(AccountingDocument accountingDocument) {
89          LOG.debug("accountingLinesDisributedToCapitalAssets(accountingDocument) - start");
90  
91          boolean distributed = true;
92          
93          if (accountingDocument instanceof CapitalAssetEditable == false) {
94              return true;
95          }
96  
97          CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) accountingDocument;
98          List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation();
99          
100         List<SourceAccountingLine> sourceAccountLines = accountingDocument.getSourceAccountingLines();
101         
102         int accountIndex = 0;
103         
104         for (SourceAccountingLine sourceAccount : sourceAccountLines)  {
105             if (capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(sourceAccount)) {
106                 
107                 
108                 if (!checkSourceDistributedAccountingLineExists(sourceAccount, capitalAssets)) {
109                     
110                     GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(OLEPropertyConstants.DOCUMENT + "." + OLEConstants.SOURCE_ACCOUNTING_LINE_ERRORS + "[" + accountIndex + "]" + "." + OLEPropertyConstants.ACCOUNT_NUMBER, OLEKeyConstants.ERROR_DOCUMENT_SOURCE_ACCOUNTING_LINE_NOT_DISTRIBUTED, sourceAccount.getAccountNumber());
111                     distributed = false;
112                     accountIndex++;
113                     
114                     break;
115                 }
116             }
117         }
118 
119         List<TargetAccountingLine> targetAccountLines = accountingDocument.getTargetAccountingLines();
120         
121         accountIndex = 0;
122         for (TargetAccountingLine targetAccount : targetAccountLines)  {
123             
124             if (capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(targetAccount)) {
125                 
126                 
127                 if (!checkTargetDistributedAccountingLineExists(targetAccount, capitalAssets)) {
128                     
129                     GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(OLEPropertyConstants.DOCUMENT + "." + OLEConstants.TARGET_ACCOUNTING_LINE_ERRORS + "[" + accountIndex + "]" + "." + OLEPropertyConstants.ACCOUNT_NUMBER, OLEKeyConstants.ERROR_DOCUMENT_TARGET_ACCOUNTING_LINE_NOT_DISTRIBUTED, targetAccount.getAccountNumber());
130                     distributed = false;
131                     accountIndex++;
132                     
133                     break;
134                 }
135             }
136         }
137         
138         return distributed;
139     }
140     
141     
142 
143 
144 
145 
146 
147 
148 
149     protected boolean checkSourceDistributedAccountingLineExists(SourceAccountingLine accountLine, List<CapitalAssetInformation> capitalAssets) {
150         boolean exists = false;
151         
152         for (CapitalAssetInformation capitalAsset : capitalAssets) {
153             for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAsset.getCapitalAssetAccountsGroupDetails()) {
154                 if (groupAccountLine.getSequenceNumber().compareTo(accountLine.getSequenceNumber()) == 0 && 
155                         groupAccountLine.getFinancialDocumentLineTypeCode().equals(accountLine.getFinancialDocumentLineTypeCode()) && 
156                         groupAccountLine.getChartOfAccountsCode().equals(accountLine.getChartOfAccountsCode()) && 
157                         groupAccountLine.getAccountNumber().equals(accountLine.getAccountNumber()) && 
158                         groupAccountLine.getFinancialObjectCode().equals(accountLine.getFinancialObjectCode())) {
159                     return true;
160                 }
161             }
162         }
163         
164         return exists;
165     }
166     
167     
168 
169 
170 
171 
172 
173 
174 
175     protected boolean checkTargetDistributedAccountingLineExists(TargetAccountingLine accountLine, List<CapitalAssetInformation> capitalAssets) {
176         boolean exists = false;
177         
178         for (CapitalAssetInformation capitalAsset : capitalAssets) {
179             for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAsset.getCapitalAssetAccountsGroupDetails()) {
180                 if (groupAccountLine.getSequenceNumber().compareTo(accountLine.getSequenceNumber()) == 0 && 
181                         groupAccountLine.getFinancialDocumentLineTypeCode().equals(accountLine.getFinancialDocumentLineTypeCode()) && 
182                         groupAccountLine.getChartOfAccountsCode().equals(accountLine.getChartOfAccountsCode()) && 
183                         groupAccountLine.getAccountNumber().equals(accountLine.getAccountNumber()) && 
184                         groupAccountLine.getFinancialObjectCode().equals(accountLine.getFinancialObjectCode())) {
185                     return true;
186                 }
187             }
188         }
189         
190         return exists;
191     }
192 
193     
194     protected boolean hasValidCapitalAssetInformation(AccountingDocument accountingDocument) {
195         LOG.debug("hasValidCapitalAssetInformation(Document) - start");
196         boolean isValid = true;
197         
198         if (accountingDocument instanceof CapitalAssetEditable == false) {
199             return true;
200         }
201 
202         CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) accountingDocument;
203         List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation();
204 
205         int index = 0;
206         for (CapitalAssetInformation capitalAssetInformation : capitalAssets) {
207             if (ObjectUtils.isNotNull(capitalAssetInformation)) {
208                 MessageMap errors = GlobalVariables.getMessageMap();
209                 errors.addToErrorPath(OLEPropertyConstants.DOCUMENT);
210                 String parentName = (capitalAssetInformation.getCapitalAssetActionIndicator().equalsIgnoreCase(OLEConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR) ? OLEPropertyConstants.CAPITAL_ASSET_INFORMATION :  OLEPropertyConstants.CAPITAL_ASSET_MODIFY_INFORMATION);
211                 errors.addToErrorPath(parentName);
212                 String errorPathPrefix = OLEPropertyConstants.CAPITAL_ASSET_INFORMATION + "[" + index + "].";
213                 errors.addToErrorPath(errorPathPrefix);
214                 
215                 isValid &= capitalAssetBuilderModuleService.validateFinancialProcessingData(accountingDocument, capitalAssetInformation, index);
216                 
217                 errors.removeFromErrorPath(errorPathPrefix);
218                 errors.removeFromErrorPath(parentName);
219                 errors.removeFromErrorPath(OLEPropertyConstants.DOCUMENT);
220                 index++;
221             }
222         }
223         
224         isValid &= capitalAssetBuilderModuleService.validateAssetTags(accountingDocument);
225         
226         return isValid;
227     }
228 
229     
230 
231 
232 
233 
234 
235 
236 
237 
238 
239     protected boolean capitalAssetsAccountLinesMatchToAccountingLines(AccountingDocument accountingDocument) {
240         LOG.debug("capitalAssetsAccountLinesMatchToAccountingLines(accountingDocument) - start");
241 
242         boolean distributed = true;
243         
244         if (accountingDocument instanceof CapitalAssetEditable == false) {
245             return true;
246         }
247 
248         CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) accountingDocument;
249         List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation();
250 
251         int index = 0;
252         for (CapitalAssetInformation capitalAsset : capitalAssets) {
253             String errorPathPrefix = OLEPropertyConstants.DOCUMENT + "." + OLEPropertyConstants.CAPITAL_ASSET_INFORMATION + "[" + index + "]." + OLEPropertyConstants.CAPITAL_ASSET_NUMBER;
254             
255             if (!checkAccountingLineExists(accountingDocument, capitalAsset, errorPathPrefix)) {
256               
257               
258               
259              
260              
261              
262                 
263              
264                 
265               
266               
267               
268                 index++;
269                 distributed = false;
270                 
271                 break;
272             }
273         }
274         
275         return distributed;
276     }
277     
278     
279 
280 
281 
282 
283 
284 
285 
286 
287 
288     protected boolean checkAccountingLineExists(AccountingDocument accountingDocument, CapitalAssetInformation capitalAsset, String errorPathPrefix) {
289         boolean exists = true;
290         
291         List<CapitalAssetAccountsGroupDetails> groupAccounts = capitalAsset.getCapitalAssetAccountsGroupDetails();
292         for (CapitalAssetAccountsGroupDetails groupAccount: groupAccounts) {
293             if (!accountLineExists(accountingDocument, groupAccount)) {
294                 
295                 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(errorPathPrefix, OLEKeyConstants.ERROR_ASSET_ACCOUNT_NUMBER_LINE_NOT_IN_SOURCE_OR_TARGET_ACCOUNTING_LINES, groupAccount.getAccountNumber());
296                 return false;
297             }
298         }
299         
300         return exists;
301     }
302     
303     
304 
305 
306 
307 
308 
309     protected boolean accountLineExists(AccountingDocument accountingDocument, CapitalAssetAccountsGroupDetails groupAccountLine) {
310         boolean exists = false;
311         
312         List<SourceAccountingLine> sourceAccountLines = accountingDocument.getSourceAccountingLines();
313         for (SourceAccountingLine sourceAccount : sourceAccountLines)  {
314             if (groupAccountLine.getSequenceNumber().compareTo(sourceAccount.getSequenceNumber()) == 0 && 
315                     groupAccountLine.getFinancialDocumentLineTypeCode().equals(sourceAccount.getFinancialDocumentLineTypeCode()) && 
316                     groupAccountLine.getChartOfAccountsCode().equals(sourceAccount.getChartOfAccountsCode()) && 
317                     groupAccountLine.getAccountNumber().equals(sourceAccount.getAccountNumber()) && 
318                     groupAccountLine.getFinancialObjectCode().equals(sourceAccount.getFinancialObjectCode())) {
319                 return true;
320             }
321         }
322         
323         List<TargetAccountingLine> targetAccountLines = accountingDocument.getTargetAccountingLines();
324         for (TargetAccountingLine targetAccount : targetAccountLines)  {
325             if (groupAccountLine.getSequenceNumber().compareTo(targetAccount.getSequenceNumber()) == 0 && 
326                     groupAccountLine.getFinancialDocumentLineTypeCode().equals(targetAccount.getFinancialDocumentLineTypeCode()) && 
327                     groupAccountLine.getChartOfAccountsCode().equals(targetAccount.getChartOfAccountsCode()) && 
328                     groupAccountLine.getAccountNumber().equals(targetAccount.getAccountNumber()) && 
329                     groupAccountLine.getFinancialObjectCode().equals(targetAccount.getFinancialObjectCode())) {
330                 return true;
331             }
332         }
333 
334         return exists;
335     
336     }
337     
338     
339 
340 
341 
342 
343 
344 
345 
346     protected boolean amountsForCapitalAssetsAndAccountLinesMatch(AccountingDocument accountingDocument) {
347         LOG.debug("amountsForCapitalAssetsAndAccountLinesMatch(accountingDocument) - start");
348 
349         boolean amountMatch = true ;
350         
351         if (accountingDocument instanceof CapitalAssetEditable == false) {
352             return true;
353         }
354 
355         CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) accountingDocument;
356         List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation();
357         
358         int accountIndex = 0;
359         
360         List<SourceAccountingLine> sourceAccountLines = accountingDocument.getSourceAccountingLines();
361         for (SourceAccountingLine sourceAccount : sourceAccountLines)  {
362             if (capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(sourceAccount)) {
363                 
364                 
365                 KualiDecimal distributedAmount = getSourceDistributedTotalAmount(sourceAccount, capitalAssets);
366                 
367                 if (sourceAccount.getAmount().compareTo(distributedAmount) != 0) {
368                     
369                     GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(OLEPropertyConstants.DOCUMENT + "." + OLEConstants.SOURCE_ACCOUNTING_LINE_ERRORS + "[" + accountIndex + "]" + "." + OLEPropertyConstants.AMOUNT, OLEKeyConstants.ERROR_DOCUMENT_SOURCE_ACCOUNTING_LINE_AMOUNT_NOT_DISTRIBUTED, sourceAccount.getAccountNumber());
370                     amountMatch = false;
371                     accountIndex++;
372                     
373                     break;
374                 }
375             }
376         }
377 
378         accountIndex = 0;
379         List<TargetAccountingLine> targetAccountLines = accountingDocument.getTargetAccountingLines();
380         for (TargetAccountingLine targetAccount : targetAccountLines)  {
381             
382             if (capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(targetAccount)) {
383                 
384                 
385                 KualiDecimal distributedAmount = getTargetDistributedTotalAmount(targetAccount, capitalAssets);
386                 
387                 if (targetAccount.getAmount().compareTo(distributedAmount) != 0) {
388                     
389                     GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(OLEPropertyConstants.DOCUMENT + "." + OLEConstants.TARGET_ACCOUNTING_LINE_ERRORS + "[" + accountIndex + "]" + "." + OLEPropertyConstants.AMOUNT, OLEKeyConstants.ERROR_DOCUMENT_TARGET_ACCOUNTING_LINE_AMOUNT_NOT_DISTRIBUTED, targetAccount.getAccountNumber());
390                     amountMatch = false;
391                     accountIndex++;
392                     
393                     break;
394                 }
395             }
396         }
397         
398         return amountMatch;
399     }
400     
401     
402 
403 
404 
405 
406 
407 
408 
409 
410     protected KualiDecimal getSourceDistributedTotalAmount(SourceAccountingLine accountLine, List<CapitalAssetInformation> capitalAssets) {
411         KualiDecimal amount = new KualiDecimal(0);
412         
413         for (CapitalAssetInformation capitalAsset : capitalAssets) {
414             for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAsset.getCapitalAssetAccountsGroupDetails()) {
415                 if (groupAccountLine.getSequenceNumber().compareTo(accountLine.getSequenceNumber()) == 0 && 
416                         groupAccountLine.getFinancialDocumentLineTypeCode().equals(accountLine.getFinancialDocumentLineTypeCode()) && 
417                         groupAccountLine.getChartOfAccountsCode().equals(accountLine.getChartOfAccountsCode()) && 
418                         groupAccountLine.getAccountNumber().equals(accountLine.getAccountNumber()) && 
419                         groupAccountLine.getFinancialObjectCode().equals(accountLine.getFinancialObjectCode())) {
420                     amount = amount.add(groupAccountLine.getAmount());
421                 }
422             }
423         }
424         
425         return amount;
426     }
427     
428     
429 
430 
431 
432 
433 
434 
435 
436 
437     protected KualiDecimal getTargetDistributedTotalAmount(TargetAccountingLine accountLine, List<CapitalAssetInformation> capitalAssets) {
438         KualiDecimal amount = new KualiDecimal(0);
439         
440         for (CapitalAssetInformation capitalAsset : capitalAssets) {
441             for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAsset.getCapitalAssetAccountsGroupDetails()) {
442                 if (groupAccountLine.getSequenceNumber().compareTo(accountLine.getSequenceNumber()) == 0 && 
443                         groupAccountLine.getFinancialDocumentLineTypeCode().equals(accountLine.getFinancialDocumentLineTypeCode()) && 
444                         groupAccountLine.getChartOfAccountsCode().equals(accountLine.getChartOfAccountsCode()) && 
445                         groupAccountLine.getAccountNumber().equals(accountLine.getAccountNumber()) && 
446                         groupAccountLine.getFinancialObjectCode().equals(accountLine.getFinancialObjectCode())) {
447                     amount = amount.add(groupAccountLine.getAmount());
448                 }
449             }
450         }
451         
452         return amount;
453     }
454     
455     
456 
457 
458 
459 
460 
461 
462 
463     protected boolean amountsForCapitalAssetsAndDistributedAccountLinesMatch(AccountingDocument accountingDocument) {
464         LOG.debug("amountsForCapitalAssetsAndDistributedAccountLinesMatch(accountingDocument) - start");
465 
466         boolean amountMatch = true;
467         
468         if (accountingDocument instanceof CapitalAssetEditable == false) {
469             return true;
470         }
471 
472         CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) accountingDocument;
473         List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation();
474 
475         int index = 0;
476         for (CapitalAssetInformation capitalAsset : capitalAssets) {
477             String errorPathPrefix = OLEPropertyConstants.DOCUMENT + "." + OLEPropertyConstants.CAPITAL_ASSET_INFORMATION + "[" + index + "]." + OLEPropertyConstants.CAPITAL_ASSET_NUMBER;
478             
479             if (!checkAmount(capitalAsset, errorPathPrefix)) {
480                 index++;
481                 amountMatch = false;
482                 
483                 break;
484             }
485         }
486         
487         return amountMatch;
488     
489     }
490     
491     
492 
493 
494 
495 
496 
497 
498 
499 
500 
501     protected boolean checkAmount(CapitalAssetInformation capitalAsset, String errorPathPrefix) {
502         boolean amountMatch = true;
503         
504         KualiDecimal distributedAccountLinesAmount = new KualiDecimal(0);
505         
506         List<CapitalAssetAccountsGroupDetails> groupAccounts = capitalAsset.getCapitalAssetAccountsGroupDetails();
507         for (CapitalAssetAccountsGroupDetails groupAccount: groupAccounts) {
508             distributedAccountLinesAmount = distributedAccountLinesAmount.add(groupAccount.getAmount());
509         }
510         
511         if (capitalAsset.getCapitalAssetLineAmount().compareTo(distributedAccountLinesAmount) != 0) {
512             
513             GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(errorPathPrefix, OLEKeyConstants.ERROR_ASSET_LINE_AMOUNT_NOT_EQUAL_TO_DISTRIBUTED_ACCOUNTING_LINES);
514             return false;
515         }
516         
517         return amountMatch;
518     }
519     
520     
521 
522 
523 
524 
525     public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
526         this.accountingDocumentForValidation = accountingDocumentForValidation;
527     }
528 
529 }