/*
* 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 java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.kuali.kfs.module.bc.BCConstants;
import org.kuali.kfs.module.bc.BCKeyConstants;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAccountSalaryDetailReport;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAccountSalaryDetailReportTotal;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAdministrativePost;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionCalculatedSalaryFoundationTracker;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionIntendedIncumbent;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition;
import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
import org.kuali.kfs.module.bc.document.service.BudgetConstructionAccountSalaryDetailReportService;
import org.kuali.kfs.module.bc.document.service.BudgetConstructionReportsServiceHelper;
import org.kuali.kfs.module.bc.document.service.SalarySettingService;
import org.kuali.kfs.module.bc.report.BudgetConstructionReportHelper;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.util.type.KualiInteger;
import org.springframework.transaction.annotation.Transactional;
/**
* Service implementation of BudgetConstructionLevelSummaryReportService.
*/
@Transactional
public class BudgetConstructionAccountSalaryDetailReportServiceImpl implements BudgetConstructionAccountSalaryDetailReportService {
protected ConfigurationService kualiConfigurationService;
protected BudgetConstructionReportsServiceHelper budgetConstructionReportsServiceHelper;
protected SalarySettingService salarySettingService;
/**
* @see org.kuali.kfs.module.bc.document.service.BudgetConstructionLevelSummaryReportService#buildReports(java.lang.Integer,
* java.util.Collection)
*/
@Override
public Collection<BudgetConstructionAccountSalaryDetailReport> buildReports(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String subAccountNumber) {
Collection<BudgetConstructionAccountSalaryDetailReport> reportSet = new ArrayList<BudgetConstructionAccountSalaryDetailReport>();
Map<String, Object> searchCriteria = buildSearchCriteria(universityFiscalYear, chartOfAccountsCode, accountNumber, subAccountNumber);
List<String> orderList = buildOrderByList();
Collection<PendingBudgetConstructionAppointmentFunding> pendingAppointmentFundingList = budgetConstructionReportsServiceHelper.getDataForBuildingReports(PendingBudgetConstructionAppointmentFunding.class, searchCriteria, orderList);
List<PendingBudgetConstructionAppointmentFunding> listForTotal = BudgetConstructionReportHelper.deleteDuplicated((List) pendingAppointmentFundingList, fieldsForTotal());
Collection<BudgetConstructionAccountSalaryDetailReportTotal> accountSalaryDetailTotal = calculateTotal(pendingAppointmentFundingList, listForTotal);
for (PendingBudgetConstructionAppointmentFunding pendingAppointmentFunding : pendingAppointmentFundingList) {
BudgetConstructionAccountSalaryDetailReport accountSalaryDetailReport = new BudgetConstructionAccountSalaryDetailReport();
buildReportsHeader(universityFiscalYear, pendingAppointmentFunding, accountSalaryDetailReport);
buildReportsBody(universityFiscalYear, pendingAppointmentFunding, accountSalaryDetailReport);
buildReportsTotal(pendingAppointmentFunding, accountSalaryDetailReport, accountSalaryDetailTotal);
reportSet.add(accountSalaryDetailReport);
}
return reportSet;
}
/**
* builds report Header
*
* @param BudgetConstructionObjectSummary bcas
*/
protected void buildReportsHeader(Integer universityFiscalYear, PendingBudgetConstructionAppointmentFunding pendingAppointmentFunding, BudgetConstructionAccountSalaryDetailReport accountSalaryDetailReport) {
Integer prevFiscalyear = universityFiscalYear - 1;
accountSalaryDetailReport.setFiscalYear(prevFiscalyear.toString() + "-" + universityFiscalYear.toString().substring(2, 4));
accountSalaryDetailReport.setAccountNumber(pendingAppointmentFunding.getAccountNumber());
accountSalaryDetailReport.setSubAccountNumber(pendingAppointmentFunding.getSubAccountNumber());
accountSalaryDetailReport.setChartOfAccountsCode(pendingAppointmentFunding.getChartOfAccountsCode());
accountSalaryDetailReport.setOrganizationCode(pendingAppointmentFunding.getAccount().getOrganizationCode());
String chartOfAccountDescription = "";
if (pendingAppointmentFunding.getChartOfAccounts() != null) {
try {
chartOfAccountDescription = pendingAppointmentFunding.getChartOfAccounts().getFinChartOfAccountDescription();
}
catch (PersistenceBrokerException e) {
chartOfAccountDescription = kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_CHART_DESCRIPTION);
}
}
else {
chartOfAccountDescription = BCConstants.Report.CHART + BCConstants.Report.NOT_DEFINED;
}
accountSalaryDetailReport.setChartOfAccountDescription(chartOfAccountDescription);
String orgName = null;
try {
orgName = pendingAppointmentFunding.getAccount().getOrganization().getOrganizationName();
}
catch (PersistenceBrokerException e) {
}
String accountName = pendingAppointmentFunding.getAccount().getAccountName();
String fundGroupCode = pendingAppointmentFunding.getAccount().getSubFundGroup().getFundGroupCode();
String fundGroupName = pendingAppointmentFunding.getAccount().getSubFundGroup().getFundGroup().getName();
if (orgName == null) {
accountSalaryDetailReport.setOrganizationName(kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_ORGANIZATION_NAME));
}
else {
accountSalaryDetailReport.setOrganizationName(orgName);
}
if (fundGroupCode == null) {
accountSalaryDetailReport.setFundGroupCode(kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_FUNDGROUP_CODE));
}
else {
accountSalaryDetailReport.setFundGroupCode(fundGroupCode);
}
if (fundGroupName == null) {
accountSalaryDetailReport.setFundGroupName(kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_FUNDGROUP_NAME));
}
else {
accountSalaryDetailReport.setFundGroupName(fundGroupName);
}
if (accountName == null) {
accountSalaryDetailReport.setAccountName(kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_ACCOUNT_DESCRIPTION));
}
else {
accountSalaryDetailReport.setAccountName(accountName);
}
String subAccountName = "";
if (!pendingAppointmentFunding.getSubAccountNumber().equals(KFSConstants.getDashSubAccountNumber())) {
try {
subAccountName = pendingAppointmentFunding.getSubAccount().getSubAccountName();
}
catch (PersistenceBrokerException e) {
subAccountName = kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_SUB_ACCOUNT_DESCRIPTION);
}
}
accountSalaryDetailReport.setSubAccountName(subAccountName);
}
/**
* builds report body
*
* @param BudgetConstructionLevelSummary bcas
*/
protected void buildReportsBody(Integer universityFiscalYear, PendingBudgetConstructionAppointmentFunding pendingAppointmentFunding, BudgetConstructionAccountSalaryDetailReport accountMonthlyDetailReport) {
Integer amountChange = new Integer(0);
BigDecimal percentChange = BigDecimal.ZERO;
BudgetConstructionIntendedIncumbent intendedIncumbent = budgetConstructionReportsServiceHelper.getBudgetConstructionIntendedIncumbent(pendingAppointmentFunding);
BudgetConstructionAdministrativePost administrativePost = budgetConstructionReportsServiceHelper.getBudgetConstructionAdministrativePost(pendingAppointmentFunding);
BudgetConstructionPosition position = budgetConstructionReportsServiceHelper.getBudgetConstructionPosition(universityFiscalYear, pendingAppointmentFunding);
BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = pendingAppointmentFunding.getEffectiveCSFTracker();
// from PendingBudgetConstructionAppointmentFunding
accountMonthlyDetailReport.setFinancialSubObjectCode(pendingAppointmentFunding.getFinancialSubObjectCode());
// from BudgetConstructionIntendedIncumbent
if (intendedIncumbent != null) {
accountMonthlyDetailReport.setIuClassificationLevel(intendedIncumbent.getIuClassificationLevel());
}
// from BudgetConstructionAdministrativePost
if (administrativePost != null) {
accountMonthlyDetailReport.setAdministrativePost(administrativePost.getAdministrativePost());
}
// from BudgetConstructionPosition
if (position != null) {
accountMonthlyDetailReport.setPositionNumber(position.getPositionNumber());
accountMonthlyDetailReport.setPositionSalaryPlanDefault(position.getPositionSalaryPlanDefault());
accountMonthlyDetailReport.setPositionGradeDefault(position.getPositionGradeDefault());
accountMonthlyDetailReport.setNormalWorkMonthsAndiuPayMonths(position.getIuNormalWorkMonths() + "/" + position.getIuPayMonths());
}
// from BudgetConstructionCalculatedSalaryFoundationTracker
if (csfTracker != null) {
accountMonthlyDetailReport.setPositionCsfAmount(csfTracker.getCsfAmount().intValue());
accountMonthlyDetailReport.setCsfTimePercent(BudgetConstructionReportHelper.setDecimalDigit(csfTracker.getCsfTimePercent(), 2, false));
accountMonthlyDetailReport.setPositionCsfFullTimeEmploymentQuantity(BudgetConstructionReportHelper.setDecimalDigit(csfTracker.getCsfFullTimeEmploymentQuantity(), 5, false));
accountMonthlyDetailReport.setPositionCsfFundingStatusCode(csfTracker.getCsfFundingStatusCode());
BigDecimal csfFte = BudgetConstructionReportHelper.setDecimalDigit(csfTracker.getCsfFullTimeEmploymentQuantity(), 5, false);
BigDecimal reqFte = BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentRequestedFteQuantity(), 5, false);
if (reqFte.compareTo(csfFte) == 0) {
amountChange = pendingAppointmentFunding.getAppointmentRequestedAmount().subtract(csfTracker.getCsfAmount()).intValue();
if (!csfTracker.getCsfAmount().equals(KualiInteger.ZERO)) {
percentChange = BudgetConstructionReportHelper.calculatePercent(amountChange, csfTracker.getCsfAmount().intValue());
}
}
}
// from PendingBudgetConstructionAppointmentFunding
accountMonthlyDetailReport.setAppointmentFundingMonth(pendingAppointmentFunding.getAppointmentFundingMonth());
if (salarySettingService.isHourlyPaidObject(pendingAppointmentFunding.getUniversityFiscalYear(), pendingAppointmentFunding.getChartOfAccountsCode(), pendingAppointmentFunding.getFinancialObjectCode())){
accountMonthlyDetailReport.setAppointmentRequestedPayRate(pendingAppointmentFunding.getAppointmentRequestedPayRate());
}
accountMonthlyDetailReport.setAppointmentRequestedAmount(pendingAppointmentFunding.getAppointmentRequestedAmount().intValue());
accountMonthlyDetailReport.setAppointmentRequestedTimePercent(BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentRequestedTimePercent(), 2, false));
accountMonthlyDetailReport.setAppointmentRequestedFteQuantity(BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentRequestedFteQuantity(), 5, false));
accountMonthlyDetailReport.setAppointmentRequestedCsfAmount(pendingAppointmentFunding.getAppointmentRequestedCsfAmount().intValue());
accountMonthlyDetailReport.setAppointmentRequestedCsfTimePercent(BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentRequestedCsfTimePercent(), 2, false));
accountMonthlyDetailReport.setAppointmentRequestedCsfFteQuantity(BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentRequestedCsfFteQuantity(), 5, false));
accountMonthlyDetailReport.setAppointmentFundingDurationCode(pendingAppointmentFunding.getAppointmentFundingDurationCode());
accountMonthlyDetailReport.setAppointmentTotalIntendedAmount(pendingAppointmentFunding.getAppointmentTotalIntendedAmount().intValue());
accountMonthlyDetailReport.setAppointmentTotalIntendedFteQuantity(BudgetConstructionReportHelper.setDecimalDigit(pendingAppointmentFunding.getAppointmentTotalIntendedFteQuantity(), 5, false));
accountMonthlyDetailReport.setFinancialObjectCode(pendingAppointmentFunding.getFinancialObjectCode());
accountMonthlyDetailReport.setFinancialObjectCodeName(pendingAppointmentFunding.getFinancialObject().getFinancialObjectCodeName());
String deleteBox = pendingAppointmentFunding.isAppointmentFundingDeleteIndicator() ? BCConstants.Report.DELETE_MARK : BCConstants.Report.BLANK;
accountMonthlyDetailReport.setDeleteBox(deleteBox);
if (pendingAppointmentFunding.getEmplid().equals(BCConstants.Report.VACANT)){
accountMonthlyDetailReport.setName(BCConstants.Report.VACANT);
} else {
int nameLength = intendedIncumbent.getName().length();
accountMonthlyDetailReport.setName(intendedIncumbent.getName().substring(0, (nameLength > 35) ? 35 : nameLength));
}
accountMonthlyDetailReport.setAmountChange(amountChange);
accountMonthlyDetailReport.setPercentChange(percentChange);
}
protected void buildReportsTotal(PendingBudgetConstructionAppointmentFunding pendingAppointmentFunding, BudgetConstructionAccountSalaryDetailReport accountMonthlyDetailReport, Collection<BudgetConstructionAccountSalaryDetailReportTotal> accountSalaryDetailTotal) {
for (BudgetConstructionAccountSalaryDetailReportTotal totalEntry : accountSalaryDetailTotal) {
if (BudgetConstructionReportHelper.isSameEntry(totalEntry.getPendingBudgetConstructionAppointmentFunding(), pendingAppointmentFunding, fieldsForTotal())) {
String objectCodeName = StringUtils.EMPTY;
if (pendingAppointmentFunding.getFinancialObject() != null) {
try {
objectCodeName = pendingAppointmentFunding.getFinancialObject().getFinancialObjectCodeName();
}
catch (PersistenceBrokerException e) {
objectCodeName = kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_OBJECT_NAME);
}
}
else {
objectCodeName = BCConstants.Report.OBJECT + BCConstants.Report.NOT_DEFINED;
}
accountMonthlyDetailReport.setTotalDescription(objectCodeName);
accountMonthlyDetailReport.setTotalBaseAmount(totalEntry.getTotalBaseAmount());
accountMonthlyDetailReport.setTotalBaseFte(totalEntry.getTotalBaseFte());
accountMonthlyDetailReport.setTotalRequestAmount(totalEntry.getTotalRequestAmount());
accountMonthlyDetailReport.setTotalRequestFte(totalEntry.getTotalRequestFte());
accountMonthlyDetailReport.setTotalAmountChange(totalEntry.getTotalRequestAmount() - totalEntry.getTotalBaseAmount());
accountMonthlyDetailReport.setTotalPercentChange(BudgetConstructionReportHelper.calculatePercent(accountMonthlyDetailReport.getTotalAmountChange(), totalEntry.getTotalBaseAmount()));
}
}
}
protected Collection<BudgetConstructionAccountSalaryDetailReportTotal> calculateTotal(Collection<PendingBudgetConstructionAppointmentFunding> pendingAppointmentFundingList, List<PendingBudgetConstructionAppointmentFunding> listForTotal) {
Collection<BudgetConstructionAccountSalaryDetailReportTotal> reportTotals = new ArrayList<BudgetConstructionAccountSalaryDetailReportTotal>();
for (PendingBudgetConstructionAppointmentFunding totalEntry : listForTotal) {
KualiInteger totalBaseAmount = KualiInteger.ZERO;
BigDecimal totalBaseFte = BigDecimal.ZERO;
Integer totalRequestAmount = new Integer(0);
BigDecimal totalRequestFte = BigDecimal.ZERO;
BudgetConstructionAccountSalaryDetailReportTotal budgetConstructionAccountSalaryDetailReportTotal = new BudgetConstructionAccountSalaryDetailReportTotal();
for (PendingBudgetConstructionAppointmentFunding appointmentFundingEntry : pendingAppointmentFundingList) {
if (BudgetConstructionReportHelper.isSameEntry(totalEntry, appointmentFundingEntry, fieldsForTotal())) {
BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFundingEntry.getEffectiveCSFTracker();
if (csfTracker != null) {
totalBaseAmount = totalBaseAmount.add(csfTracker.getCsfAmount());
totalBaseFte = totalBaseFte.add(csfTracker.getCsfFullTimeEmploymentQuantity());
}
totalRequestAmount = totalRequestAmount + new Integer(appointmentFundingEntry.getAppointmentRequestedAmount().intValue());
totalRequestFte = totalRequestFte.add(appointmentFundingEntry.getAppointmentRequestedFteQuantity());
}
}
budgetConstructionAccountSalaryDetailReportTotal.setTotalBaseAmount(totalBaseAmount.intValue());
budgetConstructionAccountSalaryDetailReportTotal.setTotalBaseFte(totalBaseFte);
budgetConstructionAccountSalaryDetailReportTotal.setTotalRequestAmount(totalRequestAmount);
budgetConstructionAccountSalaryDetailReportTotal.setTotalRequestFte(totalRequestFte);
budgetConstructionAccountSalaryDetailReportTotal.setPendingBudgetConstructionAppointmentFunding(totalEntry);
reportTotals.add(budgetConstructionAccountSalaryDetailReportTotal);
}
return reportTotals;
}
protected List<String> fieldsForTotal() {
List<String> fieldList = new ArrayList<String>();
fieldList.add(KFSPropertyConstants.FINANCIAL_OBJECT_CODE);
return fieldList;
}
/**
* builds orderByList for sort order.
*
* @return returnList
*/
protected List<String> buildOrderByList() {
List<String> returnList = new ArrayList<String>();
returnList.add(KFSPropertyConstants.FINANCIAL_OBJECT_CODE);
returnList.add(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE);
returnList.add(KFSPropertyConstants.POSITION_NUMBER);
returnList.add(KFSPropertyConstants.EMPLID);
return returnList;
}
protected Map<String, Object> buildSearchCriteria(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String subAccountNumber) {
Map<String, Object> searchCriteria = new HashMap<String, Object>();
searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear);
searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, accountNumber);
searchCriteria.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, subAccountNumber);
return searchCriteria;
}
/**
* Sets the kualiConfigurationService attribute value.
*
* @param kualiConfigurationService The kualiConfigurationService to set.
*/
public void setConfigurationService(ConfigurationService kualiConfigurationService) {
this.kualiConfigurationService = kualiConfigurationService;
}
/**
* Sets the budgetConstructionReportsServiceHelper attribute value.
*
* @param budgetConstructionReportsServiceHelper The budgetConstructionReportsServiceHelper to set.
*/
public void setBudgetConstructionReportsServiceHelper(BudgetConstructionReportsServiceHelper budgetConstructionReportsServiceHelper) {
this.budgetConstructionReportsServiceHelper = budgetConstructionReportsServiceHelper;
}
/**
* Sets the salarySettingService attribute value.
* @param salarySettingService The salarySettingService to set.
*/
public void setSalarySettingService(SalarySettingService salarySettingService) {
this.salarySettingService = salarySettingService;
}
}