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.dataaccess.impl;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    
021    import org.kuali.kfs.module.bc.BCConstants;
022    import org.kuali.kfs.module.bc.batch.dataaccess.impl.SQLForStep;
023    import org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionSalarySummaryReportDao;
024    import org.kuali.rice.kns.service.PersistenceService;
025    import org.kuali.rice.kns.util.Guid;
026    import org.kuali.rice.kns.util.KualiDecimal;
027    
028    /**
029     * builds the underlying data table for the salary summary report in budget construction
030     */
031    
032    public class BudgetConstructionSalarySummaryReportDaoJdbc extends BudgetConstructionDaoJdbcBase implements BudgetConstructionSalarySummaryReportDao {
033        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetConstructionSalarySummaryReportDaoJdbc.class);
034    
035        private static ArrayList<SQLForStep> updateReportsSalarySummaryThreshold           = new ArrayList<SQLForStep>(7);
036        private static ArrayList<SQLForStep> salarySummaryAboveThreshold                   = new ArrayList<SQLForStep>(1);
037        private static ArrayList<SQLForStep> salarySummaryBelowThreshold                   = new ArrayList<SQLForStep>(1);
038        private static ArrayList<SQLForStep> updateReportsSalarySummaryNoThresholdReason   = new ArrayList<SQLForStep>(1);
039        private static ArrayList<SQLForStep> updateReportsSalarySummaryNoThresholdNoReason = new ArrayList<SQLForStep>(1);
040        private static ArrayList<SQLForStep> updateReportsSalarySummaryCommon              = new ArrayList<SQLForStep>(2);
041        
042        private PersistenceService persistenceService;
043    
044        public BudgetConstructionSalarySummaryReportDaoJdbc() {
045    
046            // builds and updates SalarySummaryReports
047            
048            ArrayList<Integer> insertionPoints = new ArrayList<Integer>(10);
049            StringBuilder sqlText = new StringBuilder(1500);
050    
051            /* get no leave bcaf, bcsf and posn info first */
052            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM01_MT \n");
053            sqlText.append(" (SESID, EMPLID, POSITION_NBR, SAL_AMT, SAL_PCT, SAL_MTHS, POS_CSF_AMT, POS_CSF_TM_PCT, SAL_PMTHS) \n");
054            sqlText.append("SELECT ?, bcaf.emplid, bcaf.position_nbr,  bcaf.appt_rqst_amt, bcaf.appt_rqst_tm_pct, bcaf.appt_fnd_mo, bcsf.pos_csf_amt, bcsf.pos_csf_tm_pct, posn.iu_pay_months \n");
055            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_CSF_TRCKR_T bcsf \n");
056            sqlText.append(" ON ((bcaf.fin_coa_cd = bcsf.fin_coa_cd) AND (bcaf.account_nbr = bcsf.account_nbr) \n");
057            sqlText.append(" AND(bcaf.sub_acct_nbr = bcsf.sub_acct_nbr) AND (bcaf.fin_object_cd = bcsf.fin_object_cd) \n");
058            sqlText.append(" AND(bcaf.fin_sub_obj_cd = bcsf.fin_sub_obj_cd) AND (bcaf.position_nbr = bcsf.position_nbr)\n");
059            sqlText.append(" AND(bcaf.emplid = bcsf.emplid) AND (bcaf.univ_fiscal_yr= bcsf.univ_fiscal_yr))),\n");
060            sqlText.append("      LD_BCN_POS_T posn, LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick\n");
061            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
062            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
063            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
064            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
065            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
066            sqlText.append(" AND bcaf.emplid <> '");
067            //  empolyee ID for a vacant line in budget construction CSF and appointment funding
068            insertionPoints.add(sqlText.length());
069            sqlText.append("' \n");
070            sqlText.append(" AND bcaf.appt_fnd_dur_cd = '");
071            // default appointment funding duration code
072            insertionPoints.add(sqlText.length());
073            sqlText.append("' \n");
074            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
075            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
076            sqlText.append(" AND pick.select_flag > 0 \n");
077            sqlText.append(" AND bcaf.univ_fiscal_yr = posn.univ_fiscal_yr \n");
078            sqlText.append(" AND bcaf.position_nbr = posn.position_nbr \n");
079    
080            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText,insertionPoints));
081            sqlText.delete(0, sqlText.length());
082            insertionPoints.clear();
083    
084            /* get leave flagged bcaf, bcsf and posn info first */
085            /* uses leave related info from bcaf, etc */
086            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM01_MT \n");
087            sqlText.append("(SESID, EMPLID, POSITION_NBR, SAL_AMT, SAL_PCT, SAL_MTHS, \n");
088            sqlText.append(" POS_CSF_AMT, POS_CSF_TM_PCT, SAL_PMTHS) \n");
089            sqlText.append("SELECT ?, bcaf.emplid, bcaf.position_nbr, bcaf.appt_rqst_csf_amt, bcaf.appt_rqcsf_tm_pct, posn.iu_norm_work_months, \n");
090            sqlText.append("  bcsf.pos_csf_amt, bcsf.pos_csf_tm_pct, posn.iu_pay_months \n");
091            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_CSF_TRCKR_T bcsf \n");
092            sqlText.append(" ON ((bcaf.fin_coa_cd = bcsf.fin_coa_cd) AND (bcaf.account_nbr = bcsf.account_nbr) \n");
093            sqlText.append("AND (bcaf.sub_acct_nbr = bcsf.sub_acct_nbr) AND (bcaf.fin_object_cd = bcsf.fin_object_cd) \n");
094            sqlText.append("AND (bcaf.fin_sub_obj_cd = bcsf.fin_sub_obj_cd) AND (bcaf.position_nbr = bcsf.position_nbr) \n");
095            sqlText.append("AND (bcaf.emplid = bcsf.emplid) AND (bcaf.univ_fiscal_yr= bcsf.univ_fiscal_yr))), LD_BCN_POS_T posn, LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick \n");
096            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
097            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
098            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
099            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
100            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
101            sqlText.append(" AND bcaf.emplid <> '\n");
102            //  empolyee ID for a vacant line in budget construction CSF and appointment funding
103            insertionPoints.add(sqlText.length());
104            sqlText.append("' \n");
105            sqlText.append(" AND bcaf.appt_fnd_dur_cd <> '");
106            // defualt appointment funding duration code
107            insertionPoints.add(sqlText.length());
108            sqlText.append("' \n");
109            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
110            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
111            sqlText.append(" AND pick.select_flag > 0 \n");
112            sqlText.append(" AND bcaf.univ_fiscal_yr = posn.univ_fiscal_yr \n");
113            sqlText.append(" AND bcaf.position_nbr = posn.position_nbr \n");
114    
115            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText,insertionPoints));
116            sqlText.delete(0, sqlText.length());
117            insertionPoints.clear();
118    
119            /* for each emplid, find the record with the largest salary (break ties by taking the row with the smallest position number) */
120            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM02_MT \n");
121            sqlText.append("(SESID, EMPLID, SAL_MTHS, SAL_PMTHS) \n");
122            sqlText.append("SELECT DISTINCT ?, sd.emplid, sd.sal_mths, sd.sal_pmths \n");
123            sqlText.append("FROM LD_BCN_BUILD_SALSUMM01_MT sd \n");
124            sqlText.append("WHERE sesid = ? \n");
125            sqlText.append("AND sd.sal_amt = (SELECT max(sd2.sal_amt) \n");
126            sqlText.append("                  FROM LD_BCN_BUILD_SALSUMM01_MT sd2\n");
127            sqlText.append("                  WHERE sd2.sesid = sd.sesid AND sd2.emplid = sd.emplid)\n");
128            sqlText.append("AND sd.position_nbr = (SELECT min(sd3.position_nbr) \n");
129            sqlText.append("                       FROM LD_BCN_BUILD_SALSUMM01_MT sd3\n");
130            sqlText.append("                       WHERE sd3.sesid = sd.sesid  \n");
131            sqlText.append("                         AND sd3.emplid = sd.emplid AND sd3.sal_amt = sd.sal_amt) \n");
132    
133            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText));
134            sqlText.delete(0, sqlText.length());
135    
136            /* for each emplid, find the CSF from the previous year with the largest salary (break ties by taking the row with the smallest position number */
137            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM03_MT\n");
138            sqlText.append("(SESID, EMPLID, CSF_MTHS, CSF_PMTHS) \n");
139            sqlText.append("SELECT DISTINCT ?, sd.emplid, p.iu_norm_work_months, p.iu_pay_months \n");
140            sqlText.append("FROM LD_BCN_BUILD_SALSUMM01_MT sd, LD_BCN_POS_T p \n");
141            sqlText.append("WHERE sesid = ? \n");
142            sqlText.append(" AND sd.pos_csf_amt = (SELECT max(sd2.pos_csf_amt)  \n");
143            sqlText.append("                       FROM LD_BCN_BUILD_SALSUMM01_MT sd2\n");
144            sqlText.append("                       WHERE sd2.sesid = sd.sesid AND sd2.emplid = sd.emplid) \n");
145            sqlText.append(" AND sd.position_nbr = (SELECT min(sd3.position_nbr) \n");
146            sqlText.append("                        FROM LD_BCN_BUILD_SALSUMM01_MT sd3\n");
147            sqlText.append("                        WHERE sd3.sesid = sd.sesid AND sd3.emplid = sd.emplid AND sd3.pos_csf_amt = sd.pos_csf_amt) \n");
148            sqlText.append(" AND p.univ_fiscal_yr = ? AND p.position_nbr = sd.position_nbr \n");
149    
150            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText));
151            sqlText.delete(0, sqlText.length());
152    
153            /* merge the sal max,csf max info and sums to one table */
154            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM04_MT \n");
155            sqlText.append("(SESID, EMPLID, POS_CSF_AMT, RES_CSF_AMT, POS_CSF_TM_PCT, \n");
156            sqlText.append(" SAL_AMT, SAL_PCT, SAL_MTHS, SAL_PMTHS, CSF_MTHS, CSF_PMTHS) \n");
157            sqlText.append("SELECT ?, sm.emplid, SUM(COALESCE(sd.pos_csf_amt,0)), 0, SUM(COALESCE(sd.pos_csf_tm_pct,0)), \n");
158            sqlText.append(" SUM(COALESCE(sd.sal_amt,0)), SUM(COALESCE(sd.sal_pct,0)), sm.sal_mths, sm.sal_pmths, COALESCE(cm.csf_mths,0), COALESCE(cm.csf_pmths,0) \n");
159            sqlText.append("FROM (LD_BCN_BUILD_SALSUMM02_MT sm LEFT OUTER JOIN LD_BCN_BUILD_SALSUMM03_MT cm \n");
160            sqlText.append("      ON ((sm.sesid = cm.sesid) AND (sm.emplid = cm.emplid))),\n");
161            sqlText.append("      LD_BCN_BUILD_SALSUMM01_MT sd \n");
162            sqlText.append("WHERE sm.sesid = ? \n");
163            sqlText.append(" AND sd.sesid = sm.sesid \n");
164            sqlText.append(" AND sd.emplid = sm.emplid \n");
165            sqlText.append("GROUP BY sm.emplid, sm.sal_mths, sm.sal_pmths, cm.csf_mths, cm.csf_pmths \n");
166    
167            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText));
168            sqlText.delete(0, sqlText.length());
169    
170            /* restate the csf for all records, adjusting it so that it reflects changes in months appointment and percent time. */
171            /* the adjustment factor is (req pct time/base pct time)(req mnths appt/req position mnths appt)/(base mnths appt)/(base position mnths appt)*/
172            sqlText.append("UPDATE LD_BCN_BUILD_SALSUMM04_MT \n");
173            sqlText.append("SET res_csf_amt = ROUND(COALESCE(((pos_csf_amt * sal_pct * sal_mths * csf_pmths) \n");
174            sqlText.append(" / (pos_csf_tm_pct * csf_mths * sal_pmths)), 0.00),0) \n");
175            sqlText.append("WHERE sesid = ? AND pos_csf_tm_pct <> 0 AND csf_mths <> 0 AND sal_pmths <> 0 \n");
176    
177            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText));
178            sqlText.delete(0, sqlText.length());
179    
180            /* restate the csf amt for change in fte scale */
181            sqlText.append("UPDATE LD_BCN_BUILD_SALSUMM04_MT \n");
182            sqlText.append("SET res_csf_amt = ROUND(COALESCE(((res_csf_amt * sal_pmths) / csf_pmths), 0.00),0) \n");
183            sqlText.append("WHERE sesid = ? AND sal_pmths <> csf_pmths AND csf_pmths <> 0 \n");
184    
185            updateReportsSalarySummaryThreshold.add(new SQLForStep(sqlText));
186            sqlText.delete(0, sqlText.length());
187    
188            /* produce emplid set for recs >= threshold */
189            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM05_MT \n");
190            sqlText.append("(SESID, EMPLID) \n");
191            sqlText.append("SELECT ?, emplid \n");
192            sqlText.append("FROM LD_BCN_BUILD_SALSUMM04_MT \n");
193            sqlText.append("WHERE sesid = ? \n");
194            sqlText.append(" AND ROUND((((sal_amt - res_csf_amt) / res_csf_amt) * 100),1) >= ? \n");
195            sqlText.append(" AND res_csf_amt <> 0 \n");
196            sqlText.append(" AND sal_amt <> 0 \n");
197    
198            salarySummaryAboveThreshold.add(new SQLForStep(sqlText));
199            sqlText.delete(0, sqlText.length());
200    
201            /* produce emplid set for recs <= threshold */
202            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM05_MT \n");
203            sqlText.append("(SESID, EMPLID) \n");
204            sqlText.append("SELECT ?, emplid \n");
205            sqlText.append("FROM LD_BCN_BUILD_SALSUMM04_MT \n");
206            sqlText.append("WHERE sesid = ? \n");
207            sqlText.append(" AND ROUND((((sal_amt - res_csf_amt) / res_csf_amt) * 100),1) <= ? \n");
208            sqlText.append(" AND res_csf_amt <> 0 \n");
209            sqlText.append(" AND sal_amt <> 0 \n");
210    
211            salarySummaryBelowThreshold.add(new SQLForStep(sqlText));
212            sqlText.delete(0, sqlText.length());
213    
214    
215            /* get EMPLIDs with at least one reason rec from the list of select reasons */
216            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM05_MT\n");
217            sqlText.append("(SESID, EMPLID) \n");
218            sqlText.append("SELECT DISTINCT ?, bcaf.emplid  \n");
219            sqlText.append("FROM LD_BCN_CTRL_LIST_T ctrl, LD_PNDBC_APPTFND_T bcaf, LD_BCN_OBJ_PICK_T pick, LD_BCN_AF_REASON_T reas, LD_BCN_RSN_CD_PK_T rpk \n");
220            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
221            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
222            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
223            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
224            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
225            sqlText.append(" AND bcaf.emplid <> '");
226            //  empolyee ID for a vacant line in budget construction CSF and appointment funding
227            insertionPoints.add(sqlText.length());
228            sqlText.append("' \n");
229            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
230            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
231            sqlText.append(" AND pick.select_flag > 0 \n");
232            sqlText.append(" AND bcaf.univ_fiscal_yr = reas.univ_fiscal_yr \n");
233            sqlText.append(" AND bcaf.fin_coa_cd = reas.fin_coa_cd \n");
234            sqlText.append(" AND bcaf.account_nbr = reas.account_nbr \n");
235            sqlText.append(" AND bcaf.sub_acct_nbr = reas.sub_acct_nbr \n");
236            sqlText.append(" AND bcaf.fin_object_cd = reas.fin_object_cd \n");
237            sqlText.append(" AND bcaf.fin_sub_obj_cd = reas.fin_sub_obj_cd \n");
238            sqlText.append(" AND bcaf.position_nbr = reas.position_nbr \n");
239            sqlText.append(" AND bcaf.emplid = reas.emplid \n");
240            sqlText.append(" AND reas.appt_fnd_reason_cd = rpk.appt_fnd_reason_cd \n");
241            sqlText.append(" AND rpk.person_unvl_id = ctrl.person_unvl_id \n");
242            sqlText.append(" AND rpk.select_flag <> 0 \n");
243    
244            updateReportsSalarySummaryNoThresholdReason.add(new SQLForStep(sqlText,insertionPoints));
245            sqlText.delete(0, sqlText.length());
246            insertionPoints.clear();
247    
248            /* get all EMPLIDs for the selection */
249            sqlText.append("INSERT INTO LD_BCN_BUILD_SALSUMM05_MT \n");
250            sqlText.append("(SESID, EMPLID) \n");
251            sqlText.append("SELECT DISTINCT ?, bcaf.emplid \n");
252            sqlText.append("FROM LD_BCN_CTRL_LIST_T ctrl, LD_PNDBC_APPTFND_T bcaf, LD_BCN_OBJ_PICK_T pick \n");
253            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
254            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
255            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
256            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
257            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
258            sqlText.append(" AND bcaf.emplid <> '");
259            //  empolyee ID for a vacant line in budget construction CSF and appointment funding
260            insertionPoints.add(sqlText.length());
261            sqlText.append("' \n");
262            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
263            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
264            sqlText.append(" AND pick.select_flag > 0 \n");
265            
266            updateReportsSalarySummaryNoThresholdNoReason.add(new SQLForStep(sqlText,insertionPoints));
267            sqlText.delete(0, sqlText.length());
268            insertionPoints.clear();
269            
270            /*  these are the two common driving SQL statements for all the reports  */
271    
272            /* get the name recs for the set of EMPLIDs */
273            sqlText.append("INSERT INTO LD_BCN_SAL_SSN_T \n");
274            sqlText.append("(PERSON_UNVL_ID, ORG_FIN_COA_CD, ORG_CD, PERSON_NM, EMPLID)");
275            sqlText.append("SELECT DISTINCT ?, ctrl.sel_org_fin_coa, ctrl.sel_org_cd, iinc.person_nm, bcaf.emplid \n");
276            sqlText.append("FROM LD_BCN_CTRL_LIST_T ctrl, LD_PNDBC_APPTFND_T bcaf, LD_BCN_BUILD_SALSUMM05_MT tssn, LD_BCN_OBJ_PICK_T pick, LD_BCN_INTINCBNT_T iinc \n");
277            sqlText.append("WHERE  ctrl.person_unvl_id = ? \n");
278            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
279            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
280            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
281            sqlText.append(" AND bcaf.emplid = iinc.emplid \n");
282            sqlText.append(" AND bcaf.emplid = tssn.emplid \n");
283            sqlText.append(" AND tssn.sesid = ? \n");
284            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
285            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
286            sqlText.append(" AND pick.select_flag > 0 \n");
287    
288            updateReportsSalarySummaryCommon.add(new SQLForStep(sqlText));
289            sqlText.delete(0, sqlText.length());
290    
291            /* get the detail recs for the set of EMPLIDs */
292            sqlText.append("INSERT INTO LD_BCN_SAL_FND_T \n");
293            sqlText.append("(PERSON_UNVL_ID, EMPLID, POSITION_NBR, UNIV_FISCAL_YR, FIN_COA_CD,  \n");
294            sqlText.append(" ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD) \n");
295            sqlText.append("SELECT DISTINCT ?, bcaf.emplid, bcaf.position_nbr, bcaf.univ_fiscal_yr, bcaf.fin_coa_cd, \n");
296            sqlText.append(" bcaf.account_nbr, bcaf.sub_acct_nbr, bcaf.fin_object_cd, bcaf.fin_sub_obj_cd \n");
297            sqlText.append("FROM LD_BCN_CTRL_LIST_T ctrl, LD_PNDBC_APPTFND_T bcaf, LD_BCN_BUILD_SALSUMM05_MT tssn, LD_BCN_OBJ_PICK_T pick \n");
298            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
299            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
300            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
301            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
302            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
303            sqlText.append(" AND bcaf.emplid = tssn.emplid \n");
304            sqlText.append(" AND tssn.sesid = ? \n");
305            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
306            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
307            sqlText.append(" AND pick.select_flag > 0 \n");
308              
309            updateReportsSalarySummaryCommon.add(new SQLForStep(sqlText));
310            sqlText.delete(0, sqlText.length());
311    
312        }
313    
314        /**
315         * 
316         * clean out all rows in the report tables associated with this user
317         * @param principalName--the user requesting the report
318         */
319        protected void clearUserPreviouSalarySummaryReports(String principalName) {
320            this.clearTempTableByUnvlId("LD_BCN_SAL_SSN_T", "PERSON_UNVL_ID", principalName);
321            this.clearTempTableByUnvlId("LD_BCN_SAL_FND_T", "PERSON_UNVL_ID", principalName);
322        }
323        
324        /**
325         * 
326         * clean out the work table used by all reports
327         * @param idForSession--the session which requested the report
328         */
329        protected void clearCommonWorkTable(String idForSession) {
330            this.clearTempTableBySesId("LD_BCN_BUILD_SALSUMM05_MT", "SESID", idForSession);
331        }
332        
333        /**
334         * 
335         * clean out the work tables for reporting by threshold
336         * @param idForSession--the session which requested the report
337         */
338        protected void clearThresholdWorkTables(String idForSession) {
339            this.clearTempTableBySesId("LD_BCN_BUILD_SALSUMM01_MT", "SESID", idForSession);
340            this.clearTempTableBySesId("LD_BCN_BUILD_SALSUMM02_MT", "SESID", idForSession);
341            this.clearTempTableBySesId("LD_BCN_BUILD_SALSUMM03_MT", "SESID", idForSession);
342            this.clearTempTableBySesId("LD_BCN_BUILD_SALSUMM04_MT", "SESID", idForSession);
343        }
344        
345        /**
346         * 
347         * runs SQL used by every report
348         * @param principalName--the user requesting the report
349         * @param idForSession--the session of the user
350         */
351        protected void runCommonSQLForSalaryReports(String principalName, String idForSession) {
352            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(0).getSQL(), principalName, principalName, idForSession);
353            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(1).getSQL(), principalName, principalName, idForSession);
354            clearCommonWorkTable(idForSession);
355        }
356        
357        /**
358         * 
359         * @see org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionSalarySummaryReportDao#salarySummaryReports(java.lang.String, java.lang.Integer, boolean, org.kuali.rice.kns.util.KualiDecimal)
360         */
361        public void updateSalaryAndReasonSummaryReportsWithThreshold(String principalName, Integer previousFiscalYear, boolean reportGreaterThanOrEqualToThreshold, KualiDecimal threshold) {
362            // get the session ID
363            Guid guid = new Guid();
364            String idForSession = guid.toString();
365            
366            // clean out anything left from a previous report requested by this user
367            clearUserPreviouSalarySummaryReports(principalName);
368            
369            // default duration code is inserted into a couple of the SQL queries--get it now
370            ArrayList<String> durationCodeDefault = new ArrayList<String>(2);
371            durationCodeDefault.add(BCConstants.VACANT_EMPLID);
372            durationCodeDefault.add(BCConstants.AppointmentFundingDurationCodes.NONE.durationCode);
373            
374            // fetch the base and request salary parameters for people who are marked as not going on leave
375            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(0).getSQL(durationCodeDefault), idForSession, principalName);
376            // fetch the base and request salary parameters for people who are marked as going on leave
377            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(1).getSQL(durationCodeDefault), idForSession, principalName);
378            // take request percent time, months appointment, and position months from the row with the largest request salary
379            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(2).getSQL(), idForSession, idForSession);
380            // take base percent time, months appointment, and position months from the row with the largest base salary
381            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(3).getSQL(), idForSession, idForSession, previousFiscalYear);
382            // combine the base and request months/percent time/position months into a single table
383            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(4).getSQL(), idForSession, idForSession);
384            // adjust the base salary so that it reflects the same appointment parameters as the request salary (increase it if the person will work 12 months this year, but worked only 10 last year, for example)
385            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(5).getSQL(), idForSession);
386            // adjust the base salary for changes in the position months versus last year
387            getSimpleJdbcTemplate().update(updateReportsSalarySummaryThreshold.get(6).getSQL(), idForSession);
388            // the salaries taken will either be above or below the threshold
389            // April 09, 2008: Jdbc (at least Oracle's implementation) chokes on a KualiDecimal, with a message that says "illegal column type"
390            // a simple cast to Number has the same result
391            // using the code below works
392            BigDecimal thresholdValue = threshold.bigDecimalValue();
393            if (reportGreaterThanOrEqualToThreshold)
394            {
395                getSimpleJdbcTemplate().update(salarySummaryAboveThreshold.get(0).getSQL(), idForSession, idForSession, thresholdValue);
396            }
397            else
398            {
399                getSimpleJdbcTemplate().update(salarySummaryBelowThreshold.get(0).getSQL(), idForSession, idForSession, thresholdValue);
400            }
401            // populate the holding table with the rows to be reported
402            // (only request is reported--the base was manipulated above to identify people above and below the threshold)
403            // name records for the rows to be reported
404            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(0).getSQL(), principalName, principalName, idForSession);
405            // salary data for the rows to be reported
406            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(1).getSQL(), principalName, principalName, idForSession);
407            
408            // clear out the threshold work tables for this session
409            clearThresholdWorkTables(idForSession);
410            // clear out the common work table for this session
411            clearCommonWorkTable(idForSession);
412            /**
413             * this is necessary to clear any rows for the tables we have just updated from the OJB cache.  otherwise, subsequent calls to OJB will fetch the old, unupdated cached rows.
414             */
415            persistenceService.clearCache();
416        }
417        
418    
419        /**
420         * 
421         * @see org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionSalarySummaryReportDao#reasonSummaryReports(java.lang.String, boolean)
422         */
423        public void updateSalaryAndReasonSummaryReportsWithoutThreshold(String principalName, boolean listSalariesWithReasonCodes) {
424            
425            // get the session ID
426            Guid guid = new Guid();
427            String idForSession = guid.toString();
428            
429            // get the insertion String for the vacant EMPLID
430            ArrayList<String> vacantEmplid = new ArrayList<String>(1);
431            vacantEmplid.add(BCConstants.VACANT_EMPLID);
432            
433            // clean out anything left from a previous report requested by this user
434            clearUserPreviouSalarySummaryReports(principalName);
435            
436            //  the option exists to report only those people with a salary increase reason code, or to report everyone
437            if (listSalariesWithReasonCodes)
438            {
439                getSimpleJdbcTemplate().update(updateReportsSalarySummaryNoThresholdReason.get(0).getSQL(vacantEmplid), idForSession, principalName);
440            }
441            else
442            {
443                getSimpleJdbcTemplate().update(updateReportsSalarySummaryNoThresholdNoReason.get(0).getSQL(vacantEmplid), idForSession, principalName);
444            }
445            // populate the holding table with the rows to be reported
446            // name records for the rows to be reported
447            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(0).getSQL(), principalName, principalName, idForSession);
448            // salary data for the rows to be reported
449            getSimpleJdbcTemplate().update(updateReportsSalarySummaryCommon.get(1).getSQL(), principalName, principalName, idForSession);
450            
451            // clear out the common work table for this session
452            clearCommonWorkTable(idForSession);
453            /**
454             * this is necessary to clear any rows for the tables we have just updated from the OJB cache.  otherwise, subsequent calls to OJB will fetch the old, unupdated cached rows.
455             */
456            persistenceService.clearCache();
457        }
458    
459        public void setPersistenceService(PersistenceService persistenceService)
460        {
461            this.persistenceService = persistenceService;
462        }
463    
464    }
465    
466    
467