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 org.apache.commons.lang.StringUtils;
019    import org.kuali.kfs.coa.businessobject.ReportingCode;
020    import org.kuali.kfs.sys.KFSKeyConstants;
021    import org.kuali.kfs.sys.context.SpringContext;
022    import org.kuali.rice.kns.bo.PersistableBusinessObject;
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.ObjectUtils;
027    
028    /**
029     * 
030     * This class implements the business rules specific to the {@link ReportingCodes} Maintenance Document.
031     */
032    public class ReportingCodesRule extends MaintenanceDocumentRuleBase {
033    
034        protected ReportingCode oldReportingCode;
035        protected ReportingCode newReportingCode;
036    
037        protected BusinessObjectService businessObjectService;
038    
039        /**
040         * 
041         * Constructs a ReportingCodesRule and pseudo-injects services
042         */
043        public ReportingCodesRule() {
044            super();
045            setBusinessObjectService((BusinessObjectService) SpringContext.getBean(BusinessObjectService.class));
046        }
047    
048        /**
049         * This performs rules checks on document route
050         * <ul>
051         * <li>{@link ProjectCodeRule#checkReportsToReportingCode()}</li>
052         * </ul>
053         * This rule fails on business rule failures
054         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
055         */
056        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
057            boolean success = true;
058            setupConvenienceObjects(document);
059            success &= checkReportsToReportingCode();
060            return success;
061        }
062    
063        /**
064         * This performs rules checks on document save
065         * <ul>
066         * <li>{@link ProjectCodeRule#checkReportsToReportingCode()}</li>
067         * </ul>
068         * This rule does not fail on business rule failures
069         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
070         */
071        protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
072            boolean success = true;
073            setupConvenienceObjects(document);
074            checkReportsToReportingCode();
075            return success;
076        }
077    
078        /**
079         * 
080         * This method sets the convenience objects like newReportingCode and oldReportingCode, so you have short and easy handles to the new and
081         * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
082         * all sub-objects from the DB by their primary keys, if available.
083         * 
084         * @param document
085         */
086        protected void setupConvenienceObjects(MaintenanceDocument document) {
087    
088            // setup oldAccount convenience objects, make sure all possible sub-objects are populated
089            oldReportingCode = (ReportingCode) super.getOldBo();
090    
091            // setup newAccount convenience objects, make sure all possible sub-objects are populated
092            newReportingCode = (ReportingCode) super.getNewBo();
093        }
094    
095        /**
096         * 
097         * This checks to see if the user has entered in two different values for the reporting code and the 
098         * reports to reporting code. If they are different then it makes sure that the reports to reporting code actually exists
099         * in the system.
100         * @return true if the reports to reporting code is filled and exists or true if it isn't filled in (doesn't need to be), false otherwise
101         */
102        protected boolean checkReportsToReportingCode() {
103            boolean success = true;
104            boolean oneMissing = false;
105            boolean bothMissing = false;
106            boolean doExistenceTest = false;
107    
108            // if one of the codes is blank but the other isnt (ie, they are different), then
109            // do the existence test
110            if (StringUtils.isBlank(newReportingCode.getFinancialReportingCode()) && StringUtils.isBlank(newReportingCode.getFinancialReportsToReportingCode())) {
111                bothMissing = true;
112            }
113            else if (StringUtils.isBlank(newReportingCode.getFinancialReportingCode()) || StringUtils.isBlank(newReportingCode.getFinancialReportsToReportingCode())) {
114                oneMissing = true;
115            }
116            if (oneMissing && !bothMissing) {
117                doExistenceTest = true;
118            }
119    
120            // if both codes are there, but they are different, then do the existence test
121            if (StringUtils.isNotBlank(newReportingCode.getFinancialReportingCode())) {
122                if (!newReportingCode.getFinancialReportingCode().equalsIgnoreCase(newReportingCode.getFinancialReportsToReportingCode())) {
123                    doExistenceTest = true;
124                }
125            }
126    
127            // if these two aren't equal then we need to make sure that the object exists
128            if (doExistenceTest) {
129    
130                // attempt to retrieve the specified object from the db
131                PersistableBusinessObject referenceBo;
132                referenceBo = (PersistableBusinessObject)businessObjectService.getReferenceIfExists((PersistableBusinessObject) newReportingCode, "reportingCodes");
133                if (!ObjectUtils.isNotNull(referenceBo)) {
134                    putFieldError("financialReportsToReportingCode", KFSKeyConstants.ERROR_EXISTENCE, "Reports To Reporting Code");
135                    success &= false;
136                }
137            }
138            return success;
139        }
140    
141        protected void setBusinessObjectService(BusinessObjectService boService) {
142            businessObjectService = boService;
143        }
144    
145    }