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.coa.document.validation.impl;
017    
018    import java.util.List;
019    
020    import org.kuali.kfs.coa.businessobject.OrganizationReversion;
021    import org.kuali.kfs.coa.businessobject.OrganizationReversionDetail;
022    import org.kuali.kfs.sys.KFSKeyConstants;
023    import org.kuali.rice.kns.document.MaintenanceDocument;
024    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
025    import org.kuali.rice.kns.util.GlobalVariables;
026    import org.kuali.rice.kns.util.ObjectUtils;
027    
028    /**
029     * This class implements the business rules specific to the {@link OrganizationReversion} Maintenance Document.
030     */
031    public class OrganizationReversionRule extends MaintenanceDocumentRuleBase {
032    
033        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrganizationReversionRule.class);
034    
035        protected OrganizationReversion oldOrgReversion;
036        protected OrganizationReversion newOrgReversion;
037    
038        /**
039         * No-Args Constructor for an OrganizationReversionRule.
040         */
041        public OrganizationReversionRule() {
042    
043        }
044    
045        /**
046         * This performs rules checks on document route
047         * <ul>
048         * <li>{@link OrganizationReversionRule#validateDetailBusinessObjects(OrganizationReversion)}</li>
049         * </ul>
050         * This rule fails on business rule failures
051         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
052         */
053        @Override
054        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
055    
056            boolean success = true;
057    
058            // make sure its a valid organization reversion MaintenanceDocument
059            if (!isCorrectMaintenanceClass(document, OrganizationReversion.class)) {
060                throw new IllegalArgumentException("Maintenance Document passed in was of the incorrect type.  Expected " + "'" + OrganizationReversion.class.toString() + "', received " + "'" + document.getOldMaintainableObject().getBoClass().toString() + "'.");
061            }
062    
063            // get the real business object
064            newOrgReversion = (OrganizationReversion) document.getNewMaintainableObject().getBusinessObject();
065    
066            // add check to validate document recursively to get to the collection attributes
067            success &= validateDetailBusinessObjects(newOrgReversion);
068    
069            return success;
070        }
071    
072        /**
073         * Tests each option attached to the main business object and validates its properties.
074         * 
075         * @param orgReversion
076         * @return false if any of the detail objects fail with their validation
077         */
078        protected boolean validateDetailBusinessObjects(OrganizationReversion orgReversion) {
079            GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
080            List<OrganizationReversionDetail> details = orgReversion.getOrganizationReversionDetail();
081            int index = 0;
082            int originalErrorCount = GlobalVariables.getMessageMap().getErrorCount();
083            for (OrganizationReversionDetail dtl : details) {
084                String errorPath = "organizationReversionDetail[" + index + "]";
085                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
086                validateOrganizationReversionDetail(dtl);
087                validateOrganizationReversionCode(orgReversion, dtl);
088                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
089                index++;
090            }
091            GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
092            return GlobalVariables.getMessageMap().getErrorCount() == originalErrorCount;
093        }
094        
095        /**
096         * 
097         * This checks to make sure that the organization reversion object on the detail object actually exists
098         * @param detail
099         * @return false if the organization reversion object doesn't exist
100         */
101        protected boolean validateOrganizationReversionDetail(OrganizationReversionDetail detail) {
102            
103            // let's assume this detail will pass the rule
104            boolean result = true;
105            
106            // 1. makes sure the financial object code exists
107            detail.refreshReferenceObject("organizationReversionObject");
108            if (ObjectUtils.isNull(detail.getOrganizationReversionObject())) {
109                LOG.debug("organization reversion finanical object = null");
110                result = false;
111                GlobalVariables.getMessageMap().putError("organizationReversionObjectCode", KFSKeyConstants.ERROR_EXISTENCE, new String[] { "Financial Object Code: " + detail.getOrganizationReversionObjectCode() });
112            } else {
113                LOG.debug("organization reversion finanical object = " + detail.getOrganizationReversionObject().getName());            
114            }
115            return result;
116        }
117    
118        /**
119         * 
120         * Verifies that a reversion code exists when the 
121         * "Carry Forward by Object Code" indicator is selected.  If this indicator
122         * isn't selected, then the reversion codes isn't required.
123         * 
124         * @param reversion OrganizationReversion object
125         * @param detail OrganizationReversionDetail object
126         * 
127         * @return true for successful validation
128         */
129        protected boolean validateOrganizationReversionCode(OrganizationReversion reversion, OrganizationReversionDetail detail) {
130            
131            //
132            // Assume it will pass!
133            //
134            boolean result = true;
135            
136            //
137            // Only need to verify that organization reversion code exists if the
138            // "Carry Forward by Object Code Indicator" is not selected.
139            //
140            if (reversion.isCarryForwardByObjectCodeIndicator()) {
141                if (ObjectUtils.isNull(detail.getOrganizationReversionCode())) {
142                    result = false;
143                    GlobalVariables.getMessageMap().putError("organizationReversionCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_NO_REVERSION_CODE);
144                }
145            }
146            return result;
147        }
148    }