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.ld.document.web.struts; 017 018 import java.text.MessageFormat; 019 020 import javax.servlet.http.HttpServletRequest; 021 import javax.servlet.http.HttpServletResponse; 022 023 import org.apache.struts.action.ActionForm; 024 import org.apache.struts.action.ActionForward; 025 import org.apache.struts.action.ActionMapping; 026 import org.kuali.kfs.module.ld.LaborConstants; 027 import org.kuali.kfs.module.ld.LaborKeyConstants; 028 import org.kuali.kfs.module.ld.businessobject.LedgerBalance; 029 import org.kuali.kfs.module.ld.document.SalaryExpenseTransferDocument; 030 import org.kuali.kfs.module.ld.document.web.struts.SalaryExpenseTransferForm; 031 import org.kuali.kfs.module.ld.document.service.SalaryTransferPeriodValidationService; 032 import org.kuali.kfs.sys.KFSConstants; 033 import org.kuali.kfs.sys.KFSPropertyConstants; 034 import org.kuali.kfs.sys.ObjectUtil; 035 import org.kuali.kfs.sys.context.SpringContext; 036 import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer; 037 import org.kuali.rice.kns.question.ConfirmationQuestion; 038 import org.kuali.rice.kns.service.DocumentHelperService; 039 import org.kuali.rice.kns.service.KualiConfigurationService; 040 import org.kuali.rice.kns.service.ParameterService; 041 import org.kuali.rice.kns.util.ErrorMessage; 042 import org.kuali.rice.kns.util.GlobalVariables; 043 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 044 /** 045 * Struts action class for Salary Expense Transfer Document. This class extends the parent FinancialSystemTransactionalDocumentActionBase 046 * class, which contains all common action methods. Since the SEP follows the basic transactional document pattern, there are no 047 * specific actions that it has to implement; however, this empty class is necessary for integrating into the framework. 048 */ 049 public class SalaryExpenseTransferAction extends ExpenseTransferDocumentActionBase { 050 /** 051 * Resets lookup fields for salary expense transfer action 052 * 053 * @see org.kuali.kfs.module.ld.document.web.struts.ExpenseTransferDocumentActionBase#resetLookupFields(org.kuali.kfs.module.ld.document.web.struts.ExpenseTransferDocumentFormBase, 054 * org.kuali.kfs.module.ld.businessobject.LedgerBalance) 055 */ 056 @Override 057 protected void resetLookupFields(ExpenseTransferDocumentFormBase expenseTransferDocumentForm, LedgerBalance balance) { 058 SalaryExpenseTransferForm expenseTransferForm = (SalaryExpenseTransferForm) expenseTransferDocumentForm; 059 expenseTransferForm.getSalaryExpenseTransferDocument().setEmplid(balance.getEmplid()); 060 ObjectUtil.buildObject(expenseTransferForm, balance); 061 } 062 063 /** 064 * If user is approving document, capture the object code balances for comparison in business rules on route 065 * 066 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#docHandler(org.apache.struts.action.ActionMapping, 067 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 068 */ 069 @Override 070 public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 071 ActionForward forward = super.docHandler(mapping, form, request, response); 072 073 SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument(); 074 if (salaryExpenseDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested()) { 075 salaryExpenseDocument.setApprovalObjectCodeBalances(salaryExpenseDocument.getUnbalancedObjectCodes()); 076 } 077 078 return forward; 079 } 080 081 /** 082 * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#route(org.apache.struts.action.ActionMapping, 083 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 084 */ 085 @Override 086 public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 087 ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.ROUTE_METHOD); 088 if (forward != null) { 089 return forward; 090 } 091 092 return super.route(mapping, form, request, response); 093 } 094 095 /** 096 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#approve(org.apache.struts.action.ActionMapping, 097 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 098 */ 099 @Override 100 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 101 ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.APPROVE_METHOD); 102 if (forward != null) { 103 return forward; 104 } 105 106 return super.approve(mapping, form, request, response); 107 } 108 109 /** 110 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#blanketApprove(org.apache.struts.action.ActionMapping, 111 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 112 */ 113 @Override 114 public ActionForward blanketApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 115 ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.BLANKET_APPROVE_METHOD); 116 if (forward != null) { 117 return forward; 118 } 119 120 return super.blanketApprove(mapping, form, request, response); 121 } 122 123 /** 124 * Calls service to verify the salary transfer does not conflict with effort certifications and handle any errors returned. 125 * 126 * @return ActionForward which is null if everything was OK, the question redirect if errors found and user is admin, the basic 127 * mapping (which goes back to document) if errors were found and the user is not admin and document is not enroute, or 128 * finally redirect back to portal if document was disapproved due to errors 129 */ 130 protected ActionForward doEffortCertificationValidation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String caller) throws Exception { 131 SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument(); 132 133 // check sys parameter indicating if we should check effort certification rules 134 boolean doEffortValidation = SpringContext.getBean(ParameterService.class).getIndicatorParameter(SalaryExpenseTransferDocument.class, LaborConstants.SalaryExpenseTransfer.VALIDATE_AGAINST_EFFORT_PARM_NM); 135 if (!doEffortValidation) { 136 return null; 137 } 138 139 // check if we are returning from a question, in which case we previously check effort and asked admin to confirm. If not, 140 // we need to perform validation. 141 String question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME); 142 if (question == null) { // question hasn't been asked 143 boolean transferValid = SpringContext.getBean(SalaryTransferPeriodValidationService.class).validateTransfers(salaryExpenseDocument); 144 if (!transferValid) { 145 return handleEffortValidationErrors(mapping, form, request, response, caller, false); 146 } 147 } 148 else { 149 // check if admin wants to continue, or not in which case we return to document or cancel document (in enroute) 150 String buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); 151 if ((LaborConstants.SalaryExpenseTransfer.EFFORT_VALIDATION_OVERRIDE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { 152 return handleEffortValidationErrors(mapping, form, request, response, caller, true); 153 } 154 } 155 156 return null; 157 } 158 159 /** 160 * If the user is an effort administrator ask if they want to override the errors (if not already asked). Otherwise if the 161 * document is enroute it will be disapproved or if being initiated just return to doc. 162 * 163 * @return ActionForward which is question redirect, portal redirect, or basic mapping (back to doc) 164 * @throws Exception 165 */ 166 protected ActionForward handleEffortValidationErrors(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String caller, boolean questionAsked) throws Exception { 167 SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument(); 168 169 TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(salaryExpenseDocument); 170 171 boolean isAdmin = documentAuthorizer.isAuthorized(salaryExpenseDocument, LaborConstants.LABOR_MODULE_CODE, 172 LaborConstants.PermissionNames.OVERRIDE_TRANSFER_IMPACTING_EFFORT_CERTIFICATION, 173 GlobalVariables.getUserSession().getPerson().getPrincipalId()); 174 175 if (isAdmin && !questionAsked) { 176 // error found, ask admin user if they want to override 177 KualiConfigurationService kualiConfigurationService = SpringContext.getBean(KualiConfigurationService.class); 178 179 // build question text (contains error messages found) 180 String message = ""; 181 if (GlobalVariables.getMessageMap().containsKey(KFSPropertyConstants.SOURCE_ACCOUNTING_LINES)) { 182 for (Object errorMessage : GlobalVariables.getMessageMap().getMessages(KFSPropertyConstants.SOURCE_ACCOUNTING_LINES)) { 183 String errorMsg = kualiConfigurationService.getPropertyString(((ErrorMessage) errorMessage).getErrorKey()); 184 message += MessageFormat.format(errorMsg, (Object[]) ((ErrorMessage) errorMessage).getMessageParameters()); 185 } 186 } 187 188 if (GlobalVariables.getMessageMap().containsKey(KFSPropertyConstants.TARGET_ACCOUNTING_LINES)) { 189 for (Object errorMessage : GlobalVariables.getMessageMap().getMessages(KFSPropertyConstants.TARGET_ACCOUNTING_LINES)) { 190 String errorMsg = kualiConfigurationService.getPropertyString(((ErrorMessage) errorMessage).getErrorKey()); 191 message += MessageFormat.format(errorMsg, (Object[]) ((ErrorMessage) errorMessage).getMessageParameters()); 192 } 193 } 194 message += " " + kualiConfigurationService.getPropertyString(LaborKeyConstants.EFFORT_VALIDATION_OVERRIDE_MESSAGE); 195 196 return this.performQuestionWithoutInput(mapping, form, request, response, LaborConstants.SalaryExpenseTransfer.EFFORT_VALIDATION_OVERRIDE_QUESTION, message, KFSConstants.CONFIRMATION_QUESTION, caller, ""); 197 } 198 199 // errors found, return to document if it is being initiated, or disapproved if enroute 200 if (salaryExpenseDocument.getDocumentHeader().getWorkflowDocument().stateIsEnroute()) { 201 SpringContext.getBean(SalaryTransferPeriodValidationService.class).disapproveSalaryExpenseDocument(salaryExpenseDocument); 202 203 return returnToSender(request, mapping, (KualiDocumentFormBase) form); 204 } 205 206 return mapping.findForward(KFSConstants.MAPPING_BASIC); 207 } 208 209 /** 210 * Delete all source accounting lines 211 * 212 * @param mapping 213 * @param form 214 * @param request 215 * @param response 216 * @return ActionMapping 217 * @throws Exception 218 */ 219 @Override 220 public ActionForward deleteAllSourceAccountingLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 221 SalaryExpenseTransferForm financialDocumentForm = (SalaryExpenseTransferForm) form; 222 financialDocumentForm.getSalaryExpenseTransferDocument().setNextSourceLineNumber(KFSConstants.ONE.intValue()); 223 224 return super.deleteAllSourceAccountingLines(mapping, form, request, response); 225 } 226 227 /** 228 * Delete all target accounting lines 229 * 230 * @param mapping 231 * @param form 232 * @param request 233 * @param response 234 * @return ActionMapping 235 * @throws Exception 236 */ 237 @Override 238 public ActionForward deleteAllTargetAccountingLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 239 SalaryExpenseTransferForm financialDocumentForm = (SalaryExpenseTransferForm) form; 240 financialDocumentForm.getSalaryExpenseTransferDocument().setNextTargetLineNumber(KFSConstants.ONE.intValue()); 241 242 return super.deleteAllTargetAccountingLines(mapping, form, request, response); 243 } 244 } 245