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.document.web.struts;
017    
018    import java.math.BigDecimal;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.kuali.kfs.module.bc.BCPropertyConstants;
023    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAppointmentFundingReason;
024    import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
025    import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
026    import org.kuali.kfs.module.bc.document.service.SalarySettingService;
027    import org.kuali.kfs.module.bc.util.BudgetParameterFinder;
028    import org.kuali.kfs.module.bc.util.SalarySettingCalculator;
029    import org.kuali.kfs.module.bc.util.SalarySettingFieldsHolder;
030    import org.kuali.kfs.sys.DynamicCollectionComparator;
031    import org.kuali.kfs.sys.KFSPropertyConstants;
032    import org.kuali.kfs.sys.ObjectUtil;
033    import org.kuali.kfs.sys.context.SpringContext;
034    import org.kuali.rice.kim.bo.Person;
035    import org.kuali.rice.kns.util.GlobalVariables;
036    import org.kuali.rice.kns.util.KualiDecimal;
037    import org.kuali.rice.kns.util.KualiInteger;
038    import org.kuali.rice.kns.util.ObjectUtils;
039    
040    /**
041     * the base Struts form for salary setting
042     */
043    public abstract class SalarySettingBaseForm extends BudgetExpansionForm {
044        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SalarySettingBaseForm.class);
045    
046        private String documentNumber;
047        private String chartOfAccountsCode;
048        private String accountNumber;
049        private String subAccountNumber;
050        private String financialObjectCode;
051        private String financialSubObjectCode;
052        private String financialBalanceTypeCode;
053        private String financialObjectTypeCode;
054        private SalarySettingFieldsHolder salarySettingFieldsHolder;
055    
056        private boolean hideAdjustmentMeasurement = true;
057        private String adjustmentMeasurement;
058        private KualiDecimal adjustmentAmount;
059    
060        private boolean hideDetails = false;
061    
062        private boolean budgetByAccountMode;
063        private boolean singleAccountMode;
064        private boolean salarySettingClosed;
065    
066        private SalarySettingService salarySettingService = SpringContext.getBean(SalarySettingService.class);
067        private BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
068    
069        private Person person = GlobalVariables.getUserSession().getPerson();
070    
071        /**
072         * get the refresh caller name of the current form
073         * 
074         * @return the refresh caller name of the current form
075         */
076        public abstract String getRefreshCallerName();
077    
078        /**
079         * get the key map for the salary setting item: salary expension, position, or incumbent
080         * 
081         * @return the key map for the salary setting item
082         */
083        public abstract Map<String, Object> getKeyMapOfSalarySettingItem();
084    
085        /**
086         * refresh the the appointment funding lines and make them have connections with associated objects
087         */
088        public void populateBCAFLines() {
089            List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings();
090            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) {
091                this.refreshBCAFLine(appointmentFunding);
092            }
093        }
094    
095        /**
096         * do some operations on the appointment funding lines. The operations may be included updating and sorting. If everything goes
097         * well, return true; otherwise, false
098         */
099        public boolean postProcessBCAFLines() {
100            this.populateBCAFLines();
101    
102            List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings();
103            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) {
104                Integer fiscalYear = appointmentFunding.getUniversityFiscalYear();
105                String chartCode = appointmentFunding.getChartOfAccountsCode();
106                String objectCode = appointmentFunding.getFinancialObjectCode();
107    
108                boolean vacatable = salarySettingService.canBeVacant(appointmentFundings, appointmentFunding);
109                appointmentFunding.setVacatable(vacatable);
110    
111                boolean budgetable = budgetDocumentService.isAssociatedWithBudgetableDocument(appointmentFunding);
112                appointmentFunding.setBudgetable(budgetable);
113    
114                boolean hourlyPaid = salarySettingService.isHourlyPaidObject(fiscalYear, chartCode, objectCode);
115                appointmentFunding.setHourlyPaid(hourlyPaid);
116            }
117    
118            DynamicCollectionComparator.sort(appointmentFundings, KFSPropertyConstants.POSITION_NUMBER, KFSPropertyConstants.EMPLID);
119            return true;
120        }
121    
122        /**
123         * Populates the dependent fields of objects contained within the BCAF line
124         */
125        public void refreshBCAFLine(PendingBudgetConstructionAppointmentFunding appointmentFunding) {
126            appointmentFunding.refreshNonUpdateableReferences();
127            ObjectUtils.materializeObjects(appointmentFunding.getBudgetConstructionAppointmentFundingReason());
128            appointmentFunding.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
129            appointmentFunding.refreshReferenceObject(KFSPropertyConstants.SUB_ACCOUNT);
130            appointmentFunding.refreshReferenceObject(BCPropertyConstants.BUDGET_CONSTRUCTION_CALCULATED_SALARY_FOUNDATION_TRACKER);
131            this.applyDefaultReasonAmountIfEmpty(appointmentFunding);
132        }
133    
134        /**
135         * apply default reason amount of zero if the reason code is set and the amount is null
136         * adds a blank row place holder if no reason rows, to be optionally filled in by the user
137         * 
138         * @param appointmentFunding
139         */
140        public void applyDefaultReasonAmountIfEmpty (PendingBudgetConstructionAppointmentFunding appointmentFunding){
141            if (!appointmentFunding.getBudgetConstructionAppointmentFundingReason().isEmpty()){
142                BudgetConstructionAppointmentFundingReason afReason = appointmentFunding.getBudgetConstructionAppointmentFundingReason().get(0);
143                if (ObjectUtils.isNotNull(afReason)){
144                    if (afReason.getAppointmentFundingReasonAmount() == null){
145                        afReason.setAppointmentFundingReasonAmount(KualiInteger.ZERO);
146                    }
147                    if (afReason.getAppointmentFundingReasonCode() != null){
148                        afReason.refreshReferenceObject(BCPropertyConstants.APPOINTMENT_FUNDING_REASON);
149                    }
150                }
151            }
152            else {
153                appointmentFunding.getBudgetConstructionAppointmentFundingReason().add(new BudgetConstructionAppointmentFundingReason());
154            }
155        }
156        /**
157         * Gets the documentNumber attribute.
158         * 
159         * @return Returns the documentNumber.
160         */
161        public String getDocumentNumber() {
162            return documentNumber;
163        }
164    
165        /**
166         * Sets the documentNumber attribute value.
167         * 
168         * @param documentNumber The documentNumber to set.
169         */
170        public void setDocumentNumber(String documentNumber) {
171            this.documentNumber = documentNumber;
172        }
173    
174        /**
175         * Gets the chartOfAccountsCode attribute.
176         * 
177         * @return Returns the chartOfAccountsCode.
178         */
179        public String getChartOfAccountsCode() {
180            return chartOfAccountsCode;
181        }
182    
183        /**
184         * Sets the chartOfAccountsCode attribute value.
185         * 
186         * @param chartOfAccountsCode The chartOfAccountsCode to set.
187         */
188        public void setChartOfAccountsCode(String chartOfAccountsCode) {
189            this.chartOfAccountsCode = chartOfAccountsCode;
190        }
191    
192        /**
193         * Gets the accountNumber attribute.
194         * 
195         * @return Returns the accountNumber.
196         */
197        public String getAccountNumber() {
198            return accountNumber;
199        }
200    
201        /**
202         * Sets the accountNumber attribute value.
203         * 
204         * @param accountNumber The accountNumber to set.
205         */
206        public void setAccountNumber(String accountNumber) {
207            this.accountNumber = accountNumber;
208        }
209    
210        /**
211         * Gets the subAccountNumber attribute.
212         * 
213         * @return Returns the subAccountNumber.
214         */
215        public String getSubAccountNumber() {
216            return subAccountNumber;
217        }
218    
219        /**
220         * Sets the subAccountNumber attribute value.
221         * 
222         * @param subAccountNumber The subAccountNumber to set.
223         */
224        public void setSubAccountNumber(String subAccountNumber) {
225            this.subAccountNumber = subAccountNumber;
226        }
227    
228        /**
229         * Gets the financialObjectCode attribute.
230         * 
231         * @return Returns the financialObjectCode.
232         */
233        public String getFinancialObjectCode() {
234            return financialObjectCode;
235        }
236    
237        /**
238         * Sets the financialObjectCode attribute value.
239         * 
240         * @param financialObjectCode The financialObjectCode to set.
241         */
242        public void setFinancialObjectCode(String financialObjectCode) {
243            this.financialObjectCode = financialObjectCode;
244        }
245    
246        /**
247         * Gets the financialSubObjectCode attribute.
248         * 
249         * @return Returns the financialSubObjectCode.
250         */
251        public String getFinancialSubObjectCode() {
252            return financialSubObjectCode;
253        }
254    
255        /**
256         * Sets the financialSubObjectCode attribute value.
257         * 
258         * @param financialSubObjectCode The financialSubObjectCode to set.
259         */
260        public void setFinancialSubObjectCode(String financialSubObjectCode) {
261            this.financialSubObjectCode = financialSubObjectCode;
262        }
263    
264        /**
265         * Gets the financialBalanceTypeCode attribute.
266         * 
267         * @return Returns the financialBalanceTypeCode.
268         */
269        public String getFinancialBalanceTypeCode() {
270            return financialBalanceTypeCode;
271        }
272    
273        /**
274         * Sets the financialBalanceTypeCode attribute value.
275         * 
276         * @param financialBalanceTypeCode The financialBalanceTypeCode to set.
277         */
278        public void setFinancialBalanceTypeCode(String financialBalanceTypeCode) {
279            this.financialBalanceTypeCode = financialBalanceTypeCode;
280        }
281    
282        /**
283         * Gets the financialObjectTypeCode attribute.
284         * 
285         * @return Returns the financialObjectTypeCode.
286         */
287        public String getFinancialObjectTypeCode() {
288            return financialObjectTypeCode;
289        }
290    
291        /**
292         * Sets the financialObjectTypeCode attribute value.
293         * 
294         * @param financialObjectTypeCode The financialObjectTypeCode to set.
295         */
296        public void setFinancialObjectTypeCode(String financialObjectTypeCode) {
297            this.financialObjectTypeCode = financialObjectTypeCode;
298        }
299    
300        /**
301         * Gets the hideAdjustmentMeasurement attribute.
302         * 
303         * @return Returns the hideAdjustmentMeasurement.
304         */
305        public boolean isHideAdjustmentMeasurement() {
306            return hideAdjustmentMeasurement;
307        }
308    
309        /**
310         * Sets the hideAdjustmentMeasurement attribute value.
311         * 
312         * @param hideAdjustmentMeasurement The hideAdjustmentMeasurement to set.
313         */
314        public void setHideAdjustmentMeasurement(boolean hideAdjustmentMeasurement) {
315            this.hideAdjustmentMeasurement = hideAdjustmentMeasurement;
316        }
317    
318        /**
319         * Gets the adjustmentMeasurement attribute.
320         * 
321         * @return Returns the adjustmentMeasurement.
322         */
323        public String getAdjustmentMeasurement() {
324            return adjustmentMeasurement;
325        }
326    
327        /**
328         * Sets the adjustmentMeasurement attribute value.
329         * 
330         * @param adjustmentMeasurement The adjustmentMeasurement to set.
331         */
332        public void setAdjustmentMeasurement(String adjustmentMeasurement) {
333            this.adjustmentMeasurement = adjustmentMeasurement;
334        }
335    
336        /**
337         * Gets the adjustmentAmount attribute.
338         * 
339         * @return Returns the adjustmentAmount.
340         */
341        public KualiDecimal getAdjustmentAmount() {
342            return adjustmentAmount;
343        }
344    
345        /**
346         * Sets the adjustmentAmount attribute value.
347         * 
348         * @param adjustmentAmount The adjustmentAmount to set.
349         */
350        public void setAdjustmentAmount(KualiDecimal adjustmentAmount) {
351            this.adjustmentAmount = adjustmentAmount;
352        }
353    
354        /**
355         * Gets the hideDetails attribute.
356         * 
357         * @return Returns the hideDetails.
358         */
359        public boolean isHideDetails() {
360            return hideDetails;
361        }
362    
363        /**
364         * Sets the hideDetails attribute value.
365         * 
366         * @param hideDetails The hideDetails to set.
367         */
368        public void setHideDetails(boolean hideDetails) {
369            this.hideDetails = hideDetails;
370        }
371    
372        /**
373         * Gets the budgetByAccountMode attribute.
374         * 
375         * @return Returns the budgetByAccountMode.
376         */
377        public boolean isBudgetByAccountMode() {
378            return budgetByAccountMode;
379        }
380    
381        /**
382         * Sets the budgetByAccountMode attribute value.
383         * 
384         * @param budgetByAccountMode The budgetByAccountMode to set.
385         */
386        public void setBudgetByAccountMode(boolean budgetByAccountMode) {
387            this.budgetByAccountMode = budgetByAccountMode;
388        }
389    
390        /**
391         * Gets the singleAccountMode attribute.
392         * 
393         * @return Returns the singleAccountMode.
394         */
395        public boolean isSingleAccountMode() {
396            return singleAccountMode;
397        }
398    
399        /**
400         * Sets the singleAccountMode attribute value.
401         * 
402         * @param singleAccountMode The singleAccountMode to set.
403         */
404        public void setSingleAccountMode(boolean singleAccountMode) {
405            this.singleAccountMode = singleAccountMode;
406        }
407    
408        /**
409         * Gets the appointmentFundings attribute.
410         * 
411         * @return Returns the appointmentFundings.
412         */
413        public abstract List<PendingBudgetConstructionAppointmentFunding> getAppointmentFundings();
414    
415        /**
416         * Gets the appointmentRequestedCsfAmountTotal.
417         * 
418         * @return Returns the appointmentRequestedCsfAmountTotal.
419         */
420        public KualiInteger getAppointmentRequestedCsfAmountTotal() {
421            return SalarySettingCalculator.getAppointmentRequestedCsfAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
422        }
423    
424        /**
425         * Gets the appointmentRequestedCsfTimePercentTotal.
426         * 
427         * @return Returns the appointmentRequestedCsfTimePercentTotal.
428         */
429        public BigDecimal getAppointmentRequestedCsfTimePercentTotal() {
430            return SalarySettingCalculator.getAppointmentRequestedCsfTimePercentTotal(this.getAppointmentFundings());
431        }
432    
433        /**
434         * Gets the appointmentRequestedCsfStandardHoursTotal.
435         * 
436         * @return Returns the appointmentRequestedCsfStandardHoursTotal.
437         */
438        public BigDecimal getAppointmentRequestedCsfStandardHoursTotal() {
439            return SalarySettingCalculator.getAppointmentRequestedCsfStandardHoursTotal(this.getAppointmentFundings());
440        }
441    
442        /**
443         * Gets the appointmentRequestedCsfFteQuantityTotal.
444         * 
445         * @return Returns the appointmentRequestedCsfFteQuantityTotal.
446         */
447        public BigDecimal getAppointmentRequestedCsfFteQuantityTotal() {
448            return SalarySettingCalculator.getAppointmentRequestedCsfFteQuantityTotal(this.getAppointmentFundings());
449        }
450    
451        /**
452         * Gets the appointmentRequestedAmountTotal.
453         * 
454         * @return Returns the appointmentRequestedAmountTotal.
455         */
456        public KualiInteger getAppointmentRequestedAmountTotal() {
457            return SalarySettingCalculator.getAppointmentRequestedAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
458        }
459    
460        /**
461         * Gets the appointmentRequestedTimePercentTotal.
462         * 
463         * @return Returns the appointmentRequestedTimePercentTotal.
464         */
465        public BigDecimal getAppointmentRequestedTimePercentTotal() {
466            return SalarySettingCalculator.getAppointmentRequestedTimePercentTotal(this.getAppointmentFundings());
467        }
468    
469        /**
470         * Gets the appointmentRequestedStandardHoursTotal.
471         * 
472         * @return Returns the appointmentRequestedStandardHoursTotal.
473         */
474        public BigDecimal getAppointmentRequestedStandardHoursTotal() {
475            return SalarySettingCalculator.getAppointmentRequestedStandardHoursTotal(this.getAppointmentFundings());
476        }
477    
478        /**
479         * Gets the appointmentRequestedFteQuantityTotal.
480         * 
481         * @return Returns the appointmentRequestedFteQuantityTotal.
482         */
483        public BigDecimal getAppointmentRequestedFteQuantityTotal() {
484            return SalarySettingCalculator.getAppointmentRequestedFteQuantityTotal(this.getAppointmentFundings());
485        }
486    
487        /**
488         * Gets the csfAmountTotal.
489         * 
490         * @return Returns the csfAmountTotal.
491         */
492        public KualiInteger getCsfAmountTotal() {
493            return SalarySettingCalculator.getCsfAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
494        }
495    
496        /**
497         * Gets the csfTimePercentTotal.
498         * 
499         * @return Returns the csfTimePercentTotal.
500         */
501        public BigDecimal getCsfTimePercentTotal() {
502            return SalarySettingCalculator.getCsfTimePercentTotal(this.getAppointmentFundings());
503        }
504    
505        /**
506         * Gets the csfStandardHoursTotal.
507         * 
508         * @return Returns the csfStandardHoursTotal.
509         */
510        public BigDecimal getCsfStandardHoursTotal() {
511            return SalarySettingCalculator.getCsfStandardHoursTotal(this.getAppointmentFundings());
512        }
513    
514        /**
515         * Gets the csfFullTimeEmploymentQuantityTotal.
516         * 
517         * @return Returns the csfFullTimeEmploymentQuantityTotal.
518         */
519        public BigDecimal getCsfFullTimeEmploymentQuantityTotal() {
520            return SalarySettingCalculator.getCsfFullTimeEmploymentQuantityTotal(this.getAppointmentFundings());
521        }
522    
523        /**
524         * Gets the percentChangeTotal attribute.
525         * 
526         * @return Returns the percentChangeTotal.
527         */
528        public KualiDecimal getPercentChangeTotal() {
529            KualiInteger csfAmountTotal = this.getCsfAmountTotal();
530            KualiInteger requestedAmountTotal = this.getAppointmentRequestedAmountTotal();
531    
532            return SalarySettingCalculator.getPercentChange(csfAmountTotal, requestedAmountTotal);
533        }
534    
535        /**
536         * Gets the EffectivePendingBudgetConstructionAppointmentFunding.
537         * 
538         * @return Returns the EffectivePendingBudgetConstructionAppointmentFunding.
539         */
540        public List<PendingBudgetConstructionAppointmentFunding> getEffectivePendingBudgetConstructionAppointmentFunding() {
541            return SalarySettingCalculator.getEffectiveAppointmentFundings(this.getAppointmentFundings());
542        }
543    
544        /**
545         * Gets the salarySettingFieldsHolder attribute.
546         * 
547         * @return Returns the salarySettingFieldsHolder.
548         */
549        public SalarySettingFieldsHolder getSalarySettingFieldsHolder() {
550            if (salarySettingFieldsHolder == null) {
551                salarySettingFieldsHolder = new SalarySettingFieldsHolder();
552                ObjectUtil.buildObject(salarySettingFieldsHolder, this);
553            }
554    
555            return salarySettingFieldsHolder;
556        }
557    
558        /**
559         * Gets the person attribute.
560         * 
561         * @return Returns the person.
562         */
563        public Person getPerson() {
564            return person;
565        }
566    
567        /**
568         * Gets the salarySettingClosed attribute.
569         * 
570         * @return Returns the salarySettingClosed.
571         */
572        public boolean isSalarySettingClosed() {
573            return salarySettingClosed;
574        }
575    
576        /**
577         * Sets the salarySettingClosed attribute value.
578         * 
579         * @param salarySettingClosed The salarySettingClosed to set.
580         */
581        public void setSalarySettingClosed(boolean salarySettingClosed) {
582            this.salarySettingClosed = salarySettingClosed;
583        }
584    
585        /**
586         * Gets the viewOnlyEntry attribute. System view only trumps all, overriding methods should call this first and check the
587         * results for !viewOnly before continuing.
588         * 
589         * @return Returns the viewOnlyEntry.
590         */
591        public boolean isViewOnlyEntry() {
592            return isSystemViewOnly();
593        }
594    
595        /**
596         * Gets the payrollIncumbentFeedIndictor attribute.
597         * 
598         * @return Returns the payrollIncumbentFeedIndictor.
599         */
600        public boolean isPayrollIncumbentFeedIndictor() {
601            return BudgetParameterFinder.getPayrollIncumbentFeedIndictor();
602        }
603    
604        /**
605         * Gets the payrollPositionFeedIndicator attribute.
606         * 
607         * @return Returns the payrollPositionFeedIndicator.
608         */
609        public boolean isPayrollPositionFeedIndicator() {
610            return BudgetParameterFinder.getPayrollPositionFeedIndicator();
611        }
612    }