001/*
002 * Copyright 2007 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.module.cg.document.validation.impl;
017
018import java.util.Collection;
019
020import org.apache.commons.lang.StringUtils;
021import org.apache.log4j.Logger;
022import org.kuali.ole.module.cg.businessobject.Award;
023import org.kuali.ole.module.cg.businessobject.AwardAccount;
024import org.kuali.ole.module.cg.businessobject.AwardOrganization;
025import org.kuali.ole.module.cg.businessobject.AwardProjectDirector;
026import org.kuali.ole.module.cg.businessobject.AwardSubcontractor;
027import org.kuali.ole.sys.OLEConstants;
028import org.kuali.ole.sys.OLEKeyConstants;
029import org.kuali.ole.sys.OLEPropertyConstants;
030import org.kuali.ole.sys.context.SpringContext;
031import org.kuali.rice.kim.api.identity.Person;
032import org.kuali.rice.kns.document.MaintenanceDocument;
033import org.kuali.rice.kns.service.DataDictionaryService;
034import org.kuali.rice.krad.bo.PersistableBusinessObject;
035import org.kuali.rice.krad.util.GlobalVariables;
036import org.kuali.rice.krad.util.ObjectUtils;
037
038/**
039 * Rules for the Award maintenance document.
040 */
041public class AwardRule extends CGMaintenanceDocumentRuleBase {
042    protected static Logger LOG = org.apache.log4j.Logger.getLogger(AwardRule.class);
043
044    protected Award newAwardCopy;
045
046    @Override
047    protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
048        LOG.debug("Entering AwardRule.processCustomSaveDocumentBusinessRules");
049        processCustomRouteDocumentBusinessRules(document);
050        LOG.info("Leaving AwardRule.processCustomSaveDocumentBusinessRules");
051        return true; // save despite error messages
052    }
053
054    @Override
055    protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
056        LOG.debug("Entering AwardRule.processCustomRouteDocumentBusinessRules");
057        boolean success = true;
058        success &= checkProposal();
059        success &= checkEndAfterBegin(newAwardCopy.getAwardBeginningDate(), newAwardCopy.getAwardEndingDate(), OLEPropertyConstants.AWARD_ENDING_DATE);
060        success &= checkPrimary(newAwardCopy.getAwardOrganizations(), AwardOrganization.class, OLEPropertyConstants.AWARD_ORGRANIZATIONS, Award.class);
061        success &= checkPrimary(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, OLEPropertyConstants.AWARD_PROJECT_DIRECTORS, Award.class);
062        success &= checkAccounts();
063        success &= checkProjectDirectorsExist(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, OLEPropertyConstants.AWARD_PROJECT_DIRECTORS);
064        success &= checkProjectDirectorsExist(newAwardCopy.getAwardAccounts(), AwardAccount.class, OLEPropertyConstants.AWARD_ACCOUNTS);
065        success &= checkProjectDirectorsStatuses(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, OLEPropertyConstants.AWARD_PROJECT_DIRECTORS);
066        success &= checkFederalPassThrough();
067        success &= checkAgencyNotEqualToFederalPassThroughAgency(newAwardCopy.getAgency(), newAwardCopy.getFederalPassThroughAgency(), OLEPropertyConstants.AGENCY_NUMBER, OLEPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER);
068        LOG.info("Leaving AwardRule.processCustomRouteDocumentBusinessRules");
069        return success;
070    }
071
072    /**
073     * checks to see if at least 1 award account exists
074     * 
075     * @return true if the award contains at least 1 {@link AwardAccount}, false otherwise
076     */
077    protected boolean checkAccounts() {
078        boolean success = true;
079        Collection<AwardAccount> awardAccounts = newAwardCopy.getAwardAccounts();
080
081        if (ObjectUtils.isNull(awardAccounts) || awardAccounts.isEmpty()) {
082            String elementLabel = SpringContext.getBean(DataDictionaryService.class).getCollectionElementLabel(Award.class.getName(), OLEPropertyConstants.AWARD_ACCOUNTS, AwardAccount.class);
083            putFieldError(OLEPropertyConstants.AWARD_ACCOUNTS, OLEKeyConstants.ERROR_ONE_REQUIRED, elementLabel);
084            success = false;
085        }
086
087        return success;
088    }
089
090    /**
091     * checks to see if:
092     * <ol>
093     * <li>a proposal has already been awarded
094     * <li>a proposal is inactive
095     * </ol>
096     * 
097     * @return
098     */
099    protected boolean checkProposal() {
100        boolean success = true;
101        if (AwardRuleUtil.isProposalAwarded(newAwardCopy)) {
102            putFieldError(OLEPropertyConstants.PROPOSAL_NUMBER, OLEKeyConstants.ERROR_AWARD_PROPOSAL_AWARDED, newAwardCopy.getProposalNumber().toString());
103            success = false;
104        }
105        // SEE KULCG-315 for details on why this code is commented out.
106        // else if (AwardRuleUtil.isProposalInactive(newAwardCopy)) {
107        // putFieldError(OLEPropertyConstants.PROPOSAL_NUMBER, OLEKeyConstants.ERROR_AWARD_PROPOSAL_INACTIVE,
108        // newAwardCopy.getProposalNumber().toString());
109        // }
110
111        return success;
112    }
113
114    /**
115     * checks if the required federal pass through fields are filled in if the federal pass through indicator is yes
116     * 
117     * @return
118     */
119    protected boolean checkFederalPassThrough() {
120        boolean success = true;
121        success = super.checkFederalPassThrough(newAwardCopy.getFederalPassThroughIndicator(), newAwardCopy.getAgency(), newAwardCopy.getFederalPassThroughAgencyNumber(), Award.class, OLEPropertyConstants.FEDERAL_PASS_THROUGH_INDICATOR);
122
123        if (newAwardCopy.getFederalPassThroughIndicator()) {
124            String indicatorLabel = SpringContext.getBean(DataDictionaryService.class).getAttributeErrorLabel(Award.class, OLEPropertyConstants.FEDERAL_PASS_THROUGH_INDICATOR);
125            if (StringUtils.isBlank(newAwardCopy.getFederalPassThroughAgencyNumber())) {
126                putFieldError(OLEPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER, OLEKeyConstants.ERROR_FPT_AGENCY_NUMBER_REQUIRED);
127                success = false;
128            }
129        }
130        
131        return success;
132    }
133
134    /**
135     * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects()
136     */
137    @Override
138    public void setupConvenienceObjects() {
139        // oldAward = (Award) super.getOldBo();
140        newAwardCopy = (Award) super.getNewBo();
141    }
142
143    /**
144     * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument,
145     *      java.lang.String, org.kuali.rice.krad.bo.PersistableBusinessObject)
146     */
147    @Override
148    public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject bo) {
149        boolean success = true;
150
151        if (bo instanceof AwardProjectDirector) {
152            AwardProjectDirector awardProjectDirector = (AwardProjectDirector) bo;
153            success = this.checkAwardProjectDirector(awardProjectDirector);
154        }
155        else if (bo instanceof AwardAccount) {
156            AwardAccount awardAccount = (AwardAccount) bo;
157            success = this.checkAwardAccount(awardAccount);
158        }
159        else if (bo instanceof AwardSubcontractor) {
160            AwardSubcontractor awardSubcontractor = (AwardSubcontractor) bo;
161            success = this.checkAwardSubcontractor(awardSubcontractor);
162        }
163        else if (bo instanceof AwardOrganization) {
164            AwardOrganization awardOrganization = (AwardOrganization) bo;
165            success = this.checkAwardOrganization(awardOrganization);
166        }
167
168        return success;
169    }
170
171    // check if the given award organization exists
172    protected boolean checkAwardOrganization(AwardOrganization awardOrganization) {
173        boolean success = true;
174        int originalErrorCount = GlobalVariables.getMessageMap().getErrorCount();
175        String errorPathPrefix = OLEConstants.MAINTENANCE_ADD_PREFIX + OLEPropertyConstants.AWARD_ORGRANIZATIONS + ".";
176
177        this.getDictionaryValidationService().validateBusinessObject(awardOrganization);
178        if (StringUtils.isNotBlank(awardOrganization.getOrganizationCode()) && StringUtils.isNotBlank(awardOrganization.getChartOfAccountsCode())) {
179            awardOrganization.refreshReferenceObject(OLEPropertyConstants.ORGANIZATION);
180
181            if (ObjectUtils.isNull(awardOrganization.getOrganization())) {
182                String label = this.getDataDictionaryService().getAttributeLabel(AwardOrganization.class, OLEPropertyConstants.ORGANIZATION_CODE);
183                String message = label + "(" + awardOrganization.getOrganizationCode() + ")";
184
185                putFieldError(errorPathPrefix + OLEPropertyConstants.ORGANIZATION_CODE, OLEKeyConstants.ERROR_EXISTENCE, message);
186            }
187        }
188
189        success &= GlobalVariables.getMessageMap().getErrorCount() == originalErrorCount;
190
191        return success;
192    }
193
194    // check if the given award subcontrator exists
195    protected boolean checkAwardSubcontractor(AwardSubcontractor awardSubcontractor) {
196        boolean success = true;
197        int originalErrorCount = GlobalVariables.getMessageMap().getErrorCount();
198        String errorPathPrefix = OLEConstants.MAINTENANCE_ADD_PREFIX + OLEPropertyConstants.AWARD_SUBCONTRACTORS + ".";
199
200        this.getDictionaryValidationService().validateBusinessObject(awardSubcontractor);
201        if (StringUtils.isNotBlank(awardSubcontractor.getSubcontractorNumber())) {
202            awardSubcontractor.refreshReferenceObject("subcontractor");
203
204            if (ObjectUtils.isNull(awardSubcontractor.getSubcontractor())) {
205                String label = this.getDataDictionaryService().getAttributeLabel(AwardSubcontractor.class, OLEPropertyConstants.SUBCONTRACTOR_NUMBER);
206                String message = label + "(" + awardSubcontractor.getSubcontractorNumber() + ")";
207
208                putFieldError(errorPathPrefix + OLEPropertyConstants.SUBCONTRACTOR_NUMBER, OLEKeyConstants.ERROR_EXISTENCE, message);
209            }
210        }
211
212        success &= GlobalVariables.getMessageMap().getErrorCount() == originalErrorCount;
213
214        return success;
215    }
216
217    // check if the given award account exists
218    protected boolean checkAwardAccount(AwardAccount awardAccount) {
219        boolean success = true;
220        int originalErrorCount = GlobalVariables.getMessageMap().getErrorCount();
221        String errorPathPrefix = OLEConstants.MAINTENANCE_ADD_PREFIX + OLEPropertyConstants.AWARD_ACCOUNTS + ".";
222
223        this.getDictionaryValidationService().validateBusinessObject(awardAccount);
224        if (StringUtils.isNotBlank(awardAccount.getAccountNumber()) && StringUtils.isNotBlank(awardAccount.getChartOfAccountsCode())) {
225            awardAccount.refreshReferenceObject(OLEPropertyConstants.ACCOUNT);
226
227            if (ObjectUtils.isNull(awardAccount.getAccount())) {
228                String label = this.getDataDictionaryService().getAttributeLabel(AwardAccount.class, OLEPropertyConstants.ACCOUNT_NUMBER);
229                String message = label + "(" + awardAccount.getChartOfAccountsCode() + "-" + awardAccount.getAccountNumber() + ")";
230
231                putFieldError(errorPathPrefix + OLEPropertyConstants.ACCOUNT_NUMBER, OLEKeyConstants.ERROR_EXISTENCE, message);
232            }
233        }
234
235        Person projectDirector = awardAccount.getProjectDirector();
236        if (StringUtils.isBlank(awardAccount.getPrincipalId()) || ObjectUtils.isNull(projectDirector)) {
237            String label = this.getDataDictionaryService().getAttributeLabel(AwardAccount.class, "projectDirector.principalName");
238            String message = label + "(" + awardAccount.getPrincipalId() + ")";
239
240            putFieldError(errorPathPrefix + "projectDirector.principalName", OLEKeyConstants.ERROR_EXISTENCE, message);
241        }
242
243        success &= GlobalVariables.getMessageMap().getErrorCount() == originalErrorCount;
244
245        return success;
246    }
247
248    // check if the given award project director exists
249    protected boolean checkAwardProjectDirector(AwardProjectDirector awardProjectDirector) {
250        boolean success = true;
251
252        Person projectDirector = awardProjectDirector.getProjectDirector();
253        if (StringUtils.isBlank(awardProjectDirector.getPrincipalId()) || ObjectUtils.isNull(projectDirector)) {
254            String errorPath = OLEConstants.MAINTENANCE_ADD_PREFIX + OLEPropertyConstants.AWARD_PROJECT_DIRECTORS + "." + "projectDirector.principalName";
255            String label = this.getDataDictionaryService().getAttributeLabel(AwardProjectDirector.class, "projectDirector.principalName");
256            String message = label + "(" + awardProjectDirector.getPrincipalId() + ")";
257            
258            putFieldError(errorPath, OLEKeyConstants.ERROR_EXISTENCE, message);
259
260            success &= false;
261        }
262
263        return success;
264    }
265}