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.endow.document.validation.impl;
017    
018    import java.sql.Date;
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.kuali.kfs.coa.businessobject.Account;
025    import org.kuali.kfs.coa.businessobject.Chart;
026    import org.kuali.kfs.coa.businessobject.ObjectCode;
027    import org.kuali.kfs.coa.businessobject.ProjectCode;
028    import org.kuali.kfs.coa.businessobject.SubAccount;
029    import org.kuali.kfs.coa.businessobject.SubObjectCode;
030    import org.kuali.kfs.module.endow.EndowConstants;
031    import org.kuali.kfs.module.endow.EndowKeyConstants;
032    import org.kuali.kfs.module.endow.EndowPropertyConstants;
033    import org.kuali.kfs.module.endow.businessobject.EndowmentRecurringCashTransfer;
034    import org.kuali.kfs.module.endow.businessobject.EndowmentRecurringCashTransferGLTarget;
035    import org.kuali.kfs.module.endow.businessobject.EndowmentRecurringCashTransferKEMIDTarget;
036    import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionCode;
037    import org.kuali.kfs.module.endow.businessobject.KEMID;
038    import org.kuali.kfs.module.endow.businessobject.KemidGeneralLedgerAccount;
039    import org.kuali.kfs.module.endow.document.service.EndowmentTransactionDocumentService;
040    import org.kuali.kfs.module.endow.document.service.impl.FrequencyCodeServiceImpl;
041    import org.kuali.kfs.sys.KFSKeyConstants;
042    import org.kuali.kfs.sys.KFSPropertyConstants;
043    import org.kuali.kfs.sys.context.SpringContext;
044    import org.kuali.kfs.sys.service.UniversityDateService;
045    import org.kuali.rice.kns.bo.PersistableBusinessObject;
046    import org.kuali.rice.kns.document.MaintenanceDocument;
047    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
048    import org.kuali.rice.kns.service.BusinessObjectService;
049    import org.kuali.rice.kns.service.DataDictionaryService;
050    import org.kuali.rice.kns.util.GlobalVariables;
051    import org.kuali.rice.kns.util.KualiDecimal;
052    import org.kuali.rice.kns.util.ObjectUtils;
053    import org.kuali.rice.kns.util.RiceKeyConstants;
054    
055    public class EndowmentRecurringCashTransferTransactionRule extends MaintenanceDocumentRuleBase {
056        
057        @Override
058        public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) {
059            boolean isValid = true;
060            isValid &= super.processCustomAddCollectionLineBusinessRules(document, collectionName, line);
061            
062            EndowmentRecurringCashTransfer endowmentRecurringCashTransfer = (EndowmentRecurringCashTransfer) document.getNewMaintainableObject().getBusinessObject();
063            boolean success = true;
064            
065            // apply rules
066            if (collectionName.equals(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_KEMID_TARGET)){
067                EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget = (EndowmentRecurringCashTransferKEMIDTarget) document.getNewMaintainableObject().getNewCollectionLine(collectionName);
068                // check rules
069                success &= validateKEMIDTarget(endowmentRecurringCashTransferKEMIDTarget);
070                // check transaction type
071                success &= checkTransactionType(endowmentRecurringCashTransfer.getTransactionType(), collectionName, endowmentRecurringCashTransfer);
072    
073                // all rules are passed, then set sequenceNumber and add to collection
074                if (success){
075                    endowmentRecurringCashTransferKEMIDTarget.setTargetSequenceNumber(endowmentRecurringCashTransfer.incrementTargetKemidNextSeqNumber().toString());
076                    isValid = true;
077                } else isValid = false;
078            } else {
079                EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget = (EndowmentRecurringCashTransferGLTarget) document.getNewMaintainableObject().getNewCollectionLine(collectionName);
080                // check rules
081                success &= validateGlTarget(endowmentRecurringCashTransferGLTarget);
082                // check transaction type
083                success &= checkTransactionType(endowmentRecurringCashTransfer.getTransactionType(), collectionName, endowmentRecurringCashTransfer);
084                // all rules are passed, then set sequenceNumber and add to collection
085                if (success){
086                    endowmentRecurringCashTransferGLTarget.setTargetSequenceNumber(endowmentRecurringCashTransfer.incrementTargetGlNextSeqNumber().toString());
087                    isValid = true;
088                } else isValid = false;      
089            }
090            return isValid;
091        }
092        
093        @Override
094        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
095            EndowmentRecurringCashTransfer endowmentRecurringCashTransfer = (EndowmentRecurringCashTransfer) document.getNewMaintainableObject().getBusinessObject();
096            boolean success = true;
097            success &= super.processCustomRouteDocumentBusinessRules(document);
098    
099            // source rules
100            success &= checkTargetExistence(endowmentRecurringCashTransfer);
101    
102            if (ObjectUtils.isNotNull(endowmentRecurringCashTransfer.getTransactionType())){
103                success &= checkTransactionType(endowmentRecurringCashTransfer);
104            }
105            
106            // check eTran code
107            String kemid = endowmentRecurringCashTransfer.getSourceKemid();
108            String etranCode = endowmentRecurringCashTransfer.getSourceEtranCode();
109            String ipIndicator = endowmentRecurringCashTransfer.getSourceIncomeOrPrincipal();
110            // refresh Etran obj
111            endowmentRecurringCashTransfer.refreshReferenceObject(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_ETRAN_CODE_OBJ);
112            success &= checkSourceEtranType(endowmentRecurringCashTransfer.getEtranCodeObj());
113            
114            success &= checkEtranCodeWithChart(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_SOURCE_ETRAN_CODE, kemid, etranCode, ipIndicator);
115            
116            success &= checkActiveSourceKemid(endowmentRecurringCashTransfer.getKemidObj());
117            
118            success &= checkFrequencyCodeReferenceExists(endowmentRecurringCashTransfer);
119            
120            if (ObjectUtils.isNotNull(endowmentRecurringCashTransfer.getFrequencyCode())){
121                setNextProcessDate(endowmentRecurringCashTransfer);
122                setLastProcessDate(endowmentRecurringCashTransfer);
123            }
124    
125            checkSourceActiveAndSetTargetActive(endowmentRecurringCashTransfer);
126    
127            // KEMIDTarget rules
128            int kemidIndex = 0;
129            for (EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget : endowmentRecurringCashTransfer.getKemidTarget()) {
130                String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_KEMID_TARGET + "[" + kemidIndex + "]";
131                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
132        
133                success &= validateKEMIDTarget(endowmentRecurringCashTransferKEMIDTarget);
134                
135                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
136                kemidIndex++;
137            }
138            
139            success &= checkKemidAllPercent(endowmentRecurringCashTransfer.getKemidTarget());
140    
141            success &= checkKemidPercentForSameEtranCode(endowmentRecurringCashTransfer.getKemidTarget());
142            
143            // GLTarget rules
144            int glIndex = 0;
145            for (EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget : endowmentRecurringCashTransfer.getGlTarget()) {
146                String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_GL_TARGET + "[" + glIndex + "]";
147                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
148    
149                success &= validateGlTarget(endowmentRecurringCashTransferGLTarget);
150                
151                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
152                glIndex++;
153            }
154    
155            success &= checkGlAllPercent(endowmentRecurringCashTransfer.getGlTarget());
156    
157            success &= checkGlPercentForSameEtranCode(endowmentRecurringCashTransfer.getGlTarget());
158    
159            if (GlobalVariables.getMessageMap().hasErrors()) {
160                return false;
161            }
162    
163            return success;
164        }
165        
166        protected boolean validateKEMIDTarget(EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget){
167            boolean success = true;
168            
169            success &= checkTargetKemidReferenceExists(endowmentRecurringCashTransferKEMIDTarget);
170            
171            success &= checkGeneralLedgerAccount(endowmentRecurringCashTransferKEMIDTarget);
172    
173            success &= checkKemidAmountPercentEtranCodeField(endowmentRecurringCashTransferKEMIDTarget);
174            
175            String kemid = endowmentRecurringCashTransferKEMIDTarget.getTargetKemid();
176            String etranCode = endowmentRecurringCashTransferKEMIDTarget.getTargetEtranCode();
177            String ipIndicator = endowmentRecurringCashTransferKEMIDTarget.getTargetIncomeOrPrincipal();
178            
179            // refresh Etran obj
180            endowmentRecurringCashTransferKEMIDTarget.refreshReferenceObject(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_ETRAN_CODE_OBJ);
181            success &= checkTargetEtranType(endowmentRecurringCashTransferKEMIDTarget.getTargetEtranCodeObj());
182            
183            success &= checkEtranCodeWithChart(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_ETRAN_CODE, kemid, etranCode, ipIndicator);
184    
185            return success;
186        }
187    
188        protected boolean validateGlTarget(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget){
189            boolean success = true;
190            
191            success &= checkChart(endowmentRecurringCashTransferGLTarget);
192            
193            success &= checkAccount(endowmentRecurringCashTransferGLTarget);
194            
195            if(ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetSubAccountNumber())){
196                success &= checkSubAccount(endowmentRecurringCashTransferGLTarget);
197            }
198    
199            success &= checkObjectCode(endowmentRecurringCashTransferGLTarget);
200    
201            if(ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetFinancialSubObjectCode())){
202                success &= checkSubObjectCode(endowmentRecurringCashTransferGLTarget);
203            }
204            
205            if(ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetProjectCode())){
206                success &= checkProjectCode(endowmentRecurringCashTransferGLTarget);
207            }
208            
209            success &= checkGlAmountPercentEtranCodeField(endowmentRecurringCashTransferGLTarget);
210    
211            return success;
212        }
213    
214        // EndowmentRecurringCashTransfer rules
215        protected boolean checkTargetExistence(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
216            // just checking existence will be enough
217            // because document type and related target object is already checked.
218            if (endowmentRecurringCashTransfer.getKemidTarget().size() < 1 && endowmentRecurringCashTransfer.getGlTarget().size() < 1) {
219                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_TARGETOBJECT_EXIST);
220                return false;
221            }
222            return true;
223        }
224        
225        protected boolean checkTransactionType(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
226            if (endowmentRecurringCashTransfer.getTransactionType().equals(EndowConstants.ENDOWMENT_CASH_TRANSFER_TRANSACTION_TYPE)){
227                if (endowmentRecurringCashTransfer.getGlTarget().size() > 0){
228                    putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, KFSKeyConstants.ERROR_TRANSACTION_TYPE_INVALID);
229                    return false;
230                }
231            } else if (endowmentRecurringCashTransfer.getKemidTarget().size() > 0){
232                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, KFSKeyConstants.ERROR_TRANSACTION_TYPE_INVALID);
233                return false;
234            }
235            return true;
236        }
237        
238        protected boolean checkFrequencyCodeReferenceExists(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
239            endowmentRecurringCashTransfer.refreshReferenceObject("frequencyCodeObj");
240            if (ObjectUtils.isNull(endowmentRecurringCashTransfer.getFrequencyCodeObj())) {
241                String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(EndowmentRecurringCashTransfer.class.getName()).getAttributeDefinition(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_FREQUENCY_CODE).getLabel();
242                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_FREQUENCY_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
243                return false;
244            }
245            return true;
246        }
247    
248    
249        protected boolean checkActiveSourceKemid(KEMID kemid){
250            if (kemid.isClose()){
251                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_SOURCE_KEMID, RiceKeyConstants.ERROR_CLOSED, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_SOURCE_KEMID);
252                return false;
253            }
254            return true;
255        }
256    
257        protected void setNextProcessDate(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
258    
259            if (ObjectUtils.isNull(endowmentRecurringCashTransfer.getNextProcessDate())) {
260                FrequencyCodeServiceImpl frequencyCodeServiceImpl = (FrequencyCodeServiceImpl) SpringContext.getBean(FrequencyCodeServiceImpl.class);
261                Date processDate = frequencyCodeServiceImpl.calculateProcessDate(endowmentRecurringCashTransfer.getFrequencyCode());
262                endowmentRecurringCashTransfer.setNextProcessDate(processDate);
263            }
264        }
265    
266        protected void setLastProcessDate(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
267    
268            if (ObjectUtils.isNull(endowmentRecurringCashTransfer.getLastProcessDate())) {
269                FrequencyCodeServiceImpl frequencyCodeServiceImpl = (FrequencyCodeServiceImpl) SpringContext.getBean(FrequencyCodeServiceImpl.class);
270                Date processDate = frequencyCodeServiceImpl.calculateProcessDate(endowmentRecurringCashTransfer.getFrequencyCode());
271                endowmentRecurringCashTransfer.setLastProcessDate(processDate);
272            }
273        }
274    
275        protected void checkSourceActiveAndSetTargetActive(EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
276            if (!endowmentRecurringCashTransfer.isActive()) {
277                for (EndowmentRecurringCashTransferKEMIDTarget kemidTarget : endowmentRecurringCashTransfer.getKemidTarget()) {
278                    kemidTarget.setActive(false);
279                }
280    
281                for (EndowmentRecurringCashTransferGLTarget glTarget : endowmentRecurringCashTransfer.getGlTarget()) {
282                    glTarget.setActive(false);
283                }
284            }
285        }
286    
287        // EndowmentRecurringCashTransferKEMIDTarget rules
288        protected boolean checkTargetKemidReferenceExists(EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget) {
289            // TODO: need to constants?
290            endowmentRecurringCashTransferKEMIDTarget.refreshReferenceObject("targetKemidObj");
291            if (ObjectUtils.isNull(endowmentRecurringCashTransferKEMIDTarget.getTargetKemidObj())) {
292                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_KEMID, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_KEMID);
293                return false;
294            } else {
295                if (endowmentRecurringCashTransferKEMIDTarget.getTargetKemidObj().isClose()){
296                    GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_KEMID, RiceKeyConstants.ERROR_CLOSED, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_KEMID);
297                }
298            }
299            return true;
300        }
301    
302        protected boolean checkGeneralLedgerAccount(EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget) {
303            Map objectKeys = new HashMap();
304            objectKeys.put(EndowPropertyConstants.KEMID, endowmentRecurringCashTransferKEMIDTarget.getTargetKemid());
305            objectKeys.put(EndowPropertyConstants.KEMID_GL_ACCOUNT_IP_INDICATOR_CD, endowmentRecurringCashTransferKEMIDTarget.getTargetIncomeOrPrincipal());
306            KemidGeneralLedgerAccount kemidGeneralLedgerAccount = (KemidGeneralLedgerAccount) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(KemidGeneralLedgerAccount.class, objectKeys);
307            if (ObjectUtils.isNull(kemidGeneralLedgerAccount)) {
308                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_INCOME_OR_PRINCIPAL_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.KEMID_GL_ACCOUNT_IP_INDICATOR_CD);
309                return false;
310            }
311            return true;
312        }
313    
314        protected boolean checkKemidAmountPercentEtranCodeField(EndowmentRecurringCashTransferKEMIDTarget endowmentRecurringCashTransferKEMIDTarget) {
315            if (ObjectUtils.isNotNull(endowmentRecurringCashTransferKEMIDTarget.getTargetAmount())) {
316                if (ObjectUtils.isNotNull(endowmentRecurringCashTransferKEMIDTarget.getTargetPercent()) || ObjectUtils.isNotNull(endowmentRecurringCashTransferKEMIDTarget.getTargetUseEtranCode())) {
317                    GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_AMOUNT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_AMOUNT_SPECIFIED_PERCENT_OR_ETRAN);
318                    return false; 
319                }
320            }
321            return true;
322        }
323        
324        protected boolean checkSourceEtranType(EndowmentTransactionCode eTranCodeObject){
325            if (!checkEtranType(eTranCodeObject)){
326                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_SOURCE_ETRAN_CODE, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_ETRAN_CODE_INVALID_TYPE);
327                return false; 
328            }
329            return true;   
330        }
331        
332        protected boolean checkTargetEtranType(EndowmentTransactionCode eTranCodeObject){
333            if (!checkEtranType(eTranCodeObject)){
334                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_ETRAN_CODE, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_ETRAN_CODE_INVALID_TYPE);
335                return false; 
336            }
337            return true;   
338        }
339        
340        protected boolean checkEtranType(EndowmentTransactionCode eTranCodeObject) {
341            String eTranTypeCode = eTranCodeObject.getEndowmentTransactionTypeCode();
342            if (!eTranTypeCode.equals(EndowConstants.EndowmentTransactionTypeCodes.INCOME_TYPE_CODE) && !eTranTypeCode.equals(EndowConstants.EndowmentTransactionTypeCodes.EXPENSE_TYPE_CODE)){
343                return false; 
344            }
345            return true;
346        }
347        
348        protected boolean checkEtranCodeWithChart(String property, String kemid, String etranCode, String ipIndicator) {
349            EndowmentTransactionDocumentService endowmentTransactionDocumentService = SpringContext.getBean(EndowmentTransactionDocumentService.class);
350            if (!endowmentTransactionDocumentService.matchChartBetweenKEMIDAndETranCode(kemid, etranCode, ipIndicator)){
351                if (EndowConstants.IncomePrincipalIndicator.PRINCIPAL.equalsIgnoreCase(ipIndicator))
352                    GlobalVariables.getMessageMap().putError(property, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_TRANSACTION_LINE_CHART_CODE_DOES_NOT_MATCH_FOR_PRINCIPAL);
353                else
354                    GlobalVariables.getMessageMap().putError(property, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_TRANSACTION_LINE_CHART_CODE_DOES_NOT_MATCH_FOR_INCOME);
355                return false;
356            }
357            return true;
358        }
359    
360        protected boolean checkKemidAllPercent(List<EndowmentRecurringCashTransferKEMIDTarget> kemidTargetList) {
361            KualiDecimal totalTarget = KualiDecimal.ZERO;
362            for (EndowmentRecurringCashTransferKEMIDTarget kemidTarget : kemidTargetList) {
363                if (ObjectUtils.isNotNull(kemidTarget.getTargetPercent())) {
364                    totalTarget = totalTarget.add(kemidTarget.getTargetPercent());
365                }
366            }
367            if (totalTarget.isGreaterThan(new KualiDecimal(100))) {
368                String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_KEMID_TARGET + "[" + 0 + "]";
369                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
370                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PERCENT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_TOTAL_PERCENT_CANNOT_EXCEED);
371                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
372                return false;
373            }
374            return true;
375        }
376    
377        protected boolean checkKemidPercentForSameEtranCode(List<EndowmentRecurringCashTransferKEMIDTarget> kemidTargetList) {
378            List<String> etranCodeList = new ArrayList();
379    
380            for (EndowmentRecurringCashTransferKEMIDTarget kemidTarget : kemidTargetList) {
381                if (ObjectUtils.isNotNull(kemidTarget.getTargetUseEtranCode())) {
382                    etranCodeList.add(kemidTarget.getTargetUseEtranCode());
383                }
384            }
385    
386            if (etranCodeList.size() > 0) {
387                for (String etranCode : etranCodeList) {
388                    KualiDecimal totalTarget = KualiDecimal.ZERO;
389    
390                    for (EndowmentRecurringCashTransferKEMIDTarget kemidTarget : kemidTargetList) {
391                        if (kemidTarget.getTargetUseEtranCode().equals(etranCode) && ObjectUtils.isNotNull(kemidTarget.getTargetPercent())) {
392                            totalTarget = totalTarget.add(kemidTarget.getTargetPercent());
393                        }
394                    }
395                    if (totalTarget.isGreaterThan(new KualiDecimal(100))) {
396                        String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_KEMID_TARGET + "[" + 0 + "]";
397                        GlobalVariables.getMessageMap().addToErrorPath(errorPath);
398                        GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PERCENT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_TOTAL_PERCENT_CANNOT_EXCEED_SPECIFIED_ETRAN);
399                        GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
400                        return false;
401                    }
402                }
403            }
404            return true;
405        }
406    
407        // EndowmentRecurringCashTransferGLTarget rules
408        protected boolean checkChart(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
409            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.CHART);
410            Chart chart = endowmentRecurringCashTransferGLTarget.getChart();
411            if (ObjectUtils.isNull(chart) || !chart.isActive()) {
412                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_COA_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_COA_CODE);
413                return false;
414            }
415            return true;
416        }
417    
418        protected boolean checkAccount(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
419            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
420            Account account = endowmentRecurringCashTransferGLTarget.getAccount();
421            if (ObjectUtils.isNull(account) || account.isClosed()) {
422                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_ACCOUNT_NUMBER);
423                return false;
424            }
425            return true;
426        }
427    
428        protected boolean checkSubAccount(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
429            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.SUB_ACCOUNT);
430            SubAccount subAccount = endowmentRecurringCashTransferGLTarget.getSubAccount();
431            if (ObjectUtils.isNull(subAccount) || !subAccount.isActive()) {
432                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_ACCOUNT_NUMBER);
433                return false;
434            }
435    
436            Map objectKeys = new HashMap();
437            objectKeys.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, endowmentRecurringCashTransferGLTarget.getTargetChartOfAccountsCode());
438            objectKeys.put(KFSPropertyConstants.ACCOUNT_NUMBER, endowmentRecurringCashTransferGLTarget.getTargetAccountsNumber());
439            objectKeys.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, endowmentRecurringCashTransferGLTarget.getTargetSubAccountNumber());
440            subAccount = (SubAccount) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(SubAccount.class, objectKeys);
441            if (ObjectUtils.isNull(subAccount)) {
442                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_ACCOUNT_NUMBER);
443                return false;
444            }
445            return true;
446        }
447    
448        protected boolean checkObjectCode(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
449            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
450            ObjectCode objectCode = endowmentRecurringCashTransferGLTarget.getObjectCode();
451            if (ObjectUtils.isNull(objectCode) || !objectCode.isActive()) {
452                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_OBJECT_CODE);
453                return false;
454            }
455    
456            Map objectKeys = new HashMap();
457            objectKeys.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
458            objectKeys.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, endowmentRecurringCashTransferGLTarget.getTargetChartOfAccountsCode());
459            objectKeys.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, endowmentRecurringCashTransferGLTarget.getTargetFinancialObjectCode());
460            objectCode = (ObjectCode) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(ObjectCode.class, objectKeys);
461            if (ObjectUtils.isNull(objectCode)) {
462                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_OBJECT_CODE);
463                return false;
464            }
465            return true;
466        }
467    
468        protected boolean checkSubObjectCode(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
469            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.SUB_OBJECT_CODE);
470            SubObjectCode subObjectCode = endowmentRecurringCashTransferGLTarget.getSubObjectCode();
471            if (ObjectUtils.isNull(subObjectCode) || !subObjectCode.isActive()) {
472                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_OBJECT_CODE);
473                return false;
474            }
475    
476            Map objectKeys = new HashMap();
477            objectKeys.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
478            objectKeys.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, endowmentRecurringCashTransferGLTarget.getTargetChartOfAccountsCode());
479            objectKeys.put(KFSPropertyConstants.ACCOUNT_NUMBER, endowmentRecurringCashTransferGLTarget.getTargetAccountsNumber());
480            objectKeys.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, endowmentRecurringCashTransferGLTarget.getTargetFinancialObjectCode());
481            objectKeys.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, endowmentRecurringCashTransferGLTarget.getTargetFinancialSubObjectCode());
482            subObjectCode = (SubObjectCode) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(SubObjectCode.class, objectKeys);
483            if (ObjectUtils.isNull(subObjectCode)) {
484                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_SUB_OBJECT_CODE);
485                return false;
486            }
487            return true;
488        }
489    
490        protected boolean checkProjectCode(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
491            endowmentRecurringCashTransferGLTarget.refreshReferenceObject(KFSPropertyConstants.PROJECT_CODE);
492            ProjectCode projectCode = endowmentRecurringCashTransferGLTarget.getProjectCode();
493            if (ObjectUtils.isNull(projectCode) || !projectCode.isActive()) {
494                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PROJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PROJECT_CODE);
495                return false;
496            }
497            return true;
498        }
499    
500        protected boolean checkGlAmountPercentEtranCodeField(EndowmentRecurringCashTransferGLTarget endowmentRecurringCashTransferGLTarget) {
501            if (ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetFdocLineAmount())) {
502                if (ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetPercent()) || ObjectUtils.isNotNull(endowmentRecurringCashTransferGLTarget.getTargetUseEtranCode())) {
503                    GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_FDOC_LINE_AMOUNT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_AMOUNT_SPECIFIED_PERCENT_OR_ETRAN);
504                    return false;
505                }
506            }
507            return true;
508        }
509    
510        protected boolean checkGlAllPercent(List<EndowmentRecurringCashTransferGLTarget> glTargetList) {
511            KualiDecimal totalTarget = KualiDecimal.ZERO;
512            for (EndowmentRecurringCashTransferGLTarget glTarget : glTargetList) {
513                if (ObjectUtils.isNotNull(glTarget.getTargetPercent())) {
514                    totalTarget = totalTarget.add(glTarget.getTargetPercent());
515                }
516            }
517    
518            if (totalTarget.isGreaterThan(new KualiDecimal(100))) {
519                String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_GL_TARGET + "[" + 0 + "]";
520                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
521                GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PERCENT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_TOTAL_PERCENT_CANNOT_EXCEED);
522                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
523                return false;
524            }
525            return true;
526        }
527    
528        protected boolean checkGlPercentForSameEtranCode(List<EndowmentRecurringCashTransferGLTarget> glTargetList) {
529            List<String> etranCodeList = new ArrayList();
530    
531            for (EndowmentRecurringCashTransferGLTarget glTarget : glTargetList) {
532                if (ObjectUtils.isNotNull(glTarget.getTargetUseEtranCode())) {
533                    etranCodeList.add(glTarget.getTargetUseEtranCode());
534                }
535            }
536            if (etranCodeList.size() > 0) {
537                for (String etranCode : etranCodeList) {
538                    KualiDecimal totalTarget = KualiDecimal.ZERO;
539    
540                    for (EndowmentRecurringCashTransferGLTarget glTarget : glTargetList) {
541                        if (glTarget.getTargetUseEtranCode().equals(etranCode) && ObjectUtils.isNotNull(glTarget.getTargetPercent())){
542                            totalTarget = totalTarget.add(glTarget.getTargetPercent());
543                        }
544                    }
545    
546                    if (totalTarget.isGreaterThan(new KualiDecimal(100))) {
547                        String errorPath = MAINTAINABLE_ERROR_PREFIX + EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_GL_TARGET + "[" + 0 + "]";
548                        GlobalVariables.getMessageMap().addToErrorPath(errorPath);
549                        GlobalVariables.getMessageMap().putError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TARGET_PERCENT, EndowKeyConstants.EndowmentRecurringCashTransfer.ERROR_DOCUMENT_TOTAL_PERCENT_CANNOT_EXCEED_SPECIFIED_ETRAN);
550                        GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
551                        return false;
552                    }
553                }
554            }
555            return true;
556        }
557        
558        protected boolean checkTransactionType(String transactionType, String collectionName, EndowmentRecurringCashTransfer endowmentRecurringCashTransfer) {
559            if (ObjectUtils.isNull(endowmentRecurringCashTransfer.getTransactionType())){
560                putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, KFSKeyConstants.ERROR_REQUIRED, EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE);
561                return false;
562            }
563            
564            if (transactionType.equals(EndowConstants.ENDOWMENT_CASH_TRANSFER_TRANSACTION_TYPE)){
565                if (!collectionName.equals(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_KEMID_TARGET)){
566                    putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, KFSKeyConstants.ERROR_TRANSACTION_TYPE_INVALID);
567                    return false;
568                } 
569            } else {
570                if (!collectionName.equals(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_GL_TARGET)){
571                    putFieldError(EndowPropertyConstants.ENDOWMENT_RECURRING_CASH_TRANSF_TRANSACTION_TYPE, KFSKeyConstants.ERROR_TRANSACTION_TYPE_INVALID);
572                    return false;
573                } 
574            }
575            return true;
576        }
577    }