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 }