001/*
002 * Copyright 2006 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 */
016package org.kuali.ole.coa.document.validation.impl;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.ole.coa.businessobject.ReportingCode;
020import org.kuali.ole.sys.OLEKeyConstants;
021import org.kuali.ole.sys.context.SpringContext;
022import org.kuali.rice.kns.document.MaintenanceDocument;
023import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
024import org.kuali.rice.krad.bo.PersistableBusinessObject;
025import org.kuali.rice.krad.service.BusinessObjectService;
026import org.kuali.rice.krad.util.ObjectUtils;
027
028/**
029 * 
030 * This class implements the business rules specific to the {@link ReportingCodes} Maintenance Document.
031 */
032public 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", OLEKeyConstants.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}