/*
* 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.service.impl;
import static org.kuali.kfs.module.bc.BCConstants.AppointmentFundingDurationCodes.LWPA;
import static org.kuali.kfs.module.bc.BCConstants.AppointmentFundingDurationCodes.LWPF;
import static org.kuali.kfs.module.bc.BCConstants.AppointmentFundingDurationCodes.NONE;
import java.math.BigDecimal;
import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
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.SynchronizationCheckType;
import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
import org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService;
import org.kuali.kfs.module.bc.document.service.SalarySettingService;
import org.kuali.kfs.module.bc.service.HumanResourcesPayrollService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.core.api.util.type.KualiInteger;
import org.kuali.rice.krad.util.MessageMap;
/**
* provide a set of rule elements for salary setting.
*/
public class SalarySettingRuleHelperServiceImpl implements SalarySettingRuleHelperService {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SalarySettingRuleHelperServiceImpl.class);
protected SalarySettingService salarySettingService;
protected HumanResourcesPayrollService humanResourcesPayrollService;
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#canBeAdjusted(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding, org.kuali.rice.krad.util.MessageMap)
*/
public boolean canBeAdjusted(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
if (appointmentFunding.getEffectiveCSFTracker() == null) {
// These error messages should not be displayed since the reported condition is obvious and benign.
//errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_CANNOT_ADJUST_FUNDING_WITHOUT_EFFECTIVE_CSF_TRACKER);
return false;
}
if (appointmentFunding.isAppointmentFundingDeleteIndicator()) {
// These error messages should not be displayed since the reported condition is obvious and benign.
//errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_CANNOT_ADJUST_FUNDING_MARKED_AS_DELETE);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasActiveJob(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.rice.krad.util.MessageMap)
*/
public boolean hasActiveJob(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap, SynchronizationCheckType synchronizationCheckType) {
Integer fiscalYear = appointmentFunding.getUniversityFiscalYear();
String emplid = appointmentFunding.getEmplid();
String positionNumber = appointmentFunding.getPositionNumber();
if (synchronizationCheckType.equals(SynchronizationCheckType.EID) && emplid.equals("VACANT")){
return true;
} else {
boolean hasActiveJob = humanResourcesPayrollService.isActiveJob(emplid, positionNumber, fiscalYear, synchronizationCheckType);
if (!hasActiveJob) {
errorMap.putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_NO_ACTIVE_JOB_FOUND, appointmentFunding.getEmplid(), appointmentFunding.getPositionNumber());
return false;
}
return true;
}
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasObjectCodeMatchingDefaultOfPosition(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasObjectCodeMatchingDefaultOfPosition(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
String defaultObjectCode = appointmentFunding.getBudgetConstructionPosition().getIuDefaultObjectCode();
String objectCode = appointmentFunding.getFinancialObjectCode();
if (!StringUtils.equals(objectCode, defaultObjectCode)) {
errorMap.putError(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, BCKeyConstants.ERROR_NOT_DEFAULT_OBJECT_CODE, defaultObjectCode);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasRequestedAmountZeroWhenFullYearLeave(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasRequestedAmountZeroWhenFullYearLeave(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
String leaveDurationCode = appointmentFunding.getAppointmentFundingDurationCode();
// Request Salary Amount must be zero because these leave codes are for full year leave without pay.
if (StringUtils.equals(leaveDurationCode, LWPA.durationCode) || StringUtils.equals(leaveDurationCode, LWPF.durationCode)) {
KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
if (!requestedAmount.isZero()) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_REQUEST_AMOUNT_NOT_ZERO_WHEN_FULL_YEAR_LEAVE);
return false;
}
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasRequestedFteQuantityZeroWhenFullYearLeave(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasRequestedFteQuantityZeroWhenFullYearLeave(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
String leaveDurationCode = appointmentFunding.getAppointmentFundingDurationCode();
// Request Salary Amount must be zero because these leave codes are for full year leave without pay.
if (StringUtils.equals(leaveDurationCode, LWPA.durationCode) || StringUtils.equals(leaveDurationCode, LWPF.durationCode)) {
BigDecimal requestedFteQuantity = appointmentFunding.getAppointmentRequestedFteQuantity();
if (requestedFteQuantity.compareTo(BigDecimal.ZERO) != 0) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_FTE_QUANTITY, BCKeyConstants.ERROR_REQUEST_FTE_NOT_ZERO_WHEN_FULL_YEAR_LEAVE);
return false;
}
return true;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasNoExistingLine(java.util.List,
* org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding, org.kuali.rice.krad.util.MessageMap)
*/
public boolean hasNoExistingLine(List<PendingBudgetConstructionAppointmentFunding> appointmentFundings, PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
boolean hasNoExistingLine = salarySettingService.findAppointmentFunding(appointmentFundings, appointmentFunding) == null;
if (!hasNoExistingLine) {
errorMap.putError(BCPropertyConstants.NEW_BCAF_LINE, BCKeyConstants.ERROR_DUPLICATE_FUNDING_LINE);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedAmount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedAmount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
if (requestedAmount == null || requestedAmount.isNegative()) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_REQUESTED_AMOUNT_NONNEGATIVE_REQUIRED);
return false;
}
return true;
}
public boolean hasValidRequestedAmountQuickSalarySetting(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
if (this.hasValidRequestedAmount(appointmentFunding, errorMap)){
KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
BigDecimal requestedFteQuantity = appointmentFunding.getAppointmentRequestedFteQuantity();
BigDecimal hourlyRate = appointmentFunding.getAppointmentRequestedPayRate();
if (requestedAmount.isPositive() && (requestedFteQuantity != null && requestedFteQuantity.compareTo(BigDecimal.ZERO) == 0)) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_REQUESTED_AMOUNT_NEEDS_FTE_FIRST);
return false;
}
if ((hourlyRate != null && hourlyRate.compareTo(BigDecimal.ZERO) != 0) && (requestedFteQuantity != null && requestedFteQuantity.compareTo(BigDecimal.ZERO) == 0)) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_PAY_RATE, BCKeyConstants.ERROR_REQUESTED_AMOUNT_NEEDS_FTE_FIRST);
return false;
}
} else {
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedCsfAmount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedCsfAmount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
KualiInteger csfAmount = appointmentFunding.getAppointmentRequestedCsfAmount();
String leaveDurationCode = appointmentFunding.getAppointmentFundingDurationCode();
// Requested csf amount must be greater than 0 if there is a leave
if (!StringUtils.equals(leaveDurationCode, NONE.durationCode)) {
if (csfAmount == null || !csfAmount.isPositive()) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_CSF_AMOUNT, BCKeyConstants.ERROR_FTE_GREATER_THAN_ZERO_REQUIRED);
return false;
}
return true;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedCsfTimePercent(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedCsfTimePercent(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
BigDecimal csfTimePercent = appointmentFunding.getAppointmentRequestedCsfTimePercent();
String leaveDurationCode = appointmentFunding.getAppointmentFundingDurationCode();
// Requested csf amount must be greater than 0 if there is a leave
if (!StringUtils.equals(leaveDurationCode, NONE.durationCode)) {
if (csfTimePercent == null || csfTimePercent.compareTo(BigDecimal.ZERO) <= 0 || csfTimePercent.compareTo(BCConstants.ONE_HUNDRED) > 0 ) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_CSF_TIME_PERCENT, BCKeyConstants.ERROR_LEAVE_TIME_PERCENT_NOT_IN_RANGE, BigDecimal.ZERO.toPlainString(), BCConstants.ONE_HUNDRED.toPlainString());
return false;
}
return true;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedFteQuantity(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedFteQuantity(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
BigDecimal requestedFteQuantity = appointmentFunding.getAppointmentRequestedFteQuantity();
if (requestedFteQuantity == null || requestedFteQuantity.compareTo(BigDecimal.ZERO) < 0 || requestedFteQuantity.compareTo(BigDecimal.ONE) > 0) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_FTE_QUANTITY, BCKeyConstants.ERROR_FTE_QUANTITY_NOT_IN_RANGE, BigDecimal.ZERO.toPlainString(), BigDecimal.ONE.toPlainString());
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedFundingMonth(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedFundingMonth(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
Integer fundingMonths = appointmentFunding.getAppointmentFundingMonth();
if (fundingMonths == null) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_FUNDING_MONTH, BCKeyConstants.ERROR_EMPTY_FUNDIN_MONTH);
return false;
}
// Requested funding months must be between 0 and position normal work months if there is a leave
String leaveDurationCode = appointmentFunding.getAppointmentFundingDurationCode();
Integer normalWorkMonths = appointmentFunding.getBudgetConstructionPosition().getIuNormalWorkMonths();
if (!StringUtils.equals(leaveDurationCode, NONE.durationCode)) {
if (fundingMonths < 0 || fundingMonths > normalWorkMonths) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_FUNDING_MONTH, BCKeyConstants.ERROR_FUNDIN_MONTH_NOT_IN_RANGE, ObjectUtils.toString(fundingMonths), "0", ObjectUtils.toString(normalWorkMonths));
return false;
}
return true;
}
// Requested funding months must equal to position normal work months if no leave
if (!fundingMonths.equals(normalWorkMonths)) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_FUNDING_MONTH, BCKeyConstants.ERROR_NOT_EQUAL_NORMAL_WORK_MONTHS, ObjectUtils.toString(fundingMonths), ObjectUtils.toString(normalWorkMonths));
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidRequestedTimePercent(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.core.util.MessageMap)
*/
public boolean hasValidRequestedTimePercent(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
BigDecimal requestedTimePercent = appointmentFunding.getAppointmentRequestedTimePercent();
BigDecimal hourlyRate = appointmentFunding.getAppointmentRequestedPayRate();
if (requestedTimePercent == null) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_TIME_PERCENT, BCKeyConstants.ERROR_EMPTY_REQUESTED_TIME_PERCENT);
return false;
}
if (requestedTimePercent.compareTo(BigDecimal.ZERO) < 0 || requestedTimePercent.compareTo(BCConstants.ONE_HUNDRED) > 0 ) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_TIME_PERCENT, BCKeyConstants.ERROR_TIME_PERCENT_NOT_IN_RANGE, BigDecimal.ZERO.toPlainString(), BCConstants.ONE_HUNDRED.toPlainString());
return false;
}
if ((requestedAmount.isPositive() || (hourlyRate != null && hourlyRate.compareTo(BigDecimal.ZERO) != 0)) && requestedTimePercent.compareTo(BigDecimal.ZERO) <= 0) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_TIME_PERCENT, BCKeyConstants.ERROR_TIME_PERCENT_GREATER_THAN_ZERO_REQUIRED);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidAdjustmentAmount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.rice.krad.util.MessageMap)
*/
public boolean hasValidAdjustmentAmount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
KualiDecimal adjustmentAmount = appointmentFunding.getAdjustmentAmount();
if (adjustmentAmount == null) {
errorMap.putError(BCPropertyConstants.ADJUSTMENT_AMOUNT, BCKeyConstants.ERROR_ADJUSTMENT_AMOUNT_REQUIRED);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.module.bc.document.service.SalarySettingRuleHelperService#hasValidAdjustmentAmount(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding,
* org.kuali.rice.krad.util.MessageMap)
*/
public boolean hasValidPayRateOrAnnualAmount(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) {
BigDecimal payRate = appointmentFunding.getAppointmentRequestedPayRate();
KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
if (requestedAmount == null && payRate == null) {
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_PAY_RATE, BCKeyConstants.ERROR_EMPTY_PAY_RATE_ANNUAL_AMOUNT);
errorMap.putError(BCPropertyConstants.APPOINTMENT_REQUESTED_AMOUNT, BCKeyConstants.ERROR_EMPTY_PAY_RATE_ANNUAL_AMOUNT);
return false;
}
return true;
}
/**
* Sets the salarySettingService attribute value.
*
* @param salarySettingService The salarySettingService to set.
*/
public void setSalarySettingService(SalarySettingService salarySettingService) {
this.salarySettingService = salarySettingService;
}
/**
* Sets the humanResourcesPayrollService attribute value.
*
* @param humanResourcesPayrollService The humanResourcesPayrollService to set.
*/
public void setHumanResourcesPayrollService(HumanResourcesPayrollService humanResourcesPayrollService) {
this.humanResourcesPayrollService = humanResourcesPayrollService;
}
}