001 /* 002 * Copyright 2011 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 */ 016 package org.kuali.kfs.module.purap.document.validation.impl; 017 018 import java.util.Iterator; 019 import java.util.List; 020 021 import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine; 022 import org.kuali.kfs.module.purap.businessobject.PurApItem; 023 import org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocument; 024 import org.kuali.kfs.sys.KFSPropertyConstants; 025 import org.kuali.kfs.sys.businessobject.AccountingLine; 026 import org.kuali.kfs.sys.document.AccountingDocument; 027 import org.kuali.rice.kns.util.GlobalVariables; 028 import org.kuali.rice.kns.util.MessageMap; 029 030 /** 031 * Utility class to set error path for Payment Request validations 032 */ 033 public class PurchasingAccountsPayableErrorPathUtil { 034 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchasingAccountsPayableErrorPathUtil.class); 035 036 /** 037 * Fix the GlobalVariables.getErrorMap errorPath for how payment request documents needs them in order to properly display 038 * errors on the interface. This is different from other financial document accounting lines because instead payment request 039 * documents have accounting lines insides of items. Hence the error path is slightly different. 040 * 041 * @param financialDocument The financial document the errors will be posted to. 042 * @param accountingLine The accounting line the error will be posted on. 043 */ 044 public static void fixErrorPath(AccountingDocument financialDocument, AccountingLine accountingLine) { 045 List<PurApItem> items = ((PurchasingAccountsPayableDocument) financialDocument).getItems(); 046 047 if (accountingLine.isSourceAccountingLine()) { 048 PurApAccountingLine targetAccountingLineToBeFound = (PurApAccountingLine) accountingLine; 049 050 String errorPath = KFSPropertyConstants.DOCUMENT; 051 052 boolean done = false; 053 int itemLineIndex = 0; 054 for (Iterator iterItemEntries = items.iterator(); !done && iterItemEntries.hasNext(); itemLineIndex++) { 055 PurApItem item = (PurApItem) iterItemEntries.next(); 056 057 // Loop over the item to find the accountingLine's location. Keep another counter handy. 058 int accountingLineCounter = 0; 059 for (Iterator iterSourceAccountingLines = item.getSourceAccountingLines().iterator(); !done && iterSourceAccountingLines.hasNext(); accountingLineCounter++) { 060 PurApAccountingLine sourceAccountingLine = (PurApAccountingLine) iterSourceAccountingLines.next(); 061 062 // Only targetAccountingLineToBeFound has sequenceNumber always not null. We should put it in the preceding place of this comparison. Otherwise, it may run into NPE. 063 if (targetAccountingLineToBeFound.getSequenceNumber().equals(sourceAccountingLine.getSequenceNumber())) { 064 // Found the item, capture error path, and set boolean (break isn't enough for 2 loops). 065 errorPath = errorPath + "." + KFSPropertyConstants.ITEM + "[" + itemLineIndex + "]." + KFSPropertyConstants.SOURCE_ACCOUNTING_LINES + "[" + accountingLineCounter + "]"; 066 done = true; 067 } 068 } 069 } 070 071 if (!done) { 072 LOG.warn("fixErrorPath failed to locate item accountingLine=" + accountingLine.toString()); 073 } 074 075 // Clearing the error path is not a universal solution but should work. In this case it's the only choice 076 // because KualiRuleService.applyRules will miss to remove the previous transaction added error path (only this 077 // method knows how it is called). 078 MessageMap errorMap = GlobalVariables.getMessageMap(); 079 errorMap.clearErrorPath(); 080 errorMap.addToErrorPath(errorPath); 081 } 082 } 083 }