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