001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.module.bc.util;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    import org.kuali.kfs.module.bc.BCConstants;
023    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionCalculatedSalaryFoundationTracker;
024    import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
025    import org.kuali.kfs.sys.KFSConstants;
026    import org.kuali.rice.kns.util.KualiDecimal;
027    import org.kuali.rice.kns.util.KualiInteger;
028    
029    public class SalarySettingCalculator {
030        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SalarySettingCalculator.class);
031    
032        /**
033         * calculate the standard working hours through the given time percent
034         * 
035         * @param timePercent the given time percent
036         * @return the standard working hour calculated from the given time percent
037         */
038        public static BigDecimal getStandarHours(BigDecimal timePercent) {
039            BigDecimal standarHours = timePercent.multiply(BudgetParameterFinder.getWeeklyWorkingHoursAsDecimal()).divide(BCConstants.ONE_HUNDRED, 2, KualiDecimal.ROUND_BEHAVIOR);
040            return standarHours;
041        }
042    
043        /**
044         * calcaulte the total requested csf amount for the given appointment funding lines
045         * 
046         * @param AppointmentFundings the given appointment funding lines
047         * @return the total requested csf amount for the given appointment funding lines
048         */
049        public static KualiInteger getAppointmentRequestedCsfAmountTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
050            KualiInteger appointmentRequestedCsfAmountTotal = KualiInteger.ZERO;
051    
052            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
053                KualiInteger requestedCsfAmount = appointmentFunding.getAppointmentRequestedCsfAmount();
054    
055                if (requestedCsfAmount != null) {
056                    appointmentRequestedCsfAmountTotal = appointmentRequestedCsfAmountTotal.add(requestedCsfAmount);
057                }
058            }
059    
060            return appointmentRequestedCsfAmountTotal;
061        }
062    
063        /**
064         * calcaulte the total requested csf time percent for the given appointment funding lines
065         * 
066         * @param AppointmentFundings the given appointment funding lines
067         * @return the total requested csf time percent for the given appointment funding lines
068         */
069        public static BigDecimal getAppointmentRequestedCsfTimePercentTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
070            BigDecimal appointmentRequestedCsfTimePercentTotal = BigDecimal.ZERO;
071    
072            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
073                BigDecimal requestedCsfTimePercent = appointmentFunding.getAppointmentRequestedCsfTimePercent();
074    
075                if (requestedCsfTimePercent != null) {
076                    appointmentRequestedCsfTimePercentTotal = appointmentRequestedCsfTimePercentTotal.add(requestedCsfTimePercent);
077                }
078            }
079    
080            return appointmentRequestedCsfTimePercentTotal;
081        }
082    
083        /**
084         * calcaulte the total requested csf standard hours for the given appointment funding lines
085         * 
086         * @param AppointmentFundings the given appointment funding lines
087         * @return the total requested csf standard hours for the given appointment funding lines
088         */
089        public static BigDecimal getAppointmentRequestedCsfStandardHoursTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
090            return getStandarHours(getAppointmentRequestedCsfTimePercentTotal(AppointmentFundings));
091        }
092    
093        /**
094         * calcaulte the total requested csf full time employee quantity for the given appointment funding lines
095         * 
096         * @param AppointmentFundings the given appointment funding lines
097         * @return the total requested csf full time employee quantity for the given appointment funding lines
098         */
099        public static BigDecimal getAppointmentRequestedCsfFteQuantityTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
100            BigDecimal appointmentRequestedCsfFteQuantityTotal = BigDecimal.ZERO;
101    
102            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
103                BigDecimal requestedCsfFteQuantity = appointmentFunding.getAppointmentRequestedCsfFteQuantity();
104    
105                if (requestedCsfFteQuantity != null) {
106                    appointmentRequestedCsfFteQuantityTotal = appointmentRequestedCsfFteQuantityTotal.add(requestedCsfFteQuantity);
107                }
108            }
109    
110            return appointmentRequestedCsfFteQuantityTotal;
111        }
112    
113        /**
114         * calcaulte the total requested amount for the given appointment funding lines
115         * 
116         * @param AppointmentFundings the given appointment funding lines
117         * @return the total requested amount for the given appointment funding lines
118         */
119        public static KualiInteger getAppointmentRequestedAmountTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
120            KualiInteger appointmentRequestedAmountTotal = KualiInteger.ZERO;
121    
122            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
123                KualiInteger requestedAmount = appointmentFunding.getAppointmentRequestedAmount();
124    
125                if (requestedAmount != null) {
126                    appointmentRequestedAmountTotal = appointmentRequestedAmountTotal.add(requestedAmount);
127                }
128            }
129            return appointmentRequestedAmountTotal;
130        }
131    
132        /**
133         * calcaulte the total requested time percent for the given appointment funding lines
134         * 
135         * @param AppointmentFundings the given appointment funding lines
136         * @return the total requested time percent for the given appointment funding lines
137         */
138        public static BigDecimal getAppointmentRequestedTimePercentTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
139            BigDecimal appointmentRequestedTimePercentTotal = BigDecimal.ZERO;
140    
141            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
142                BigDecimal requestedTimePercent = appointmentFunding.getAppointmentRequestedTimePercent();
143    
144                if (requestedTimePercent != null) {
145                    appointmentRequestedTimePercentTotal = appointmentRequestedTimePercentTotal.add(requestedTimePercent);
146                }
147            }
148            return appointmentRequestedTimePercentTotal;
149        }
150    
151        /**
152         * calcaulte the total requested standard hours for the given appointment funding lines
153         * 
154         * @param AppointmentFundings the given appointment funding lines
155         * @return the total requested standard hours for the given appointment funding lines
156         */
157        public static BigDecimal getAppointmentRequestedStandardHoursTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
158            return getStandarHours(getAppointmentRequestedTimePercentTotal(AppointmentFundings));
159        }
160    
161        /**
162         * calcaulte the total requested full time employee quantity for the given appointment funding lines
163         * 
164         * @param AppointmentFundings the given appointment funding lines
165         * @return the total requested full time employee quantity for the given appointment funding lines
166         */
167        public static BigDecimal getAppointmentRequestedFteQuantityTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
168            BigDecimal appointmentRequestedFteQuantityTotal = BigDecimal.ZERO;
169    
170            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
171                BigDecimal requestedFteQuantity = appointmentFunding.getAppointmentRequestedFteQuantity();
172    
173                if (requestedFteQuantity != null) {
174                    appointmentRequestedFteQuantityTotal = appointmentRequestedFteQuantityTotal.add(requestedFteQuantity);
175                }
176            }
177            return appointmentRequestedFteQuantityTotal;
178        }
179    
180        /**
181         * calcaulte the total csf amount for the given appointment funding lines
182         * 
183         * @param AppointmentFundings the given appointment funding lines
184         * @return the total csf amount for the given appointment funding lines
185         */
186        public static KualiInteger getCsfAmountTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
187            KualiInteger csfAmountTotal = KualiInteger.ZERO;
188    
189            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
190                BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFunding.getEffectiveCSFTracker();
191    
192                if (csfTracker != null && csfTracker.getCsfAmount() != null) {
193                    csfAmountTotal = csfAmountTotal.add(csfTracker.getCsfAmount());
194                }
195            }
196            return csfAmountTotal;
197        }
198    
199        /**
200         * calcaulte the total csf time percent for the given appointment funding lines
201         * 
202         * @param AppointmentFundings the given appointment funding lines
203         * @return the total csf time percent for the given appointment funding lines
204         */
205        public static BigDecimal getCsfTimePercentTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
206            BigDecimal csfTimePercentTotal = BigDecimal.ZERO;
207    
208            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
209                BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFunding.getEffectiveCSFTracker();
210    
211                if (csfTracker != null && csfTracker.getCsfTimePercent() != null) {
212                    csfTimePercentTotal = csfTimePercentTotal.add(csfTracker.getCsfTimePercent());
213                }
214            }
215            return csfTimePercentTotal;
216        }
217    
218        /**
219         * calcaulte the total csf standard hours for the given appointment funding lines
220         * 
221         * @param AppointmentFundings the given appointment funding lines
222         * @return the total csf standard hours for the given appointment funding lines
223         */
224        public static BigDecimal getCsfStandardHoursTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
225            return getStandarHours(getCsfTimePercentTotal(AppointmentFundings));
226        }
227    
228        /**
229         * calcaulte the total csf full time employee quantity for the given appointment funding lines
230         * 
231         * @param AppointmentFundings the given appointment funding lines
232         * @return the total csf full time employee quantity for the given appointment funding lines
233         */
234        public static BigDecimal getCsfFullTimeEmploymentQuantityTotal(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
235            BigDecimal csfFullTimeEmploymentQuantityTotal = BigDecimal.ZERO;
236    
237            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
238                BudgetConstructionCalculatedSalaryFoundationTracker csfTracker = appointmentFunding.getEffectiveCSFTracker();
239    
240                if (csfTracker != null && csfTracker.getCsfFullTimeEmploymentQuantity() != null) {
241                    csfFullTimeEmploymentQuantityTotal = csfFullTimeEmploymentQuantityTotal.add(csfTracker.getCsfFullTimeEmploymentQuantity());
242                }
243            }
244            return csfFullTimeEmploymentQuantityTotal;
245        }
246    
247        /**
248         * Get a collection of PendingBudgetConstructionAppointmentFunding objects that are not purged and not excluded from total. This
249         * is used to decide whether or not to include csf, request or requestCsf amounts in the totals. This allows marked deleted line
250         * in the set, but this is benign since marked deleted lines have zero request and requestCsf amounts by definition and we want
251         * marked delete csf amounts included in the totals.
252         * 
253         * @param AppointmentFundings the given appointment funding lines
254         * @return a collection of PendingBudgetConstructionAppointmentFunding objects that are not marked as deleted
255         */
256        public static List<PendingBudgetConstructionAppointmentFunding> getEffectiveAppointmentFundings(List<PendingBudgetConstructionAppointmentFunding> AppointmentFundings) {
257            List<PendingBudgetConstructionAppointmentFunding> effectiveAppointmentFundings = new ArrayList<PendingBudgetConstructionAppointmentFunding>();
258    
259            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : AppointmentFundings) {
260                // if (!appointmentFunding.isAppointmentFundingDeleteIndicator() && !appointmentFunding.isExcludedFromTotal() &&
261                // !appointmentFunding.isPurged()) {
262                if (!appointmentFunding.isExcludedFromTotal() && !appointmentFunding.isPurged()) {
263                    effectiveAppointmentFundings.add(appointmentFunding);
264                }
265            }
266    
267            return effectiveAppointmentFundings;
268        }
269    
270        /**
271         * calculate the changing percent between the requested amount and the base amount
272         * 
273         * @param baseAmount the given base amount
274         * @param requestedAmount the requested amount
275         * @return the changing percent between the requested amount and the base amount if both of amounts are numbers; otherwise,
276         *         return null
277         */
278        public static KualiDecimal getPercentChange(KualiInteger baseAmount, KualiInteger requestedAmount) {
279            KualiDecimal percentChange = null;
280    
281            if (requestedAmount != null && baseAmount != null && baseAmount.isNonZero()) {
282                KualiInteger difference = requestedAmount.subtract(baseAmount);
283                BigDecimal percentChangeAsBigDecimal = difference.multiply(KFSConstants.ONE_HUNDRED).divide(baseAmount);
284    
285                percentChange = new KualiDecimal(percentChangeAsBigDecimal);
286            }
287    
288            return percentChange;
289        }
290    }