/* * 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.kuali.kfs.module.bc.BCConstants; import org.kuali.kfs.module.bc.BCKeyConstants; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAdministrativePost; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAppointmentFundingReason; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAppointmentFundingReasonCode; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionCalculatedSalaryFoundationTracker; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionIntendedIncumbent; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionOrgReasonSummaryReport; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionOrgReasonSummaryReportTotal; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionReportThresholdSettings; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionSalaryFunding; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionSalarySocialSecurityNumber; import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding; import org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionSalarySummaryReportDao; import org.kuali.kfs.module.bc.document.service.BudgetConstructionOrganizationReportsService; import org.kuali.kfs.module.bc.document.service.BudgetConstructionReasonSummaryReportService; import org.kuali.kfs.module.bc.document.service.BudgetConstructionReportsServiceHelper; 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.KualiDecimal; import org.kuali.rice.core.api.util.type.KualiInteger; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.util.ObjectUtils; import org.springframework.transaction.annotation.Transactional; /** * Service implementation of BudgetConstructionReasonSummaryReportService. */ @Transactional public class BudgetConstructionReasonSummaryReportServiceImpl implements BudgetConstructionReasonSummaryReportService { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetConstructionReasonSummaryReportServiceImpl.class); protected BudgetConstructionSalarySummaryReportDao budgetConstructionSalarySummaryReportDao; protected BudgetConstructionOrganizationReportsService budgetConstructionOrganizationReportsService; protected BudgetConstructionReportsServiceHelper budgetConstructionReportsServiceHelper; protected ConfigurationService kualiConfigurationService; protected BusinessObjectService businessObjectService; /** * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionReasonSummaryReportService#updateReasonSummaryReport(java.lang.String, * java.lang.Integer, org.kuali.kfs.module.bc.businessobject.BudgetConstructionReportThresholdSettings) */ @Override public void updateReasonSummaryReport(String principalId, Integer universityFiscalYear, BudgetConstructionReportThresholdSettings budgetConstructionReportThresholdSettings) { boolean selectOnlyGreaterThanOrEqualToThreshold = budgetConstructionReportThresholdSettings.isUseGreaterThanOperator(); KualiDecimal thresholdPercent = budgetConstructionReportThresholdSettings.getThresholdPercent(); boolean applyAThreshold = budgetConstructionReportThresholdSettings.isUseThreshold(); if (applyAThreshold) { budgetConstructionSalarySummaryReportDao.updateSalaryAndReasonSummaryReportsWithThreshold(principalId, universityFiscalYear - 1, selectOnlyGreaterThanOrEqualToThreshold, thresholdPercent); } else { budgetConstructionSalarySummaryReportDao.updateSalaryAndReasonSummaryReportsWithoutThreshold(principalId, true); } } /** * @see org.kuali.kfs.module.bc.document.service.BudgetConstructionReasonSummaryReportService#buildReports(java.lang.Integer, * java.lang.String, org.kuali.kfs.module.bc.businessobject.BudgetConstructionReportThresholdSettings) */ @Override public Collection<BudgetConstructionOrgReasonSummaryReport> buildReports(Integer universityFiscalYear, String principalId, BudgetConstructionReportThresholdSettings reportThresholdSettings) { Collection<BudgetConstructionOrgReasonSummaryReport> reportSet = new ArrayList<BudgetConstructionOrgReasonSummaryReport>(); BudgetConstructionOrgReasonSummaryReport reasonSummaryReport; Collection<BudgetConstructionSalarySocialSecurityNumber> bcSalarySsnList = budgetConstructionReportsServiceHelper.getDataForBuildingReports(BudgetConstructionSalarySocialSecurityNumber.class, principalId, buildOrderByList()); Map salaryFundingMap = new HashMap(); for (BudgetConstructionSalarySocialSecurityNumber ssnEntry : bcSalarySsnList) { Collection<BudgetConstructionSalaryFunding> salaryFundingList = budgetConstructionReportsServiceHelper.getSalaryFunding(principalId, ssnEntry.getEmplid()); salaryFundingMap.put(ssnEntry, salaryFundingList); } List<BudgetConstructionSalarySocialSecurityNumber> listForCalculateTotalPerson = deleteDuplicated((List) bcSalarySsnList, 1); List<BudgetConstructionSalarySocialSecurityNumber> listForCalculateTotalOrg = deleteDuplicated((List) bcSalarySsnList, 2); // Calculate Total Section Collection<BudgetConstructionOrgReasonSummaryReportTotal> reasonSummaryTotalPerson = calculatePersonTotal(universityFiscalYear, bcSalarySsnList, listForCalculateTotalPerson, salaryFundingMap); Collection<BudgetConstructionOrgReasonSummaryReportTotal> reasonSummaryTotalOrg = calculateOrgTotal(reasonSummaryTotalPerson, listForCalculateTotalOrg, salaryFundingMap); // get object codes String objectCodes = budgetConstructionReportsServiceHelper.getSelectedObjectCodes(principalId); // get reason codes String reasonCodes = budgetConstructionReportsServiceHelper.getSelectedReasonCodes(principalId); for (BudgetConstructionSalarySocialSecurityNumber ssnEntry : bcSalarySsnList) { Collection<BudgetConstructionSalaryFunding> salaryFundingList = (Collection) salaryFundingMap.get(ssnEntry); for (BudgetConstructionSalaryFunding salaryFundingEntry : salaryFundingList) { reasonSummaryReport = new BudgetConstructionOrgReasonSummaryReport(); buildReportsHeader(universityFiscalYear, objectCodes, reasonCodes, reasonSummaryReport, salaryFundingEntry, ssnEntry, reportThresholdSettings); buildReportsBody(universityFiscalYear, reasonSummaryReport, salaryFundingEntry, ssnEntry); buildReportsTotal(reasonSummaryReport, ssnEntry, reasonSummaryTotalPerson, reasonSummaryTotalOrg); reportSet.add(reasonSummaryReport); } } return reportSet; } /** * builds report Header */ public void buildReportsHeader(Integer universityFiscalYear, String objectCodes, String reasonCodes, BudgetConstructionOrgReasonSummaryReport reasonSummaryReport, BudgetConstructionSalaryFunding salaryFundingEntry, BudgetConstructionSalarySocialSecurityNumber bcSSN, BudgetConstructionReportThresholdSettings budgetConstructionReportThresholdSettings) { Integer prevFiscalyear = universityFiscalYear - 1; reasonSummaryReport.setFiscalYear(prevFiscalyear + "-" + universityFiscalYear.toString().substring(2, 4)); reasonSummaryReport.setOrganizationCode(bcSSN.getOrganizationCode()); String organizationName = bcSSN.getOrganization().getOrganizationName(); if (organizationName == null) { String wrongOrganizationName = kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_ORGANIZATION_NAME); reasonSummaryReport.setOrganizationName(wrongOrganizationName); } else { reasonSummaryReport.setOrganizationName(organizationName); } reasonSummaryReport.setOrgChartOfAccountsCode(bcSSN.getOrganizationChartOfAccountsCode()); String chartDescription = bcSSN.getOrganizationChartOfAccounts().getFinChartOfAccountDescription(); if (chartDescription == null) { String wrongChartDescription = kualiConfigurationService.getPropertyValueAsString(BCKeyConstants.ERROR_REPORT_GETTING_CHART_DESCRIPTION); reasonSummaryReport.setOrgChartOfAccountDescription(wrongChartDescription); } else { reasonSummaryReport.setOrgChartOfAccountDescription(chartDescription); } Integer prevPrevFiscalyear = prevFiscalyear - 1; reasonSummaryReport.setReqFy(prevFiscalyear + "-" + universityFiscalYear.toString().substring(2, 4)); reasonSummaryReport.setFinancialObjectCode(salaryFundingEntry.getFinancialObjectCode()); reasonSummaryReport.setObjectCodes(objectCodes); if (budgetConstructionReportThresholdSettings.isUseThreshold()) { if (budgetConstructionReportThresholdSettings.isUseGreaterThanOperator()) { reasonSummaryReport.setThresholdOrReason(BCConstants.Report.THRESHOLD + BCConstants.Report.THRESHOLD_GREATER + budgetConstructionReportThresholdSettings.getThresholdPercent().toString() + BCConstants.Report.PERCENT); } else { reasonSummaryReport.setThresholdOrReason(BCConstants.Report.THRESHOLD + BCConstants.Report.THRESHOLD_LESS + budgetConstructionReportThresholdSettings.getThresholdPercent().toString() + BCConstants.Report.PERCENT); } } else { reasonSummaryReport.setThresholdOrReason(BCConstants.Report.SELECTED_REASONS + reasonCodes); } // reason, amt, desc List<BudgetConstructionAppointmentFundingReason> appointmentFundingReasonList = salaryFundingEntry.getPendingAppointmentFunding().getBudgetConstructionAppointmentFundingReason(); if (ObjectUtils.isNotNull(appointmentFundingReasonList) && !appointmentFundingReasonList.isEmpty()) { BudgetConstructionAppointmentFundingReason appointmentFundingReason = appointmentFundingReasonList.get(0); Integer reasonAmount = BudgetConstructionReportHelper.convertKualiInteger(appointmentFundingReason.getAppointmentFundingReasonAmount()); reasonSummaryReport.setAppointmentFundingReasonAmount(reasonAmount); BudgetConstructionAppointmentFundingReasonCode reasonCode = appointmentFundingReason.getAppointmentFundingReason(); if (ObjectUtils.isNotNull(reasonCode)) { reasonSummaryReport.setAppointmentFundingReasonDescription(reasonCode.getAppointmentFundingReasonDescription()); } } } /** * builds report body */ public void buildReportsBody(Integer fiscalYear, BudgetConstructionOrgReasonSummaryReport reasonSummaryReport, BudgetConstructionSalaryFunding salaryFundingEntry, BudgetConstructionSalarySocialSecurityNumber salarySSN) { int curToInt = -1; double curFteInt = -1.00; PendingBudgetConstructionAppointmentFunding appointmentFunding = salaryFundingEntry.getPendingAppointmentFunding(); BudgetConstructionIntendedIncumbent intendedIncumbent = budgetConstructionReportsServiceHelper.getBudgetConstructionIntendedIncumbent(appointmentFunding); if (intendedIncumbent != null) { reasonSummaryReport.setIuClassificationLevel(intendedIncumbent.getIuClassificationLevel()); } int nameLength = salarySSN.getName().length(); reasonSummaryReport.setName(salarySSN.getName().substring(0, (nameLength > 35) ? 35 : nameLength)); BudgetConstructionAdministrativePost administrativePost = budgetConstructionReportsServiceHelper.getBudgetConstructionAdministrativePost(appointmentFunding); BudgetConstructionPosition budgetConstructionPosition = budgetConstructionReportsServiceHelper.getBudgetConstructionPosition(fiscalYear, appointmentFunding); // set report body reasonSummaryReport.setChartOfAccountsCode(salaryFundingEntry.getChartOfAccountsCode()); reasonSummaryReport.setAccountNumber(salaryFundingEntry.getAccountNumber()); reasonSummaryReport.setSubAccountNumber(salaryFundingEntry.getSubAccountNumber()); reasonSummaryReport.setFinancialSubObjectCode(salaryFundingEntry.getFinancialSubObjectCode()); if (administrativePost != null) { reasonSummaryReport.setAdministrativePost(administrativePost.getAdministrativePost()); } if (budgetConstructionPosition != null) { reasonSummaryReport.setPositionNumber(budgetConstructionPosition.getPositionNumber()); reasonSummaryReport.setNormalWorkMonthsAndiuPayMonths(budgetConstructionPosition.getIuNormalWorkMonths() + "/" + budgetConstructionPosition.getIuPayMonths()); reasonSummaryReport.setPositionFte(BudgetConstructionReportHelper.setDecimalDigit(budgetConstructionPosition.getPositionFullTimeEquivalency(), 5, false)); reasonSummaryReport.setPositionSalaryPlanDefault(budgetConstructionPosition.getPositionSalaryPlanDefault()); reasonSummaryReport.setPositionGradeDefault(budgetConstructionPosition.getPositionGradeDefault()); } BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFunding.getEffectiveCSFTracker(); if (ObjectUtils.isNotNull(csfTracker)) { reasonSummaryReport.setCsfTimePercent(BudgetConstructionReportHelper.setDecimalDigit(csfTracker.getCsfTimePercent(), 2, false)); reasonSummaryReport.setCsfAmount(csfTracker.getCsfAmount().intValue()); // calculate amountChange and percentChange if (appointmentFunding.getAppointmentRequestedFteQuantity().equals(csfTracker.getCsfFullTimeEmploymentQuantity())) { Integer amountChange = appointmentFunding.getAppointmentRequestedAmount().subtract(csfTracker.getCsfAmount()).intValue(); reasonSummaryReport.setAmountChange(amountChange); BigDecimal percentChange = BudgetConstructionReportHelper.calculatePercent(new BigDecimal(amountChange), csfTracker.getCsfAmount().bigDecimalValue()); reasonSummaryReport.setPercentChange(percentChange); } } if (StringUtils.equals(appointmentFunding.getFinancialSubObjectCode(), KFSConstants.getDashFinancialSubObjectCode())) { reasonSummaryReport.setFinancialSubObjectCode(BCConstants.Report.BLANK); } else { reasonSummaryReport.setFinancialSubObjectCode(appointmentFunding.getFinancialSubObjectCode()); } reasonSummaryReport.setEmplid(appointmentFunding.getEmplid()); reasonSummaryReport.setAppointmentFundingDurationCode(appointmentFunding.getAppointmentFundingDurationCode()); reasonSummaryReport.setAppointmentTotalIntendedAmount(appointmentFunding.getAppointmentTotalIntendedAmount().intValue()); BigDecimal totalIntendedFteQuantity = BudgetConstructionReportHelper.setDecimalDigit(appointmentFunding.getAppointmentTotalIntendedFteQuantity(), 5, false); reasonSummaryReport.setAppointmentTotalIntendedFteQuantity(totalIntendedFteQuantity); if (StringUtils.equals(appointmentFunding.getAppointmentFundingDurationCode(), BCConstants.Report.NONE)) { reasonSummaryReport.setSalaryAmount(appointmentFunding.getAppointmentRequestedAmount().intValue()); reasonSummaryReport.setPercentAmount(appointmentFunding.getAppointmentRequestedTimePercent()); reasonSummaryReport.setSalaryMonths(appointmentFunding.getAppointmentFundingMonth()); } else { reasonSummaryReport.setSalaryAmount(appointmentFunding.getAppointmentRequestedCsfAmount().intValue()); reasonSummaryReport.setPercentAmount(appointmentFunding.getAppointmentRequestedCsfTimePercent()); if (budgetConstructionPosition != null) { reasonSummaryReport.setSalaryMonths(budgetConstructionPosition.getIuNormalWorkMonths()); } } if (appointmentFunding.isAppointmentFundingDeleteIndicator()) { reasonSummaryReport.setDeleteBox(BCConstants.Report.DELETE_MARK); } else { reasonSummaryReport.setDeleteBox(BCConstants.Report.BLANK); } // set tiFlag if (appointmentFunding.isAppointmentFundingDeleteIndicator()) { if (curToInt == -1) { curToInt = appointmentFunding.getAppointmentTotalIntendedAmount().intValue(); } else if (curToInt != appointmentFunding.getAppointmentTotalIntendedAmount().intValue()) { reasonSummaryReport.setTiFlag(BCConstants.Report.PLUS); } if (curFteInt == -1.00) { curFteInt = appointmentFunding.getAppointmentTotalIntendedFteQuantity().doubleValue(); } else if (curFteInt != appointmentFunding.getAppointmentTotalIntendedFteQuantity().doubleValue()) { reasonSummaryReport.setTiFlag(BCConstants.Report.PLUS); } } } /** * build the total sections for the report */ public void buildReportsTotal(BudgetConstructionOrgReasonSummaryReport reasonSummaryReportEntry, BudgetConstructionSalarySocialSecurityNumber ssnEntry, Collection<BudgetConstructionOrgReasonSummaryReportTotal> reasonSummaryTotalPerson, Collection<BudgetConstructionOrgReasonSummaryReportTotal> reasonSummaryTotalOrg) { for (BudgetConstructionOrgReasonSummaryReportTotal totalPersonEntry : reasonSummaryTotalPerson) { if (isSameSsnEntryForTotalPerson(totalPersonEntry.getBudgetConstructionSalarySocialSecurityNumber(), ssnEntry)) { reasonSummaryReportEntry.setPersonPositionNumber(totalPersonEntry.getPersonPositionNumber()); reasonSummaryReportEntry.setPersonFiscalYearTag(totalPersonEntry.getPersonFiscalYearTag()); reasonSummaryReportEntry.setPersonNormalMonthsAndPayMonths(totalPersonEntry.getPersonCsfNormalMonths().toString() + "/" + totalPersonEntry.getPersonCsfPayMonths().toString()); reasonSummaryReportEntry.setPersonCsfAmount(totalPersonEntry.getPersonCsfAmount()); reasonSummaryReportEntry.setPersonCsfPercent(totalPersonEntry.getPersonCsfPercent()); reasonSummaryReportEntry.setPersonSalaryNormalMonths(totalPersonEntry.getPersonSalaryNormalMonths()); reasonSummaryReportEntry.setPersonSalaryAmount(totalPersonEntry.getPersonSalaryAmount()); reasonSummaryReportEntry.setPersonSalaryPercent(totalPersonEntry.getPersonSalaryPercent()); reasonSummaryReportEntry.setPersonSalaryFte(totalPersonEntry.getPersonSalaryFte()); reasonSummaryReportEntry.setPersonTiFlag(totalPersonEntry.getPersonTiFlag()); reasonSummaryReportEntry.setPersonAmountChange(totalPersonEntry.getPersonAmountChange()); reasonSummaryReportEntry.setPersonPercentChange(totalPersonEntry.getPersonPercentChange()); } for (BudgetConstructionOrgReasonSummaryReportTotal totalOrgEntry : reasonSummaryTotalOrg) { if (isSameSsnEntryForTotalOrg(totalOrgEntry.getBudgetConstructionSalarySocialSecurityNumber(), ssnEntry)) { reasonSummaryReportEntry.setNewFte(totalOrgEntry.getNewFte()); reasonSummaryReportEntry.setNewTotalAmount(totalOrgEntry.getNewTotalAmount()); reasonSummaryReportEntry.setConTotalBaseAmount(totalOrgEntry.getConTotalBaseAmount()); reasonSummaryReportEntry.setConFte(totalOrgEntry.getConFte()); reasonSummaryReportEntry.setConTotalRequestAmount(totalOrgEntry.getConTotalRequestAmount()); reasonSummaryReportEntry.setNewAverageAmount(totalOrgEntry.getNewAverageAmount()); reasonSummaryReportEntry.setConAverageBaseAmount(totalOrgEntry.getConAverageBaseAmount()); reasonSummaryReportEntry.setConAverageRequestAmount(totalOrgEntry.getConAverageRequestAmount()); reasonSummaryReportEntry.setConAveragechange(totalOrgEntry.getConAveragechange()); reasonSummaryReportEntry.setConPercentChange(totalOrgEntry.getConPercentChange()); } } } } // calculate the totals for the given person protected Collection<BudgetConstructionOrgReasonSummaryReportTotal> calculatePersonTotal(Integer universityFiscalYear, Collection<BudgetConstructionSalarySocialSecurityNumber> bcSalarySsnList, List<BudgetConstructionSalarySocialSecurityNumber> listForCalculateTotalPerson, Map salaryFundingMap) { Collection<BudgetConstructionOrgReasonSummaryReportTotal> returnCollection = new ArrayList<BudgetConstructionOrgReasonSummaryReportTotal>(); for (BudgetConstructionSalarySocialSecurityNumber personEntry : listForCalculateTotalPerson) { PersonTotalHolder totalsHolder = new PersonTotalHolder(); totalsHolder.emplid = personEntry.getEmplid(); for (BudgetConstructionSalarySocialSecurityNumber salaryFundingEntry : bcSalarySsnList) { if (isSameSsnEntryForTotalPerson(personEntry, salaryFundingEntry)) { Collection<BudgetConstructionSalaryFunding> salaryFundings = (Collection<BudgetConstructionSalaryFunding>) salaryFundingMap.get(personEntry); this.collectPersonTotal(universityFiscalYear, salaryFundings, totalsHolder); } } this.adjustPersonTotal(totalsHolder); returnCollection.add(this.createReportTotal(personEntry, totalsHolder)); } return returnCollection; } // adjust the total amount that just is held by the given holder protected void adjustPersonTotal(PersonTotalHolder totalsHolder) { Integer restatementCsfAmount = 0; if (totalsHolder.salaryPayMonth == 0 || totalsHolder.csfPayMonths == 0 || BigDecimal.ZERO.compareTo(totalsHolder.csfPercent) == 0 || totalsHolder.csfNormalMonths == 0) { restatementCsfAmount = 0; } else { BigDecimal salaryMonthPercent = new BigDecimal(totalsHolder.salaryNormalMonths * 1.0 / totalsHolder.salaryPayMonth); BigDecimal salaryFteQuantity = totalsHolder.salaryPercent.multiply(salaryMonthPercent); BigDecimal csfMonthpercent = new BigDecimal(totalsHolder.csfNormalMonths * 1.0 / totalsHolder.csfPayMonths); BigDecimal csfFteQuantity = totalsHolder.csfPercent.multiply(csfMonthpercent); BigDecimal restatementCsfPercent = salaryFteQuantity.divide(csfFteQuantity, 6, BigDecimal.ROUND_HALF_UP); BigDecimal csfAmount = new BigDecimal(totalsHolder.csfAmount); restatementCsfAmount = csfAmount.multiply(restatementCsfPercent).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(); } if (totalsHolder.salaryPayMonth == 0) { totalsHolder.salaryFte = BigDecimal.ZERO; } else { BigDecimal salaryFte = totalsHolder.salaryPercent.multiply(new BigDecimal(totalsHolder.salaryNormalMonths * 1.0 / (totalsHolder.salaryPayMonth * 100.0))); totalsHolder.salaryFte = BudgetConstructionReportHelper.setDecimalDigit(salaryFte, 5, false); } if (totalsHolder.salaryPayMonth != totalsHolder.csfPayMonths) { if (totalsHolder.csfPayMonths == 0) { restatementCsfAmount = 0; } else { BigDecimal amount = new BigDecimal(restatementCsfAmount * totalsHolder.salaryPayMonth * 1.0 / totalsHolder.csfPayMonths); restatementCsfAmount = BudgetConstructionReportHelper.setDecimalDigit(amount, 0, false).intValue(); } } totalsHolder.csfAmount = restatementCsfAmount; totalsHolder.amountChange = totalsHolder.salaryAmount - totalsHolder.csfAmount; if (totalsHolder.csfAmount != 0) { totalsHolder.percentChange = BudgetConstructionReportHelper.calculatePercent(totalsHolder.amountChange, totalsHolder.csfAmount); } else { totalsHolder.percentChange = BigDecimal.ZERO; } if (totalsHolder.curToInt != 0 && totalsHolder.curToInt != -1 && totalsHolder.curToInt != totalsHolder.salaryAmount.intValue() || totalsHolder.curFteInt != 0 && totalsHolder.curFteInt != -1.00 && totalsHolder.curFteInt != totalsHolder.salaryFte.doubleValue()) { totalsHolder.tiFlag = BCConstants.Report.PLUS; } else { totalsHolder.tiFlag = BCConstants.Report.BLANK; } } // collect the total amounts for a single person and save the totals in the given holder protected void collectPersonTotal(Integer universityFiscalYear, Collection<BudgetConstructionSalaryFunding> salaryFundings, PersonTotalHolder totalsHolder) { int maxSalaryAmount = 0; int maxCsfAmount = 0; for (BudgetConstructionSalaryFunding salaryFunding : salaryFundings) { PendingBudgetConstructionAppointmentFunding appointmentFunding = salaryFunding.getPendingAppointmentFunding(); BudgetConstructionPosition budgetConstructionPosition = budgetConstructionReportsServiceHelper.getBudgetConstructionPosition(universityFiscalYear, appointmentFunding); int salaryAmount = 0; Integer salaryMonths = 0; BigDecimal salaryPercent = BigDecimal.ZERO; String durationCode = appointmentFunding.getAppointmentFundingDurationCode(); if (StringUtils.equals(durationCode, BCConstants.Report.NONE)) { salaryAmount = appointmentFunding.getAppointmentRequestedAmount().intValue(); salaryMonths = appointmentFunding.getAppointmentFundingMonth(); salaryPercent = appointmentFunding.getAppointmentRequestedTimePercent(); } else { salaryAmount = appointmentFunding.getAppointmentRequestedCsfAmount().intValue(); salaryMonths = budgetConstructionPosition.getIuNormalWorkMonths(); boolean hasRequestedCsfTimePercent = appointmentFunding.getAppointmentRequestedCsfTimePercent() != null; salaryPercent = hasRequestedCsfTimePercent ? appointmentFunding.getAppointmentRequestedCsfTimePercent() : BigDecimal.ZERO; } if (salaryAmount > maxSalaryAmount) { maxSalaryAmount = totalsHolder.salaryAmount; totalsHolder.salaryPayMonth = budgetConstructionPosition.getIuPayMonths(); totalsHolder.salaryNormalMonths = salaryMonths; } totalsHolder.salaryAmount += salaryAmount; totalsHolder.salaryPercent = totalsHolder.salaryPercent.add(salaryPercent); BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFunding.getEffectiveCSFTracker(); if (csfTracker == null) { continue; } KualiInteger effectiveCsfAmount = csfTracker.getCsfAmount(); if (effectiveCsfAmount == null || effectiveCsfAmount.isZero()) { continue; } if (effectiveCsfAmount.intValue() > maxCsfAmount) { maxCsfAmount = effectiveCsfAmount.intValue(); } totalsHolder.csfAmount += effectiveCsfAmount.intValue(); totalsHolder.csfPercent = totalsHolder.csfPercent.add(csfTracker.getCsfTimePercent()); // data for previous year, position table has two data, one is for current year and another is for previous year. Integer previousFiscalYear = universityFiscalYear - 1; BudgetConstructionPosition previousYearBudgetConstructionPosition = budgetConstructionReportsServiceHelper.getBudgetConstructionPosition(previousFiscalYear, appointmentFunding); totalsHolder.csfPayMonths = previousYearBudgetConstructionPosition.getIuPayMonths(); totalsHolder.csfNormalMonths = previousYearBudgetConstructionPosition.getIuNormalWorkMonths(); totalsHolder.positionNumber = budgetConstructionPosition.getPositionNumber(); totalsHolder.fiscalYearTag = previousFiscalYear.toString() + ":"; if (!appointmentFunding.isAppointmentFundingDeleteIndicator()) { if (totalsHolder.curToInt <= -1) { totalsHolder.curToInt = appointmentFunding.getAppointmentTotalIntendedAmount().intValue(); } if (totalsHolder.curFteInt <= -1.00) { totalsHolder.curFteInt = appointmentFunding.getAppointmentTotalIntendedFteQuantity().doubleValue(); } } } } // calculate the totals for the given organization protected Collection<BudgetConstructionOrgReasonSummaryReportTotal> calculateOrgTotal(Collection<BudgetConstructionOrgReasonSummaryReportTotal> reasonSummaryTotalPerson, List<BudgetConstructionSalarySocialSecurityNumber> listForCalculateTotalOrg, Map salaryFundingMap) { Collection<BudgetConstructionOrgReasonSummaryReportTotal> returnCollection = new ArrayList<BudgetConstructionOrgReasonSummaryReportTotal>(); for (BudgetConstructionSalarySocialSecurityNumber totalOrgEntry : listForCalculateTotalOrg) { OrganizationTotalHolder totalsHolder = new OrganizationTotalHolder(); for (BudgetConstructionOrgReasonSummaryReportTotal reportTotalPersonEntry : reasonSummaryTotalPerson) { if (isSameSsnEntryForTotalOrg(totalOrgEntry, reportTotalPersonEntry.getBudgetConstructionSalarySocialSecurityNumber())) { if (reportTotalPersonEntry.getPersonCsfAmount() == 0) { totalsHolder.newFte = totalsHolder.newFte.add(reportTotalPersonEntry.getPersonSalaryFte()); totalsHolder.newTotalAmount += reportTotalPersonEntry.getPersonSalaryAmount(); } else { totalsHolder.conTotalBaseAmount += reportTotalPersonEntry.getPersonCsfAmount(); totalsHolder.conFte = totalsHolder.conFte.add(reportTotalPersonEntry.getPersonSalaryFte()); totalsHolder.conTotalRequestAmount += reportTotalPersonEntry.getPersonSalaryAmount(); } } } // calculate average and change if (BigDecimal.ZERO.compareTo(totalsHolder.newFte) != 0) { BigDecimal averageAmount = BudgetConstructionReportHelper.calculateDivide(new BigDecimal(totalsHolder.newTotalAmount), totalsHolder.newFte); totalsHolder.newAverageAmount = BudgetConstructionReportHelper.setDecimalDigit(averageAmount, 0, false).intValue(); } if (BigDecimal.ZERO.compareTo(totalsHolder.conFte) != 0) { BigDecimal averageAmount = BudgetConstructionReportHelper.calculateDivide(new BigDecimal(totalsHolder.conTotalBaseAmount), totalsHolder.conFte); totalsHolder.conAverageBaseAmount = BudgetConstructionReportHelper.setDecimalDigit(averageAmount, 0, false).intValue(); BigDecimal averageRequestAmount = BudgetConstructionReportHelper.calculateDivide(new BigDecimal(totalsHolder.conTotalRequestAmount), totalsHolder.conFte); totalsHolder.conAverageRequestAmount = BudgetConstructionReportHelper.setDecimalDigit(averageRequestAmount, 0, false).intValue(); } totalsHolder.conAveragechange = totalsHolder.conAverageRequestAmount - totalsHolder.conAverageBaseAmount; if (totalsHolder.conAverageBaseAmount != 0) { totalsHolder.conPercentChange = BudgetConstructionReportHelper.calculatePercent(totalsHolder.conAveragechange, totalsHolder.conAverageBaseAmount); } returnCollection.add(this.createReportTotal(totalOrgEntry, totalsHolder)); } return returnCollection; } // create a report total for the given organization with the values in the given total holder protected BudgetConstructionOrgReasonSummaryReportTotal createReportTotal(BudgetConstructionSalarySocialSecurityNumber totalOrgEntry, OrganizationTotalHolder totalsHolder) { BudgetConstructionOrgReasonSummaryReportTotal reportTotal = new BudgetConstructionOrgReasonSummaryReportTotal(); reportTotal.setBudgetConstructionSalarySocialSecurityNumber(totalOrgEntry); reportTotal.setNewFte(totalsHolder.newFte); reportTotal.setNewTotalAmount(totalsHolder.newTotalAmount); reportTotal.setConTotalBaseAmount(totalsHolder.conTotalBaseAmount); reportTotal.setConFte(totalsHolder.conFte); reportTotal.setConTotalRequestAmount(totalsHolder.conTotalRequestAmount); reportTotal.setNewAverageAmount(totalsHolder.newAverageAmount); reportTotal.setConAverageBaseAmount(totalsHolder.conAverageBaseAmount); reportTotal.setConAverageRequestAmount(totalsHolder.conAverageRequestAmount); reportTotal.setConAveragechange(totalsHolder.conAveragechange); reportTotal.setConPercentChange(totalsHolder.conPercentChange); return reportTotal; } // create a report total for the given person with the values in the given total holder protected BudgetConstructionOrgReasonSummaryReportTotal createReportTotal(BudgetConstructionSalarySocialSecurityNumber totalPersonEntry, PersonTotalHolder totalsHolder) { BudgetConstructionOrgReasonSummaryReportTotal reportTotal = new BudgetConstructionOrgReasonSummaryReportTotal(); reportTotal.setBudgetConstructionSalarySocialSecurityNumber(totalPersonEntry); reportTotal.setPersonPositionNumber(totalsHolder.positionNumber); reportTotal.setPersonFiscalYearTag(totalsHolder.fiscalYearTag); reportTotal.setPersonCsfNormalMonths(totalsHolder.csfNormalMonths); reportTotal.setPersonCsfPayMonths(totalsHolder.csfPayMonths); reportTotal.setPersonCsfAmount(totalsHolder.csfAmount); reportTotal.setPersonCsfPercent(totalsHolder.csfPercent); reportTotal.setPersonSalaryNormalMonths(totalsHolder.salaryNormalMonths); reportTotal.setPersonSalaryAmount(totalsHolder.salaryAmount); reportTotal.setPersonSalaryPercent(totalsHolder.salaryPercent); reportTotal.setPersonSalaryFte(BudgetConstructionReportHelper.setDecimalDigit(totalsHolder.salaryFte, 5, false)); reportTotal.setPersonTiFlag(totalsHolder.tiFlag); reportTotal.setPersonAmountChange(totalsHolder.amountChange); reportTotal.setPersonPercentChange(totalsHolder.percentChange); return reportTotal; } // a total holder that contains the totals for a single person protected class PersonTotalHolder { String emplid = StringUtils.EMPTY; String positionNumber = StringUtils.EMPTY; String fiscalYearTag = StringUtils.EMPTY; String tiFlag = StringUtils.EMPTY; Integer csfNormalMonths = 0; Integer csfPayMonths = 0; Integer csfAmount = 0; BigDecimal csfPercent = BigDecimal.ZERO; Integer salaryNormalMonths = 0; Integer salaryPayMonth = 0; Integer salaryAmount = 0; BigDecimal salaryPercent = BigDecimal.ZERO; BigDecimal salaryFte = BigDecimal.ZERO; Integer amountChange = 0; BigDecimal percentChange = BigDecimal.ZERO; int curToInt = -1; double curFteInt = -1.00; } // a total holder that contains the totals for an organization protected class OrganizationTotalHolder { BigDecimal newFte = BigDecimal.ZERO; Integer newTotalAmount = 0; Integer newAverageAmount = 0; BigDecimal conFte = BigDecimal.ZERO; Integer conTotalBaseAmount = 0; Integer conTotalRequestAmount = 0; Integer conAverageBaseAmount = 0; Integer conAverageRequestAmount = 0; Integer conAveragechange = 0; BigDecimal conPercentChange = BigDecimal.ZERO; } /** * builds orderByList for sort order. * * @return returnList */ public List<String> buildOrderByList() { List<String> returnList = new ArrayList<String>(); returnList.add(KFSPropertyConstants.ORGANIZATION_CHART_OF_ACCOUNTS_CODE); returnList.add(KFSPropertyConstants.ORGANIZATION_CODE); returnList.add(KFSPropertyConstants.PERSON_NAME); returnList.add(KFSPropertyConstants.EMPLID); return returnList; } /** * Deletes duplicated entry from list * * @param List list * @return a list that all duplicated entries were deleted */ protected List deleteDuplicated(List list, int mode) { // mode 1 is for getting a list of total object // mode 2 is for getting a list of total account int count = 0; BudgetConstructionSalarySocialSecurityNumber ssnEntry = null; BudgetConstructionSalarySocialSecurityNumber ssnEntryAux = null; List returnList = new ArrayList(); if ((list != null) && (list.size() > 0)) { ssnEntry = (BudgetConstructionSalarySocialSecurityNumber) list.get(count); ssnEntryAux = (BudgetConstructionSalarySocialSecurityNumber) list.get(count); returnList.add(ssnEntry); count++; while (count < list.size()) { ssnEntry = (BudgetConstructionSalarySocialSecurityNumber) list.get(count); switch (mode) { case 1: { if (!isSameSsnEntryForTotalPerson(ssnEntry, ssnEntryAux)) { returnList.add(ssnEntry); ssnEntryAux = ssnEntry; } } case 2: { if (!isSameSsnEntryForTotalOrg(ssnEntry, ssnEntryAux)) { returnList.add(ssnEntry); ssnEntryAux = ssnEntry; } } } count++; } } return returnList; } protected boolean isSameSsnEntryForTotalPerson(BudgetConstructionSalarySocialSecurityNumber firstSsn, BudgetConstructionSalarySocialSecurityNumber secondSsn) { if (firstSsn.getOrganizationChartOfAccountsCode().equals(secondSsn.getOrganizationChartOfAccountsCode()) && firstSsn.getOrganizationCode().equals(secondSsn.getOrganizationCode()) && firstSsn.getEmplid().equals(secondSsn.getEmplid())) { return true; } else { return false; } } protected boolean isSameSsnEntryForTotalOrg(BudgetConstructionSalarySocialSecurityNumber firstSsn, BudgetConstructionSalarySocialSecurityNumber secondSsn) { if (firstSsn.getOrganizationChartOfAccountsCode().equals(secondSsn.getOrganizationChartOfAccountsCode()) && firstSsn.getOrganizationCode().equals(secondSsn.getOrganizationCode())) { return true; } else { return false; } } /** * Sets the budgetConstructionSalarySummaryReportDao attribute value. * * @param budgetConstructionSalarySummaryReportDao The budgetConstructionSalarySummaryReportDao to set. */ public void setBudgetConstructionSalarySummaryReportDao(BudgetConstructionSalarySummaryReportDao budgetConstructionSalarySummaryReportDao) { this.budgetConstructionSalarySummaryReportDao = budgetConstructionSalarySummaryReportDao; } /** * Sets the budgetConstructionOrganizationReportsService attribute value. * * @param budgetConstructionOrganizationReportsService The budgetConstructionOrganizationReportsService to set. */ public void setBudgetConstructionOrganizationReportsService(BudgetConstructionOrganizationReportsService budgetConstructionOrganizationReportsService) { this.budgetConstructionOrganizationReportsService = budgetConstructionOrganizationReportsService; } /** * Sets the budgetConstructionReportsServiceHelper attribute value. * * @param budgetConstructionReportsServiceHelper The budgetConstructionReportsServiceHelper to set. */ public void setBudgetConstructionReportsServiceHelper(BudgetConstructionReportsServiceHelper budgetConstructionReportsServiceHelper) { this.budgetConstructionReportsServiceHelper = budgetConstructionReportsServiceHelper; } /** * Sets the kualiConfigurationService attribute value. * * @param kualiConfigurationService The kualiConfigurationService to set. */ public void setConfigurationService(ConfigurationService kualiConfigurationService) { this.kualiConfigurationService = kualiConfigurationService; } /** * Sets the businessObjectService attribute value. * * @param businessObjectService The businessObjectService to set. */ public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } }