/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.module.ld.document.web.struts;
import java.text.MessageFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.kuali.kfs.module.ld.LaborConstants;
import org.kuali.kfs.module.ld.LaborKeyConstants;
import org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine;
import org.kuali.kfs.module.ld.businessobject.LedgerBalance;
import org.kuali.kfs.module.ld.document.LaborExpenseTransferDocumentBase;
import org.kuali.kfs.module.ld.document.SalaryExpenseTransferDocument;
import org.kuali.kfs.module.ld.document.service.SalaryTransferPeriodValidationService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.ObjectUtil;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
import org.kuali.rice.kns.question.ConfirmationQuestion;
import org.kuali.rice.kns.service.DocumentHelperService;
import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
import org.kuali.rice.krad.util.ErrorMessage;
import org.kuali.rice.krad.util.GlobalVariables;
/**
* Struts action class for Salary Expense Transfer Document. This class extends the parent FinancialSystemTransactionalDocumentActionBase
* class, which contains all common action methods. Since the SEP follows the basic transactional document pattern, there are no
* specific actions that it has to implement; however, this empty class is necessary for integrating into the framework.
*/
public class SalaryExpenseTransferAction extends ExpenseTransferDocumentActionBase {
/**
* Resets lookup fields for salary expense transfer action
*
* @see org.kuali.kfs.module.ld.document.web.struts.ExpenseTransferDocumentActionBase#resetLookupFields(org.kuali.kfs.module.ld.document.web.struts.ExpenseTransferDocumentFormBase,
* org.kuali.kfs.module.ld.businessobject.LedgerBalance)
*/
@Override
protected void resetLookupFields(ExpenseTransferDocumentFormBase expenseTransferDocumentForm, LedgerBalance balance) {
SalaryExpenseTransferForm expenseTransferForm = (SalaryExpenseTransferForm) expenseTransferDocumentForm;
expenseTransferForm.getSalaryExpenseTransferDocument().setEmplid(balance.getEmplid());
ObjectUtil.buildObject(expenseTransferForm, balance);
}
/**
* If user is approving document, capture the object code balances for comparison in business rules on route
*
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#docHandler(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = super.docHandler(mapping, form, request, response);
SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument();
if (salaryExpenseDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested()) {
salaryExpenseDocument.setApprovalObjectCodeBalances(salaryExpenseDocument.getUnbalancedObjectCodes());
}
return forward;
}
/**
* @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#route(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.ROUTE_METHOD);
if (forward != null) {
return forward;
}
return super.route(mapping, form, request, response);
}
/**
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#approve(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.APPROVE_METHOD);
if (forward != null) {
return forward;
}
return super.approve(mapping, form, request, response);
}
/**
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#blanketApprove(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward blanketApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = doEffortCertificationValidation(mapping, form, request, response, KFSConstants.BLANKET_APPROVE_METHOD);
if (forward != null) {
return forward;
}
return super.blanketApprove(mapping, form, request, response);
}
/**
* Calls service to verify the salary transfer does not conflict with effort certifications and handle any errors returned.
*
* @return ActionForward which is null if everything was OK, the question redirect if errors found and user is admin, the basic
* mapping (which goes back to document) if errors were found and the user is not admin and document is not enroute, or
* finally redirect back to portal if document was disapproved due to errors
*/
protected ActionForward doEffortCertificationValidation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String caller) throws Exception {
SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument();
// check sys parameter indicating if we should check effort certification rules
boolean doEffortValidation = SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(SalaryExpenseTransferDocument.class, LaborConstants.SalaryExpenseTransfer.VALIDATE_AGAINST_EFFORT_PARM_NM);
if (!doEffortValidation) {
return null;
}
// check if we are returning from a question, in which case we previously check effort and asked admin to confirm. If not,
// we need to perform validation.
String question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
if (question == null) { // question hasn't been asked
boolean transferValid = SpringContext.getBean(SalaryTransferPeriodValidationService.class).validateTransfers(salaryExpenseDocument);
if (!transferValid) {
return handleEffortValidationErrors(mapping, form, request, response, caller, false);
}
}
else {
// check if admin wants to continue, or not in which case we return to document or cancel document (in enroute)
String buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
if ((LaborConstants.SalaryExpenseTransfer.EFFORT_VALIDATION_OVERRIDE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) {
return handleEffortValidationErrors(mapping, form, request, response, caller, true);
}
}
return null;
}
/**
* If the user is an effort administrator ask if they want to override the errors (if not already asked). Otherwise if the
* document is enroute it will be disapproved or if being initiated just return to doc.
*
* @return ActionForward which is question redirect, portal redirect, or basic mapping (back to doc)
* @throws Exception
*/
protected ActionForward handleEffortValidationErrors(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String caller, boolean questionAsked) throws Exception {
SalaryExpenseTransferDocument salaryExpenseDocument = (SalaryExpenseTransferDocument) ((KualiDocumentFormBase) form).getDocument();
TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(salaryExpenseDocument);
boolean isAdmin = documentAuthorizer.isAuthorized(salaryExpenseDocument, LaborConstants.LABOR_MODULE_CODE,
LaborConstants.PermissionNames.OVERRIDE_TRANSFER_IMPACTING_EFFORT_CERTIFICATION,
GlobalVariables.getUserSession().getPerson().getPrincipalId());
if (isAdmin && !questionAsked) {
// error found, ask admin user if they want to override
ConfigurationService kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
// build question text (contains error messages found)
String message = "";
if (GlobalVariables.getMessageMap().doesPropertyHaveError(KFSPropertyConstants.SOURCE_ACCOUNTING_LINES)) {
for (Object errorMessage : GlobalVariables.getMessageMap().getMessages(KFSPropertyConstants.SOURCE_ACCOUNTING_LINES)) {
String errorMsg = kualiConfigurationService.getPropertyValueAsString(((ErrorMessage) errorMessage).getErrorKey());
message += MessageFormat.format(errorMsg, (Object[]) ((ErrorMessage) errorMessage).getMessageParameters());
}
}
if (GlobalVariables.getMessageMap().doesPropertyHaveError(KFSPropertyConstants.TARGET_ACCOUNTING_LINES)) {
for (Object errorMessage : GlobalVariables.getMessageMap().getMessages(KFSPropertyConstants.TARGET_ACCOUNTING_LINES)) {
String errorMsg = kualiConfigurationService.getPropertyValueAsString(((ErrorMessage) errorMessage).getErrorKey());
message += MessageFormat.format(errorMsg, (Object[]) ((ErrorMessage) errorMessage).getMessageParameters());
}
}
message += " " + kualiConfigurationService.getPropertyValueAsString(LaborKeyConstants.EFFORT_VALIDATION_OVERRIDE_MESSAGE);
return this.performQuestionWithoutInput(mapping, form, request, response, LaborConstants.SalaryExpenseTransfer.EFFORT_VALIDATION_OVERRIDE_QUESTION, message, KFSConstants.CONFIRMATION_QUESTION, caller, "");
}
// errors found, return to document if it is being initiated, or disapproved if enroute
if (salaryExpenseDocument.getDocumentHeader().getWorkflowDocument().isEnroute()) {
SpringContext.getBean(SalaryTransferPeriodValidationService.class).disapproveSalaryExpenseDocument(salaryExpenseDocument);
return returnToSender(request, mapping, (KualiDocumentFormBase) form);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Delete all source accounting lines
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionMapping
* @throws Exception
*/
@Override
public ActionForward deleteAllSourceAccountingLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
SalaryExpenseTransferForm financialDocumentForm = (SalaryExpenseTransferForm) form;
financialDocumentForm.getSalaryExpenseTransferDocument().setNextSourceLineNumber(KFSConstants.ONE.intValue());
return super.deleteAllSourceAccountingLines(mapping, form, request, response);
}
/**
* Delete all target accounting lines
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionMapping
* @throws Exception
*/
@Override
public ActionForward deleteAllTargetAccountingLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
SalaryExpenseTransferForm financialDocumentForm = (SalaryExpenseTransferForm) form;
financialDocumentForm.getSalaryExpenseTransferDocument().setNextTargetLineNumber(KFSConstants.ONE.intValue());
return super.deleteAllTargetAccountingLines(mapping, form, request, response);
}
}