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.cg.document.validation.impl;
017    
018    import java.util.Collection;
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.apache.log4j.Logger;
022    import org.kuali.kfs.module.cg.businessobject.Award;
023    import org.kuali.kfs.module.cg.businessobject.AwardAccount;
024    import org.kuali.kfs.module.cg.businessobject.AwardOrganization;
025    import org.kuali.kfs.module.cg.businessobject.AwardProjectDirector;
026    import org.kuali.kfs.module.cg.businessobject.AwardSubcontractor;
027    import org.kuali.kfs.sys.KFSConstants;
028    import org.kuali.kfs.sys.KFSKeyConstants;
029    import org.kuali.kfs.sys.KFSPropertyConstants;
030    import org.kuali.kfs.sys.context.SpringContext;
031    import org.kuali.rice.kim.bo.Person;
032    import org.kuali.rice.kns.bo.PersistableBusinessObject;
033    import org.kuali.rice.kns.document.MaintenanceDocument;
034    import org.kuali.rice.kns.service.DataDictionaryService;
035    import org.kuali.rice.kns.util.GlobalVariables;
036    import org.kuali.rice.kns.util.ObjectUtils;
037    
038    /**
039     * Rules for the Award maintenance document.
040     */
041    public 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.info("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.info("Entering AwardRule.processCustomRouteDocumentBusinessRules");
057            boolean success = true;
058            success &= checkProposal();
059            success &= checkEndAfterBegin(newAwardCopy.getAwardBeginningDate(), newAwardCopy.getAwardEndingDate(), KFSPropertyConstants.AWARD_ENDING_DATE);
060            success &= checkPrimary(newAwardCopy.getAwardOrganizations(), AwardOrganization.class, KFSPropertyConstants.AWARD_ORGRANIZATIONS, Award.class);
061            success &= checkPrimary(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, KFSPropertyConstants.AWARD_PROJECT_DIRECTORS, Award.class);
062            success &= checkAccounts();
063            success &= checkProjectDirectorsExist(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, KFSPropertyConstants.AWARD_PROJECT_DIRECTORS);
064            success &= checkProjectDirectorsExist(newAwardCopy.getAwardAccounts(), AwardAccount.class, KFSPropertyConstants.AWARD_ACCOUNTS);
065            success &= checkProjectDirectorsStatuses(newAwardCopy.getAwardProjectDirectors(), AwardProjectDirector.class, KFSPropertyConstants.AWARD_PROJECT_DIRECTORS);
066            success &= checkFederalPassThrough();
067            success &= checkAgencyNotEqualToFederalPassThroughAgency(newAwardCopy.getAgency(), newAwardCopy.getFederalPassThroughAgency(), KFSPropertyConstants.AGENCY_NUMBER, KFSPropertyConstants.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(), KFSPropertyConstants.AWARD_ACCOUNTS, AwardAccount.class);
083                putFieldError(KFSPropertyConstants.AWARD_ACCOUNTS, KFSKeyConstants.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(KFSPropertyConstants.PROPOSAL_NUMBER, KFSKeyConstants.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(KFSPropertyConstants.PROPOSAL_NUMBER, KFSKeyConstants.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, KFSPropertyConstants.FEDERAL_PASS_THROUGH_INDICATOR);
122    
123            if (newAwardCopy.getFederalPassThroughIndicator()) {
124                String indicatorLabel = SpringContext.getBean(DataDictionaryService.class).getAttributeErrorLabel(Award.class, KFSPropertyConstants.FEDERAL_PASS_THROUGH_INDICATOR);
125                if (StringUtils.isBlank(newAwardCopy.getFederalPassThroughAgencyNumber())) {
126                    putFieldError(KFSPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER, KFSKeyConstants.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.kns.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 = KFSConstants.MAINTENANCE_ADD_PREFIX + KFSPropertyConstants.AWARD_ORGRANIZATIONS + ".";
176    
177            this.getDictionaryValidationService().validateBusinessObject(awardOrganization);
178            if (StringUtils.isNotBlank(awardOrganization.getOrganizationCode()) && StringUtils.isNotBlank(awardOrganization.getChartOfAccountsCode())) {
179                awardOrganization.refreshReferenceObject(KFSPropertyConstants.ORGANIZATION);
180    
181                if (ObjectUtils.isNull(awardOrganization.getOrganization())) {
182                    String label = this.getDataDictionaryService().getAttributeLabel(AwardOrganization.class, KFSPropertyConstants.ORGANIZATION_CODE);
183                    String message = label + "(" + awardOrganization.getOrganizationCode() + ")";
184    
185                    putFieldError(errorPathPrefix + KFSPropertyConstants.ORGANIZATION_CODE, KFSKeyConstants.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 = KFSConstants.MAINTENANCE_ADD_PREFIX + KFSPropertyConstants.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, KFSPropertyConstants.SUBCONTRACTOR_NUMBER);
206                    String message = label + "(" + awardSubcontractor.getSubcontractorNumber() + ")";
207    
208                    putFieldError(errorPathPrefix + KFSPropertyConstants.SUBCONTRACTOR_NUMBER, KFSKeyConstants.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 = KFSConstants.MAINTENANCE_ADD_PREFIX + KFSPropertyConstants.AWARD_ACCOUNTS + ".";
222    
223            this.getDictionaryValidationService().validateBusinessObject(awardAccount);
224            if (StringUtils.isNotBlank(awardAccount.getAccountNumber()) && StringUtils.isNotBlank(awardAccount.getChartOfAccountsCode())) {
225                awardAccount.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
226    
227                if (ObjectUtils.isNull(awardAccount.getAccount())) {
228                    String label = this.getDataDictionaryService().getAttributeLabel(AwardAccount.class, KFSPropertyConstants.ACCOUNT_NUMBER);
229                    String message = label + "(" + awardAccount.getChartOfAccountsCode() + "-" + awardAccount.getAccountNumber() + ")";
230    
231                    putFieldError(errorPathPrefix + KFSPropertyConstants.ACCOUNT_NUMBER, KFSKeyConstants.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", KFSKeyConstants.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 = KFSConstants.MAINTENANCE_ADD_PREFIX + KFSPropertyConstants.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, KFSKeyConstants.ERROR_EXISTENCE, message);
259    
260                success &= false;
261            }
262    
263            return success;
264        }
265    }