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.dataaccess.impl; 017 018 import java.math.BigDecimal; 019 import java.sql.Date; 020 import java.sql.ResultSet; 021 import java.sql.SQLException; 022 import java.util.Calendar; 023 import java.util.Collection; 024 import java.util.GregorianCalendar; 025 import java.util.LinkedHashMap; 026 027 import org.kuali.kfs.gl.Constant; 028 import org.kuali.kfs.gl.businessobject.TransientBalanceInquiryAttributes; 029 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition; 030 import org.kuali.kfs.module.bc.businessobject.Position; 031 import org.kuali.kfs.module.bc.dataaccess.HumanResourcesPayrollDao; 032 import org.kuali.kfs.module.bc.document.dataaccess.impl.BudgetConstructionDaoJdbcBase; 033 import org.kuali.rice.kns.bo.PersistableBusinessObjectBase; 034 import org.springframework.jdbc.core.simple.ParameterizedRowMapper; 035 036 /** 037 * Implementation of <code>HumanResourcesPayrollDao</code> using JDBC to query PS_POSITION_DATA and then set other 038 * <code>Position</code> fields to hard-coded IU values. This is for bootstrap only. 039 * 040 * @see org.kuali.kfs.module.bc.dataaccess.HumanResourcesPayrollDao 041 */ 042 public class HumanResourcesPayrollDaoJdbc extends BudgetConstructionDaoJdbcBase implements HumanResourcesPayrollDao { 043 044 /** 045 * Gets the <code>Position</code> data by querying PS_POSITION_DATA then setting other fields using IU business rules. This is 046 * used in the bootstrap service implementation for an example. 047 * 048 * @see org.kuali.kfs.module.bc.dataaccess.HumanResourcesPayrollDao#getPosition(java.lang.Integer, java.lang.String) 049 */ 050 public Position getPosition(Integer universityFiscalYear, String positionNumber) { 051 PositionData positionData = getPositionDataForFiscalYear(universityFiscalYear, positionNumber); 052 053 if (positionData == null) { 054 return null; 055 } 056 057 Position position = new BudgetConstructionPosition(); 058 position.setUniversityFiscalYear(universityFiscalYear); 059 position.setPositionNumber(positionNumber); 060 061 populatePositionData(position, positionData); 062 063 setDefaultObjectClass(position); 064 065 return position; 066 } 067 068 /** 069 * find positions with effective date before July 1 of fiscal year or on August 1 of fiscal year for academic tenure salary plan 070 * 071 * @param universityFiscalYear 072 * @param positionNumber 073 * @return 074 */ 075 protected PositionData getPositionDataForFiscalYear(Integer universityFiscalYear, String positionNumber) { 076 Collection<PositionData> positionData = getPositionData(positionNumber); 077 078 if (positionData == null || positionData.isEmpty()) { 079 return null; 080 } 081 082 // find positions with effective date before July 1 of fiscal year or on August 1 of fiscal year 083 // for academic tenure salary plan 084 Integer baseFiscalYear = universityFiscalYear - 1; 085 086 GregorianCalendar calendarJuly1 = new GregorianCalendar(baseFiscalYear, Calendar.JULY, 1); 087 GregorianCalendar calendarAugust1 = new GregorianCalendar(universityFiscalYear, Calendar.AUGUST, 1); 088 Date julyFirst = new Date(calendarJuly1.getTimeInMillis()); 089 Date augustFirst = new Date(calendarAugust1.getTimeInMillis()); 090 091 String academicTenureTrackSalaryPlan = new String("AC1"); 092 093 PositionData positionDataMaxEffectiveDate = null; 094 for (PositionData posData : positionData) { 095 Date positionEffectiveDate = posData.getEffectiveDate(); 096 if ((positionEffectiveDate.compareTo(julyFirst) <= 0) || (academicTenureTrackSalaryPlan.equals(posData.getPositionSalaryPlanDefault()) && positionEffectiveDate.equals(augustFirst))) { 097 // get position with max effective date for year 098 if (positionDataMaxEffectiveDate == null || positionDataMaxEffectiveDate.getEffectiveDate().compareTo(positionEffectiveDate) < 0) { 099 positionDataMaxEffectiveDate = posData; 100 } 101 } 102 } 103 104 return positionDataMaxEffectiveDate; 105 } 106 107 /** 108 * Retrieves record for position key from PS_POSITION_DATA and returns populated <code>PositionData</code> business object. 109 */ 110 public Collection<PositionData> getPositionData(String positionNumber) { 111 StringBuilder sqlBuilder = new StringBuilder(); 112 sqlBuilder.append("SELECT POSITION_NBR, EFFDT, JOBCODE, POS_EFF_STATUS, DESCR, \n"); 113 sqlBuilder.append(" DESCRSHORT, BUSINESS_UNIT, DEPTID, POSN_STATUS, STATUS_DT, \n"); 114 sqlBuilder.append(" BUDGETED_POSN, STD_HRS_DEFAULT, STD_HRS_FREQUENCY, POS_REG_TEMP, \n"); 115 sqlBuilder.append(" POS_FTE, POS_SAL_PLAN_DFLT, POS_GRADE_DFLT \n"); 116 sqlBuilder.append(" FROM PS_POSITION_DATA \n"); 117 sqlBuilder.append(" WHERE POSITION_NBR = ? \n"); 118 119 String sqlString = sqlBuilder.toString(); 120 121 ParameterizedRowMapper<PositionData> mapper = new ParameterizedRowMapper<PositionData>() { 122 123 public PositionData mapRow(ResultSet rs, int rowNum) throws SQLException { 124 PositionData positionData = new PositionData(); 125 positionData.setPositionNumber(rs.getString("POSITION_NBR")); 126 positionData.setEffectiveDate(rs.getDate("EFFDT")); 127 positionData.setJobCode(rs.getString("JOBCODE")); 128 positionData.setPositionEffectiveStatus(rs.getString("POS_EFF_STATUS")); 129 positionData.setDescription(rs.getString("DESCR")); 130 positionData.setShortDescription(rs.getString("DESCRSHORT")); 131 positionData.setBusinessUnit(rs.getString("BUSINESS_UNIT")); 132 positionData.setDepartmentId(rs.getString("DEPTID")); 133 positionData.setPositionStatus(rs.getString("POSN_STATUS")); 134 positionData.setStatusDate(rs.getDate("STATUS_DT")); 135 positionData.setBudgetedPosition(rs.getString("BUDGETED_POSN")); 136 positionData.setStandardHoursDefault(rs.getBigDecimal("STD_HRS_DEFAULT")); 137 positionData.setStandardHoursFrequency(rs.getString("STD_HRS_FREQUENCY")); 138 positionData.setPositionRegularTemporary(rs.getString("POS_REG_TEMP")); 139 positionData.setPositionFullTimeEquivalency(rs.getBigDecimal("POS_FTE")); 140 positionData.setPositionSalaryPlanDefault(rs.getString("POS_SAL_PLAN_DFLT")); 141 positionData.setPositionGradeDefault(rs.getString("POS_GRADE_DFLT")); 142 143 return positionData; 144 } 145 }; 146 147 return this.getSimpleJdbcTemplate().query(sqlString, mapper, positionNumber); 148 } 149 150 /** 151 * Sets <code>Position</code> fields with data from <code>PositionData</code> 152 */ 153 public void populatePositionData(Position position, PositionData positionData) { 154 position.setPositionEffectiveDate(positionData.getEffectiveDate()); 155 position.setJobCode(positionData.getJobCode()); 156 position.setPositionEffectiveStatus(positionData.getPositionEffectiveStatus()); 157 position.setPositionDescription(positionData.getDescription()); 158 position.setSetidDepartment(positionData.getBusinessUnit()); 159 position.setPositionDepartmentIdentifier(positionData.getDepartmentId()); 160 position.setPositionStatus(positionData.getPositionStatus()); 161 162 if ("Y".equalsIgnoreCase(positionData.getBudgetedPosition())) { 163 position.setBudgetedPosition(true); 164 } 165 else { 166 position.setBudgetedPosition(false); 167 } 168 169 position.setPositionStandardHoursDefault(positionData.getStandardHoursDefault()); 170 position.setPositionRegularTemporary(positionData.getPositionRegularTemporary()); 171 position.setPositionFullTimeEquivalency(positionData.getPositionFullTimeEquivalency()); 172 position.setPositionSalaryPlanDefault(positionData.getPositionSalaryPlanDefault()); 173 position.setPositionGradeDefault(positionData.getPositionGradeDefault()); 174 } 175 176 /** 177 * Sets defaults based on salary plan. 178 * 179 * @param position <code>Position</code> to update 180 */ 181 public void setDefaultObjectClass(Position position) { 182 String salaryPlan = position.getPositionSalaryPlanDefault(); 183 184 if ("AC1".equals(salaryPlan)) { 185 position.setIuNormalWorkMonths(new Integer(10)); 186 position.setIuPayMonths(new Integer(10)); 187 position.setIuPositionType("AC"); 188 position.setIuDefaultObjectCode("2000"); 189 } 190 191 else if ("PAO".equals(salaryPlan) || "PAU".equals(salaryPlan)) { 192 position.setIuNormalWorkMonths(new Integer(12)); 193 position.setIuPayMonths(new Integer(12)); 194 position.setIuPositionType("SM"); 195 position.setIuDefaultObjectCode("2480"); 196 } 197 198 else if (salaryPlan.startsWith("P")) { 199 position.setIuNormalWorkMonths(new Integer(12)); 200 position.setIuPayMonths(new Integer(12)); 201 position.setIuPositionType("SM"); 202 position.setIuDefaultObjectCode("2400"); 203 } 204 205 else { 206 position.setIuNormalWorkMonths(new Integer(12)); 207 position.setIuPayMonths(new Integer(12)); 208 position.setIuPositionType("SB"); 209 position.setIuDefaultObjectCode("2500"); 210 position.setPositionUnionCode("B1"); 211 } 212 } 213 214 protected class PositionData extends PersistableBusinessObjectBase { 215 private String positionNumber; 216 private String jobCode; 217 private Date effectiveDate; 218 private String positionEffectiveStatus; 219 private String description; 220 private String shortDescription; 221 private String businessUnit; 222 private String departmentId; 223 private String positionStatus; 224 private Date statusDate; 225 private String budgetedPosition; 226 private BigDecimal standardHoursDefault; 227 private String standardHoursFrequency; 228 private String positionRegularTemporary; 229 private BigDecimal positionFullTimeEquivalency; 230 private String positionSalaryPlanDefault; 231 private String positionGradeDefault; 232 private TransientBalanceInquiryAttributes dummyBusinessObject; 233 234 /** 235 * Default constructor. 236 */ 237 public PositionData() { 238 super(); 239 this.dummyBusinessObject = new TransientBalanceInquiryAttributes(); 240 this.dummyBusinessObject.setLinkButtonOption(Constant.LOOKUP_BUTTON_VALUE); 241 } 242 243 /** 244 * Gets the positionNumber 245 * 246 * @return Returns the positionNumber 247 */ 248 public String getPositionNumber() { 249 return positionNumber; 250 } 251 252 /** 253 * Sets the positionNumber 254 * 255 * @param positionNumber The positionNumber to set. 256 */ 257 public void setPositionNumber(String positionNumber) { 258 this.positionNumber = positionNumber; 259 } 260 261 /** 262 * Gets the jobCode 263 * 264 * @return Returns the jobCode 265 */ 266 public String getJobCode() { 267 return jobCode; 268 } 269 270 /** 271 * Sets the jobCode 272 * 273 * @param jobCode The jobCode to set. 274 */ 275 public void setJobCode(String jobCode) { 276 this.jobCode = jobCode; 277 } 278 279 /** 280 * Gets the effectiveDate 281 * 282 * @return Returns the effectiveDate 283 */ 284 public Date getEffectiveDate() { 285 return effectiveDate; 286 } 287 288 /** 289 * Sets the effectiveDate 290 * 291 * @param effectiveDate The effectiveDate to set. 292 */ 293 public void setEffectiveDate(Date effectiveDate) { 294 this.effectiveDate = effectiveDate; 295 } 296 297 /** 298 * Gets the positionEffectiveStatus 299 * 300 * @return Returns the positionEffectiveStatus 301 */ 302 public String getPositionEffectiveStatus() { 303 return positionEffectiveStatus; 304 } 305 306 /** 307 * Sets the positionEffectiveStatus 308 * 309 * @param positionEffectiveStatus The positionEffectiveStatus to set. 310 */ 311 public void setPositionEffectiveStatus(String positionEffectiveStatus) { 312 this.positionEffectiveStatus = positionEffectiveStatus; 313 } 314 315 /** 316 * Gets the description 317 * 318 * @return Returns the description 319 */ 320 public String getDescription() { 321 return description; 322 } 323 324 /** 325 * Sets the description 326 * 327 * @param description The description to set. 328 */ 329 public void setDescription(String description) { 330 this.description = description; 331 } 332 333 /** 334 * Gets the shortDescription 335 * 336 * @return Returns the shortDescription 337 */ 338 public String getShortDescription() { 339 return shortDescription; 340 } 341 342 /** 343 * Sets the shortDescription 344 * 345 * @param shortDescription The shortDescription to set. 346 */ 347 public void setShortDescription(String shortDescription) { 348 this.shortDescription = shortDescription; 349 } 350 351 /** 352 * Gets the businessUnit 353 * 354 * @return Returns the businessUnit 355 */ 356 public String getBusinessUnit() { 357 return businessUnit; 358 } 359 360 /** 361 * Sets the businessUnit 362 * 363 * @param businessUnit The businessUnit to set. 364 */ 365 public void setBusinessUnit(String businessUnit) { 366 this.businessUnit = businessUnit; 367 } 368 369 /** 370 * Gets the departmentId 371 * 372 * @return Returns the departmentId 373 */ 374 public String getDepartmentId() { 375 return departmentId; 376 } 377 378 /** 379 * Sets the departmentId 380 * 381 * @param departmentId The departmentId to set. 382 */ 383 public void setDepartmentId(String departmentId) { 384 this.departmentId = departmentId; 385 } 386 387 /** 388 * Gets the positionStatus 389 * 390 * @return Returns the positionStatus 391 */ 392 public String getPositionStatus() { 393 return positionStatus; 394 } 395 396 /** 397 * Sets the positionStatus 398 * 399 * @param positionStatus The positionStatus to set. 400 */ 401 public void setPositionStatus(String positionStatus) { 402 this.positionStatus = positionStatus; 403 } 404 405 /** 406 * Gets the statusDate 407 * 408 * @return Returns the statusDate 409 */ 410 public Date getStatusDate() { 411 return statusDate; 412 } 413 414 /** 415 * Sets the statusDate 416 * 417 * @param statusDate The statusDate to set. 418 */ 419 public void setStatusDate(Date statusDate) { 420 this.statusDate = statusDate; 421 } 422 423 /** 424 * Gets the budgetedPosition 425 * 426 * @return Returns the budgetedPosition 427 */ 428 public String getBudgetedPosition() { 429 return budgetedPosition; 430 } 431 432 /** 433 * Sets the budgetedPosition 434 * 435 * @param budgetedPosition The budgetedPosition to set. 436 */ 437 public void setBudgetedPosition(String budgetedPosition) { 438 this.budgetedPosition = budgetedPosition; 439 } 440 441 /** 442 * Gets the standardHoursDefault 443 * 444 * @return Returns the standardHoursDefault 445 */ 446 public BigDecimal getStandardHoursDefault() { 447 return standardHoursDefault; 448 } 449 450 /** 451 * Sets the standardHoursDefault 452 * 453 * @param standardHoursDefault The standardHoursDefault to set. 454 */ 455 public void setStandardHoursDefault(BigDecimal standardHoursDefault) { 456 this.standardHoursDefault = standardHoursDefault; 457 } 458 459 /** 460 * Gets the standardHoursFrequency 461 * 462 * @return Returns the standardHoursFrequency 463 */ 464 public String getStandardHoursFrequency() { 465 return standardHoursFrequency; 466 } 467 468 /** 469 * Sets the standardHoursFrequency 470 * 471 * @param standardHoursFrequency The standardHoursFrequency to set. 472 */ 473 public void setStandardHoursFrequency(String standardHoursFrequency) { 474 this.standardHoursFrequency = standardHoursFrequency; 475 } 476 477 /** 478 * Gets the positionRegularTemporary 479 * 480 * @return Returns the positionRegularTemporary 481 */ 482 public String getPositionRegularTemporary() { 483 return positionRegularTemporary; 484 } 485 486 /** 487 * Sets the positionRegularTemporary 488 * 489 * @param positionRegularTemporary The positionRegularTemporary to set. 490 */ 491 public void setPositionRegularTemporary(String positionRegularTemporary) { 492 this.positionRegularTemporary = positionRegularTemporary; 493 } 494 495 /** 496 * Gets the positionFullTimeEquivalency 497 * 498 * @return Returns the positionFullTimeEquivalency 499 */ 500 public BigDecimal getPositionFullTimeEquivalency() { 501 return positionFullTimeEquivalency; 502 } 503 504 /** 505 * Sets the positionFullTimeEquivalency 506 * 507 * @param positionFullTimeEquivalency The positionFullTimeEquivalency to set. 508 */ 509 public void setPositionFullTimeEquivalency(BigDecimal positionFullTimeEquivalency) { 510 this.positionFullTimeEquivalency = positionFullTimeEquivalency; 511 } 512 513 /** 514 * Gets the positionSalaryPlanDefault 515 * 516 * @return Returns the positionSalaryPlanDefault 517 */ 518 public String getPositionSalaryPlanDefault() { 519 return positionSalaryPlanDefault; 520 } 521 522 /** 523 * Sets the positionSalaryPlanDefault 524 * 525 * @param positionSalaryPlanDefault The positionSalaryPlanDefault to set. 526 */ 527 public void setPositionSalaryPlanDefault(String positionSalaryPlanDefault) { 528 this.positionSalaryPlanDefault = positionSalaryPlanDefault; 529 } 530 531 /** 532 * Gets the positionGradeDefault 533 * 534 * @return Returns the positionGradeDefault 535 */ 536 public String getPositionGradeDefault() { 537 return positionGradeDefault; 538 } 539 540 /** 541 * Sets the positionGradeDefault 542 * 543 * @param positionGradeDefault The positionGradeDefault to set. 544 */ 545 public void setPositionGradeDefault(String positionGradeDefault) { 546 this.positionGradeDefault = positionGradeDefault; 547 } 548 549 /** 550 * construct the key list of the business object. 551 * 552 * @see org.kuali.rice.kns.bo.BusinessObjectBase#toStringMapper() 553 */ 554 protected LinkedHashMap toStringMapper() { 555 LinkedHashMap m = new LinkedHashMap(); 556 m.put("positionNumber", this.positionNumber); 557 if (this.effectiveDate != null) { 558 m.put("effectiveDate", this.effectiveDate.toString()); 559 } 560 561 return m; 562 } 563 564 /** 565 * Gets the dummyBusinessObject 566 * 567 * @return Returns the dummyBusinessObject. 568 */ 569 public TransientBalanceInquiryAttributes getDummyBusinessObject() { 570 return dummyBusinessObject; 571 } 572 573 /** 574 * Sets the dummyBusinessObject 575 * 576 * @param dummyBusinessObject The dummyBusinessObject to set. 577 */ 578 public void setDummyBusinessObject(TransientBalanceInquiryAttributes dummyBusinessObject) { 579 this.dummyBusinessObject = dummyBusinessObject; 580 } 581 } 582 583 }