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.external.kc.service.impl;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.kuali.kfs.coa.businessobject.Account;
022    import org.kuali.kfs.coa.businessobject.ObjectCode;
023    import org.kuali.kfs.coa.service.ObjectCodeService;
024    import org.kuali.kfs.fp.businessobject.BudgetAdjustmentAccountingLine;
025    import org.kuali.kfs.fp.businessobject.BudgetAdjustmentSourceAccountingLine;
026    import org.kuali.kfs.fp.businessobject.BudgetAdjustmentTargetAccountingLine;
027    import org.kuali.kfs.fp.document.BudgetAdjustmentDocument;
028    import org.kuali.kfs.integration.cg.ContractsAndGrantsConstants;
029    import org.kuali.kfs.integration.cg.dto.BudgetAdjustmentCreationStatusDTO;
030    import org.kuali.kfs.integration.cg.dto.BudgetAdjustmentParametersDTO;
031    import org.kuali.kfs.integration.cg.dto.BudgetAdjustmentParametersDTO.Details;
032    import org.kuali.kfs.integration.cg.service.AccountCreationService;
033    import org.kuali.kfs.integration.cg.service.BudgetAdjustmentService;
034    import org.kuali.kfs.module.external.kc.util.GlobalVariablesExtractHelper;
035    import org.kuali.kfs.module.external.kc.util.KcUtils;
036    import org.kuali.kfs.sys.KFSConstants;
037    import org.kuali.kfs.sys.businessobject.AccountingLine;
038    import org.kuali.kfs.sys.context.SpringContext;
039    import org.kuali.rice.kim.bo.Person;
040    import org.kuali.rice.kim.service.KIMServiceLocator;
041    import org.kuali.rice.kim.service.PersonService;
042    import org.kuali.rice.kns.UserSession;
043    import org.kuali.rice.kns.document.Document;
044    import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
045    import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizerBase;
046    import org.kuali.rice.kns.exception.ValidationException;
047    import org.kuali.rice.kns.rule.event.BlanketApproveDocumentEvent;
048    import org.kuali.rice.kns.rule.event.RouteDocumentEvent;
049    import org.kuali.rice.kns.rule.event.SaveDocumentEvent;
050    import org.kuali.rice.kns.service.BusinessObjectService;
051    import org.kuali.rice.kns.service.DataDictionaryService;
052    import org.kuali.rice.kns.service.DocumentService;
053    import org.kuali.rice.kns.service.KualiRuleService;
054    import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
055    import org.kuali.rice.kns.service.ParameterService;
056    import org.kuali.rice.kns.service.TransactionalDocumentDictionaryService;
057    import org.kuali.rice.kns.util.GlobalVariables;
058    import org.kuali.rice.kns.util.KualiDecimal;
059    
060    public class BudgetAdjustmentServiceImpl implements BudgetAdjustmentService {
061    
062        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetAdjustmentServiceImpl.class);
063    
064        private DocumentService documentService;
065        private ParameterService parameterService;
066        private DataDictionaryService dataDictionaryService;
067        private BusinessObjectService businessObjectService;
068    
069        /**
070         * This is the web service method that facilitates budget adjustment 1. Creates a Budget Adjustment Doc using the parameters
071         * from KC 2. Returns the status object
072         * 
073         * @param BudgetAdjustmentParametersDTO
074         * @return BudgetAdjustmentStatusDTO
075         */
076        public BudgetAdjustmentCreationStatusDTO createBudgetAdjustment(BudgetAdjustmentParametersDTO budgetAdjustmentParameters) {
077            BudgetAdjustmentDocument budgetAdjustmentDoc = null;
078    
079            BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatus = new BudgetAdjustmentCreationStatusDTO();
080            budgetAdjustmentCreationStatus.setErrorMessages(new ArrayList<String>());
081            budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_SUCCESS);
082    
083            // check to see if the user has the permission to create account
084            String principalId = budgetAdjustmentParameters.getPrincipalId();
085            if (!isValidUser(principalId)) {
086                budgetAdjustmentCreationStatus.getErrorMessages().add(KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_INVALID_USER, new String[]{principalId}));
087                budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
088                return budgetAdjustmentCreationStatus;
089            }
090            try {
091                // create a Budget Adjustment object
092                budgetAdjustmentDoc = createBudgetAdjustmentObject( budgetAdjustmentCreationStatus);
093                
094                if (!isValidParameters(budgetAdjustmentDoc.getPostingYear(), budgetAdjustmentCreationStatus, budgetAdjustmentParameters)) {
095                    return budgetAdjustmentCreationStatus;
096                }
097    
098                // create a Budget Adjustment object, then route if successful
099                if( populateBudgetAdjustmentDocDetails(budgetAdjustmentParameters, budgetAdjustmentDoc, budgetAdjustmentCreationStatus) ){                            
100                    routeBudgetAdjustmentDocument(budgetAdjustmentDoc, budgetAdjustmentCreationStatus);
101                }else{
102                    //return as we have a failure
103                    return budgetAdjustmentCreationStatus;
104                }
105    
106            }
107            catch (Exception ex) {
108                this.setFailStatus(budgetAdjustmentCreationStatus, ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_ACCOUNT_GENERATION_PROBLEM);
109                return budgetAdjustmentCreationStatus;
110            }
111            // set required values to AccountCreationStatus
112    
113            if (budgetAdjustmentCreationStatus.getStatus().equals(ContractsAndGrantsConstants.KcWebService.STATUS_KC_SUCCESS) && getDocumentService().documentExists(budgetAdjustmentDoc.getDocumentHeader().getDocumentNumber())) {
114                budgetAdjustmentCreationStatus.setDocumentNumber(budgetAdjustmentDoc.getDocumentNumber());
115            }
116            else {
117                // save the document
118                try {
119                    try{                 
120                        GlobalVariables.getMessageMap().clearErrorMessages();
121                        getDocumentService().saveDocument(budgetAdjustmentDoc);
122                    }catch(ValidationException ve){                    
123                    }
124                    budgetAdjustmentCreationStatus.setDocumentNumber(budgetAdjustmentDoc.getDocumentNumber());
125                }
126                catch (Exception ex) {
127                    LOG.error( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_NOT_SAVED, null) + ": " + ex.getMessage());                
128                    budgetAdjustmentCreationStatus.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());
129                    budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
130    
131                }
132    
133            }
134            return budgetAdjustmentCreationStatus;
135        }
136    
137        protected boolean checkforEmptyField(BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatusDTO, String fieldName, String value, int lineNumber) {
138            if ((value == null) || value.isEmpty()) {
139                if (lineNumber != 0)
140                    value = "Detail " + lineNumber + " " + value;
141                String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.AUTOMATCICG_ACCOUNT_MAINTENANCE_CHART_REQUIRED_FIELD, fieldName);
142                this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
143                return false;
144            }
145            return true;
146        }
147    
148    
149        protected void setFailStatus(BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatusDTO, String message) {
150            budgetAdjustmentCreationStatusDTO.getErrorMessages().add(message);
151            budgetAdjustmentCreationStatusDTO.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
152        }
153    
154        protected boolean isValidParameters(Integer postingFiscalYear, BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatusDTO, BudgetAdjustmentParametersDTO budgetAdjustmentParameters) {
155            boolean isValid = true;
156            boolean isValidAcct = true;
157            isValid &= checkforEmptyField(budgetAdjustmentCreationStatusDTO, "Description", budgetAdjustmentParameters.getDescription(), 0);
158            List<Details> details = budgetAdjustmentParameters.getDetails();
159            AccountCreationService accountCreationService = SpringContext.getBean(AccountCreationService.class);
160            ObjectCodeService objectCodeService = SpringContext.getBean(ObjectCodeService.class);
161            int lineNumber = 0;
162            for (Details detail : details) {
163                lineNumber++;
164                isValid &= checkforEmptyField(budgetAdjustmentCreationStatusDTO, "Account", detail.getAccount(), lineNumber);
165                isValid &= checkforEmptyField(budgetAdjustmentCreationStatusDTO, "Chart", detail.getChart(), lineNumber);
166                isValid &= checkforEmptyField(budgetAdjustmentCreationStatusDTO, "Object Code", detail.getObjectCode(), lineNumber);
167                isValid &= checkforEmptyField(budgetAdjustmentCreationStatusDTO, "Amount", detail.getCurrentAmount(), lineNumber);
168                if (!KualiDecimal.isNumeric(detail.getCurrentAmount())) {
169                    isValid = false;
170                    String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_AMT_IS_NONUMERIC, detail.getObjectCode(), detail.getCurrentAmount());
171                    this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
172                }
173                else {
174                    // test if amount is non zero
175                    KualiDecimal amt = new KualiDecimal(detail.getCurrentAmount());
176                    if (amt.isZero()) {
177                        isValid = false;
178                        String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_AMT_IS_NONUMERIC, detail.getObjectCode(), detail.getCurrentAmount());
179                        this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
180                    }
181                }
182                if (isValidAcct && (!accountCreationService.isValidChartAccount(detail.getChart(), detail.getAccount()))) {
183                    isValid = false;
184                    isValidAcct = false;
185                    String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_INVALID_ACCT, detail.getChart(), detail.getAccount());
186                    this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
187                }
188                else {
189    
190                    ObjectCode objCode = objectCodeService.getByPrimaryId(postingFiscalYear, detail.getChart(), detail.getObjectCode());
191                    if (objCode == null) {
192                        isValid = false;
193                        String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_INVALID_OBJECTCODE, detail.getChart(), detail.getObjectCode());
194                        this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
195                    } else if (!objCode.isFinancialObjectActiveCode()) {
196                        isValid = false;
197                        String message = GlobalVariablesExtractHelper.replaceTokens(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_INACTIVE_OBJECTCODE, detail.getChart(), detail.getObjectCode(), postingFiscalYear.toString());
198                        this.setFailStatus(budgetAdjustmentCreationStatusDTO, message);
199                    }
200                }
201            }
202            return isValid;
203        }
204    
205        /**
206         * This method creates an account to be used for automatic maintenance document
207         * 
208         * @param AccountParametersDTO
209         * @return Account
210         */
211        protected BudgetAdjustmentDocument createBudgetAdjustmentObject(BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatus) {
212            BudgetAdjustmentDocument budgetAdjustmentDocument = (BudgetAdjustmentDocument) createBADocument(budgetAdjustmentCreationStatus);
213            // also populates posting year
214            budgetAdjustmentDocument.initiateDocument();
215             return budgetAdjustmentDocument;
216        }
217        
218        protected boolean populateBudgetAdjustmentDocDetails(BudgetAdjustmentParametersDTO parameters, BudgetAdjustmentDocument budgetAdjustmentDocument, BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatus) {
219            
220            boolean methodSuccessful = true;
221    
222            // The Description of the BA document should carry the Award Document Number and Budget Version Number.
223            budgetAdjustmentDocument.getDocumentHeader().setDocumentDescription(parameters.getDescription());
224            budgetAdjustmentDocument.getDocumentHeader().setExplanation(parameters.getExplanation());
225            budgetAdjustmentDocument.getDocumentHeader().setOrganizationDocumentNumber(parameters.getOrgDocNumber());
226            KualiDecimal runningtotal = KualiDecimal.ZERO;
227            Integer fiscalYear = budgetAdjustmentDocument.getPostingYear();
228            if (parameters.getDetails() != null) {
229                for (BudgetAdjustmentParametersDTO.Details detail : parameters.getDetails()) {
230                    if (KualiDecimal.isNumeric(detail.getCurrentAmount())) {
231                        KualiDecimal amount = new KualiDecimal(detail.getCurrentAmount());
232                        runningtotal = runningtotal.add(amount);
233                        if (amount.isPositive()) {
234                            budgetAdjustmentDocument.addTargetAccountingLine(createBudgetAdjustmentTargetAccountingLine(detail,fiscalYear));
235                        }
236                        else {
237                            budgetAdjustmentDocument.addSourceAccountingLine(createBudgetAdjustmentSourceAccountingLine(detail,fiscalYear));
238                        }
239                    }
240                }
241                if (runningtotal.isNonZero()) {
242                    boolean success = this.generateIncomeAccountingLine(fiscalYear, parameters.getSponsorType(), budgetAdjustmentDocument, runningtotal);
243                    if (!success) {
244                        budgetAdjustmentCreationStatus.getErrorMessages().add(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_SYSTEM_PARAMETER_INCORRECT_VALUE + ContractsAndGrantsConstants.BudgetAdjustmentService.PARAMETER_INCOME_OBJECT_CODES_BY_SPONSOR_TYPE);
245                        budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
246                        methodSuccessful = false;
247                    }
248                }
249            }
250            
251            return methodSuccessful;        
252        }
253    
254        protected void populateAccountingLine(BudgetAdjustmentAccountingLine acctLine, Integer postingYear, String chart, String accountNumber, String proj, String objCode, KualiDecimal currentBudgetAdjustmentAmount) {
255            acctLine.setChartOfAccountsCode(chart);
256            acctLine.setAccountNumber(accountNumber);
257            if ((proj != null) && (!proj.isEmpty()))
258                acctLine.setProjectCode(proj);
259            acctLine.setFinancialObjectCode(objCode);
260            acctLine.setCurrentBudgetAdjustmentAmount(currentBudgetAdjustmentAmount);
261            acctLine.setPostingYear(postingYear);
262            acctLine.refresh();
263        }
264    
265        protected BudgetAdjustmentSourceAccountingLine createBudgetAdjustmentSourceAccountingLine(BudgetAdjustmentParametersDTO.Details detail, Integer postingYear) {
266    
267            BudgetAdjustmentSourceAccountingLine budgetAdjustmentSourceAccountingLine = new BudgetAdjustmentSourceAccountingLine();
268            // from / decrease chart -account
269            KualiDecimal amount = new KualiDecimal(detail.getCurrentAmount()).abs();
270            populateAccountingLine(budgetAdjustmentSourceAccountingLine, postingYear, detail.getChart(), detail.getAccount(), detail.getProjectCode(), detail.getObjectCode(), amount);
271            return budgetAdjustmentSourceAccountingLine;
272        }
273    
274        protected BudgetAdjustmentTargetAccountingLine createBudgetAdjustmentTargetAccountingLine(BudgetAdjustmentParametersDTO.Details detail, Integer postingYear) {
275            BudgetAdjustmentTargetAccountingLine budgetAdjustmentTargetAccountingLine = new BudgetAdjustmentTargetAccountingLine();
276            // TO / increase chart -account
277            KualiDecimal amount = new KualiDecimal(detail.getCurrentAmount()).abs();
278            populateAccountingLine(budgetAdjustmentTargetAccountingLine, postingYear, detail.getChart(), detail.getAccount(), detail.getProjectCode(), detail.getObjectCode(), amount);
279            return budgetAdjustmentTargetAccountingLine;
280    
281        }
282    
283        protected boolean generateIncomeAccountingLine(Integer postingYear, String sponsorType, BudgetAdjustmentDocument baDoc, KualiDecimal amount) {
284            BudgetAdjustmentParametersDTO.Details incomeDetail = new BudgetAdjustmentParametersDTO.Details();
285            if (!parameterService.parameterExists(BudgetAdjustmentDocument.class, ContractsAndGrantsConstants.BudgetAdjustmentService.PARAMETER_INCOME_OBJECT_CODES_BY_SPONSOR_TYPE))
286                return false;
287            String sponsorCodeMapValue = parameterService.getParameterValue(BudgetAdjustmentDocument.class, ContractsAndGrantsConstants.BudgetAdjustmentService.PARAMETER_INCOME_OBJECT_CODES_BY_SPONSOR_TYPE, sponsorType);
288            if (sponsorCodeMapValue == null)
289                return false;
290            if (amount.isNegative()) { // from side
291                AccountingLine accountingLineDetail = baDoc.getSourceAccountingLine(0);
292                BudgetAdjustmentSourceAccountingLine budgetAdjustmentSourceAccountingLine = new BudgetAdjustmentSourceAccountingLine();
293                populateAccountingLine(budgetAdjustmentSourceAccountingLine,postingYear, accountingLineDetail.getChartOfAccountsCode(), accountingLineDetail.getAccountNumber(), accountingLineDetail.getProjectCode(), sponsorCodeMapValue, amount.abs());
294                baDoc.addSourceAccountingLine(budgetAdjustmentSourceAccountingLine);
295            }
296            else {
297                AccountingLine accountingLineDetail = baDoc.getTargetAccountingLine(0);
298                BudgetAdjustmentTargetAccountingLine budgetAdjustmentTargetAccountingLine = new BudgetAdjustmentTargetAccountingLine();
299                populateAccountingLine(budgetAdjustmentTargetAccountingLine,postingYear, accountingLineDetail.getChartOfAccountsCode(), accountingLineDetail.getAccountNumber(), accountingLineDetail.getProjectCode(), sponsorCodeMapValue, amount.abs());
300                baDoc.addTargetAccountingLine(budgetAdjustmentTargetAccountingLine);
301            }
302            return true;
303        }
304    
305    
306        /**
307         * This method will use the DocumentService to create a new document. The documentTypeName is gathered by using
308         * MaintenanceDocumentDictionaryService which uses Account class to get the document type name.
309         * 
310         * @param AccountCreationStatusDTO
311         * @return document returns a new document for the account document type or null if there is an exception thrown.
312         */
313        protected Document createBADocument(BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatusDTO) {
314            try {
315                Document document = getDocumentService().getNewDocument(SpringContext.getBean(TransactionalDocumentDictionaryService.class).getDocumentClassByName("BA"));
316                return document;
317            }
318            catch (Exception e) {
319                budgetAdjustmentCreationStatusDTO.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());
320                budgetAdjustmentCreationStatusDTO.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
321                return null;
322    
323    
324            }
325        }
326    
327        /**
328         * This method processes the workflow document actions like save, route and blanket approve depending on the
329         * ACCOUNT_AUTO_CREATE_ROUTE system parameter value. If the system parameter value is not of save or submit or blanketapprove,
330         * put an error message and quit. Throws an document WorkflowException if the specific document action fails to perform.
331         * 
332         * @param maintenanceAccountDocument, errorMessages
333         * @return success returns true if the workflow document action is successful else return false.
334         */
335        protected boolean routeBudgetAdjustmentDocument(BudgetAdjustmentDocument budgetAdjustmentDocument, BudgetAdjustmentCreationStatusDTO budgetAdjustmentCreationStatus) {
336    
337            try {
338                // getParameterService().setParameterForTesting(BudgetAdjustmentDocument.class,
339                // KcConstants.BudgetAdjustmentService.PARAMETER_KC_ADMIN_AUTO_BA_DOCUMENT_WORKFLOW_ROUTE,
340                // KFSConstants.WORKFLOW_DOCUMENT_ROUTE);
341    
342                String BudgetAdjustAutoRouteValue = getParameterService().getParameterValue(BudgetAdjustmentDocument.class, ContractsAndGrantsConstants.BudgetAdjustmentService.PARAMETER_KC_ADMIN_AUTO_BA_DOCUMENT_WORKFLOW_ROUTE);
343                // String BudgetAdjustAutoRouteValue = getParameterService().getParameterValue(Account.class,
344                // KcConstants.BudgetAdjustmentService.PARAMETER_KC_BA_DOCUMENT_ROUTE);
345                // if the accountAutoCreateRouteValue is not save or submit or blanketApprove then put an error message and quit.
346                if (!BudgetAdjustAutoRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_SAVE) && !BudgetAdjustAutoRouteValue.equalsIgnoreCase("submit") && !BudgetAdjustAutoRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_BLANKET_APPROVE)) {
347                    budgetAdjustmentCreationStatus.getErrorMessages().add(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_SYSTEM_PARAMETER_INCORRECT_DOCUMENT_ACTION_VALUE);
348                    budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
349                    return false;
350                }
351    
352                if (BudgetAdjustAutoRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_SAVE)) {
353                    //attempt to save if apply rules were successful and there are no errors
354                    boolean rulesPassed = SpringContext.getBean(KualiRuleService.class).applyRules(new SaveDocumentEvent(budgetAdjustmentDocument));
355                    
356                    if( rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()){
357                        getDocumentService().saveDocument(budgetAdjustmentDocument);
358                    }else{
359                        //get errors from apply rules invocation, also clears global variables
360                        budgetAdjustmentCreationStatus.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());                        
361                        try{
362                            //save document, and catch VE's as we want to do this silently
363                            getDocumentService().saveDocument(budgetAdjustmentDocument);
364                        }catch(ValidationException ve){}
365                        
366                        budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_SUCCESS);                    
367                        LOG.error( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_BA_RULES_EXCEPTION, new String[]{budgetAdjustmentDocument.getDocumentNumber()}));
368                        
369                        return false;
370                    }
371    
372                }
373                else if (BudgetAdjustAutoRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_BLANKET_APPROVE)) {
374    
375                    //attempt to blanket approve if apply rules were successful and there are no errors
376                    boolean rulesPassed = SpringContext.getBean(KualiRuleService.class).applyRules(new BlanketApproveDocumentEvent(budgetAdjustmentDocument));
377                    
378                    if( rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()){
379                        getDocumentService().blanketApproveDocument(budgetAdjustmentDocument, "", null);
380                    }else{
381                        //get errors from apply rules invocation, also clears global variables
382                        budgetAdjustmentCreationStatus.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());                        
383                        try{
384                            //save document, and catch VE's as we want to do this silently
385                            getDocumentService().saveDocument(budgetAdjustmentDocument);
386                        }catch(ValidationException ve){}
387                        
388                        budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_SUCCESS);                    
389                        LOG.error( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_BA_RULES_EXCEPTION, new String[]{budgetAdjustmentDocument.getDocumentNumber()}));
390                        
391                        return false;
392                    }
393                    
394                }
395                else if (BudgetAdjustAutoRouteValue.equalsIgnoreCase("submit")) {
396    
397                    //attempt to blanket approve if apply rules were successful and there are no errors
398                    boolean rulesPassed = SpringContext.getBean(KualiRuleService.class).applyRules(new RouteDocumentEvent(budgetAdjustmentDocument));
399                    
400                    if( rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()){
401                        getDocumentService().routeDocument(budgetAdjustmentDocument, "", null);
402                    }else{
403                        //get errors from apply rules invocation, also clears global variables
404                        budgetAdjustmentCreationStatus.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());                        
405                        try{
406                            //save document, and catch VE's as we want to do this silently
407                            getDocumentService().saveDocument(budgetAdjustmentDocument);
408                        }catch(ValidationException ve){}
409                        
410                        budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_SUCCESS);                    
411                        LOG.error( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_BA_RULES_EXCEPTION, new String[]{budgetAdjustmentDocument.getDocumentNumber()}));
412                    
413                        return false;
414                    }
415    
416                }
417                return true;
418    
419            }
420            catch (Exception ex) {
421                LOG.error(KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,null) + ": " + ex.getMessage());
422                budgetAdjustmentCreationStatus.setErrorMessages(GlobalVariablesExtractHelper.extractGlobalVariableErrors());
423                budgetAdjustmentCreationStatus.getErrorMessages().add( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS, null) + ": " + ex.getMessage());
424                budgetAdjustmentCreationStatus.setStatus(ContractsAndGrantsConstants.KcWebService.STATUS_KC_FAILURE);
425                return false;
426            }
427        }
428    
429        /**
430         * This method check to see if the user can create the account maintenance document and set the user session
431         * 
432         * @param String principalId
433         * @return boolean
434         */
435    
436        protected boolean isValidUser(String principalId) {
437    
438            PersonService<Person> personService = KIMServiceLocator.getPersonService();
439    
440            try {
441                Person user = personService.getPerson(principalId);
442                // Person user = personService.getPersonByPrincipalName(principalId);
443                DocumentAuthorizer documentAuthorizer = new TransactionalDocumentAuthorizerBase();
444                if (documentAuthorizer.canInitiate(SpringContext.getBean(MaintenanceDocumentDictionaryService.class).getDocumentTypeName(Account.class), user)) {
445                    // set the user session so that the user name can be displayed in the saved document
446                    GlobalVariables.setUserSession(new UserSession(user.getPrincipalName()));
447                    return true;
448                }
449                else {
450                    return false;
451                }
452            }
453            catch (Exception ex) {
454                
455                LOG.error( KcUtils.getErrorMessage(ContractsAndGrantsConstants.BudgetAdjustmentService.ERROR_KC_DOCUMENT_INVALID_USER, new String[]{principalId}));
456                return false;
457            }
458        }
459    
460    
461        /**
462         * Gets the documentService attribute.
463         * 
464         * @return Current value of documentService.
465         */
466        protected DocumentService getDocumentService() {
467            return documentService;
468        }
469    
470        /**
471         * Sets the documentService attribute value.
472         * 
473         * @param documentService
474         */
475        public void setDocumentService(DocumentService documentService) {
476            this.documentService = documentService;
477        }
478    
479        /**
480         * Gets the parameterService attribute.
481         * 
482         * @return Returns the parameterService.
483         */
484        protected ParameterService getParameterService() {
485            return parameterService;
486        }
487    
488        /**
489         * Sets the parameterService attribute value.
490         * 
491         * @param parameterService The parameterService to set.
492         */
493        public void setParameterService(ParameterService parameterService) {
494            this.parameterService = parameterService;
495        }
496    
497        protected DataDictionaryService getDataDictionaryService() {
498            return dataDictionaryService;
499        }
500    
501        public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
502            this.dataDictionaryService = dataDictionaryService;
503        }
504    
505        /**
506         * Sets the businessObjectService attribute value.
507         * 
508         * @param businessObjectService The businessObjectService to set.
509         */
510        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
511            this.businessObjectService = businessObjectService;
512        }
513    
514        /**
515         * Gets the businessObjectService attribute.
516         * 
517         * @return Returns the businessObjectService.
518         */
519        protected BusinessObjectService getBusinessObjectService() {
520            return businessObjectService;
521        }
522    
523    }