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 org.kuali.kfs.module.endow.EndowConstants;
019    import org.kuali.kfs.module.endow.EndowKeyConstants;
020    import org.kuali.kfs.module.endow.EndowPropertyConstants;
021    import org.kuali.kfs.module.endow.businessobject.ClassCode;
022    import org.kuali.kfs.sys.context.SpringContext;
023    import org.kuali.rice.kns.document.MaintenanceDocument;
024    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
025    import org.kuali.rice.kns.service.BusinessObjectService;
026    import org.kuali.rice.kns.util.GlobalVariables;
027    import org.kuali.rice.kns.util.MessageMap;
028    import org.kuali.rice.kns.util.ObjectUtils;
029    
030    public class ClassCodeRule extends MaintenanceDocumentRuleBase {
031        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ClassCodeRule.class);
032    
033        private ClassCode newClassCode;
034    
035        /**
036         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects()
037         */
038        @Override
039        public void setupConvenienceObjects() {
040            newClassCode = (ClassCode) super.getNewBo();
041        }
042    
043        /**
044         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
045         */
046        @Override
047        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
048    
049            boolean isValid = true;
050            isValid &= super.processCustomRouteDocumentBusinessRules(document);
051            MessageMap errorMap = GlobalVariables.getMessageMap();
052            isValid &= errorMap.hasNoErrors();
053    
054            if (isValid) {
055    
056                isValid = validateClassCodeType(newClassCode);
057                isValid = validateTransactionTypeCode(newClassCode);
058                isValid = validateIncomneTransactionPostTypeCode(newClassCode);
059                isValid = validateValuationMethodForPooledInvestments(newClassCode);
060            }
061    
062            return isValid;
063        }
064    
065        /**
066         * This method validates that if the Class Code Type is Liability, the Security Transaction Code must be a Liability Type Code.
067         * Also it checks if endowment transaction type code is Asset or Liability. Also
068         * 
069         * @param classCode
070         * @return true if endowment transaction type code is Asset or Liability, false otherwise
071         */
072        public boolean validateTransactionTypeCode(ClassCode classCode) {
073            boolean success = true;
074            BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
075    
076            classCode.refreshReferenceObject(EndowPropertyConstants.CLASS_CODE_ENDOWMENT_TRANSACTION);
077    
078            if (ObjectUtils.isNotNull(classCode.getEndowmentTransactionCode())) {
079    
080                String endTransactionTypeCode = classCode.getEndowmentTransactionCode().getEndowmentTransactionTypeCode();
081    
082                // If the Class Code is a Liability, the ETRAN code must be a Liability Type Code.
083                if (EndowConstants.ClassCodeTypes.LIABILITY.equalsIgnoreCase(classCode.getClassCodeType())) {
084                    if (ObjectUtils.isNotNull(classCode.getEndowmentTransactionCode()) && !(EndowConstants.EndowmentTransactionTypeCodes.LIABILITY_TYPE_CODE.equalsIgnoreCase(classCode.getEndowmentTransactionCode().getEndowmentTransactionTypeCode()))) {
085                        putFieldError(EndowPropertyConstants.CLASS_CODE_SEC_END_TRANSACTION_CODE, EndowKeyConstants.ClassCodeConstants.ERROR_CLASS_CODE_TYPE_LIABILITY_MUST_HAVE_SEC_ETRAN_TYPE_LIABILITY);
086                        success = false;
087                    }
088                }
089                else if (!(EndowConstants.EndowmentTransactionTypeCodes.ASSET_TYPE_CODE.equals(endTransactionTypeCode) || EndowConstants.EndowmentTransactionTypeCodes.LIABILITY_TYPE_CODE.equals(endTransactionTypeCode))) {
090                    putFieldError(EndowPropertyConstants.CLASS_CODE_SEC_END_TRANSACTION_CODE, EndowKeyConstants.ClassCodeConstants.ERROR_ENDOWMENT_TRANSACTION_TYPE_ASSET_OR_LIABILITY);
091                    success = false;
092                }
093            }
094    
095            return success;
096        }
097    
098        /**
099         * This method checks if income endowment transaction post type code is Income.
100         * 
101         * @param classCode
102         * @return true if income endowment transaction post type code is Income, false otherwise
103         */
104        public boolean validateIncomneTransactionPostTypeCode(ClassCode classCode) {
105            boolean success = false;
106            BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
107    
108            classCode.refreshReferenceObject(EndowPropertyConstants.CLASS_CODE_INCOME_ENDOWMENT_TRANSACTION_POST);
109    
110            if (ObjectUtils.isNotNull(classCode.getIncomeEndowmentTransactionPost())) {
111    
112                String incomeEndTransactionPostTypeCode = classCode.getIncomeEndowmentTransactionPost().getEndowmentTransactionTypeCode();
113    
114                if (EndowConstants.EndowmentTransactionTypeCodes.INCOME_TYPE_CODE.equals(incomeEndTransactionPostTypeCode)) {
115    
116                    success = true;
117                }
118                else {
119    
120                    putFieldError(EndowPropertyConstants.CLASS_CODE_SEC_INCOME_END_TRANSACTION_CODE, EndowKeyConstants.ClassCodeConstants.ERROR_INCOME_ENDOWMENT_TRANSACTION_POST_TYPE_INCOME);
121                }
122            }
123    
124            return success;
125    
126        }
127    
128        /**
129         * This method checks that security reporting group is Cash Equivalents when class code type is Cash Equivalents.
130         * 
131         * @param classCode
132         * @return true if security reporting group is Cash Equivalents when class code type is Cash Equivalents, false otherwise.
133         */
134        public boolean validateClassCodeType(ClassCode classCode) {
135            boolean success = true;
136    
137            if (EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS.equalsIgnoreCase(classCode.getClassCodeType())) {
138                if (!EndowConstants.SecurityReportingGroups.CASH_EQUIVALENTS.equalsIgnoreCase(classCode.getSecurityReportingGrp())) {
139    
140                    putFieldError(EndowPropertyConstants.CLASS_CODE_SEC_REPORTING_GRP, EndowKeyConstants.ClassCodeConstants.ERROR_CLASS_CODE_TYPE_CASH_EQ_REP_GRPCASH_EQ);
141                    success = false;
142                }
143            }
144    
145            // If the class Code is C (Cash Equivalents) or L (Liabilities), the tax lot indicator must be No.
146            if (EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS.equalsIgnoreCase(classCode.getClassCodeType()) || EndowConstants.ClassCodeTypes.LIABILITY.equalsIgnoreCase(classCode.getClassCodeType())) {
147                if (classCode.isTaxLotIndicator()) {
148    
149                    putFieldError(EndowPropertyConstants.CLASS_CODE_TAX_LOT_INDICATOR, EndowKeyConstants.ClassCodeConstants.ERROR_CLASS_CODE_TYPE_CASHEQ_OR_LIABILITY_MUST_HAVE_TAX_LOT_IND_NO);
150                    success = false;
151                }
152            }
153            return success;
154        }
155    
156        /**
157         * This method validates that the valuation method is Unit for class code with class code type P=Pooled Investment or B=Bond or
158         * L=Liability.
159         * 
160         * @param classCode
161         * @return true if valuation method is Unit for class code type P, false otherwise
162         */
163        public boolean validateValuationMethodForPooledInvestments(ClassCode classCode) {
164            boolean success = true;
165    
166            // If class code type ="P" or "B" or "L", the value of END_SEC_VLTN_MTHD.VLTN_MTHD must be "U"
167            if (EndowConstants.ClassCodeTypes.POOLED_INVESTMENT.equalsIgnoreCase(classCode.getClassCodeType()) || EndowConstants.ClassCodeTypes.BOND.equalsIgnoreCase(classCode.getClassCodeType()) || EndowConstants.ClassCodeTypes.LIABILITY.equalsIgnoreCase(classCode.getClassCodeType())) {
168                if (!EndowConstants.ValuationMethod.UNITS.equalsIgnoreCase(classCode.getValuationMethod())) {
169    
170                    putFieldError(EndowPropertyConstants.CLASS_CODE_VALUATION_METHOD, EndowKeyConstants.ClassCodeConstants.ERROR_CLASS_CODE_TYPE_POOLED_INVESTMENT_MUST_HAVE_VLTN_MTHD_UNITS);
171                    success = false;
172                }
173            }
174            return success;
175        }
176    }