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.util.ArrayList;
019    
020    import org.kuali.kfs.module.bc.batch.dataaccess.impl.SQLForStep;
021    import org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionPositionFundingDetailReportDao;
022    import org.kuali.rice.kns.service.PersistenceService;
023    import org.kuali.rice.kns.util.Guid;
024    import org.kuali.rice.kns.util.KualiDecimal;
025    
026    
027    /**
028     * populates the report table for positon funding detail for a given user
029     */
030    
031    public class BudgetConstructionPositionFundingDetailReportDaoJdbc extends BudgetConstructionDaoJdbcBase implements BudgetConstructionPositionFundingDetailReportDao {
032        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetConstructionPositionFundingDetailReportDaoJdbc.class);
033    
034        private static ArrayList<SQLForStep> updateReportsPositionFundingDetailTable = new ArrayList<SQLForStep>(5);
035        
036        private PersistenceService persistenceService;
037        
038        public BudgetConstructionPositionFundingDetailReportDaoJdbc() {
039            
040            /* populate the table based on threshold settings */
041            /* sum the request and base by ssn */
042            StringBuilder sqlText = new StringBuilder(1500);
043            sqlText.append("INSERT INTO LD_BCN_BUILD_POSLIST01_MT \n");
044            sqlText.append("(SESID, EMPLID, POS_CSF_AMT, POS_CSF_FTE_QTY, APPT_RQST_AMT, APPT_RQST_FTE_QTY) \n");
045            sqlText.append("SELECT ?, bcaf.emplid, SUM(COALESCE(bcsf.pos_csf_amt,0)), SUM(COALESCE(bcsf.pos_csf_fte_qty,0)), SUM(bcaf.appt_rqst_amt), SUM(bcaf.appt_rqst_fte_qty) \n");
046            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_CSF_TRCKR_T bcsf ON \n");
047            sqlText.append(" ((bcaf.univ_fiscal_yr = bcsf.univ_fiscal_yr) AND \n");
048            sqlText.append(" (bcaf.fin_coa_cd = bcsf.fin_coa_cd) AND \n");
049            sqlText.append(" (bcaf.account_nbr = bcsf.account_nbr) AND \n");
050            sqlText.append(" (bcaf.sub_acct_nbr = bcsf.sub_acct_nbr) AND \n");
051            sqlText.append(" (bcaf.fin_object_cd = bcsf.fin_object_cd) AND \n");
052            sqlText.append(" (bcaf.fin_sub_obj_cd = bcsf.fin_sub_obj_cd) AND \n");
053            sqlText.append(" (bcaf.position_nbr = bcsf.position_nbr) AND \n");
054            sqlText.append(" (bcaf.emplid = bcsf.emplid))), LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick \n");
055            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
056            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
057            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
058            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
059            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
060            sqlText.append(" AND bcaf.appt_rqst_amt <> 0 \n");
061            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
062            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
063            sqlText.append(" AND pick.select_flag > 0 \n");
064            sqlText.append("GROUP BY bcaf.emplid \n");          
065    
066            updateReportsPositionFundingDetailTable.add(new SQLForStep(sqlText));
067            sqlText.delete(0, sqlText.length());
068            
069            /* get the set where percent change (fraction * 100) in the salary exceeds the threshold */
070            sqlText.append("INSERT INTO LD_BCN_POS_FND_T \n");
071            sqlText.append(" (PERSON_UNVL_ID, SEL_ORG_FIN_COA, SEL_ORG_CD, PERSON_NM, EMPLID, POSITION_NBR, UNIV_FISCAL_YR, \n");
072            sqlText.append(" FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD) \n");
073            sqlText.append("SELECT ?, ctrl.sel_org_fin_coa, ctrl.sel_org_cd, COALESCE(iinc.person_nm,'VACANT'), bcaf.emplid, bcaf.position_nbr, bcaf.univ_fiscal_yr,\n");
074            sqlText.append(" bcaf.fin_coa_cd, bcaf.account_nbr, bcaf.sub_acct_nbr, bcaf.fin_object_cd, bcaf.fin_sub_obj_cd \n");
075            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_INTINCBNT_T iinc \n");
076            sqlText.append(" ON (bcaf.emplid = iinc.emplid)), LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick, LD_BCN_BUILD_POSLIST01_MT tssn \n");
077            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
078            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
079            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
080            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
081            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
082            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
083            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
084            sqlText.append(" AND pick.select_flag > 0 \n");
085            sqlText.append(" AND bcaf.emplid = tssn.emplid \n");
086            sqlText.append(" AND tssn.appt_rqst_fte_qty = tssn.pos_csf_fte_qty \n");
087            sqlText.append(" AND ROUND((((tssn.appt_rqst_amt - tssn.pos_csf_amt) / tssn.pos_csf_amt) * 100),1) >= ? \n");
088            sqlText.append(" AND tssn.pos_csf_amt <> 0 \n");
089            sqlText.append(" AND tssn.sesid = ? \n");
090                                                
091            updateReportsPositionFundingDetailTable.add(new SQLForStep(sqlText));
092            sqlText.delete(0, sqlText.length());
093            
094            /* get the set where the percent change (fraction * 100) in the salary is less than or equal to the threshold */        
095            sqlText.append("INSERT INTO LD_BCN_POS_FND_T \n");
096            sqlText.append(" (PERSON_UNVL_ID, SEL_ORG_FIN_COA, SEL_ORG_CD, PERSON_NM, EMPLID, POSITION_NBR, UNIV_FISCAL_YR, \n");
097            sqlText.append(" FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD) \n");
098            sqlText.append(" SELECT ?, ctrl.sel_org_fin_coa, ctrl.sel_org_cd, COALESCE(iinc.person_nm,'VACANT'), bcaf.emplid, bcaf.position_nbr, bcaf.univ_fiscal_yr, \n");
099            sqlText.append(" bcaf.fin_coa_cd, bcaf.account_nbr, bcaf.sub_acct_nbr, bcaf.fin_object_cd, bcaf.fin_sub_obj_cd \n");
100            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_INTINCBNT_T iinc ON (bcaf.emplid = iinc.emplid)), \n");
101            sqlText.append(" LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick, LD_BCN_BUILD_POSLIST01_MT tssn \n");
102            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
103            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
104            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
105            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
106            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
107            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
108            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
109            sqlText.append(" AND pick.select_flag > 0 \n");
110            sqlText.append(" AND bcaf.emplid = tssn.emplid \n");
111            sqlText.append(" AND tssn.appt_rqst_fte_qty = tssn.pos_csf_fte_qty \n");
112            sqlText.append(" AND ROUND((((tssn.appt_rqst_amt - tssn.pos_csf_amt) / tssn.pos_csf_amt) * 100),1) <= ? \n");
113            sqlText.append(" AND tssn.pos_csf_amt <> 0 \n");
114            sqlText.append(" AND tssn.sesid = ? \n");
115            
116            updateReportsPositionFundingDetailTable.add(new SQLForStep(sqlText));
117            sqlText.delete(0, sqlText.length());
118            
119            /* populate the table using the full set--no check on the percent change in the salary */
120            sqlText.append("INSERT INTO LD_BCN_POS_FND_T \n");
121            sqlText.append(" (PERSON_UNVL_ID, SEL_ORG_FIN_COA, SEL_ORG_CD, PERSON_NM, EMPLID, POSITION_NBR, UNIV_FISCAL_YR, \n");
122            sqlText.append(" FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD) \n");
123            sqlText.append("SELECT ?, ctrl.sel_org_fin_coa, ctrl.sel_org_cd, COALESCE(iinc.person_nm,'VACANT'), bcaf.emplid, bcaf.position_nbr, bcaf.univ_fiscal_yr, \n");
124            sqlText.append(" bcaf.fin_coa_cd, bcaf.account_nbr, bcaf.sub_acct_nbr, bcaf.fin_object_cd, bcaf.fin_sub_obj_cd \n");
125            sqlText.append("FROM (LD_PNDBC_APPTFND_T bcaf LEFT OUTER JOIN LD_BCN_INTINCBNT_T iinc \n");
126            sqlText.append(" ON (bcaf.emplid = iinc.emplid)), LD_BCN_CTRL_LIST_T ctrl, LD_BCN_OBJ_PICK_T pick \n");
127            sqlText.append("WHERE ctrl.person_unvl_id = ? \n");
128            sqlText.append(" AND bcaf.univ_fiscal_yr = ctrl.univ_fiscal_yr \n");
129            sqlText.append(" AND bcaf.fin_coa_cd = ctrl.fin_coa_cd \n");
130            sqlText.append(" AND bcaf.account_nbr = ctrl.account_nbr \n");
131            sqlText.append(" AND bcaf.sub_acct_nbr = ctrl.sub_acct_nbr \n");
132            sqlText.append(" AND bcaf.fin_object_cd = pick.fin_object_cd \n");
133            sqlText.append(" AND pick.person_unvl_id = ctrl.person_unvl_id \n");
134            sqlText.append(" AND pick.select_flag > 0 \n");
135            
136            updateReportsPositionFundingDetailTable.add(new SQLForStep(sqlText));
137            sqlText.delete(0, sqlText.length());
138        }
139        
140        public void cleanReportsPositionFundingDetailTable(String principalName) {
141            clearTempTableByUnvlId("LD_BCN_POS_FND_T", "PERSON_UNVL_ID", principalName);
142            /**
143             * 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.
144             */
145            persistenceService.clearCache();
146        }
147        /**
148         * 
149         * build a list of people with salaries at or above the threshold
150         * @param principalName--the user requesting the list
151         * @param thresholdPercent--the percent marking the threshold
152         */
153        protected void updateReportsPositionFundingDetailTableAboveThreshold(String principalName, KualiDecimal thresholdPercent)
154        {
155            Guid guid = new Guid();
156            String idForSession = guid.toString();
157            // get rid of any previous reporting data from this user
158            cleanReportsPositionFundingDetailTable(principalName);
159            // sum the FTE and amounts into a temporary table
160            getSimpleJdbcTemplate().update(updateReportsPositionFundingDetailTable.get(0).getSQL(),idForSession,principalName);
161            // fill the reporting table with only those people who are at or above the threshold
162            // (jdbcTemplate will apparenlty not accept a parameter of type KualiDecimal, and a cast when we pass the parameter doesn't help: 04/09/2008)
163            // (apparently, creating a new value from a cast doesn't help either)
164            Number thresholdValue = thresholdPercent.floatValue();
165            getSimpleJdbcTemplate().update(updateReportsPositionFundingDetailTable.get(1).getSQL(),principalName, principalName, thresholdValue, idForSession);
166            // remove the data for this user's session from the temporary table for total amounts and FTE
167            this.clearTempTableBySesId("LD_BCN_BUILD_POSLIST01_MT","SESID",idForSession);
168        }
169    
170        /**
171         * 
172         * build a list of people with salaries at or below the threshhold
173         * @param principalName--the user requesting the list
174         * @param thresholdPercent--the percent marking the threshold
175         */
176        protected void updateReportsPositionFundingDetailTableBelowThreshold(String principalName, KualiDecimal thresholdPercent)
177        {
178            Guid guid = new Guid();
179            String idForSession = guid.toString();
180            // get rid of any previous reporting data from this user
181            cleanReportsPositionFundingDetailTable(principalName);
182            // sum the FTE and amounts into a temporary table
183            getSimpleJdbcTemplate().update(updateReportsPositionFundingDetailTable.get(0).getSQL(),idForSession,principalName);
184            // fill the reporting table with only those people who are at or below the threshold
185            // (jdbcTemplate will apparenlty not accept a parameter of type KualiDecimal, and a cast when we pass the parameter doesn't help: 04/09/2008)
186            // (apparently, creating a new value from a cast doesn't help either)
187            Number thresholdValue = thresholdPercent.floatValue();
188            getSimpleJdbcTemplate().update(updateReportsPositionFundingDetailTable.get(2).getSQL(),principalName, principalName, thresholdValue, idForSession);
189            // remove the data for this user's session from the temporary table for total amounts and FTE
190            this.clearTempTableBySesId("LD_BCN_BUILD_POSLIST01_MT","SESID",idForSession);
191        }
192        
193        /**
194         * 
195         * build a list of all salaries which this user can see
196         * @param principalName--the user requesting the list
197         */
198        protected void updateReportsPositionFundingDetailTableWithAllData(String principalName)
199        {
200            // get rid of any previous reporting data from this user
201            cleanReportsPositionFundingDetailTable(principalName);
202            // dump all the data this user is authorized to report on into the reporting table
203            getSimpleJdbcTemplate().update(updateReportsPositionFundingDetailTable.get(3).getSQL(), principalName, principalName);
204        }
205    
206        /**
207         * 
208         * @see org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionPositionFundingDetailReportDao#updateReportsPositionFundingDetailTable(java.lang.String, boolean, boolean, java.lang.Number)
209         */
210        public void updateReportsPositionFundingDetailTable(String principalName, boolean applyAThreshold, boolean selectOnlyGreaterThanOrEqualToThreshold, KualiDecimal thresholdPercent) {
211            // if there is no threshold, just dump everything in and return
212            if (! applyAThreshold)
213            {
214                updateReportsPositionFundingDetailTableWithAllData(principalName);
215                return;
216            }
217            // the user wants a threshold--list above or below?
218            if (selectOnlyGreaterThanOrEqualToThreshold)
219            {
220                updateReportsPositionFundingDetailTableAboveThreshold(principalName, thresholdPercent);
221            }
222            else
223            {
224                updateReportsPositionFundingDetailTableBelowThreshold(principalName, thresholdPercent);
225            }
226            /**
227             * 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.
228             */
229            persistenceService.clearCache();
230        }
231        
232        public void setPersistenceService(PersistenceService persistenceService)
233        {
234            this.persistenceService = persistenceService;
235        }
236    
237    }
238