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.bc.document.service.impl;
017    
018    import org.apache.log4j.Logger;
019    import org.kuali.kfs.coa.businessobject.Account;
020    import org.kuali.kfs.coa.businessobject.Chart;
021    import org.kuali.kfs.coa.businessobject.ObjectCode;
022    import org.kuali.kfs.coa.businessobject.SubAccount;
023    import org.kuali.kfs.coa.businessobject.SubObjectCode;
024    import org.kuali.kfs.integration.ld.LaborLedgerObject;
025    import org.kuali.kfs.integration.ld.LaborModuleService;
026    import org.kuali.kfs.module.bc.BCConstants;
027    import org.kuali.kfs.module.bc.BCKeyConstants;
028    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionIntendedIncumbent;
029    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition;
030    import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
031    import org.kuali.kfs.module.bc.document.BudgetConstructionDocument;
032    import org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService;
033    import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
034    import org.kuali.kfs.sys.KFSConstants;
035    import org.kuali.kfs.sys.KFSKeyConstants;
036    import org.kuali.kfs.sys.KFSPropertyConstants;
037    import org.kuali.kfs.sys.MessageBuilder;
038    import org.kuali.rice.kns.service.DictionaryValidationService;
039    import org.kuali.rice.kns.util.MessageMap;
040    import org.kuali.rice.kns.util.ObjectUtils;
041    
042    /**
043     * implementing the validation methods defined in BudgetConstructionRuleHelperService
044     */
045    public class BudgetConstructionRuleHelperServiceImpl implements BudgetConstructionRuleHelperService {
046        private static final Logger LOG = Logger.getLogger(BudgetConstructionRuleHelperServiceImpl.class);
047    
048        private DictionaryValidationService dictionaryValidationService;
049        private LaborModuleService laborModuleService;
050        private BudgetDocumentService budgetDocumentService;
051    
052        /**
053         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasDetailPositionRequiredObjectCode(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
054         *      org.kuali.core.util.ErrorMap)
055         */
056        public boolean hasDetailPositionRequiredObjectCode(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
057            String objectCode = appointmentFunding.getFinancialObjectCode();
058            ObjectCode financialObject = appointmentFunding.getFinancialObject();
059    
060            return this.isDetailPositionRequiredObjectCode(financialObject, objectCode, errorMap, KFSPropertyConstants.FINANCIAL_OBJECT);
061        }
062    
063        /**
064         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidAccount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
065         *      org.kuali.core.util.ErrorMap)
066         */
067        public boolean hasValidAccount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
068            String accountNumber = appointmentFunding.getAccountNumber();
069            Account account = appointmentFunding.getAccount();
070            return this.isValidAccount(account, accountNumber, errorMap, KFSPropertyConstants.ACCOUNT_NAME);
071        }
072    
073        /**
074         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidChart(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
075         *      org.kuali.core.util.ErrorMap)
076         */
077        public boolean hasValidChart(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
078            String chartOfAccountsCode = appointmentFunding.getChartOfAccountsCode();
079            Chart chart = appointmentFunding.getChartOfAccounts();
080    
081            return this.isValidChart(chart, chartOfAccountsCode, errorMap, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
082        }
083    
084        /**
085         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidIncumbent(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
086         *      org.kuali.core.util.ErrorMap)
087         */
088        public boolean hasValidIncumbent(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
089            String emplid = appointmentFunding.getEmplid();
090    
091            // VACANT emplid value is valid, don't do lookup in this case
092            if (BCConstants.VACANT_EMPLID.equalsIgnoreCase(emplid)) {
093                return true;
094            }
095    
096            BudgetConstructionIntendedIncumbent intendedIncumbent = appointmentFunding.getBudgetConstructionIntendedIncumbent();
097    
098            return this.isValidIncumbent(intendedIncumbent, emplid, errorMap, KFSPropertyConstants.EMPLID);
099        }
100    
101        /**
102         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidObjectCode(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
103         *      org.kuali.core.util.ErrorMap)
104         */
105        public boolean hasValidObjectCode(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
106            String objectCode = appointmentFunding.getFinancialObjectCode();
107            ObjectCode financialObject = appointmentFunding.getFinancialObject();
108    
109            return this.isValidObjectCode(financialObject, objectCode, errorMap, KFSPropertyConstants.FINANCIAL_OBJECT);
110        }
111    
112        /**
113         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidPosition(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
114         *      org.kuali.core.util.ErrorMap)
115         */
116        public boolean hasValidPosition(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
117            String positionNumber = appointmentFunding.getPositionNumber();
118            BudgetConstructionPosition position = appointmentFunding.getBudgetConstructionPosition();
119    
120            return this.isValidPosition(position, positionNumber, errorMap, KFSPropertyConstants.POSITION_NUMBER);
121        }
122    
123        /**
124         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidSubAccount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
125         *      org.kuali.core.util.ErrorMap)
126         */
127        public boolean hasValidSubAccount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
128            String subAccountNumber = appointmentFunding.getSubAccountNumber();
129            
130            // ok when dashes, no lookup
131            if (KFSConstants.getDashSubAccountNumber().equals(subAccountNumber)) {
132                return true;
133            }
134    
135            SubAccount subAccount = appointmentFunding.getSubAccount();
136    
137            return this.isValidSubAccount(subAccount, subAccountNumber, errorMap, KFSPropertyConstants.SUB_ACCOUNT_NAME);
138        }
139    
140        /**
141         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#hasValidSubObjectCode(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
142         *      org.kuali.core.util.ErrorMap)
143         */
144        public boolean hasValidSubObjectCode(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
145            String subObjectCode = appointmentFunding.getFinancialSubObjectCode();
146    
147            // ok when dashes, no lookup
148            if (KFSConstants.getDashFinancialSubObjectCode().equals(subObjectCode)) {
149                return true;
150            }
151            
152            SubObjectCode subObject = appointmentFunding.getFinancialSubObject();
153    
154            return this.isValidSubObjectCode(subObject, subObjectCode, errorMap, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE);
155        }
156    
157        /**
158         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isAssociatedWithValidDocument(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
159         *      org.kuali.core.util.ErrorMap, java.lang.String)
160         */
161        public boolean isAssociatedWithValidDocument(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap, String errorPropertyName) {
162            BudgetConstructionDocument budgetConstructionDocument = budgetDocumentService.getBudgetConstructionDocument(appointmentFunding);
163    
164            if (ObjectUtils.isNull(budgetConstructionDocument)) {
165                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE);
166                return false;
167            }
168    
169            return this.isBudgetableDocument(budgetConstructionDocument, errorMap, errorPropertyName);
170        }
171    
172        /**
173         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isBudgetableDocument(org.kuali.kfs.module.bc.document.BudgetConstructionDocument,
174         *      org.kuali.core.util.ErrorMap, java.lang.String)
175         */
176        public boolean isBudgetableDocument(BudgetConstructionDocument budgetConstructionDocument, MessageMap errorMap, String errorPropertyName) {
177            boolean isBudgetAllowed = budgetDocumentService.isBudgetableDocument(budgetConstructionDocument);
178    
179            if (!isBudgetAllowed) {
180                errorMap.putError(errorPropertyName, BCKeyConstants.ERROR_BUDGET_DOCUMENT_NOT_BUDGETABLE, budgetConstructionDocument.getAccountNumber() + ";" + budgetConstructionDocument.getSubAccountNumber());
181            }
182    
183            return isBudgetAllowed;
184        }
185    
186        /**
187         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#isDetailPositionRequiredObjectCode(org.kuali.kfs.coa.businessobject.ObjectCode,
188         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
189         */
190        public boolean isDetailPositionRequiredObjectCode(ObjectCode financialObject, String currentValue, MessageMap errorMap, String errorPropertyName) {
191            if (ObjectUtils.isNull(financialObject)) {
192                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(ObjectCode.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE, currentValue);
193                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
194                return false;
195            }
196    
197            LaborLedgerObject laborObject = laborModuleService.retrieveLaborLedgerObject(financialObject);
198            if (laborObject == null || !laborObject.isDetailPositionRequiredIndicator()) {
199                errorMap.putError(errorPropertyName, BCKeyConstants.ERROR_DETAIL_POSITION_NOT_REQUIRED, currentValue);
200                return false;
201            }
202            return true;
203        }
204    
205        /**
206         * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionRuleHelperService#isFieldFormatValid(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
207         *      org.kuali.core.util.ErrorMap)
208         */
209        public boolean isFieldFormatValid(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
210            return dictionaryValidationService.isBusinessObjectValid(appointmentFunding);
211        }
212    
213        /**
214         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidAccount(org.kuali.kfs.coa.businessobject.Account,
215         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
216         */
217        public boolean isValidAccount(Account account, String currentValue, MessageMap errorMap, String errorPropertyName) {
218            if (ObjectUtils.isNull(account)) {
219                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(Account.class, KFSPropertyConstants.ACCOUNT_NAME, currentValue);
220                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
221                return false;
222            }
223    
224            if (!account.isActive()) {
225                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(Account.class, KFSPropertyConstants.ACCOUNT_NAME, currentValue);
226                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
227                return false;
228            }
229            return true;
230        }
231    
232        /**
233         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidChart(org.kuali.kfs.coa.businessobject.Chart,
234         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
235         */
236        public boolean isValidChart(Chart chart, String currentValue, MessageMap errorMap, String errorPropertyName) {
237            if (ObjectUtils.isNull(chart)) {
238                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(Chart.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, currentValue);
239                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
240                return false;
241            }
242    
243            if (!chart.isActive()) {
244                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(Chart.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, currentValue);
245                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
246                return false;
247            }
248    
249            return true;
250        }
251    
252        /**
253         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidIncumbent(org.kuali.kfs.module.bc.businessobject.BudgetConstructionIntendedIncumbent,
254         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
255         */
256        public boolean isValidIncumbent(BudgetConstructionIntendedIncumbent intendedIncumbent, String currentValue, MessageMap errorMap, String errorPropertyName) {
257            // if (BCConstants.VACANT_EMPLID.equalsIgnoreCase(currentValue)) {
258            // return true;
259            // }
260    
261            if (ObjectUtils.isNull(intendedIncumbent)) {
262                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(BudgetConstructionIntendedIncumbent.class, KFSPropertyConstants.EMPLID, currentValue);
263                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
264                return false;
265            }
266    
267            return true;
268        }
269    
270        /**
271         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidObjectCode(org.kuali.kfs.coa.businessobject.ObjectCode,
272         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
273         */
274        public boolean isValidObjectCode(ObjectCode objectCode, String currentValue, MessageMap errorMap, String errorPropertyName) {
275            if (ObjectUtils.isNull(objectCode)) {
276                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(ObjectCode.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE, currentValue);
277                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
278                return false;
279            }
280    
281            if (!objectCode.isActive()) {
282                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(ObjectCode.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE, currentValue);
283                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
284                return false;
285            }
286    
287            return true;
288        }
289    
290        /**
291         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidPosition(org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition,
292         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
293         */
294        public boolean isValidPosition(BudgetConstructionPosition position, String currentValue, MessageMap errorMap, String errorPropertyName) {
295            if (ObjectUtils.isNull(position)) {
296                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(BudgetConstructionPosition.class, KFSPropertyConstants.POSITION_NUMBER, currentValue);
297                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
298                return false;
299            }
300    
301            if (!position.isEffective()) {
302                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(BudgetConstructionPosition.class, KFSPropertyConstants.POSITION_NUMBER, currentValue);
303                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
304                return false;
305            }
306    
307            if (!position.isBudgetedPosition()) {
308                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(BudgetConstructionPosition.class, KFSPropertyConstants.POSITION_NUMBER, currentValue);
309                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
310                return false;
311            }
312    
313            return true;
314        }
315    
316        /**
317         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidSubAccount(org.kuali.kfs.coa.businessobject.SubAccount,
318         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
319         */
320        public boolean isValidSubAccount(SubAccount subAccount, String currentValue, MessageMap errorMap, String errorPropertyName) {
321    //        if (KFSConstants.getDashSubAccountNumber().equals(currentValue)) {
322    //            return true;
323    //        }
324    
325            if (ObjectUtils.isNull(subAccount)) {
326                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(SubAccount.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER, currentValue);
327                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
328                return false;
329            }
330    
331            if (!subAccount.isActive()) {
332                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(SubAccount.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER, currentValue);
333                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_DOCUMENT_SUB_ACCOUNT_INACTIVE, errorMessage);
334                return false;
335            }
336    
337            return true;
338        }
339    
340        /**
341         * @see org.kuali.kfs.module.bc.document.service.impl.BudgetConstructionRuleHelperService#isValidSubObjectCode(org.kuali.kfs.coa.businessobject.SubObjCd,
342         *      java.lang.String, org.kuali.core.util.ErrorMap, java.lang.String)
343         */
344        public boolean isValidSubObjectCode(SubObjectCode subObjectCode, String currentValue, MessageMap errorMap, String errorPropertyName) {
345    //        if (KFSConstants.getDashFinancialSubObjectCode().equals(currentValue)) {
346    //            return true;
347    //        }
348    
349            if (ObjectUtils.isNull(subObjectCode)) {
350                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(SubObjectCode.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, currentValue);
351                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
352                return false;
353            }
354    
355            if (!subObjectCode.isActive()) {
356                String errorMessage = MessageBuilder.buildErrorMessageWithDataDictionary(SubObjectCode.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, currentValue);
357                errorMap.putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, errorMessage);
358                return false;
359            }
360            return true;
361        }
362    
363        /**
364         * Sets the budgetDocumentService attribute value.
365         * 
366         * @param budgetDocumentService The budgetDocumentService to set.
367         */
368        public void setBudgetDocumentService(BudgetDocumentService budgetDocumentService) {
369            this.budgetDocumentService = budgetDocumentService;
370        }
371    
372        /**
373         * Sets the dictionaryValidationService attribute value.
374         * 
375         * @param dictionaryValidationService The dictionaryValidationService to set.
376         */
377        public void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) {
378            this.dictionaryValidationService = dictionaryValidationService;
379        }
380    
381        /**
382         * Sets the laborModuleService attribute value.
383         * 
384         * @param laborModuleService The laborModuleService to set.
385         */
386        public void setLaborModuleService(LaborModuleService laborModuleService) {
387            this.laborModuleService = laborModuleService;
388        }
389    }