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 }