/*
* 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.bc.document.web.struts;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.kuali.kfs.module.bc.BCConstants;
import org.kuali.kfs.module.bc.BCKeyConstants;
import org.kuali.kfs.module.bc.BCPropertyConstants;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionIntendedIncumbent;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition;
import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
import org.kuali.kfs.module.bc.businessobject.SalarySettingExpansion;
import org.kuali.kfs.module.bc.document.BudgetConstructionDocument;
import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
import org.kuali.kfs.module.bc.document.service.SalarySettingService;
import org.kuali.kfs.module.bc.document.validation.event.QuickSaveSalarySettingEvent;
import org.kuali.kfs.module.bc.util.BudgetUrlUtil;
import org.kuali.kfs.sys.DynamicCollectionComparator;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kns.util.KNSGlobalVariables;
import org.kuali.rice.kns.web.struts.form.KualiForm;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.ObjectUtils;
import org.kuali.rice.krad.util.UrlFactory;
/**
* the struts action for the quick salary setting
*/
public class QuickSalarySettingAction extends SalarySettingBaseAction {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(QuickSalarySettingAction.class);
private BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
private SalarySettingService salarySettingService = SpringContext.getBean(SalarySettingService.class);
private BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
/**
* @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
LOG.debug("refresh() started");
super.refresh(mapping, form, request, response);
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
salarySettingForm.setRefreshIncumbentBeforeSalarySetting(false);
salarySettingForm.setRefreshPositionBeforeSalarySetting(false);
return this.loadExpansionScreen(mapping, form, request, response);
}
/**
* Forwards to budget incumbent lookup passing parameters for new funding line.
*/
public ActionForward addIncumbent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
if (!salarySettingForm.isViewOnlyEntry()) {
boolean isSaved = this.save(form);
if (!isSaved) {
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
}
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, salarySettingForm.getChartOfAccountsCode());
parameters.put(KFSPropertyConstants.ACCOUNT_NUMBER, salarySettingForm.getAccountNumber());
parameters.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, salarySettingForm.getSubAccountNumber());
parameters.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, salarySettingForm.getFinancialObjectCode());
parameters.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, salarySettingForm.getFinancialSubObjectCode());
parameters.put(BCConstants.SHOW_SALARY_BY_INCUMBENT_ACTION, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.BUDGET_BY_ACCOUNT_MODE, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.ADD_LINE, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.MAIN_WINDOW, (salarySettingForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(salarySettingForm.getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, salarySettingForm.getAnchor());
}
// the form object is retrieved and removed upon return by KualiRequestProcessor.processActionForm()
parameters.put(BCConstants.RETURN_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(form, BCConstants.FORMKEY_PREFIX));
String lookupUrl = BudgetUrlUtil.buildTempListLookupUrl(mapping, salarySettingForm, BCConstants.TempListLookupMode.INTENDED_INCUMBENT, BudgetConstructionIntendedIncumbent.class.getName(), parameters);
this.cleanupAnySessionForm(mapping, request);
return new ActionForward(lookupUrl, true);
}
/**
* Forwards to budget position lookup passing parameters for new funding line.
*/
public ActionForward addPosition(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
if (!salarySettingForm.isViewOnlyEntry()) {
boolean isSaved = this.save(form);
if (!isSaved) {
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
}
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, salarySettingForm.getChartOfAccountsCode());
parameters.put(KFSPropertyConstants.ACCOUNT_NUMBER, salarySettingForm.getAccountNumber());
parameters.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, salarySettingForm.getSubAccountNumber());
parameters.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, salarySettingForm.getFinancialObjectCode());
parameters.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, salarySettingForm.getFinancialSubObjectCode());
parameters.put(BCConstants.SHOW_SALARY_BY_POSITION_ACTION, Boolean.toString(salarySettingForm.isBudgetByAccountMode()));
parameters.put(BCPropertyConstants.BUDGET_BY_ACCOUNT_MODE, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.ADD_LINE, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.MAIN_WINDOW, (salarySettingForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(salarySettingForm.getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, salarySettingForm.getAnchor());
}
// the form object is retrieved and removed upon return by KualiRequestProcessor.processActionForm()
parameters.put(BCConstants.RETURN_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(form, BCConstants.FORMKEY_PREFIX));
String lookupUrl = BudgetUrlUtil.buildTempListLookupUrl(mapping, salarySettingForm, BCConstants.TempListLookupMode.BUDGET_POSITION_LOOKUP, BudgetConstructionPosition.class.getName(), parameters);
this.cleanupAnySessionForm(mapping, request);
return new ActionForward(lookupUrl, true);
}
/**
* @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseAction#loadExpansionScreen(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward loadExpansionScreen(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
Map<String, Object> keyMap = salarySettingForm.getKeyMapOfSalarySettingItem();
SalarySettingExpansion salarySettingExpansion = (SalarySettingExpansion) businessObjectService.findByPrimaryKey(SalarySettingExpansion.class, keyMap);
if (salarySettingExpansion == null) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_MESSAGES, BCKeyConstants.ERROR_SALARY_SETTING_EXPANSION_NOT_FOUND);
return this.returnToCaller(mapping, form, request, response);
}
salarySettingForm.setSalarySettingExpansion(salarySettingExpansion);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* perform salary setting by incumbent with the specified funding line
*/
public ActionForward performIncumbentSalarySetting(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
if (!salarySettingForm.isViewOnlyEntry()) {
boolean isSaved = this.save(form);
if (!isSaved) {
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
}
String salarySettingURL = this.buildDetailSalarySettingURL(mapping, form, request, BCConstants.INCUMBENT_SALARY_SETTING_ACTION);
this.cleanupAnySessionForm(mapping, request);
return new ActionForward(salarySettingURL, true);
}
/**
* perform salary setting by position with the specified funding line
*/
public ActionForward performPositionSalarySetting(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
if (!salarySettingForm.isViewOnlyEntry()) {
boolean isSaved = this.save(form);
if (!isSaved) {
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
}
String salarySettingURL = this.buildDetailSalarySettingURL(mapping, form, request, BCConstants.POSITION_SALARY_SETTING_ACTION);
this.cleanupAnySessionForm(mapping, request);
return new ActionForward(salarySettingURL, true);
}
/**
* adjust the salary amounts of all funding lines
*/
public ActionForward adjustAllSalarySettingLinesPercent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
SalarySettingExpansion salarySettingExpansion = salarySettingForm.getSalarySettingExpansion();
List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = salarySettingForm.getAppointmentFundings();
KualiDecimal adjustmentAmount = salarySettingForm.getAdjustmentAmount();
String adjustmentMeasurement = salarySettingForm.getAdjustmentMeasurement();
// the adjustment measurement and amount must be provided
if (StringUtils.isBlank(adjustmentMeasurement)) {
GlobalVariables.getMessageMap().putError(BCPropertyConstants.ADJUSTMENT_MEASUREMENT, BCKeyConstants.ERROR_ADJUSTMENT_PERCENT_REQUIRED);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
if (ObjectUtils.isNull(adjustmentAmount)) {
GlobalVariables.getMessageMap().putError(BCPropertyConstants.ADJUSTMENT_AMOUNT, BCKeyConstants.ERROR_ADJUSTMENT_AMOUNT_REQUIRED);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
// retrieve corresponding document in advance in order to use the rule framework
BudgetConstructionDocument document = budgetDocumentService.getBudgetConstructionDocument(salarySettingExpansion);
if (document == null) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_DOCUMENT_NOT_FOUND, salarySettingExpansion.getSalarySettingExpansionString());
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) {
appointmentFunding.setAdjustmentAmount(adjustmentAmount);
appointmentFunding.setAdjustmentMeasurement(adjustmentMeasurement);
String errorKeyPrefix = this.getErrorKeyPrefixOfAppointmentFundingLine(appointmentFundings, appointmentFunding);
ActionForward adjustAction = this.adjustSalarySettingLinePercent(mapping, salarySettingForm, appointmentFunding, document, errorKeyPrefix);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* perform salary setting by position with the specified funding line
*/
public ActionForward toggleAdjustmentMeasurement(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
boolean currentStatus = salarySettingForm.isHideAdjustmentMeasurement();
salarySettingForm.setHideAdjustmentMeasurement(!currentStatus);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseAction#close(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward close(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
ActionForward closeActionForward;
if (salarySettingForm.isViewOnlyEntry() || salarySettingForm.isSalarySettingClosed()) {
closeActionForward = this.returnAfterClose(salarySettingForm, mapping, request, response);
}
else {
closeActionForward = super.close(mapping, salarySettingForm, request, response);
}
return closeActionForward;
}
/**
* @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseAction#save(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
boolean isSaved = this.save(form);
if (isSaved) {
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_SALARY_SETTING_SAVED);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
// save the savable appointment funding lines
private boolean save(ActionForm form) {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
SalarySettingExpansion salarySettingExpansion = salarySettingForm.getSalarySettingExpansion();
BudgetConstructionDocument document = budgetDocumentService.getBudgetConstructionDocument(salarySettingExpansion);
if (document == null) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_DOCUMENT_NOT_FOUND, salarySettingExpansion.getSalarySettingExpansionString());
return false;
}
// get budget allowed flag which is used to deny any updates other than delete
boolean isBudgetAllowed = budgetDocumentService.isBudgetableDocument(document);
List<PendingBudgetConstructionAppointmentFunding> savableAppointmentFundings = salarySettingForm.getAppointmentFundings();
List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = salarySettingForm.getAppointmentFundings();
for (PendingBudgetConstructionAppointmentFunding savableFunding : savableAppointmentFundings) {
String errorKeyPrefix = this.getErrorKeyPrefixOfAppointmentFundingLine(appointmentFundings, savableFunding);
// added 12/3/2008 - gwp
// no rules check for marked delete line
if (savableFunding.isAppointmentFundingDeleteIndicator()) {
continue;
}
salarySettingService.recalculateDerivedInformation(savableFunding);
// any other update must be against a budget allowed document
if (!isBudgetAllowed) {
GlobalVariables.getMessageMap().addToErrorPath(errorKeyPrefix);
GlobalVariables.getMessageMap().putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_BUDGET_DOCUMENT_NOT_BUDGETABLE, salarySettingExpansion.getSalarySettingExpansionString());
return false;
}
// validate the savable appointment funding lines
boolean isValid = this.invokeRules(new QuickSaveSalarySettingEvent(KFSConstants.EMPTY_STRING, errorKeyPrefix, document, savableFunding));
if (!isValid) {
return false;
}
}
salarySettingService.saveSalarySetting(salarySettingExpansion);
salarySettingExpansion.refresh();
return true;
}
// build the URL for the specified salary setting method
private String buildDetailSalarySettingURL(ActionMapping mapping, ActionForm form, HttpServletRequest request, String salarySettingAction) {
QuickSalarySettingForm salarySettingForm = (QuickSalarySettingForm) form;
int indexOfSelectedLine = this.getSelectedLine(request);
List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = salarySettingForm.getAppointmentFundings();
DynamicCollectionComparator.sort(appointmentFundings, KFSPropertyConstants.POSITION_NUMBER, KFSPropertyConstants.EMPLID);
PendingBudgetConstructionAppointmentFunding appointmentFunding = appointmentFundings.get(indexOfSelectedLine);
// get the base action
Map<String, String> salarySettingMethodAction = this.getSalarySettingMethodActionInfo();
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
String baseAction = basePath + "/" + salarySettingAction;
String methodToCall = salarySettingMethodAction.get(salarySettingAction);
// build the query strings with the information of the selected line
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + KFSConstants.ACTION_EXTENSION_DOT_DO);
parameters.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, appointmentFunding.getUniversityFiscalYear().toString());
parameters.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, appointmentFunding.getChartOfAccountsCode());
parameters.put(KFSPropertyConstants.ACCOUNT_NUMBER, appointmentFunding.getAccountNumber());
parameters.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, appointmentFunding.getSubAccountNumber());
parameters.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, appointmentFunding.getFinancialObjectCode());
parameters.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, appointmentFunding.getFinancialSubObjectCode());
parameters.put(KFSPropertyConstants.POSITION_NUMBER, appointmentFunding.getPositionNumber());
parameters.put(KFSPropertyConstants.EMPLID, appointmentFunding.getEmplid());
parameters.put(BCPropertyConstants.REFRESH_INCUMBENT_BEFORE_SALARY_SETTING, Boolean.valueOf(salarySettingForm.isRefreshIncumbentBeforeSalarySetting()).toString());
parameters.put(BCPropertyConstants.REFRESH_POSITION_BEFORE_SALARY_SETTING, Boolean.valueOf(salarySettingForm.isRefreshPositionBeforeSalarySetting()).toString());
parameters.put(BCPropertyConstants.BUDGET_BY_ACCOUNT_MODE, Boolean.TRUE.toString());
parameters.put(BCPropertyConstants.ADD_LINE, Boolean.FALSE.toString());
parameters.put(BCPropertyConstants.MAIN_WINDOW, (salarySettingForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(salarySettingForm.getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, salarySettingForm.getAnchor());
}
// the form object is retrieved and removed upon return by KualiRequestProcessor.processActionForm()
parameters.put(BCConstants.RETURN_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(form, BCConstants.FORMKEY_PREFIX));
return UrlFactory.parameterizeUrl(baseAction, parameters);
}
// get the pairs of the method and action of salary settings
private Map<String, String> getSalarySettingMethodActionInfo() {
Map<String, String> salarySettingMethodAction = new HashMap<String, String>();
salarySettingMethodAction.put(BCConstants.INCUMBENT_SALARY_SETTING_ACTION, BCConstants.INCUMBENT_SALARY_SETTING_METHOD);
salarySettingMethodAction.put(BCConstants.POSITION_SALARY_SETTING_ACTION, BCConstants.POSITION_SALARY_SETTING_METHOD);
return salarySettingMethodAction;
}
/**
* @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseAction#getFundingAwareObjectName()
*/
@Override
protected String getFundingAwareObjectName() {
return BCPropertyConstants.SALARY_SETTING_EXPANSION;
}
}