/*
* 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.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
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 javax.xml.namespace.QName;
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.BCConstants.LockStatus;
import org.kuali.kfs.module.bc.BCConstants.MonthSpreadDeleteType;
import org.kuali.kfs.module.bc.businessobject.BCKeyLabelPair;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAccountOrganizationHierarchy;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAuthorizationStatus;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionHeader;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionLockStatus;
import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionGeneralLedger;
import org.kuali.kfs.module.bc.document.BudgetConstructionDocument;
import org.kuali.kfs.module.bc.document.service.BudgetConstructionMonthlyBudgetsCreateDeleteService;
import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
import org.kuali.kfs.module.bc.document.service.LockService;
import org.kuali.kfs.module.bc.document.validation.event.AddPendingBudgetGeneralLedgerLineEvent;
import org.kuali.kfs.module.bc.document.validation.event.DeletePendingBudgetGeneralLedgerLineEvent;
import org.kuali.kfs.module.bc.exception.BudgetConstructionDocumentAuthorizationException;
import org.kuali.kfs.module.bc.identity.BudgetConstructionNoAccessMessageSetting;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.core.api.util.type.KualiInteger;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kew.api.exception.WorkflowException;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.principal.Principal;
import org.kuali.rice.kim.api.role.Role;
import org.kuali.rice.kim.api.services.KimApiServiceLocator;
import org.kuali.rice.kim.api.type.KimType;
import org.kuali.rice.kim.framework.role.RoleTypeService;
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.util.KNSGlobalVariables;
import org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase;
import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
import org.kuali.rice.kns.web.struts.form.KualiForm;
import org.kuali.rice.krad.UserSession;
import org.kuali.rice.krad.document.Document;
import org.kuali.rice.krad.exception.AuthorizationException;
import org.kuali.rice.krad.exception.UnknownDocumentIdException;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.KualiRuleService;
import org.kuali.rice.krad.service.PersistenceService;
import org.kuali.rice.krad.service.SessionDocumentService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;
import org.kuali.rice.krad.util.UrlFactory;
/**
* need to figure out if this should extend KualiAction, KualiDocumentActionBase or KualiTransactionDocumentActionBase
*/
public class BudgetConstructionAction extends KualiTransactionalDocumentActionBase {
protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetConstructionAction.class);
/**
* Entry point to all actions Checks for cases where methodToCall is loadDocument, performAccountPullup or
* performAccountPushdown and creates global messages to describe the new editingMode state. Also handles document locking if
* the editingMode is BudgetConstructionEditMode.FULL_ENTRY. (Re)Populates the pullup and pushdown selection controls based on
* the current level of the document and the user's approval access for the levels above and below the current level.
*
* @see org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase#execute(org.apache.struts.action.ActionMapping,
* org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
// this is only used to indicate to the rules the user has clicked save or close save-yes
// which forces tighter checks (nonZeroRequest amount) when access is cleanup mode
if (budgetConstructionForm.getBudgetConstructionDocument().isCleanupModeActionForceCheck()) {
budgetConstructionForm.getBudgetConstructionDocument().setCleanupModeActionForceCheck(Boolean.FALSE);
}
// TODO: the catch code comes from KualiDocumentActionBase.loadDocument()
// this allows the top portion of the document to be populated and the close button to function
// and also displays all the possible error messages for now
// we need to update this once KIM is adjusted to handle BC no access cases
// and maybe just show the authorization exception message
ActionForward forward = null;
try {
forward = super.execute(mapping, form, request, response);
}
catch (AuthorizationException e) {
forward = mapping.findForward(KFSConstants.MAPPING_BASIC);
String docId = budgetConstructionForm.getDocId();
Document doc = null;
doc = getDocumentService().getByDocumentHeaderId(docId);
if (doc == null) {
throw new UnknownDocumentIdException("Document no longer exists. It may have been cancelled before being saved.");
}
WorkflowDocument workflowDocument = doc.getDocumentHeader().getWorkflowDocument();
// if (!getDocumentHelperService().getDocumentAuthorizer(doc).canOpen(doc,
// GlobalVariables.getUserSession().getPerson())) {
// throw buildAuthorizationException("open", doc);
// }
// re-retrieve the document using the current user's session - remove the system user from the WorkflowDcument object
if (workflowDocument != doc.getDocumentHeader().getWorkflowDocument()) {
LOG.warn("Workflow document changed via canOpen check");
doc.getDocumentHeader().setWorkflowDocument(workflowDocument);
}
budgetConstructionForm.setDocument(doc);
WorkflowDocument workflowDoc = doc.getDocumentHeader().getWorkflowDocument();
budgetConstructionForm.setDocTypeName(workflowDoc.getDocumentTypeName());
// KualiDocumentFormBase.populate() needs this updated in the session
SpringContext.getBean(SessionDocumentService.class).addDocumentToUserSession(GlobalVariables.getUserSession(), workflowDoc);
budgetConstructionForm.setSecurityNoAccess(true);
setBudgetDocumentNoAccessMessage(budgetConstructionForm);
budgetConstructionForm.getDocumentActions().put(KRADConstants.KUALI_ACTION_CAN_CLOSE, Boolean.TRUE);
}
// apprise user of granted access
if (budgetConstructionForm.getMethodToCall().equals(BCConstants.BC_DOCUMENT_METHOD) || budgetConstructionForm.getMethodToCall().equals(BCConstants.BC_DOCUMENT_PULLUP_METHOD) || budgetConstructionForm.getMethodToCall().equals(BCConstants.BC_DOCUMENT_PUSHDOWN_METHOD)) {
// init the account org hier state on initial load only - this is stored as hiddens
if (budgetConstructionForm.getMethodToCall().equals(BCConstants.BC_DOCUMENT_METHOD)) {
budgetConstructionForm.setAccountOrgHierLevels(SpringContext.getBean(BudgetDocumentService.class).getPushPullLevelList(budgetConstructionForm.getBudgetConstructionDocument(), GlobalVariables.getUserSession().getPerson()));
}
if (budgetConstructionForm.isSystemViewOnly()) {
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_SYSTEM_VIEW_ONLY);
}
if (!budgetConstructionForm.isEditAllowed()) {
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_VIEW_ONLY);
}
if (budgetConstructionForm.isEditAllowed()) {
if (budgetConstructionForm.isSystemViewOnly()) {
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_VIEW_ONLY);
}
else {
// tell the user if the document is in not budgetable mode
budgetConstructionForm.getBudgetConstructionDocument().setBudgetableDocument(SpringContext.getBean(BudgetDocumentService.class).isBudgetableDocumentNoWagesCheck(budgetConstructionForm.getBudgetConstructionDocument()));
// budgetConstructionForm.setBudgetableDocument(SpringContext.getBean(BudgetDocumentService.class).isBudgetableDocumentNoWagesCheck(budgetConstructionForm.getBudgetConstructionDocument()));
if (!budgetConstructionForm.isBudgetableDocument()) {
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_DOCUMENT_NOT_BUDGETABLE);
}
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_EDIT_ACCESS);
}
if (!budgetConstructionForm.isSystemViewOnly()) {
LockService lockService = SpringContext.getBean(LockService.class);
HashMap primaryKey = new HashMap();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, budgetConstructionForm.getDocument().getDocumentNumber());
BudgetConstructionHeader budgetConstructionHeader = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BudgetConstructionHeader.class, primaryKey);
if (budgetConstructionHeader != null) {
// BudgetConstructionLockStatus bcLockStatus = lockService.lockAccount(budgetConstructionHeader,
// GlobalVariables.getUserSession().getPerson().getPrincipalId());
BudgetConstructionLockStatus bcLockStatus = lockService.lockAccountAndCommit(budgetConstructionHeader, GlobalVariables.getUserSession().getPerson().getPrincipalId());
if (bcLockStatus.getLockStatus() == LockStatus.SUCCESS) {
// update the document version number
// so the saved lock of header doesn't produce an optimistic lock error
// and has the info we just put in the header so doc save doesn't wipe out the lock
budgetConstructionForm.getBudgetConstructionDocument().setVersionNumber(bcLockStatus.getBudgetConstructionHeader().getVersionNumber());
budgetConstructionForm.getBudgetConstructionDocument().setBudgetLockUserIdentifier(bcLockStatus.getBudgetConstructionHeader().getBudgetLockUserIdentifier());
}
else {
if (bcLockStatus.getLockStatus() == LockStatus.BY_OTHER) {
Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(bcLockStatus.getAccountLockOwner());
String lockerName = principal.getPrincipalName();
this.cleanupForLockError(budgetConstructionForm);
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_DOCUMENT_LOCKED, lockerName);
return forward;
}
else {
if (bcLockStatus.getLockStatus() == LockStatus.FLOCK_FOUND) {
this.cleanupForLockError(budgetConstructionForm);
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_FUNDING_LOCKED);
return forward;
}
else {
this.cleanupForLockError(budgetConstructionForm);
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_DOCUMENT_OTHER);
return forward;
}
}
}
}
else {
// unlikely
throw new BudgetConstructionDocumentAuthorizationException(GlobalVariables.getUserSession().getPerson().getName(), "open", budgetConstructionForm.getDocument().getDocumentHeader().getDocumentNumber(), "(can't find document for locking)", budgetConstructionForm.isPickListMode());
}
// if editing, check if 2plg adjustment needed and calc benefits
// since checkTwoPlugAdjusmtent will only be set in docHandler during initial load
// if document is initially view only we want the 2plg adjustment to happen if the user does a pullup to edit
if (budgetConstructionForm.isCheckTwoPlugAdjustment() && budgetConstructionForm.getBudgetConstructionDocument().isContainsTwoPlug() && !budgetConstructionForm.getBudgetConstructionDocument().isSalarySettingOnly()) {
// do 2plg related benefits calc and adjust 2plg for any diff - reset checkTwoPlugAdjusment
budgetConstructionForm.setCheckTwoPlugAdjustment(false);
this.adjustForSalarySettingChanges(budgetConstructionForm);
}
}
// getting here implies a lock or system view mode, try to build a pullup list
// pushdown is only allowed if user has edit access (regardless of system view only mode)
if (budgetConstructionForm.getBudgetConstructionDocument().getOrganizationLevelCode() != 0) {
if (!budgetConstructionForm.getAccountOrgHierLevels().isEmpty()) {
budgetConstructionForm.populatePushPullLevelKeyLabels(budgetConstructionForm.getBudgetConstructionDocument(), budgetConstructionForm.getAccountOrgHierLevels(), false);
}
}
else {
// document(account) at level zero - clear out the pushdownKeyLabels widget for any previous performPush case
budgetConstructionForm.setPushdownLevelKeyLabels(new ArrayList<BCKeyLabelPair>());
}
} // FULL_ENTRY
// pullup is allowed regardless of editMode
if (!budgetConstructionForm.getAccountOrgHierLevels().isEmpty()) {
budgetConstructionForm.populatePushPullLevelKeyLabels(budgetConstructionForm.getBudgetConstructionDocument(), budgetConstructionForm.getAccountOrgHierLevels(), true);
}
}
// cleanup the session edit mode store so we don't side effect organization salary setting
if (budgetConstructionForm.isClosingDocument()) {
GlobalVariables.getUserSession().removeObject(BCConstants.BC_DOC_AUTHORIZATION_STATUS_SESSIONKEY);
}
return forward;
}
/**
* Finds the role type service associated with the document viewer role, than calls method on role type service to set the no
* access message
*
* @param budgetConstructionForm form containing budget document
*/
protected void setBudgetDocumentNoAccessMessage(BudgetConstructionForm budgetConstructionForm) {
Role roleInfo = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(BCConstants.BUDGET_CONSTRUCTION_NAMESPACE, BCConstants.KimApiConstants.DOCUMENT_VIEWER_ROLE_NAME);
KimType typeInfo = KimApiServiceLocator.getKimTypeInfoService().getKimType(roleInfo.getKimTypeId());
if (StringUtils.isNotBlank(typeInfo.getServiceName())) {
// fix to find service using new prefixed name if so configured
// RoleTypeService roleTypeService = (RoleTypeService) SpringContext.getService(typeInfo.getServiceName());
RoleTypeService roleTypeService;
String svcName = typeInfo.getServiceName();
String[] svcNameParts = svcName.split("\\{|\\}");
if (svcNameParts.length == 3){
String nameSpaceURI = svcNameParts[1];
String remoteServiceName = svcNameParts[2];
roleTypeService = (RoleTypeService)GlobalResourceLoader.getService(new QName(nameSpaceURI, remoteServiceName));
} else {
roleTypeService = (RoleTypeService) SpringContext.getService(typeInfo.getServiceName());
}
if (roleTypeService instanceof BudgetConstructionNoAccessMessageSetting) {
((BudgetConstructionNoAccessMessageSetting) roleTypeService).setNoAccessMessage(budgetConstructionForm.getBudgetConstructionDocument(), GlobalVariables.getUserSession().getPerson(), GlobalVariables.getMessageMap());
} else {
LOG.warn(String.format("typeInfo.getServiceName() = %s is not an instance of BudgetConstructionNoAccessMessageSetting for role %s/%s", typeInfo.getServiceName(), BCConstants.BUDGET_CONSTRUCTION_NAMESPACE, BCConstants.KimApiConstants.DOCUMENT_VIEWER_ROLE_NAME));
}
} else {
LOG.warn(String.format("typeInfo.getServiceName() returned a blank service name for role %s/%s", BCConstants.BUDGET_CONSTRUCTION_NAMESPACE, BCConstants.KimApiConstants.DOCUMENT_VIEWER_ROLE_NAME));
}
}
/**
* gwp - no call to super, need to work through command we will use randall - This method might be unnecessary, but putting it
* here allows URL to be consistent with Document URLs gwp - i think we still want this method, just need to figure out if we
* use command initiate or displayDocSearchView or something else. i expect we will get the account/subaccount or docnumber from
* the previous form and assume the document will already exist regardless of creation by genesis or
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws IOException
* @throws ServletException
*/
@Override
public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
loadDocument(budgetConstructionForm);
// set flag to have execute perform 2plug adjusment if the doc goes into edit mode later
budgetConstructionForm.setCheckTwoPlugAdjustment(true);
this.initAuthorization(budgetConstructionForm);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Initially load the document from the DB Coded this to look like KualiDocumentActionBase.loadDocument()
*
* @param budgetConstructionForm
* @throws WorkflowException
*/
@Override
protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) kualiDocumentFormBase;
BudgetConstructionHeader budgetConstructionHeader;
if (budgetConstructionForm.getDocId() != null) {
Map<String, Object> primaryKey = new HashMap<String, Object>();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, budgetConstructionForm.getDocId());
budgetConstructionHeader = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BudgetConstructionHeader.class, primaryKey);
// getting called from doc search?
if (budgetConstructionForm.getMethodToCall().equalsIgnoreCase(KFSConstants.DOC_HANDLER_METHOD)){
// now fill in the form parms normally passed from BC selection or Account selection screens
budgetConstructionForm.setChartOfAccountsCode(budgetConstructionHeader.getChartOfAccountsCode());
budgetConstructionForm.setAccountNumber(budgetConstructionHeader.getAccountNumber());
budgetConstructionForm.setSubAccountNumber(budgetConstructionHeader.getSubAccountNumber());
budgetConstructionForm.setUniversityFiscalYear(budgetConstructionHeader.getUniversityFiscalYear());
budgetConstructionForm.setPickListMode(Boolean.TRUE);
}
}
else {
// use the passed url autoloaded parms to get the record from DB
// BudgetConstructionDaoOjb bcHeaderDao;
String chartOfAccountsCode = budgetConstructionForm.getChartOfAccountsCode();
String accountNumber = budgetConstructionForm.getAccountNumber();
String subAccountNumber = budgetConstructionForm.getSubAccountNumber();
Integer universityFiscalYear = budgetConstructionForm.getUniversityFiscalYear();
budgetConstructionHeader = SpringContext.getBean(BudgetDocumentService.class).getByCandidateKey(chartOfAccountsCode, accountNumber, subAccountNumber, universityFiscalYear);
}
kualiDocumentFormBase.setDocId(budgetConstructionHeader.getDocumentNumber());
super.loadDocument(kualiDocumentFormBase);
BudgetConstructionDocument budgetConstructionDocument = (BudgetConstructionDocument) kualiDocumentFormBase.getDocument();
// init the benefits calc flags
budgetConstructionDocument.setBenefitsCalcNeeded(false);
budgetConstructionDocument.setMonthlyBenefitsCalcNeeded(false);
// init the new line objects
budgetConstructionForm.initNewLine(budgetConstructionForm.getNewRevenueLine(), true);
budgetConstructionForm.initNewLine(budgetConstructionForm.getNewExpenditureLine(), false);
// need this here to do totaling on initial load
budgetConstructionForm.populatePBGLLines();
budgetConstructionForm.initializePersistedRequestAmounts();
}
/**
* Cleans up state info to handle no access lock errors
*
* @param budgetConstructionForm
*/
protected void cleanupForLockError(BudgetConstructionForm budgetConstructionForm) {
budgetConstructionForm.setSecurityNoAccess(true);
budgetConstructionForm.getDocumentActions().remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
budgetConstructionForm.getDocumentActions().remove(KRADConstants.KUALI_ACTION_CAN_SAVE);
KNSGlobalVariables.getMessageList().remove(BCKeyConstants.MESSAGE_BUDGET_EDIT_ACCESS);
}
/**
* Override to set authorization Maps from session
*
* @see org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase#populateAuthorizationFields(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
*/
@Override
protected void populateAuthorizationFields(KualiDocumentFormBase formBase) {
BudgetConstructionAuthorizationStatus authorizationStatus = (BudgetConstructionAuthorizationStatus) GlobalVariables.getUserSession().retrieveObject(BCConstants.BC_DOC_AUTHORIZATION_STATUS_SESSIONKEY);
if (authorizationStatus == null) {
// execute handles any session timeout before this is called
return;
}
formBase.setDocumentActions(authorizationStatus.getDocumentActions());
formBase.setEditingMode(authorizationStatus.getEditingMode());
}
/**
* Calls authorizer to determine if the user has edit permission and checks if budget construction is active is fiscal year
* function table. Then updates the <code>BudgetConstructionEditStatus</code> in session. Finally updates authorization in the
* form
*
* @param budgetConstructionForm current bc action form that will be updated
*/
protected void initAuthorization(BudgetConstructionForm budgetConstructionForm) {
// GlobalVariables.setRequestCache(ROLE_QUALIFICATION_CACHE_NAME, budgetConstructionForm)
super.populateAuthorizationFields(budgetConstructionForm);
BudgetConstructionAuthorizationStatus editStatus = new BudgetConstructionAuthorizationStatus();
editStatus.setDocumentActions(budgetConstructionForm.getDocumentActions());
editStatus.setEditingMode(budgetConstructionForm.getEditingMode());
GlobalVariables.getUserSession().addObject(BCConstants.BC_DOC_AUTHORIZATION_STATUS_SESSIONKEY, editStatus);
}
/**
* Applies adjustments due to 2plg existence at initial load or detected salary setting changes upon returning from the Quick
* Salary Setting screen. The adjustments consist of calculating benefits and adding any expenditure total before/after
* difference back into a 2plg row, creating or updating as needed. Then, validation is performed. Sucessful validation removes
* the 2plg row if the final, post benefits calc, adjusted amount is zero. This method assumes the set of expenditure rows in
* memory currently matches the DB.
*
* @param bcForm
*/
protected void adjustForSalarySettingChanges(BudgetConstructionForm bcForm) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
BudgetConstructionDocument bcDoc = (BudgetConstructionDocument) bcForm.getDocument();
KualiInteger oldRequestAmount = bcDoc.getExpenditureAccountLineAnnualBalanceAmountTotal();
// calc benefits also handles setting persisted amounts and populating reloaded benefit rows
budgetDocumentService.calculateBenefits(bcDoc);
// bcForm.initializePersistedRequestAmounts();
// repop and refresh refs - esp monthly so jsp can properly display state
// bcForm.populatePBGLLines();
// need 2plg adjustment and save, even if it is zero
KualiInteger newRquestAmount = bcForm.getBudgetConstructionDocument().getExpenditureAccountLineAnnualBalanceAmountTotal();
PendingBudgetConstructionGeneralLedger twoPlugRow = budgetDocumentService.updatePendingBudgetGeneralLedgerPlug(bcDoc, newRquestAmount.subtract(oldRequestAmount));
}
/**
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#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 {
// return super.close(mapping, form, request, response);
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
// only want to prompt them to save if they already can save
if (docForm.getDocumentActions().keySet().contains(KRADConstants.KUALI_ACTION_CAN_SAVE)) {
Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
ConfigurationService kualiConfiguration = SpringContext.getBean(ConfigurationService.class);
// logic for close question
if (question == null) {
// ask question if not already asked
return this.performQuestionWithoutInput(mapping, form, request, response, KFSConstants.DOCUMENT_SAVE_BEFORE_CLOSE_QUESTION, kualiConfiguration.getPropertyValueAsString(KFSKeyConstants.QUESTION_SAVE_BEFORE_CLOSE), KFSConstants.CONFIRMATION_QUESTION, KFSConstants.MAPPING_CLOSE, "");
}
else {
Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
if ((KFSConstants.DOCUMENT_SAVE_BEFORE_CLOSE_QUESTION.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
// if yes button clicked - save the doc
BudgetConstructionDocument bcDoc = (BudgetConstructionDocument) docForm.getDocument();
// force tighter checks when saving in cleanup mode
if (!bcDoc.isBudgetableDocument()) {
bcDoc.setCleanupModeActionForceCheck(Boolean.TRUE);
}
// SpringContext.getBean(DocumentService.class).updateDocument(docForm.getDocument());
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
budgetDocumentService.saveDocument(bcDoc);
docForm.initializePersistedRequestAmounts();
if (bcDoc.isBenefitsCalcNeeded() || bcDoc.isMonthlyBenefitsCalcNeeded()) {
budgetDocumentService.calculateBenefitsIfNeeded(bcDoc);
KNSGlobalVariables.getMessageList().add(KFSKeyConstants.MESSAGE_SAVED);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
else {
// else drop to close logic below
}
}
// else drop to close logic below
}
}
// do the unlock if they have full access and not system view mode
if (docForm.isEditAllowed() && !docForm.isSystemViewOnly()) {
LockService lockService = SpringContext.getBean(LockService.class);
HashMap primaryKey = new HashMap();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, docForm.getDocument().getDocumentNumber());
BudgetConstructionHeader budgetConstructionHeader = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BudgetConstructionHeader.class, primaryKey);
if (budgetConstructionHeader != null) {
LockStatus lockStatus = lockService.unlockAccount(budgetConstructionHeader);
}
else {
// unlikely, but benign problem here
}
}
// flag to cleanup the session edit mode store so we don't side effect organization salary setting
// used in the bottom of execute()
docForm.setClosingDocument(Boolean.TRUE);
if (docForm.isPickListMode()) {
// redisplay with a message
KNSGlobalVariables.getMessageList().add(BCKeyConstants.MESSAGE_BUDGET_SUCCESSFUL_CLOSE);
docForm.setPickListClose(true);
// this is a hack to do our own session document cleanup since refreshCaller=QuestionRefresh
// prevents proper cleanup in KualiRequestProcessor.processActionPerform()
UserSession userSession = (UserSession) request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY);
String docFormKey = docForm.getFormKey();
SpringContext.getBean(SessionDocumentService.class).purgeDocumentForm(docForm.getDocument().getDocumentNumber(), docFormKey, userSession, request.getRemoteAddr());
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
else {
if (docForm.getReturnFormKey() == null) {
// assume called from doc search or lost the session - go back to main
return returnToSender(request, mapping, docForm);
}
else {
// setup the return parms for the document and anchor and go back to doc select
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, BCConstants.BC_SELECTION_REFRESH_METHOD);
parameters.put(KFSConstants.DOC_FORM_KEY, docForm.getReturnFormKey());
parameters.put(KFSConstants.ANCHOR, docForm.getReturnAnchor());
parameters.put(KFSConstants.REFRESH_CALLER, BCConstants.BC_DOCUMENT_REFRESH_CALLER);
String lookupUrl = UrlFactory.parameterizeUrl("/" + BCConstants.BC_SELECTION_ACTION, parameters);
// this is a hack to do our own session document cleanup since refreshCaller=QuestionRefresh
// prevents proper cleanup in KualiRequestProcessor.processActionPerform()
UserSession userSession = (UserSession) request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY);
String docFormKey = docForm.getFormKey();
SpringContext.getBean(SessionDocumentService.class).purgeDocumentForm(docForm.getDocument().getDocumentNumber(), docFormKey, userSession, request.getRemoteAddr());
return new ActionForward(lookupUrl, true);
}
}
}
/**
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#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 {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = (BudgetConstructionDocument) budgetConstructionForm.getDocument();
// DocumentService documentService = SpringContext.getBean(DocumentService.class);
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// force tighter checks when saving in cleanup mode
if (!bcDocument.isBudgetableDocument()) {
bcDocument.setCleanupModeActionForceCheck(Boolean.TRUE);
}
budgetDocumentService.saveDocument(bcDocument);
budgetConstructionForm.initializePersistedRequestAmounts();
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
KNSGlobalVariables.getMessageList().add(KFSKeyConstants.MESSAGE_SAVED);
budgetConstructionForm.setAnnotation("");
// redisplay the document along with document saved message
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Calls the single line benefits impact screen by setting up the required parameters and feeding them to the temporary list
* lookup action for the expenditure line selected. This is called from the ShowBenefits button on the BC document screen when
* an expenditure line is associated with benefits and benefits calculation is enabled.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performShowBenefits(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument tDoc = tForm.getBudgetConstructionDocument();
int selectIndex = this.getSelectedLine(request);
PendingBudgetConstructionGeneralLedger expLine = tDoc.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(selectIndex);
// when we return from the lookup, our next request's method to call is going to be refresh
tForm.registerEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.START_METHOD);
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + ".do");
if (StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, ((KualiForm) form).getAnchor());
}
// this hack sets the return anchor we want to return too after the inquiry
// do this here so it gets into the session stored form version
// refresh checks for this after and resets the anchor
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
tForm.setBalanceInquiryReturnAnchor(((KualiForm) form).getAnchor());
}
parameters.put(KRADConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(form, BCConstants.FORMKEY_PREFIX));
parameters.put(KFSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, BCConstants.REQUEST_BENEFITS_BO);
parameters.put(KFSConstants.HIDE_LOOKUP_RETURN_LINK, "true");
parameters.put(KFSConstants.SUPPRESS_ACTIONS, "true");
parameters.put(BCConstants.SHOW_INITIAL_RESULTS, "true");
parameters.put(BCConstants.TempListLookupMode.TEMP_LIST_LOOKUP_MODE, Integer.toString(BCConstants.TempListLookupMode.SHOW_BENEFITS));
parameters.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, expLine.getUniversityFiscalYear().toString());
parameters.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, expLine.getChartOfAccountsCode());
parameters.put(KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, expLine.getFinancialObjectCode());
parameters.put(KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT, expLine.getAccountLineAnnualBalanceAmount().toString());
parameters.put(KFSPropertyConstants.ACCOUNT_NUMBER, expLine.getAccountNumber());
parameters.put(KRADConstants.LOOKUP_READ_ONLY_FIELDS, KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR + "," + KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE + "," + KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME + "," + KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT);
String url = UrlFactory.parameterizeUrl(basePath + "/" + BCConstants.ORG_TEMP_LIST_LOOKUP, parameters);
this.setupDocumentExit();
return new ActionForward(url, true);
}
public ActionForward performBalanceInquiryForRevenueLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return performBalanceInquiry(true, mapping, form, request, response);
}
public ActionForward performBalanceInquiryForExpenditureLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return performBalanceInquiry(false, mapping, form, request, response);
}
/**
* This method is similar to org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase.performBalanceInquiry()
*
* @param isRevenue
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performBalanceInquiry(boolean isRevenue, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
final String docNumber;
// get the selected line, setup parms and redirect to balance inquiry
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = (BudgetConstructionDocument) budgetConstructionForm.getDocument();
// when we return from the lookup, our next request's method to call is going to be refresh
budgetConstructionForm.registerEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
PendingBudgetConstructionGeneralLedger pbglLine;
if (isRevenue) {
pbglLine = bcDocument.getPendingBudgetConstructionGeneralLedgerRevenueLines().get(this.getSelectedLine(request));
}
else {
pbglLine = bcDocument.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(this.getSelectedLine(request));
}
// build out base path for return location, use config service
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
// this hack sets the return anchor we want to return too after the inquiry
// do this here so it gets into the session stored form version
// refresh checks for this after and resets the anchor
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
budgetConstructionForm.setBalanceInquiryReturnAnchor(((KualiForm) form).getAnchor());
}
// build out the actual form key that will be used to retrieve the form on refresh
String callerDocFormKey = GlobalVariables.getUserSession().addObjectWithGeneratedKey(form, BCConstants.FORMKEY_PREFIX);
// now add required parameters
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.START_METHOD);
// need this next param b/c the lookup's return back will overwrite
// the original doc form key
parameters.put(KFSConstants.BALANCE_INQUIRY_REPORT_MENU_CALLER_DOC_FORM_KEY, callerDocFormKey);
parameters.put(KFSConstants.DOC_FORM_KEY, callerDocFormKey);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + ".do");
// anchor, if it exists
// this doesn't seem to work with the balance inquiry infrastructure, so added hack above
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, ((KualiForm) form).getAnchor());
}
if (StringUtils.isNotBlank(pbglLine.getChartOfAccountsCode())) {
parameters.put("chartOfAccountsCode", pbglLine.getChartOfAccountsCode());
}
if (StringUtils.isNotBlank(pbglLine.getAccountNumber())) {
parameters.put("accountNumber", pbglLine.getAccountNumber());
}
if (StringUtils.isNotBlank(pbglLine.getFinancialObjectCode())) {
parameters.put("financialObjectCode", pbglLine.getFinancialObjectCode());
}
if (StringUtils.isNotBlank(pbglLine.getSubAccountNumber())) {
parameters.put("subAccountNumber", pbglLine.getSubAccountNumber());
}
if (StringUtils.isNotBlank(pbglLine.getFinancialSubObjectCode())) {
parameters.put("financialSubObjectCode", pbglLine.getFinancialSubObjectCode());
}
String lookupUrl = UrlFactory.parameterizeUrl(basePath + "/" + KFSConstants.BALANCE_INQUIRY_REPORT_MENU_ACTION, parameters);
this.setupDocumentExit();
return new ActionForward(lookupUrl, true);
}
/**
* Calls performMonthlyBudget for the selected revenue line
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performMonthlyRevenueBudget(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return performMonthlyBudget(true, mapping, form, request, response);
}
/**
* Calls performMonthlyBudget for the selected expenditure line
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performMonthlyExpenditureBudget(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return performMonthlyBudget(false, mapping, form, request, response);
}
/**
* Forwards the user to the monthly budget screen. Doing this in edit mode causes the document to be validated, saved and
* benefits calculated (if needed).
*
* @param isRevenue
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performMonthlyBudget(boolean isRevenue, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
final String docNumber;
// this to checks for 2PLG and turns off SS/monthly RI check if found
// the final save after removing 2PLG will catch any monthly discrepencies
// also need to save object,subobject key we are operating on so refresh can get the latest row version from DB
// validate, save, etc first then goto the monthly screen or redisplay if errors
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = (BudgetConstructionDocument) budgetConstructionForm.getDocument();
PendingBudgetConstructionGeneralLedger pbglLine;
if (isRevenue) {
pbglLine = bcDocument.getPendingBudgetConstructionGeneralLedgerRevenueLines().get(this.getSelectedLine(request));
}
else {
pbglLine = bcDocument.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(this.getSelectedLine(request));
}
// when we return from the lookup, our next request's method to call is going to be refresh
budgetConstructionForm.registerEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
if (budgetConstructionForm.isEditAllowed() && !budgetConstructionForm.isSystemViewOnly()) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// if the doc contains a 2plg line, turn off RI checking to allow cleanup.
// The act of attempting to remove a 2plg (delete) forces a complete RI check.
// The document is assumed inconsistent as long as a 2plg exists.
if (!isRevenue && bcDocument.isContainsTwoPlug()) {
if (pbglLine.getLaborObject() != null && pbglLine.getLaborObject().isDetailPositionRequiredIndicator()) {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.EXPENDITURE, false);
}
else {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.EXPENDITURE, true);
}
}
else {
budgetDocumentService.saveDocumentNoWorkflow(bcDocument);
}
budgetConstructionForm.initializePersistedRequestAmounts();
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
// budgetConstructionForm.populatePBGLLines();
}
// String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +
// request.getContextPath();
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, BCConstants.MONTHLY_BUDGET_METHOD);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + ".do");
parameters.put("documentNumber", pbglLine.getDocumentNumber());
parameters.put("universityFiscalYear", pbglLine.getUniversityFiscalYear().toString());
parameters.put("chartOfAccountsCode", pbglLine.getChartOfAccountsCode());
parameters.put("accountNumber", pbglLine.getAccountNumber());
parameters.put("subAccountNumber", pbglLine.getSubAccountNumber());
parameters.put("financialObjectCode", pbglLine.getFinancialObjectCode());
parameters.put("financialSubObjectCode", pbglLine.getFinancialSubObjectCode());
parameters.put("financialBalanceTypeCode", pbglLine.getFinancialBalanceTypeCode());
parameters.put("financialObjectTypeCode", pbglLine.getFinancialObjectTypeCode());
parameters.put("revenue", (isRevenue ? "true" : "false"));
parameters.put(BCPropertyConstants.MAIN_WINDOW, (budgetConstructionForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, ((KualiForm) form).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 = UrlFactory.parameterizeUrl(basePath + "/" + BCConstants.MONTHLY_BUDGET_ACTION, parameters);
this.setupDocumentExit();
return new ActionForward(lookupUrl, true);
}
/**
* Forwards the user to the quick salary setting screen. Doing this in edit mode causes the document to be validated, saved and
* benefits calculated (if needed).
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performSalarySetting(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
final String docNumber;
// this to checks for 2PLG and turns off monthly RI check if found
// the final save after removing 2PLG will catch any monthly discrepencies
// validate, save, etc first then goto the SalarySetting screen or redisplay if errors
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = (BudgetConstructionDocument) budgetConstructionForm.getDocument();
// when we return from the lookup, our next request's method to call is going to be refresh
budgetConstructionForm.registerEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
if (budgetConstructionForm.isEditAllowed() && !budgetConstructionForm.isSystemViewOnly()) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// Regardless if the doc contains a 2plg line, turn off RI checking to allow cleanup.
// The act of attempting to remove a 2plg (delete) forces a complete RI check.
// The document is assumed inconsistent as long as a 2plg exists.
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.EXPENDITURE, false);
// init persisted property and get the current list of salary setting related rows
budgetConstructionForm.initializePersistedRequestAmounts(true);
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
// budgetConstructionForm.populatePBGLLines();
}
PendingBudgetConstructionGeneralLedger pbglLine;
pbglLine = bcDocument.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(this.getSelectedLine(request));
// String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +
// request.getContextPath();
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, BCConstants.QUICK_SALARY_SETTING_METHOD);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + ".do");
parameters.put("documentNumber", pbglLine.getDocumentNumber());
parameters.put("universityFiscalYear", pbglLine.getUniversityFiscalYear().toString());
parameters.put("chartOfAccountsCode", pbglLine.getChartOfAccountsCode());
parameters.put("accountNumber", pbglLine.getAccountNumber());
parameters.put("subAccountNumber", pbglLine.getSubAccountNumber());
parameters.put("financialObjectCode", pbglLine.getFinancialObjectCode());
parameters.put("financialSubObjectCode", pbglLine.getFinancialSubObjectCode());
parameters.put("financialBalanceTypeCode", pbglLine.getFinancialBalanceTypeCode());
parameters.put("financialObjectTypeCode", pbglLine.getFinancialObjectTypeCode());
parameters.put(BCPropertyConstants.MAIN_WINDOW, (budgetConstructionForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, ((KualiForm) form).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 = UrlFactory.parameterizeUrl(basePath + "/" + BCConstants.QUICK_SALARY_SETTING_ACTION, parameters);
this.setupDocumentExit();
return new ActionForward(lookupUrl, true);
}
/**
* This adds a revenue line to the BC document
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward insertRevenueLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
PendingBudgetConstructionGeneralLedger line = budgetConstructionForm.getNewRevenueLine();
boolean rulePassed = true;
rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AddPendingBudgetGeneralLedgerLineEvent(BCConstants.NEW_REVENUE_LINE_PROPERTY_NAME, budgetConstructionForm.getDocument(), line, true));
if (rulePassed) {
// add PBGLLine
insertPBGLLine(true, budgetConstructionForm, line);
// clear the used newRevenueLine
budgetConstructionForm.setNewRevenueLine(new PendingBudgetConstructionGeneralLedger());
budgetConstructionForm.initNewLine(budgetConstructionForm.getNewRevenueLine(), true);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* This adds an expenditure line to the BC document
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward insertExpenditureLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
PendingBudgetConstructionGeneralLedger line = budgetConstructionForm.getNewExpenditureLine();
boolean rulePassed = true;
rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AddPendingBudgetGeneralLedgerLineEvent(BCConstants.NEW_EXPENDITURE_LINE_PROPERTY_NAME, budgetConstructionForm.getDocument(), line, false));
if (rulePassed) {
// add PBGLLine
insertPBGLLine(false, budgetConstructionForm, line);
// clear the used newExpenditureLine
budgetConstructionForm.setNewExpenditureLine(new PendingBudgetConstructionGeneralLedger());
budgetConstructionForm.initNewLine(budgetConstructionForm.getNewExpenditureLine(), false);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* This inserts a PBGL revenue or expenditure line
*
* @param isRevenue
* @param budgetConstructionForm
* @param line
*/
protected void insertPBGLLine(boolean isRevenue, BudgetConstructionForm budgetConstructionForm, PendingBudgetConstructionGeneralLedger line) {
BudgetConstructionDocument bcDoc = (BudgetConstructionDocument) budgetConstructionForm.getDocument();
// KFSMI-7828 reset object type from object code table
line.setFinancialObjectTypeCode(line.getFinancialObject().getFinancialObjectTypeCode());
// null subobj must be set to dashes
if (StringUtils.isBlank(line.getFinancialSubObjectCode())) {
line.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
}
// check the DB for an existing persisted version of the line
// and reinstate that with a message to the user indicating such
boolean isReinstated = false;
Map<String, Object> primaryKey = new HashMap<String, Object>();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, line.getDocumentNumber());
primaryKey.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, line.getUniversityFiscalYear());
primaryKey.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, line.getChartOfAccountsCode());
primaryKey.put(KFSPropertyConstants.ACCOUNT_NUMBER, line.getAccountNumber());
primaryKey.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, line.getSubAccountNumber());
primaryKey.put(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, line.getFinancialBalanceTypeCode());
primaryKey.put(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE, line.getFinancialObjectTypeCode());
primaryKey.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, line.getFinancialObjectCode());
primaryKey.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, line.getFinancialSubObjectCode());
PendingBudgetConstructionGeneralLedger dbLine = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(PendingBudgetConstructionGeneralLedger.class, primaryKey);
if (dbLine != null){
line = dbLine;
SpringContext.getBean(BudgetDocumentService.class).populatePBGLLine(line);
isReinstated = true;
}
// add the line in the proper order - assumes already exists check is done in rules
int insertPoint = bcDoc.addPBGLLine(line, isRevenue);
if (isReinstated){
String errorKey;
if (isRevenue){
errorKey = KRADConstants.DOCUMENT_PROPERTY_NAME + "." + BCPropertyConstants.PENDING_BUDGET_CONSTRUCTION_GENERAL_LEDGER_REVENUE_LINES + "[" + insertPoint + "]." + KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT;
}
else {
errorKey = KRADConstants.DOCUMENT_PROPERTY_NAME + "." + BCPropertyConstants.PENDING_BUDGET_CONSTRUCTION_GENERAL_LEDGER_EXPENDITURE_LINES + "[" + insertPoint + "]." + KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT;
}
GlobalVariables.getMessageMap().putError(errorKey, BCKeyConstants.ERROR_BUDGET_LINE_REINSTATED, dbLine.getFinancialObjectCode() + "," + dbLine.getFinancialSubObjectCode());
}
// adjust totals
if (line.getAccountLineAnnualBalanceAmount() != null && line.getAccountLineAnnualBalanceAmount() != KualiInteger.ZERO) {
if (isRevenue) {
bcDoc.setRevenueAccountLineAnnualBalanceAmountTotal(bcDoc.getRevenueAccountLineAnnualBalanceAmountTotal().add(line.getAccountLineAnnualBalanceAmount()));
}
else {
bcDoc.setExpenditureAccountLineAnnualBalanceAmountTotal(bcDoc.getExpenditureAccountLineAnnualBalanceAmountTotal().add(line.getAccountLineAnnualBalanceAmount()));
}
}
if (line.getFinancialBeginningBalanceLineAmount() != null && line.getFinancialBeginningBalanceLineAmount() != KualiInteger.ZERO) {
if (isRevenue) {
bcDoc.setRevenueFinancialBeginningBalanceLineAmountTotal(bcDoc.getRevenueFinancialBeginningBalanceLineAmountTotal().add(line.getFinancialBeginningBalanceLineAmount()));
}
else {
bcDoc.setExpenditureFinancialBeginningBalanceLineAmountTotal(bcDoc.getExpenditureFinancialBeginningBalanceLineAmountTotal().add(line.getFinancialBeginningBalanceLineAmount()));
}
}
}
/**
* Deletes an existing PendingBudgetConstructionGeneralLedger revenue line if rules passed. Any associated monthly budget
* (BudgetConstructionMonthly) is also deleted.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward deleteRevenueLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument tDoc = tForm.getBudgetConstructionDocument();
boolean rulePassed = true;
int deleteIndex = this.getLineToDelete(request);
// check business rule if there is a persisted request amount, otherwise the line can just be removed
PendingBudgetConstructionGeneralLedger revLine = tDoc.getPendingBudgetConstructionGeneralLedgerRevenueLines().get(deleteIndex);
if (revLine.getPersistedAccountLineAnnualBalanceAmount() == null) {
rulePassed = true;
}
else {
// check deletion rules and delete if passed
String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + BCPropertyConstants.PENDING_BUDGET_CONSTRUCTION_GENERAL_LEDGER_REVENUE_LINES + "[" + deleteIndex + "]";
rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new DeletePendingBudgetGeneralLedgerLineEvent(errorPath, tDoc, revLine, true));
}
if (rulePassed) {
deletePBGLLine(true, tForm, deleteIndex, revLine);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Deletes an existing PendingBudgetConstructionGeneralLedger expenditure line if rules passed Any associated monthly budget
* (BudgetConstructionMonthly) is also deleted. Check for the special case where the line is a 2PLG line, in which case the
* document is validated and RI checks are forced even if there are no current differences between persisted and request
* amounts.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward deleteExpenditureLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument tDoc = tForm.getBudgetConstructionDocument();
boolean rulePassed = true;
int deleteIndex = this.getLineToDelete(request);
// check business rule if there is a persisted request amount, otherwise the line can just be removed
PendingBudgetConstructionGeneralLedger expLine = tDoc.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(deleteIndex);
if (expLine.getPersistedAccountLineAnnualBalanceAmount() == null) {
rulePassed = true;
}
else {
// check regular deletion rules and delete if passed
String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + BCPropertyConstants.PENDING_BUDGET_CONSTRUCTION_GENERAL_LEDGER_EXPENDITURE_LINES + "[" + deleteIndex + "]";
rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new DeletePendingBudgetGeneralLedgerLineEvent(errorPath, tDoc, expLine, false));
}
if (rulePassed) {
// if the line is a 2PLG line do document validation, which forces RI checks in no current change situation
if (expLine.getFinancialObjectCode().equalsIgnoreCase(KFSConstants.BudgetConstructionConstants.OBJECT_CODE_2PLG)) {
SpringContext.getBean(BudgetDocumentService.class).validateDocument(tDoc);
}
// gets here if line is not 2PLG or doc is valid from 2plg perspective
deletePBGLLine(false, tForm, deleteIndex, expLine);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Deletes an existing PendingBudgetConstructionGeneralLedger revenue or expenditure line along with any associated monthly
* budget (BudgetConstructionMonthly)
*
* @param isRevenue
* @param budgetConstructionForm
* @param deleteIndex
*/
protected void deletePBGLLine(boolean isRevenue, BudgetConstructionForm budgetConstructionForm, int deleteIndex, PendingBudgetConstructionGeneralLedger line) {
BudgetConstructionDocument bcDoc = budgetConstructionForm.getBudgetConstructionDocument();
// adjust totals
if (line.getAccountLineAnnualBalanceAmount() != null && line.getAccountLineAnnualBalanceAmount() != KualiInteger.ZERO) {
if (isRevenue) {
bcDoc.setRevenueAccountLineAnnualBalanceAmountTotal(bcDoc.getRevenueAccountLineAnnualBalanceAmountTotal().subtract(line.getAccountLineAnnualBalanceAmount()));
}
else {
bcDoc.setExpenditureAccountLineAnnualBalanceAmountTotal(bcDoc.getExpenditureAccountLineAnnualBalanceAmountTotal().subtract(line.getAccountLineAnnualBalanceAmount()));
}
}
if (line.getFinancialBeginningBalanceLineAmount() != null && line.getFinancialBeginningBalanceLineAmount() != KualiInteger.ZERO) {
if (isRevenue) {
bcDoc.setRevenueFinancialBeginningBalanceLineAmountTotal(bcDoc.getRevenueFinancialBeginningBalanceLineAmountTotal().subtract(line.getFinancialBeginningBalanceLineAmount()));
}
else {
bcDoc.setExpenditureFinancialBeginningBalanceLineAmountTotal(bcDoc.getExpenditureFinancialBeginningBalanceLineAmountTotal().subtract(line.getFinancialBeginningBalanceLineAmount()));
}
}
// remove the line
if (isRevenue) {
bcDoc.getPendingBudgetConstructionGeneralLedgerRevenueLines().remove(deleteIndex);
}
else {
if (line.getFinancialObjectCode().equalsIgnoreCase(KFSConstants.BudgetConstructionConstants.OBJECT_CODE_2PLG)) {
bcDoc.setContainsTwoPlug(false);
}
bcDoc.getPendingBudgetConstructionGeneralLedgerExpenditureLines().remove(deleteIndex);
}
}
/*
* public ActionForward returnFromMonthly(ActionMapping mapping, ActionForm form, HttpServletRequest request,
* HttpServletResponse response) throws Exception { BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm)
* form; String documentNumber = request.getParameter("documentNumber"); BudgetConstructionDocument budgetConstructionDocument =
* (BudgetConstructionDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(documentNumber);
* budgetConstructionForm.setDocument(budgetConstructionDocument); KualiWorkflowDocument workflowDoc =
* budgetConstructionDocument.getDocumentHeader().getWorkflowDocument();
* budgetConstructionForm.setDocTypeName(workflowDoc.getDocumentType()); // KualiDocumentFormBase.populate() needs this updated
* in the session GlobalVariables.getUserSession().setWorkflowDocument(workflowDoc); return
* mapping.findForward(KFSConstants.MAPPING_BASIC); }
*/
/**
* @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#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 {
BudgetConstructionForm budgetConstructionForm = (BudgetConstructionForm) form;
budgetConstructionForm.setDerivedValuesOnForm(request);
// Do specific refresh stuff here based on refreshCaller parameter
// typical refresh callers would be monthlyBudget or salarySetting or lookupable
String refreshCaller = request.getParameter(KFSConstants.REFRESH_CALLER);
if (refreshCaller != null && refreshCaller.endsWith(BCConstants.MONTHLY_BUDGET_REFRESH_CALLER)) {
// monthly process applies any changes to the DB and the form session object
// including any override to the request amount which also changes the request total
// it also sets up calc monthly benefits if the line is involved in benefits
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
budgetDocumentService.calculateBenefitsIfNeeded(budgetConstructionForm.getBudgetConstructionDocument());
}
if (refreshCaller != null && refreshCaller.endsWith(BCConstants.QUICK_SALARY_SETTING_REFRESH_CALLER)) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// if editing - reload expenditure and check for changes to detail salary lines and 2plg request amount
boolean diffFound = false;
if (budgetConstructionForm.isEditAllowed() && !budgetConstructionForm.isSystemViewOnly()) {
BudgetConstructionDocument currentBCDoc = budgetConstructionForm.getBudgetConstructionDocument();
// get the current set of salary setting related rows from DB and compare against preSalarySettingRows
List<PendingBudgetConstructionGeneralLedger> dbSalarySettingRows = budgetDocumentService.getPBGLSalarySettingRows(currentBCDoc);
for (PendingBudgetConstructionGeneralLedger dbSalarySettingRow : dbSalarySettingRows) {
if (budgetConstructionForm.getPreSalarySettingRows().containsKey(dbSalarySettingRow.getFinancialObjectCode() + dbSalarySettingRow.getFinancialSubObjectCode())) {
// update the existing row if a difference is found
KualiInteger dbReqAmount = dbSalarySettingRow.getAccountLineAnnualBalanceAmount();
KualiInteger preReqAmount = budgetConstructionForm.getPreSalarySettingRows().get(dbSalarySettingRow.getFinancialObjectCode() + dbSalarySettingRow.getFinancialSubObjectCode()).getAccountLineAnnualBalanceAmount();
Long dbVersionNumber = dbSalarySettingRow.getVersionNumber();
Long preReqVersionNumber = budgetConstructionForm.getPreSalarySettingRows().get(dbSalarySettingRow.getFinancialObjectCode() + dbSalarySettingRow.getFinancialSubObjectCode()).getVersionNumber();
if ((dbVersionNumber.compareTo(preReqVersionNumber) != 0) || (dbReqAmount.compareTo(preReqAmount) != 0)) {
budgetDocumentService.addOrUpdatePBGLRow(currentBCDoc, dbSalarySettingRow, Boolean.FALSE);
// only flag for existing line diff when the request amount changes
// changes in versionNumber implies offsetting updates of some sort
if (dbReqAmount.compareTo(preReqAmount) != 0) {
diffFound = true;
}
}
}
else {
// update the req amount and version or add the new row to the current doc as needed
// insert the new DB row to the set in memory
budgetDocumentService.addOrUpdatePBGLRow(currentBCDoc, dbSalarySettingRow, Boolean.FALSE);
diffFound = true;
}
}
if (diffFound) {
this.adjustForSalarySettingChanges(budgetConstructionForm);
}
}
}
if (refreshCaller != null && refreshCaller.endsWith(KFSConstants.LOOKUPABLE_SUFFIX)) {
this.checkAndFixReturnedLookupValues(budgetConstructionForm.getNewRevenueLine(), budgetConstructionForm.getBudgetConstructionDocument());
this.checkAndFixReturnedLookupValues(budgetConstructionForm.getNewExpenditureLine(), budgetConstructionForm.getBudgetConstructionDocument());
final List REFRESH_FIELDS = Collections.unmodifiableList(Arrays.asList(new String[] { "financialObject", "financialSubObject" }));
SpringContext.getBean(PersistenceService.class).retrieveReferenceObjects(budgetConstructionForm.getNewRevenueLine(), REFRESH_FIELDS);
SpringContext.getBean(PersistenceService.class).retrieveReferenceObjects(budgetConstructionForm.getNewExpenditureLine(), REFRESH_FIELDS);
}
// balance inquiry anchor is set before doing a balance inquiry
if (budgetConstructionForm.getBalanceInquiryReturnAnchor() != null) {
budgetConstructionForm.setAnchor(budgetConstructionForm.getBalanceInquiryReturnAnchor());
budgetConstructionForm.setBalanceInquiryReturnAnchor(null);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* checks the passed in newLine for any data consistency problems compared to the currently loaded document
* this is typically called after return from a lookup since the user can potentially select from other fiscal years, etc.
*
* @param newLine
* @param bcDoc
*/
protected void checkAndFixReturnedLookupValues(PendingBudgetConstructionGeneralLedger newLine, BudgetConstructionDocument bcDoc){
if (!newLine.getUniversityFiscalYear().equals(bcDoc.getUniversityFiscalYear())){
newLine.setUniversityFiscalYear(bcDoc.getUniversityFiscalYear());
}
if (!newLine.getChartOfAccountsCode().equals(bcDoc.getChartOfAccountsCode())){
newLine.setChartOfAccountsCode(bcDoc.getChartOfAccountsCode());
}
if (!newLine.getAccountNumber().equals(bcDoc.getAccountNumber())){
newLine.setAccountNumber(bcDoc.getAccountNumber());
}
}
/**
* This action changes the value of the hide field in the user interface so that when the page is rendered, the UI knows to show
* all of the descriptions and labels for each of the pbgl line values.
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
* @throws Exception
*/
public ActionForward showDetails(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
tForm.setHideDetails(false);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* This action toggles the value of the hide field in the user interface to "hide" so that when the page is rendered, the UI
* displays values without all of the descriptions and labels for each of the pbgl lines.
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
* @throws Exception
*/
public ActionForward hideDetails(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
tForm.setHideDetails(true);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward toggleAdjustmentMeasurement(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
boolean currentStatus = docForm.isHideAdjustmentMeasurement();
docForm.setHideAdjustmentMeasurement(!currentStatus);
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward adjustRevenueLinePercent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDoc = docForm.getBudgetConstructionDocument();
PendingBudgetConstructionGeneralLedger revLine = bcDoc.getPendingBudgetConstructionGeneralLedgerRevenueLines().get(this.getSelectedLine(request));
if (revLine.getAdjustmentAmount() != null) {
this.adjustRequest(revLine);
docForm.populatePBGLLines();
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward adjustExpenditureLinePercent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDoc = docForm.getBudgetConstructionDocument();
PendingBudgetConstructionGeneralLedger expLine = bcDoc.getPendingBudgetConstructionGeneralLedgerExpenditureLines().get(this.getSelectedLine(request));
if (expLine.getAdjustmentAmount() != null) {
this.adjustRequest(expLine);
docForm.populatePBGLLines();
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward adjustAllRevenueLinesPercent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDoc = docForm.getBudgetConstructionDocument();
List<PendingBudgetConstructionGeneralLedger> revenueLines = bcDoc.getPendingBudgetConstructionGeneralLedgerRevenueLines();
KualiDecimal adjustmentAmount = docForm.getRevenueAdjustmentAmount();
if (adjustmentAmount != null) {
// not sure we need this check since the tool isn't displayed in view mode
boolean isEditable = docForm.isEditAllowed() && !docForm.isSystemViewOnly();
for (PendingBudgetConstructionGeneralLedger revenueLine : revenueLines) {
if (isEditable) {
revenueLine.setAdjustmentAmount(adjustmentAmount);
this.adjustRequest(revenueLine);
}
}
if (isEditable){
docForm.populatePBGLLines();
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward adjustAllExpenditureLinesPercent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm docForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDoc = docForm.getBudgetConstructionDocument();
List<PendingBudgetConstructionGeneralLedger> expenditureLines = bcDoc.getPendingBudgetConstructionGeneralLedgerExpenditureLines();
KualiDecimal adjustmentAmount = docForm.getExpenditureAdjustmentAmount();
if (adjustmentAmount != null) {
// not sure we need this check since the tool isn't displayed in view mode
boolean isEditable = docForm.isEditAllowed() && !docForm.isSystemViewOnly();
// (!benecalcDisabled && !empty item.laborObject && item.laborObject.financialObjectFringeOrSalaryCode == 'F')
for (PendingBudgetConstructionGeneralLedger expenditureLine : expenditureLines) {
boolean isLineEditable = (isEditable && (docForm.isBenefitsCalculationDisabled() || (expenditureLine.getLaborObject() == null) || !expenditureLine.getLaborObject().getFinancialObjectFringeOrSalaryCode().equalsIgnoreCase(BCConstants.LABOR_OBJECT_FRINGE_CODE)));
if (isLineEditable) {
expenditureLine.setAdjustmentAmount(adjustmentAmount);
this.adjustRequest(expenditureLine);
}
}
if (isEditable){
docForm.populatePBGLLines();
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Handles the document (account) pullup action, resetting the cached editingMode as appropriate for the new level.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performAccountPullup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
boolean doAllowPullup = false;
boolean lockNeeded = false;
boolean prePullReadOnlyAccess;
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// if system view only or view only - reload to get the latest status
// and check that the document is still below the selected POV
if (!tForm.isEditAllowed() || tForm.isSystemViewOnly()) {
prePullReadOnlyAccess = true;
// now reload the document and get latest status info
loadDocument(tForm);
this.initAuthorization(tForm);
if (tForm.getBudgetConstructionDocument().getOrganizationLevelCode() < Integer.parseInt(tForm.getPullupKeyCode())) {
doAllowPullup = true;
// if not system view only mode, we are in document view mode - we'll need a lock before the pullup
// since by definition pullup puts the account at a full_entry level
// and we need exclusive access to perform the pullup
if (!tForm.isSystemViewOnly()) {
lockNeeded = true;
}
}
else {
// document has been moved and is either at the desired level or above
doAllowPullup = false;
lockNeeded = false;
// document has been moved above the desired level - let populate through an authorization exception
if (tForm.getBudgetConstructionDocument().getOrganizationLevelCode() > Integer.parseInt(tForm.getPullupKeyCode())) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_MESSAGES, BCKeyConstants.ERROR_BUDGET_PULLUP_DOCUMENT, "Document has already been moved above the selected level.");
}
}
}
else {
// we are in document full_entry
// assume we already have a lock, allow the pullup
// and we need to ensure the user can finish editing work if after pullup system goes to system view only
prePullReadOnlyAccess = false;
doAllowPullup = true;
}
if (lockNeeded || doAllowPullup) {
// get a fresh header to use for lock and/or pullup
HashMap primaryKey = new HashMap();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, tForm.getDocument().getDocumentNumber());
BudgetConstructionHeader budgetConstructionHeader = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BudgetConstructionHeader.class, primaryKey);
if (budgetConstructionHeader == null) {
GlobalVariables.getMessageMap().putError(BCConstants.BUDGET_CONSTRUCTION_SYSTEM_INFORMATION_TAB_ERRORS, BCKeyConstants.ERROR_BUDGET_PULLUP_DOCUMENT, "Fatal, Document not found.");
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
if (lockNeeded) {
// only successful lock allows pullup here
doAllowPullup = false;
LockService lockService = SpringContext.getBean(LockService.class);
BudgetConstructionLockStatus bcLockStatus = lockService.lockAccount(budgetConstructionHeader, GlobalVariables.getUserSession().getPerson().getPrincipalId());
LockStatus lockStatus = bcLockStatus.getLockStatus();
switch (lockStatus) {
case SUCCESS:
doAllowPullup = true;
break;
case BY_OTHER:
Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(bcLockStatus.getAccountLockOwner());
String lockerName = principal.getPrincipalName();
GlobalVariables.getMessageMap().putError(BCConstants.BUDGET_CONSTRUCTION_SYSTEM_INFORMATION_TAB_ERRORS, BCKeyConstants.ERROR_BUDGET_PULLUP_DOCUMENT, "Locked by " + lockerName);
break;
case FLOCK_FOUND:
GlobalVariables.getMessageMap().putError(BCConstants.BUDGET_CONSTRUCTION_SYSTEM_INFORMATION_TAB_ERRORS, BCKeyConstants.ERROR_BUDGET_PULLUP_DOCUMENT, "Funding lock found.");
break;
default:
GlobalVariables.getMessageMap().putError(BCConstants.BUDGET_CONSTRUCTION_SYSTEM_INFORMATION_TAB_ERRORS, BCKeyConstants.ERROR_BUDGET_PULLUP_DOCUMENT, "Optimistic lock or other failure during lock attempt.");
break;
}
}
// attempt pullup
if (doAllowPullup) {
budgetConstructionHeader.setOrganizationLevelCode(Integer.parseInt(tForm.getPullupKeyCode()));
budgetConstructionHeader.setOrganizationLevelChartOfAccountsCode(tForm.getAccountOrgHierLevels().get(Integer.parseInt(tForm.getPullupKeyCode())).getOrganizationChartOfAccountsCode());
budgetConstructionHeader.setOrganizationLevelOrganizationCode(tForm.getAccountOrgHierLevels().get(Integer.parseInt(tForm.getPullupKeyCode())).getOrganizationCode());
SpringContext.getBean(BusinessObjectService.class).save(budgetConstructionHeader);
// finally refresh the doc with the changed header info
tForm.getBudgetConstructionDocument().setVersionNumber(budgetConstructionHeader.getVersionNumber());
tForm.getBudgetConstructionDocument().setOrganizationLevelCode(budgetConstructionHeader.getOrganizationLevelCode());
tForm.getBudgetConstructionDocument().setOrganizationLevelChartOfAccountsCode(budgetConstructionHeader.getOrganizationLevelChartOfAccountsCode());
tForm.getBudgetConstructionDocument().setOrganizationLevelOrganizationCode(budgetConstructionHeader.getOrganizationLevelOrganizationCode());
// refresh the lock info even though the user may be pulling while in edit mode
tForm.getBudgetConstructionDocument().setBudgetLockUserIdentifier(budgetConstructionHeader.getBudgetLockUserIdentifier());
// refresh organization - so UI shows new level description
tForm.getBudgetConstructionDocument().refreshReferenceObject("organizationLevelOrganization");
this.initAuthorization(tForm);
// if before pullup, system was 'not system view only' goes to 'system view only' after pull
// need to manually remove the system view only editingMode here to allow the user to save work since still
// full_entry
if (tForm.isEditAllowed() && !prePullReadOnlyAccess) {
if (tForm.isSystemViewOnly()) {
tForm.getEditingMode().remove(BCConstants.EditModes.SYSTEM_VIEW_ONLY);
}
}
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Handles the document (account) pushdown action, resetting the cached editingMode as appropriate for the new level.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward performAccountPushdown(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
boolean doAllowPushdown = false;
boolean unlockNeeded = false;
boolean prePushSystemViewOnly;
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = tForm.getBudgetConstructionDocument();
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// This method is called only if user has edit access and there is somewhere to push to.
// If not system view only and the intended push level is view, we need to validate and save
// Otherwise new level is still allowing editing, just push and keep current lock
if (!tForm.isSystemViewOnly()) {
prePushSystemViewOnly = false;
// check editing mode at the intended level
if (!hasEditPermission(bcDocument, tForm.getPushdownKeyCode(), GlobalVariables.getUserSession().getPerson())) {
budgetDocumentService.saveDocumentNoWorkflow(bcDocument);
tForm.initializePersistedRequestAmounts();
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
// tForm.populatePBGLLines();
unlockNeeded = true;
}
doAllowPushdown = true;
}
else {
prePushSystemViewOnly = true;
// reload document to get most up-to-date status and recheck that we still have FULL_ENTRY access
// anything else means the document was moved by someone else and we may no longer even have read access
loadDocument(tForm);
this.initAuthorization(tForm);
if (tForm.isEditAllowed()) {
doAllowPushdown = true;
}
else {
// document has moved
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_MESSAGES, BCKeyConstants.ERROR_BUDGET_PUSHDOWN_DOCUMENT, "Full Access Control Lost.");
}
}
// gets here if editing and pushing to view and doc is valid and persisted
// or we are pushing from edit to edit
// or we are in system view only
if (doAllowPushdown) {
HashMap primaryKey = new HashMap();
primaryKey.put(KFSPropertyConstants.DOCUMENT_NUMBER, tForm.getDocument().getDocumentNumber());
BudgetConstructionHeader budgetConstructionHeader = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BudgetConstructionHeader.class, primaryKey);
if (budgetConstructionHeader != null) {
budgetConstructionHeader.setOrganizationLevelCode(Integer.parseInt(tForm.getPushdownKeyCode()));
if (Integer.parseInt(tForm.getPushdownKeyCode()) == 0) {
budgetConstructionHeader.setOrganizationLevelChartOfAccountsCode(null);
budgetConstructionHeader.setOrganizationLevelOrganizationCode(null);
}
else {
budgetConstructionHeader.setOrganizationLevelChartOfAccountsCode(tForm.getAccountOrgHierLevels().get(Integer.parseInt(tForm.getPushdownKeyCode())).getOrganizationChartOfAccountsCode());
budgetConstructionHeader.setOrganizationLevelOrganizationCode(tForm.getAccountOrgHierLevels().get(Integer.parseInt(tForm.getPushdownKeyCode())).getOrganizationCode());
}
}
// unlock if needed (which stores) - otherwise store the new level
if (unlockNeeded) {
LockService lockService = SpringContext.getBean(LockService.class);
lockService.unlockAccount(budgetConstructionHeader);
}
else {
SpringContext.getBean(BusinessObjectService.class).save(budgetConstructionHeader);
}
// finally refresh the doc with the changed header info
tForm.getBudgetConstructionDocument().setVersionNumber(budgetConstructionHeader.getVersionNumber());
tForm.getBudgetConstructionDocument().setOrganizationLevelCode(budgetConstructionHeader.getOrganizationLevelCode());
tForm.getBudgetConstructionDocument().setOrganizationLevelChartOfAccountsCode(budgetConstructionHeader.getOrganizationLevelChartOfAccountsCode());
tForm.getBudgetConstructionDocument().setOrganizationLevelOrganizationCode(budgetConstructionHeader.getOrganizationLevelOrganizationCode());
tForm.getBudgetConstructionDocument().setBudgetLockUserIdentifier(budgetConstructionHeader.getBudgetLockUserIdentifier());
// refresh organization - so UI shows new level description
tForm.getBudgetConstructionDocument().refreshReferenceObject("organizationLevelOrganization");
this.initAuthorization(tForm);
// if before push, system is 'not system view only' goes to 'system view only' after push
// need to manually remove the system view only editingMode here to allow the user to save work if still full_entry
if (tForm.isEditAllowed()) {
if (tForm.isSystemViewOnly() && !prePushSystemViewOnly) {
tForm.getEditingMode().remove(BCConstants.EditModes.SYSTEM_VIEW_ONLY);
}
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* Checks whether the current user would have access for the given budget document for the given organization level code
*
* @param document current bc document
* @param orgLevelCode organization level code for access check
* @param user user to check access for
* @return true if user would have edit permission, false otherwise
*/
protected boolean hasEditPermission(BudgetConstructionDocument document, String orgLevelCode, Person user) {
TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(document);
Map<String,String> roleQualifiers = new HashMap<String,String>();
roleQualifiers.put(BCPropertyConstants.ORGANIZATION_LEVEL_CODE, orgLevelCode);
List<BudgetConstructionAccountOrganizationHierarchy> accountOrganizationHierarchy = SpringContext.getBean(BudgetDocumentService.class).retrieveOrBuildAccountOrganizationHierarchy(document.getUniversityFiscalYear(), document.getChartOfAccountsCode(), document.getAccountNumber());
for (BudgetConstructionAccountOrganizationHierarchy accountOrganization : accountOrganizationHierarchy) {
if (accountOrganization.getOrganizationLevelCode().intValue() == Integer.parseInt(orgLevelCode)) {
roleQualifiers.put(BCPropertyConstants.ORGANIZATION_CHART_OF_ACCOUNTS_CODE, accountOrganization.getOrganizationChartOfAccountsCode());
roleQualifiers.put(KfsKimAttributes.ORGANIZATION_CODE, accountOrganization.getOrganizationCode());
}
}
return documentAuthorizer.isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId(), null, roleQualifiers);
}
public ActionForward performReportDump(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = tForm.getBudgetConstructionDocument();
// when we return from the lookup, our next request's method to call is going to be refresh
tForm.registerEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
if (tForm.isEditAllowed() && !tForm.isSystemViewOnly()) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
budgetDocumentService.saveDocumentNoWorkflow(bcDocument);
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
tForm.initializePersistedRequestAmounts();
// repop and refresh refs - esp monthly so jsp can properly display state
// tForm.populatePBGLLines();
}
// gets here if rules passed and doc detail gets persisted and refreshed
String basePath = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.APPLICATION_URL_KEY);
Properties parameters = new Properties();
parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, BCConstants.MONTHLY_BUDGET_METHOD);
parameters.put(KFSConstants.BACK_LOCATION, basePath + mapping.getPath() + ".do");
parameters.put("documentNumber", tForm.getDocument().getDocumentNumber());
parameters.put("universityFiscalYear", tForm.getUniversityFiscalYear().toString());
parameters.put("chartOfAccountsCode", tForm.getChartOfAccountsCode());
parameters.put("accountNumber", tForm.getAccountNumber());
parameters.put("subAccountNumber", tForm.getSubAccountNumber());
parameters.put(BCPropertyConstants.MAIN_WINDOW, (tForm.isMainWindow() ? "true" : "false"));
// anchor, if it exists
if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
parameters.put(BCConstants.RETURN_ANCHOR, ((KualiForm) form).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 = UrlFactory.parameterizeUrl(basePath + "/" + BCConstants.REPORT_RUNNER_ACTION, parameters);
this.setupDocumentExit();
return new ActionForward(lookupUrl, true);
}
public ActionForward performPercentChange(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_MESSAGES, KFSKeyConstants.ERROR_UNIMPLEMENTED, "Percent Change");
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward performRevMonthSpread(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return this.performMonthSpread(mapping, form, request, response, true);
}
public ActionForward performExpMonthSpread(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return this.performMonthSpread(mapping, form, request, response, false);
}
public ActionForward performMonthSpread(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, boolean isRevenue) throws Exception {
// no check for full_entry and system edit mode since this control is not displayed for this case
// need to validate, save and calc benefits first
// this is different than client/server model - need to always keep DB consistent
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = tForm.getBudgetConstructionDocument();
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// validate and save without checking monthly RI since the spread will keep things consistent
if (isRevenue) {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.REVENUE, false);
}
else {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.EXPENDITURE, false);
}
tForm.initializePersistedRequestAmounts();
// budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
BudgetConstructionMonthlyBudgetsCreateDeleteService monthlyBudgetService = SpringContext.getBean(BudgetConstructionMonthlyBudgetsCreateDeleteService.class);
if (isRevenue) {
monthlyBudgetService.spreadBudgetConstructionMonthlyBudgetsRevenue(bcDocument.getDocumentNumber(), bcDocument.getUniversityFiscalYear(), bcDocument.getChartOfAccountsCode(), bcDocument.getAccountNumber(), bcDocument.getSubAccountNumber());
}
else {
// service returns true if benefit eligible monthly lines exist
if (monthlyBudgetService.spreadBudgetConstructionMonthlyBudgetsExpenditure(bcDocument.getDocumentNumber(), bcDocument.getUniversityFiscalYear(), bcDocument.getChartOfAccountsCode(), bcDocument.getAccountNumber(), bcDocument.getSubAccountNumber())) {
bcDocument.setMonthlyBenefitsCalcNeeded(true);
// budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
}
}
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
tForm.populatePBGLLines();
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward performRevMonthDelete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return this.performMonthDelete(mapping, form, request, response, true);
}
public ActionForward performExpMonthDelete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return this.performMonthDelete(mapping, form, request, response, false);
}
public ActionForward performMonthDelete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, boolean isRevenue) throws Exception {
// no check for full_entry and system edit mode since this control is not displayed for this case
// need to validate, save and calc benefits first
// this is different than client/server model - need to always keep DB consistent
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = tForm.getBudgetConstructionDocument();
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
// validate and save without checking monthly RI since the delete will make RI check moot
if (isRevenue) {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.REVENUE, false);
}
else {
budgetDocumentService.saveDocumentNoWorkFlow(bcDocument, MonthSpreadDeleteType.EXPENDITURE, false);
}
tForm.initializePersistedRequestAmounts();
// budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
BudgetConstructionMonthlyBudgetsCreateDeleteService monthlyBudgetService = SpringContext.getBean(BudgetConstructionMonthlyBudgetsCreateDeleteService.class);
if (isRevenue) {
monthlyBudgetService.deleteBudgetConstructionMonthlyBudgetsRevenue(bcDocument.getDocumentNumber(), bcDocument.getUniversityFiscalYear(), bcDocument.getChartOfAccountsCode(), bcDocument.getAccountNumber(), bcDocument.getSubAccountNumber());
}
else {
monthlyBudgetService.deleteBudgetConstructionMonthlyBudgetsExpenditure(bcDocument.getDocumentNumber(), bcDocument.getUniversityFiscalYear(), bcDocument.getChartOfAccountsCode(), bcDocument.getAccountNumber(), bcDocument.getSubAccountNumber());
}
budgetDocumentService.calculateBenefitsIfNeeded(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
tForm.populatePBGLLines();
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
public ActionForward performCalculateBenefits(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
// no check for full_entry and system edit mode since this control is not displayed for this case
BudgetConstructionForm tForm = (BudgetConstructionForm) form;
BudgetConstructionDocument bcDocument = (BudgetConstructionDocument) tForm.getDocument();
// allow benecalc if account is not salary only and benefits calc not disabled
if (!tForm.isBenefitsCalculationDisabled() && !bcDocument.isSalarySettingOnly()) {
BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
budgetDocumentService.saveDocumentNoWorkflow(bcDocument);
tForm.initializePersistedRequestAmounts();
budgetDocumentService.calculateBenefits(bcDocument);
// repop and refresh refs - esp monthly so jsp can properly display state
// tForm.populatePBGLLines();
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
protected void adjustRequest(PendingBudgetConstructionGeneralLedger pbglLine) {
KualiInteger baseAmount = pbglLine.getFinancialBeginningBalanceLineAmount();
if (baseAmount.isNonZero()) {
KualiDecimal percent = pbglLine.getAdjustmentAmount();
BigDecimal adjustedAmount = baseAmount.multiply(percent).divide(KFSConstants.ONE_HUNDRED);
KualiInteger requestAmount = new KualiInteger(adjustedAmount).add(baseAmount);
pbglLine.setAccountLineAnnualBalanceAmount(requestAmount);
}
}
}