View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.module.bc.document.web.struts;
20  
21  import java.math.BigDecimal;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.kuali.kfs.module.bc.BCPropertyConstants;
26  import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAppointmentFundingReason;
27  import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
28  import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
29  import org.kuali.kfs.module.bc.document.service.SalarySettingService;
30  import org.kuali.kfs.module.bc.util.BudgetParameterFinder;
31  import org.kuali.kfs.module.bc.util.SalarySettingCalculator;
32  import org.kuali.kfs.module.bc.util.SalarySettingFieldsHolder;
33  import org.kuali.kfs.sys.DynamicCollectionComparator;
34  import org.kuali.kfs.sys.KFSConstants;
35  import org.kuali.kfs.sys.KFSPropertyConstants;
36  import org.kuali.kfs.sys.ObjectUtil;
37  import org.kuali.kfs.sys.context.SpringContext;
38  import org.kuali.rice.core.api.util.type.KualiDecimal;
39  import org.kuali.rice.core.api.util.type.KualiInteger;
40  import org.kuali.rice.kim.api.identity.Person;
41  import org.kuali.rice.krad.util.GlobalVariables;
42  import org.kuali.rice.krad.util.ObjectUtils;
43  
44  /**
45   * the base Struts form for salary setting
46   */
47  public abstract class SalarySettingBaseForm extends BudgetExpansionForm {
48      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SalarySettingBaseForm.class);
49  
50      private String documentNumber;
51      private String chartOfAccountsCode;
52      private String accountNumber;
53      private String subAccountNumber;
54      private String financialObjectCode;
55      private String financialSubObjectCode;
56      private String financialBalanceTypeCode;
57      private String financialObjectTypeCode;
58      private SalarySettingFieldsHolder salarySettingFieldsHolder;
59  
60      private boolean hideAdjustmentMeasurement = true;
61      private String adjustmentMeasurement;
62      private KualiDecimal adjustmentAmount;
63  
64      private boolean hideDetails = false;
65  
66      private boolean budgetByAccountMode;
67      private boolean singleAccountMode;
68      private boolean salarySettingClosed;
69  
70      private SalarySettingService salarySettingService = SpringContext.getBean(SalarySettingService.class);
71      private BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class);
72  
73      private Person person = GlobalVariables.getUserSession().getPerson();
74  
75      protected String dashSubAccountNumber;
76      protected String dashFinancialSubObjectCode;
77  
78      public SalarySettingBaseForm() {
79          super();
80  
81          this.setDashFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
82          this.setDashSubAccountNumber(KFSConstants.getDashSubAccountNumber());
83      }
84  
85      /**
86       * get the refresh caller name of the current form
87       *
88       * @return the refresh caller name of the current form
89       */
90      public abstract String getRefreshCallerName();
91  
92      /**
93       * get the key map for the salary setting item: salary expension, position, or incumbent
94       *
95       * @return the key map for the salary setting item
96       */
97      public abstract Map<String, Object> getKeyMapOfSalarySettingItem();
98  
99      /**
100      * refresh the the appointment funding lines and make them have connections with associated objects
101      */
102     public void populateBCAFLines() {
103         List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings();
104         for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) {
105             this.refreshBCAFLine(appointmentFunding);
106         }
107     }
108 
109     /**
110      * do some operations on the appointment funding lines. The operations may be included updating and sorting. If everything goes
111      * well, return true; otherwise, false
112      */
113     public boolean postProcessBCAFLines() {
114         this.populateBCAFLines();
115 
116         List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings();
117         for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) {
118             Integer fiscalYear = appointmentFunding.getUniversityFiscalYear();
119             String chartCode = appointmentFunding.getChartOfAccountsCode();
120             String objectCode = appointmentFunding.getFinancialObjectCode();
121 
122             boolean vacatable = salarySettingService.canBeVacant(appointmentFundings, appointmentFunding);
123             appointmentFunding.setVacatable(vacatable);
124 
125             boolean budgetable = budgetDocumentService.isAssociatedWithBudgetableDocument(appointmentFunding);
126             appointmentFunding.setBudgetable(budgetable);
127 
128             boolean hourlyPaid = salarySettingService.isHourlyPaidObject(fiscalYear, chartCode, objectCode);
129             appointmentFunding.setHourlyPaid(hourlyPaid);
130         }
131 
132         DynamicCollectionComparator.sort(appointmentFundings, KFSPropertyConstants.POSITION_NUMBER, KFSPropertyConstants.EMPLID);
133         return true;
134     }
135 
136     /**
137      * Populates the dependent fields of objects contained within the BCAF line
138      */
139     public void refreshBCAFLine(PendingBudgetConstructionAppointmentFunding appointmentFunding) {
140         appointmentFunding.refreshNonUpdateableReferences();
141         ObjectUtils.materializeObjects(appointmentFunding.getBudgetConstructionAppointmentFundingReason());
142         appointmentFunding.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
143         appointmentFunding.refreshReferenceObject(KFSPropertyConstants.SUB_ACCOUNT);
144         appointmentFunding.refreshReferenceObject(BCPropertyConstants.BUDGET_CONSTRUCTION_CALCULATED_SALARY_FOUNDATION_TRACKER);
145         this.applyDefaultReasonAmountIfEmpty(appointmentFunding);
146         this.applyDefaultTotalIntendedAmountIfEmpty(appointmentFunding);
147     }
148 
149     /**
150      * apply default reason amount of zero if the reason code is set and the amount is null
151      * adds a blank row place holder if no reason rows, to be optionally filled in by the user
152      *
153      * @param appointmentFunding
154      */
155     public void applyDefaultReasonAmountIfEmpty (PendingBudgetConstructionAppointmentFunding appointmentFunding){
156         if (!appointmentFunding.getBudgetConstructionAppointmentFundingReason().isEmpty()){
157             BudgetConstructionAppointmentFundingReason afReason = appointmentFunding.getBudgetConstructionAppointmentFundingReason().get(0);
158             if (ObjectUtils.isNotNull(afReason)){
159                 if (afReason.getAppointmentFundingReasonAmount() == null){
160                     afReason.setAppointmentFundingReasonAmount(KualiInteger.ZERO);
161                 }
162                 if (afReason.getAppointmentFundingReasonCode() != null){
163                     afReason.refreshReferenceObject(BCPropertyConstants.APPOINTMENT_FUNDING_REASON);
164                 }
165             }
166         }
167         else {
168             appointmentFunding.getBudgetConstructionAppointmentFundingReason().add(new BudgetConstructionAppointmentFundingReason());
169         }
170     }
171 
172     /**
173      * apply total intended amount and fte of zero when field is blank
174      *
175      * @param appointmentFunding
176      */
177     public void applyDefaultTotalIntendedAmountIfEmpty (PendingBudgetConstructionAppointmentFunding appointmentFunding){
178         if (appointmentFunding.getAppointmentTotalIntendedAmount() == null){
179             appointmentFunding.setAppointmentTotalIntendedAmount(KualiInteger.ZERO);
180         }
181         if (appointmentFunding.getAppointmentTotalIntendedFteQuantity() == null){
182             appointmentFunding.setAppointmentTotalIntendedFteQuantity(BigDecimal.ZERO);
183         }
184     }
185 
186     /**
187      * Gets the documentNumber attribute.
188      *
189      * @return Returns the documentNumber.
190      */
191     public String getDocumentNumber() {
192         return documentNumber;
193     }
194 
195     /**
196      * Sets the documentNumber attribute value.
197      *
198      * @param documentNumber The documentNumber to set.
199      */
200     public void setDocumentNumber(String documentNumber) {
201         this.documentNumber = documentNumber;
202     }
203 
204     /**
205      * Gets the chartOfAccountsCode attribute.
206      *
207      * @return Returns the chartOfAccountsCode.
208      */
209     public String getChartOfAccountsCode() {
210         return chartOfAccountsCode;
211     }
212 
213     /**
214      * Sets the chartOfAccountsCode attribute value.
215      *
216      * @param chartOfAccountsCode The chartOfAccountsCode to set.
217      */
218     public void setChartOfAccountsCode(String chartOfAccountsCode) {
219         this.chartOfAccountsCode = chartOfAccountsCode;
220     }
221 
222     /**
223      * Gets the accountNumber attribute.
224      *
225      * @return Returns the accountNumber.
226      */
227     public String getAccountNumber() {
228         return accountNumber;
229     }
230 
231     /**
232      * Sets the accountNumber attribute value.
233      *
234      * @param accountNumber The accountNumber to set.
235      */
236     public void setAccountNumber(String accountNumber) {
237         this.accountNumber = accountNumber;
238     }
239 
240     /**
241      * Gets the subAccountNumber attribute.
242      *
243      * @return Returns the subAccountNumber.
244      */
245     public String getSubAccountNumber() {
246         return subAccountNumber;
247     }
248 
249     /**
250      * Sets the subAccountNumber attribute value.
251      *
252      * @param subAccountNumber The subAccountNumber to set.
253      */
254     public void setSubAccountNumber(String subAccountNumber) {
255         this.subAccountNumber = subAccountNumber;
256     }
257 
258     /**
259      * Gets the financialObjectCode attribute.
260      *
261      * @return Returns the financialObjectCode.
262      */
263     public String getFinancialObjectCode() {
264         return financialObjectCode;
265     }
266 
267     /**
268      * Sets the financialObjectCode attribute value.
269      *
270      * @param financialObjectCode The financialObjectCode to set.
271      */
272     public void setFinancialObjectCode(String financialObjectCode) {
273         this.financialObjectCode = financialObjectCode;
274     }
275 
276     /**
277      * Gets the financialSubObjectCode attribute.
278      *
279      * @return Returns the financialSubObjectCode.
280      */
281     public String getFinancialSubObjectCode() {
282         return financialSubObjectCode;
283     }
284 
285     /**
286      * Sets the financialSubObjectCode attribute value.
287      *
288      * @param financialSubObjectCode The financialSubObjectCode to set.
289      */
290     public void setFinancialSubObjectCode(String financialSubObjectCode) {
291         this.financialSubObjectCode = financialSubObjectCode;
292     }
293 
294     /**
295      * Gets the financialBalanceTypeCode attribute.
296      *
297      * @return Returns the financialBalanceTypeCode.
298      */
299     public String getFinancialBalanceTypeCode() {
300         return financialBalanceTypeCode;
301     }
302 
303     /**
304      * Sets the financialBalanceTypeCode attribute value.
305      *
306      * @param financialBalanceTypeCode The financialBalanceTypeCode to set.
307      */
308     public void setFinancialBalanceTypeCode(String financialBalanceTypeCode) {
309         this.financialBalanceTypeCode = financialBalanceTypeCode;
310     }
311 
312     /**
313      * Gets the financialObjectTypeCode attribute.
314      *
315      * @return Returns the financialObjectTypeCode.
316      */
317     public String getFinancialObjectTypeCode() {
318         return financialObjectTypeCode;
319     }
320 
321     /**
322      * Sets the financialObjectTypeCode attribute value.
323      *
324      * @param financialObjectTypeCode The financialObjectTypeCode to set.
325      */
326     public void setFinancialObjectTypeCode(String financialObjectTypeCode) {
327         this.financialObjectTypeCode = financialObjectTypeCode;
328     }
329 
330     /**
331      * Gets the hideAdjustmentMeasurement attribute.
332      *
333      * @return Returns the hideAdjustmentMeasurement.
334      */
335     public boolean isHideAdjustmentMeasurement() {
336         return hideAdjustmentMeasurement;
337     }
338 
339     /**
340      * Sets the hideAdjustmentMeasurement attribute value.
341      *
342      * @param hideAdjustmentMeasurement The hideAdjustmentMeasurement to set.
343      */
344     public void setHideAdjustmentMeasurement(boolean hideAdjustmentMeasurement) {
345         this.hideAdjustmentMeasurement = hideAdjustmentMeasurement;
346     }
347 
348     /**
349      * Gets the adjustmentMeasurement attribute.
350      *
351      * @return Returns the adjustmentMeasurement.
352      */
353     public String getAdjustmentMeasurement() {
354         return adjustmentMeasurement;
355     }
356 
357     /**
358      * Sets the adjustmentMeasurement attribute value.
359      *
360      * @param adjustmentMeasurement The adjustmentMeasurement to set.
361      */
362     public void setAdjustmentMeasurement(String adjustmentMeasurement) {
363         this.adjustmentMeasurement = adjustmentMeasurement;
364     }
365 
366     /**
367      * Gets the adjustmentAmount attribute.
368      *
369      * @return Returns the adjustmentAmount.
370      */
371     public KualiDecimal getAdjustmentAmount() {
372         return adjustmentAmount;
373     }
374 
375     /**
376      * Sets the adjustmentAmount attribute value.
377      *
378      * @param adjustmentAmount The adjustmentAmount to set.
379      */
380     public void setAdjustmentAmount(KualiDecimal adjustmentAmount) {
381         this.adjustmentAmount = adjustmentAmount;
382     }
383 
384     /**
385      * Gets the hideDetails attribute.
386      *
387      * @return Returns the hideDetails.
388      */
389     public boolean isHideDetails() {
390         return hideDetails;
391     }
392 
393     /**
394      * Sets the hideDetails attribute value.
395      *
396      * @param hideDetails The hideDetails to set.
397      */
398     public void setHideDetails(boolean hideDetails) {
399         this.hideDetails = hideDetails;
400     }
401 
402     /**
403      * Gets the budgetByAccountMode attribute.
404      *
405      * @return Returns the budgetByAccountMode.
406      */
407     public boolean isBudgetByAccountMode() {
408         return budgetByAccountMode;
409     }
410 
411     /**
412      * Sets the budgetByAccountMode attribute value.
413      *
414      * @param budgetByAccountMode The budgetByAccountMode to set.
415      */
416     public void setBudgetByAccountMode(boolean budgetByAccountMode) {
417         this.budgetByAccountMode = budgetByAccountMode;
418     }
419 
420     /**
421      * Gets the singleAccountMode attribute.
422      *
423      * @return Returns the singleAccountMode.
424      */
425     public boolean isSingleAccountMode() {
426         return singleAccountMode;
427     }
428 
429     /**
430      * Sets the singleAccountMode attribute value.
431      *
432      * @param singleAccountMode The singleAccountMode to set.
433      */
434     public void setSingleAccountMode(boolean singleAccountMode) {
435         this.singleAccountMode = singleAccountMode;
436     }
437 
438     /**
439      * Gets the appointmentFundings attribute.
440      *
441      * @return Returns the appointmentFundings.
442      */
443     public abstract List<PendingBudgetConstructionAppointmentFunding> getAppointmentFundings();
444 
445     /**
446      * Gets the appointmentRequestedCsfAmountTotal.
447      *
448      * @return Returns the appointmentRequestedCsfAmountTotal.
449      */
450     public KualiInteger getAppointmentRequestedCsfAmountTotal() {
451         return SalarySettingCalculator.getAppointmentRequestedCsfAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
452     }
453 
454     /**
455      * Gets the appointmentRequestedCsfTimePercentTotal.
456      *
457      * @return Returns the appointmentRequestedCsfTimePercentTotal.
458      */
459     public BigDecimal getAppointmentRequestedCsfTimePercentTotal() {
460         return SalarySettingCalculator.getAppointmentRequestedCsfTimePercentTotal(this.getAppointmentFundings());
461     }
462 
463     /**
464      * Gets the appointmentRequestedCsfStandardHoursTotal.
465      *
466      * @return Returns the appointmentRequestedCsfStandardHoursTotal.
467      */
468     public BigDecimal getAppointmentRequestedCsfStandardHoursTotal() {
469         return SalarySettingCalculator.getAppointmentRequestedCsfStandardHoursTotal(this.getAppointmentFundings());
470     }
471 
472     /**
473      * Gets the appointmentRequestedCsfFteQuantityTotal.
474      *
475      * @return Returns the appointmentRequestedCsfFteQuantityTotal.
476      */
477     public BigDecimal getAppointmentRequestedCsfFteQuantityTotal() {
478         return SalarySettingCalculator.getAppointmentRequestedCsfFteQuantityTotal(this.getAppointmentFundings());
479     }
480 
481     /**
482      * Gets the appointmentRequestedAmountTotal.
483      *
484      * @return Returns the appointmentRequestedAmountTotal.
485      */
486     public KualiInteger getAppointmentRequestedAmountTotal() {
487         return SalarySettingCalculator.getAppointmentRequestedAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
488     }
489 
490     /**
491      * Gets the appointmentRequestedTimePercentTotal.
492      *
493      * @return Returns the appointmentRequestedTimePercentTotal.
494      */
495     public BigDecimal getAppointmentRequestedTimePercentTotal() {
496         return SalarySettingCalculator.getAppointmentRequestedTimePercentTotal(this.getAppointmentFundings());
497     }
498 
499     /**
500      * Gets the appointmentRequestedStandardHoursTotal.
501      *
502      * @return Returns the appointmentRequestedStandardHoursTotal.
503      */
504     public BigDecimal getAppointmentRequestedStandardHoursTotal() {
505         return SalarySettingCalculator.getAppointmentRequestedStandardHoursTotal(this.getAppointmentFundings());
506     }
507 
508     /**
509      * Gets the appointmentRequestedFteQuantityTotal.
510      *
511      * @return Returns the appointmentRequestedFteQuantityTotal.
512      */
513     public BigDecimal getAppointmentRequestedFteQuantityTotal() {
514         return SalarySettingCalculator.getAppointmentRequestedFteQuantityTotal(this.getAppointmentFundings());
515     }
516 
517     /**
518      * Gets the csfAmountTotal.
519      *
520      * @return Returns the csfAmountTotal.
521      */
522     public KualiInteger getCsfAmountTotal() {
523         return SalarySettingCalculator.getCsfAmountTotal(this.getEffectivePendingBudgetConstructionAppointmentFunding());
524     }
525 
526     /**
527      * Gets the csfTimePercentTotal.
528      *
529      * @return Returns the csfTimePercentTotal.
530      */
531     public BigDecimal getCsfTimePercentTotal() {
532         return SalarySettingCalculator.getCsfTimePercentTotal(this.getAppointmentFundings());
533     }
534 
535     /**
536      * Gets the csfStandardHoursTotal.
537      *
538      * @return Returns the csfStandardHoursTotal.
539      */
540     public BigDecimal getCsfStandardHoursTotal() {
541         return SalarySettingCalculator.getCsfStandardHoursTotal(this.getAppointmentFundings());
542     }
543 
544     /**
545      * Gets the csfFullTimeEmploymentQuantityTotal.
546      *
547      * @return Returns the csfFullTimeEmploymentQuantityTotal.
548      */
549     public BigDecimal getCsfFullTimeEmploymentQuantityTotal() {
550         return SalarySettingCalculator.getCsfFullTimeEmploymentQuantityTotal(this.getAppointmentFundings());
551     }
552 
553     /**
554      * Gets the percentChangeTotal attribute.
555      *
556      * @return Returns the percentChangeTotal.
557      */
558     public KualiDecimal getPercentChangeTotal() {
559         KualiInteger csfAmountTotal = this.getCsfAmountTotal();
560         KualiInteger requestedAmountTotal = this.getAppointmentRequestedAmountTotal();
561 
562         return SalarySettingCalculator.getPercentChange(csfAmountTotal, requestedAmountTotal);
563     }
564 
565     /**
566      * Gets the EffectivePendingBudgetConstructionAppointmentFunding.
567      *
568      * @return Returns the EffectivePendingBudgetConstructionAppointmentFunding.
569      */
570     public List<PendingBudgetConstructionAppointmentFunding> getEffectivePendingBudgetConstructionAppointmentFunding() {
571         return SalarySettingCalculator.getEffectiveAppointmentFundings(this.getAppointmentFundings());
572     }
573 
574     /**
575      * Gets the salarySettingFieldsHolder attribute.
576      *
577      * @return Returns the salarySettingFieldsHolder.
578      */
579     public SalarySettingFieldsHolder getSalarySettingFieldsHolder() {
580         if (salarySettingFieldsHolder == null) {
581             salarySettingFieldsHolder = new SalarySettingFieldsHolder();
582             ObjectUtil.buildObject(salarySettingFieldsHolder, this);
583         }
584 
585         return salarySettingFieldsHolder;
586     }
587 
588     /**
589      * Gets the person attribute.
590      *
591      * @return Returns the person.
592      */
593     public Person getPerson() {
594         return person;
595     }
596 
597     /**
598      * Gets the salarySettingClosed attribute.
599      *
600      * @return Returns the salarySettingClosed.
601      */
602     public boolean isSalarySettingClosed() {
603         return salarySettingClosed;
604     }
605 
606     /**
607      * Sets the salarySettingClosed attribute value.
608      *
609      * @param salarySettingClosed The salarySettingClosed to set.
610      */
611     public void setSalarySettingClosed(boolean salarySettingClosed) {
612         this.salarySettingClosed = salarySettingClosed;
613     }
614 
615     /**
616      * Gets the viewOnlyEntry attribute. System view only trumps all, overriding methods should call this first and check the
617      * results for !viewOnly before continuing.
618      *
619      * @return Returns the viewOnlyEntry.
620      */
621     public boolean isViewOnlyEntry() {
622         return isSystemViewOnly();
623     }
624 
625     /**
626      * Gets the payrollIncumbentFeedIndictor attribute.
627      *
628      * @return Returns the payrollIncumbentFeedIndictor.
629      */
630     public boolean isPayrollIncumbentFeedIndictor() {
631         return BudgetParameterFinder.getPayrollIncumbentFeedIndictor();
632     }
633 
634     /**
635      * Gets the payrollPositionFeedIndicator attribute.
636      *
637      * @return Returns the payrollPositionFeedIndicator.
638      */
639     public boolean isPayrollPositionFeedIndicator() {
640         return BudgetParameterFinder.getPayrollPositionFeedIndicator();
641     }
642 
643     /**
644      * Gets the dashSubAccountNumber attribute.
645      *
646      * @return Returns the dashSubAccountNumber
647      */
648 
649     public String getDashSubAccountNumber() {
650         return dashSubAccountNumber;
651     }
652 
653     /**
654      * Sets the dashSubAccountNumber attribute.
655      *
656      * @param dashSubAccountNumber The dashSubAccountNumber to set.
657      */
658     public void setDashSubAccountNumber(String dashSubAccountNumber) {
659         this.dashSubAccountNumber = dashSubAccountNumber;
660     }
661 
662     /**
663      * Gets the dashFinancialSubObjectCode attribute.
664      *
665      * @return Returns the dashFinancialSubObjectCode
666      */
667 
668     public String getDashFinancialSubObjectCode() {
669         return dashFinancialSubObjectCode;
670     }
671 
672     /**
673      * Sets the dashFinancialSubObjectCode attribute.
674      *
675      * @param dashFinancialSubObjectCode The dashFinancialSubObjectCode to set.
676      */
677     public void setDashFinancialSubObjectCode(String dashFinancialSubObjectCode) {
678         this.dashFinancialSubObjectCode = dashFinancialSubObjectCode;
679     }
680 }