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.io.ByteArrayOutputStream;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Locale;
024    import java.util.Map;
025    import java.util.ResourceBundle;
026    
027    import javax.servlet.http.HttpServletRequest;
028    import javax.servlet.http.HttpServletResponse;
029    
030    import net.sf.jasperreports.engine.JRParameter;
031    
032    import org.apache.struts.action.ActionForm;
033    import org.apache.struts.action.ActionForward;
034    import org.apache.struts.action.ActionMapping;
035    import org.kuali.kfs.module.bc.BCConstants;
036    import org.kuali.kfs.module.bc.BCKeyConstants;
037    import org.kuali.kfs.module.bc.BCPropertyConstants;
038    import org.kuali.kfs.module.bc.BudgetConstructionReportMode;
039    import org.kuali.kfs.module.bc.BCConstants.Report.ReportSelectMode;
040    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionObjectPick;
041    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPullup;
042    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionReasonCodePick;
043    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionReportThresholdSettings;
044    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionSubFundPick;
045    import org.kuali.kfs.module.bc.document.service.BudgetConstructionAccountFundingDetailReportService;
046    import org.kuali.kfs.module.bc.document.service.BudgetConstructionAccountObjectDetailReportService;
047    import org.kuali.kfs.module.bc.document.service.BudgetConstructionAccountSummaryReportService;
048    import org.kuali.kfs.module.bc.document.service.BudgetConstructionLevelSummaryReportService;
049    import org.kuali.kfs.module.bc.document.service.BudgetConstructionList2PLGReportService;
050    import org.kuali.kfs.module.bc.document.service.BudgetConstructionMonthSummaryReportService;
051    import org.kuali.kfs.module.bc.document.service.BudgetConstructionObjectSummaryReportService;
052    import org.kuali.kfs.module.bc.document.service.BudgetConstructionPositionFundingDetailReportService;
053    import org.kuali.kfs.module.bc.document.service.BudgetConstructionReasonStatisticsReportService;
054    import org.kuali.kfs.module.bc.document.service.BudgetConstructionReasonSummaryReportService;
055    import org.kuali.kfs.module.bc.document.service.BudgetConstructionReportsServiceHelper;
056    import org.kuali.kfs.module.bc.document.service.BudgetConstructionSalaryStatisticsReportService;
057    import org.kuali.kfs.module.bc.document.service.BudgetConstructionSalarySummaryReportService;
058    import org.kuali.kfs.module.bc.document.service.BudgetConstructionSubFundSummaryReportService;
059    import org.kuali.kfs.module.bc.document.service.BudgetConstructionSynchronizationProblemsReportService;
060    import org.kuali.kfs.module.bc.document.service.BudgetReportsControlListService;
061    import org.kuali.kfs.module.bc.report.ReportControlListBuildHelper;
062    import org.kuali.kfs.module.bc.util.BudgetUrlUtil;
063    import org.kuali.kfs.sys.KFSConstants;
064    import org.kuali.kfs.sys.KFSConstants.ReportGeneration;
065    import org.kuali.kfs.sys.context.SpringContext;
066    import org.kuali.kfs.sys.service.ReportGenerationService;
067    import org.kuali.rice.kns.util.GlobalVariables;
068    import org.kuali.rice.kns.util.WebUtils;
069    
070    /**
071     * Struts Action Class for the Organization Report Selection Screen.
072     */
073    public class OrganizationReportSelectionAction extends BudgetExpansionAction {
074        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrganizationReportSelectionAction.class);
075    
076        /**
077         * Called from org select or account listing. Checks for needed control list build, makes call to build control list if
078         * necessary, and forwards to subfund or object code select page.
079         */
080        public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
081            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
082            String principalName = GlobalVariables.getUserSession().getPerson().getPrincipalId();
083    
084            // retrieve report mode to determine how control list should be built and what select screen should be rendered
085            BudgetConstructionReportMode reportMode = BudgetConstructionReportMode.getBudgetConstructionReportModeByName(organizationReportSelectionForm.getReportMode());
086            if (reportMode == null) {
087                LOG.error("Invalid report mode passed to report select action: " + organizationReportSelectionForm.getReportMode());
088                throw new RuntimeException("Invalid report mode passed to report select action: " + organizationReportSelectionForm.getReportMode());
089            }
090    
091            // retrieve build helper to determine if a control list rebuild is needed
092            ReportControlListBuildHelper buildHelper = (ReportControlListBuildHelper) GlobalVariables.getUserSession().retrieveObject(BCConstants.Report.CONTROL_BUILD_HELPER_SESSION_NAME);
093            if (buildHelper == null) {
094                // session timeout, need to rebuild build request
095                buildHelper = new ReportControlListBuildHelper();
096    
097                Collection<BudgetConstructionPullup> selectedOrganizations = SpringContext.getBean(BudgetReportsControlListService.class).retrieveSelectedOrganziations(principalName);
098                buildHelper.addBuildRequest(organizationReportSelectionForm.getCurrentPointOfViewKeyCode(), selectedOrganizations, reportMode.reportBuildMode);
099                GlobalVariables.getUserSession().addObject(BCConstants.Report.CONTROL_BUILD_HELPER_SESSION_NAME, buildHelper);
100            }
101    
102            // do list builds
103            buildControlLists(principalName, organizationReportSelectionForm.getUniversityFiscalYear(), buildHelper, reportMode.reportSelectMode);
104    
105            // a few reports go just against the account control table, therefore we are ready to run the report
106            if (ReportSelectMode.ACCOUNT.equals(reportMode.reportSelectMode)) {
107                // fixed null point exception of operationgModeTitle.
108                organizationReportSelectionForm.setOperatingModeTitle(BCConstants.Report.NONE_SELECTION_TITLE);
109                return performReport(mapping, form, request, response);
110            }
111    
112            // setup action form
113            if (ReportSelectMode.SUBFUND.equals(reportMode.reportSelectMode)) {
114                organizationReportSelectionForm.setSubFundPickList((List) SpringContext.getBean(BudgetReportsControlListService.class).retrieveSubFundList(principalName));
115                organizationReportSelectionForm.setOperatingModeTitle(BCConstants.Report.SUB_FUND_SELECTION_TITLE);
116            }
117            else if (ReportSelectMode.OBJECT_CODE.equals(reportMode.reportSelectMode) || ReportSelectMode.REASON.equals(reportMode.reportSelectMode)) {
118                organizationReportSelectionForm.setObjectCodePickList((List) SpringContext.getBean(BudgetReportsControlListService.class).retrieveObjectCodeList(principalName));
119                organizationReportSelectionForm.setOperatingModeTitle(BCConstants.Report.OBJECT_CODE_SELECTION_TITLE);
120                organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings().setLockThreshold(reportMode.lockThreshold);
121            }
122    
123            return mapping.findForward(KFSConstants.MAPPING_BASIC);
124        }
125    
126        /**
127         * Makes service calls to rebuild the report control and sub-fund or object code select lists if needed.
128         * 
129         * @param principalName - current user requesting the report
130         * @param buildHelper - contains the current and requested build states
131         * @param reportSelectMode - indicates whether the report takes a sub-fund or object code select list
132         */
133        private void buildControlLists(String principalName, Integer universityFiscalYear, ReportControlListBuildHelper buildHelper, ReportSelectMode reportSelectMode) {
134            BudgetReportsControlListService budgetReportsControlListService = SpringContext.getBean(BudgetReportsControlListService.class);
135    
136            if (buildHelper.isBuildNeeded()) {
137                String[] pointOfViewFields = buildHelper.getRequestedState().getPointOfView().split("[-]");
138                budgetReportsControlListService.updateReportsControlList(principalName, universityFiscalYear, pointOfViewFields[0], pointOfViewFields[1], buildHelper.getRequestedState().getBuildMode());
139    
140                if (ReportSelectMode.SUBFUND.equals(reportSelectMode)) {
141                    budgetReportsControlListService.updateReportSubFundGroupSelectList(principalName);
142                }
143                else if (ReportSelectMode.OBJECT_CODE.equals(reportSelectMode) || ReportSelectMode.REASON.equals(reportSelectMode)) {
144                    budgetReportsControlListService.updateReportObjectCodeSelectList(principalName);
145                }
146    
147                buildHelper.requestBuildComplete();
148                GlobalVariables.getUserSession().addObject(BCConstants.Report.CONTROL_BUILD_HELPER_SESSION_NAME, buildHelper);
149            }
150        }
151    
152        /**
153         * Generates the Budget Report and returns pdf.
154         */
155        public ActionForward performReport(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
156            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
157            String principalId = GlobalVariables.getUserSession().getPerson().getPrincipalId();
158    
159            BudgetConstructionReportMode reportMode = BudgetConstructionReportMode.getBudgetConstructionReportModeByName(organizationReportSelectionForm.getReportMode());
160            if (!storeCodeSelections(organizationReportSelectionForm, reportMode, principalId)) {
161                return mapping.findForward(KFSConstants.MAPPING_BASIC);
162            }
163            
164            // validate threshold settings if needed
165            if (reportMode == BudgetConstructionReportMode.REASON_STATISTICS_REPORT || reportMode == BudgetConstructionReportMode.REASON_SUMMARY_REPORT || reportMode == BudgetConstructionReportMode.SALARY_SUMMARY_REPORT){
166                if (!this.validThresholdSettings(organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings())){
167                    return mapping.findForward(KFSConstants.MAPPING_BASIC);
168                }
169            }
170    
171            // for report exports foward to export action to display formatting screen
172            if (reportMode.export) {
173                String exportUrl = this.buildReportExportForwardURL(organizationReportSelectionForm, mapping);
174                return new ActionForward(exportUrl, true);
175            }
176    
177            // build report data and populate report objects for rendering
178            Collection reportSet = buildReportData(reportMode, organizationReportSelectionForm.getUniversityFiscalYear(), principalId, organizationReportSelectionForm.isReportConsolidation(), organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings());
179    
180            // build pdf and stream back
181            ByteArrayOutputStream baos = new ByteArrayOutputStream();
182    
183            // output the report or a message if empty
184            if (reportSet.isEmpty()) {
185                List<String> messageList = new ArrayList<String>();
186                messageList.add(BCConstants.Report.MSG_REPORT_NO_DATA);
187                SpringContext.getBean(BudgetConstructionReportsServiceHelper.class).generatePdf(messageList, baos);
188                WebUtils.saveMimeOutputStreamAsFile(response, ReportGeneration.PDF_MIME_TYPE, baos, reportMode.jasperFileName + ReportGeneration.PDF_FILE_EXTENSION);
189            }
190            else {
191                ResourceBundle resourceBundle = ResourceBundle.getBundle(BCConstants.Report.REPORT_MESSAGES_CLASSPATH, Locale.getDefault());
192                Map<String, Object> reportData = new HashMap<String, Object>();
193                reportData.put(JRParameter.REPORT_RESOURCE_BUNDLE, resourceBundle);
194    
195                SpringContext.getBean(ReportGenerationService.class).generateReportToOutputStream(reportData, reportSet, BCConstants.Report.REPORT_TEMPLATE_CLASSPATH + reportMode.jasperFileName, baos);
196                WebUtils.saveMimeOutputStreamAsFile(response, ReportGeneration.PDF_MIME_TYPE, baos, reportMode.jasperFileName + ReportGeneration.PDF_FILE_EXTENSION);
197            }
198            return null;
199        }
200    
201    
202        /**
203         * Checks and stores sub-fund, object code, or reason code list depenending on the report mode and which screen we are on.
204         * 
205         * @param organizationReportSelectionForm - OrganizationReportSelectionForm containing the select lists
206         * @param reportMode - BudgetConstructionReportMode for the report being ran
207         * @return - true if a selection was found and the list was stored or if we need to show reason code select screen, false
208         *         otherwise
209         */
210        private boolean storeCodeSelections(OrganizationReportSelectionForm organizationReportSelectionForm, BudgetConstructionReportMode reportMode, String principalName) {
211            boolean codeSelected = true;
212    
213            if (ReportSelectMode.SUBFUND.equals(reportMode.reportSelectMode)) {
214                // came from sub fund select screen so need to store sub fund selection settings
215                if (!storedSelectedSubFunds(organizationReportSelectionForm.getSubFundPickList())) {
216                    codeSelected = false;
217                }
218            }
219            else if (organizationReportSelectionForm.getOperatingModeTitle().equals(BCConstants.Report.OBJECT_CODE_SELECTION_TITLE)) {
220                // came from object code select screen so need to store object code selection settings
221                if (!storedSelectedObjectCodes(organizationReportSelectionForm.getObjectCodePickList())) {
222                    codeSelected = false;
223                }
224    
225                // determine if we need to setup reason code select
226                if (ReportSelectMode.REASON.equals(reportMode.reportSelectMode) && !organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings().isUseThreshold()) {
227                    BudgetReportsControlListService budgetReportsControlListService = SpringContext.getBean(BudgetReportsControlListService.class);
228    
229                    // rebuild reason code control list
230                    budgetReportsControlListService.updateReportReasonCodeSelectList(principalName);
231    
232                    // setup form
233                    organizationReportSelectionForm.setReasonCodePickList((List) budgetReportsControlListService.retrieveReasonCodeList(principalName));
234                    organizationReportSelectionForm.setOperatingModeTitle(BCConstants.Report.REASON_CODE_SELECTION_TITLE);
235                    codeSelected = false;
236                }
237            }
238            else if (organizationReportSelectionForm.getOperatingModeTitle().equals(BCConstants.Report.REASON_CODE_SELECTION_TITLE)) {
239                // came from reason code select screen so need to store reason code selection settings
240                if (!storedSelectedReasonCodes(organizationReportSelectionForm.getReasonCodePickList())) {
241                    codeSelected = false;
242                }
243            }
244    
245            return codeSelected;
246        }
247    
248        /**
249         * Calls the report service for the given reportMode to build the report data in the db then populate the reports objects for
250         * rendering to pdf.
251         * 
252         * @param reportMode - BudgetConstructionReportMode indicates which report we are running
253         * @param universityFiscalYear - budget fiscal year
254         * @param principalId - user running report
255         * @param runConsolidated - indicates whether the report should be ran consolidated (if it has a consolidated option)
256         * @param budgetConstructionReportThresholdSettings - contains threshold setting options
257         * @return Collection - Reports objects that contain built data
258         */
259        private Collection buildReportData(BudgetConstructionReportMode reportMode, Integer universityFiscalYear, String principalId, boolean runConsolidated, BudgetConstructionReportThresholdSettings budgetConstructionReportThresholdSettings) {
260            Collection reportData = new ArrayList();
261    
262            switch (reportMode) {
263                case ACCOUNT_SUMMARY_REPORT:
264                    SpringContext.getBean(BudgetConstructionAccountSummaryReportService.class).updateReportsAccountSummaryTable(principalId, runConsolidated);
265                    reportData = SpringContext.getBean(BudgetConstructionAccountSummaryReportService.class).buildReports(universityFiscalYear, principalId, runConsolidated);
266                    break;
267                case SUBFUND_SUMMARY_REPORT:
268                    SpringContext.getBean(BudgetConstructionSubFundSummaryReportService.class).updateSubFundSummaryReport(principalId);
269                    reportData = SpringContext.getBean(BudgetConstructionSubFundSummaryReportService.class).buildReports(universityFiscalYear, principalId);
270                    break;
271                case LEVEL_SUMMARY_REPORT:
272                    SpringContext.getBean(BudgetConstructionLevelSummaryReportService.class).updateLevelSummaryReport(principalId);
273                    reportData = SpringContext.getBean(BudgetConstructionLevelSummaryReportService.class).buildReports(universityFiscalYear, principalId);
274                    break;
275                case OBJECT_SUMMARY_REPORT:
276                    SpringContext.getBean(BudgetConstructionObjectSummaryReportService.class).updateObjectSummaryReport(principalId);
277                    reportData = SpringContext.getBean(BudgetConstructionObjectSummaryReportService.class).buildReports(universityFiscalYear, principalId);
278                    break;
279                case ACCOUNT_OBJECT_DETAIL_REPORT:
280                    SpringContext.getBean(BudgetConstructionAccountObjectDetailReportService.class).updateAccountObjectDetailReport(principalId, runConsolidated);
281                    reportData = SpringContext.getBean(BudgetConstructionAccountObjectDetailReportService.class).buildReports(universityFiscalYear, principalId, runConsolidated);
282                    break;
283                case ACCOUNT_FUNDING_DETAIL_REPORT:
284                    SpringContext.getBean(BudgetConstructionAccountFundingDetailReportService.class).updateAccountFundingDetailTable(principalId);
285                    reportData = SpringContext.getBean(BudgetConstructionAccountFundingDetailReportService.class).buildReports(universityFiscalYear, principalId);
286                    break;
287                case MONTH_SUMMARY_REPORT:
288                    SpringContext.getBean(BudgetConstructionMonthSummaryReportService.class).updateMonthSummaryReport(principalId, runConsolidated);
289                    reportData = SpringContext.getBean(BudgetConstructionMonthSummaryReportService.class).buildReports(universityFiscalYear, principalId, runConsolidated);
290                    break;
291                case POSITION_FUNDING_DETAIL_REPORT:
292                    SpringContext.getBean(BudgetConstructionPositionFundingDetailReportService.class).updatePositionFundingDetailReport(principalId, budgetConstructionReportThresholdSettings);
293                    reportData = SpringContext.getBean(BudgetConstructionPositionFundingDetailReportService.class).buildReports(universityFiscalYear, principalId);
294                    break;
295                case SALARY_SUMMARY_REPORT:
296                    SpringContext.getBean(BudgetConstructionSalarySummaryReportService.class).updateSalarySummaryReport(principalId, universityFiscalYear, budgetConstructionReportThresholdSettings);
297                    reportData = SpringContext.getBean(BudgetConstructionSalarySummaryReportService.class).buildReports(universityFiscalYear, principalId, budgetConstructionReportThresholdSettings);
298                    break;
299                case SALARY_STATISTICS_REPORT:
300                    SpringContext.getBean(BudgetConstructionSalaryStatisticsReportService.class).updateSalaryStatisticsReport(principalId, universityFiscalYear);
301                    reportData = SpringContext.getBean(BudgetConstructionSalaryStatisticsReportService.class).buildReports(universityFiscalYear, principalId);
302                    break;
303                case REASON_SUMMARY_REPORT:
304                    SpringContext.getBean(BudgetConstructionReasonSummaryReportService.class).updateReasonSummaryReport(principalId, universityFiscalYear, budgetConstructionReportThresholdSettings);
305                    reportData = SpringContext.getBean(BudgetConstructionReasonSummaryReportService.class).buildReports(universityFiscalYear, principalId, budgetConstructionReportThresholdSettings);
306                    break;
307                case REASON_STATISTICS_REPORT:
308                    SpringContext.getBean(BudgetConstructionReasonStatisticsReportService.class).updateReasonStatisticsReport(principalId, universityFiscalYear, budgetConstructionReportThresholdSettings);
309                    reportData = SpringContext.getBean(BudgetConstructionReasonStatisticsReportService.class).buildReports(universityFiscalYear, principalId, budgetConstructionReportThresholdSettings);
310                    break;
311    
312                case TWOPLG_LIST_REPORT:
313                    SpringContext.getBean(BudgetConstructionList2PLGReportService.class).updateList2PLGReport(principalId, universityFiscalYear);
314                    reportData = SpringContext.getBean(BudgetConstructionList2PLGReportService.class).buildReports(universityFiscalYear, principalId);
315                    break;
316    
317                case SYNCHRONIZATION_PROBLEMS_REPORT:
318                    SpringContext.getBean(BudgetConstructionSynchronizationProblemsReportService.class).updateSynchronizationProblemsReport(principalId);
319                    reportData = SpringContext.getBean(BudgetConstructionSynchronizationProblemsReportService.class).buildReports(universityFiscalYear, principalId);
320                    break;
321    
322            }
323    
324            return reportData;
325        }
326    
327        /**
328         * Builds URL for the report dump url.
329         */
330        private String buildReportExportForwardURL(OrganizationReportSelectionForm organizationReportSelectionForm, ActionMapping mapping) {
331            Map<String, String> parameters = new HashMap<String, String>();
332            parameters.put(BCConstants.Report.REPORT_MODE, organizationReportSelectionForm.getReportMode());
333            parameters.put(BCConstants.IS_ORG_REPORT_REQUEST_PARAMETER, "true");
334    
335            return BudgetUrlUtil.buildBudgetUrl(mapping, organizationReportSelectionForm, BCConstants.REPORT_EXPORT_ACTION, parameters);
336        }
337    
338        /**
339         * Selects all sub-fund codes.
340         */
341        public ActionForward selectAllSubFunds(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
342            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
343            for (BudgetConstructionSubFundPick budgetConstructionSubFundPick : organizationReportSelectionForm.getSubFundPickList()) {
344                budgetConstructionSubFundPick.setReportFlag(new Integer(1));
345            }
346    
347            return mapping.findForward(KFSConstants.MAPPING_BASIC);
348        }
349    
350        /**
351         * Selects all object codes.
352         */
353        public ActionForward selectAllObjectCodes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
354            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
355            for (BudgetConstructionObjectPick budgetConstructionObjectPick : organizationReportSelectionForm.getObjectCodePickList()) {
356                budgetConstructionObjectPick.setSelectFlag(new Integer(1));
357            }
358    
359            return mapping.findForward(KFSConstants.MAPPING_BASIC);
360        }
361    
362        /**
363         * Selects all reason codes.
364         */
365        public ActionForward selectAllReasonCodes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
366            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
367            for (BudgetConstructionReasonCodePick budgetConstructionReasonCodePick : organizationReportSelectionForm.getReasonCodePickList()) {
368                budgetConstructionReasonCodePick.setSelectFlag(new Integer(1));
369            }
370    
371            return mapping.findForward(KFSConstants.MAPPING_BASIC);
372        }
373    
374        /**
375         * Unselects all sub-fund codes.
376         */
377        public ActionForward unselectAllSubFunds(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
378            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
379            for (BudgetConstructionSubFundPick budgetConstructionSubFundPick : organizationReportSelectionForm.getSubFundPickList()) {
380                budgetConstructionSubFundPick.setReportFlag(new Integer(0));
381            }
382    
383            return mapping.findForward(KFSConstants.MAPPING_BASIC);
384        }
385    
386        /**
387         * unselects all object codes.
388         */
389        public ActionForward unselectAllObjectCodes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
390            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
391            for (BudgetConstructionObjectPick budgetConstructionObjectPick : organizationReportSelectionForm.getObjectCodePickList()) {
392                budgetConstructionObjectPick.setSelectFlag(new Integer(0));
393            }
394    
395            return mapping.findForward(KFSConstants.MAPPING_BASIC);
396        }
397    
398        /**
399         * Unselects all reason codes.
400         */
401        public ActionForward unselectAllReasonCodes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
402            OrganizationReportSelectionForm organizationReportSelectionForm = (OrganizationReportSelectionForm) form;
403            for (BudgetConstructionReasonCodePick budgetConstructionReasonCodePick : organizationReportSelectionForm.getReasonCodePickList()) {
404                budgetConstructionReasonCodePick.setSelectFlag(new Integer(0));
405            }
406    
407            return mapping.findForward(KFSConstants.MAPPING_BASIC);
408        }
409    
410        /**
411         * Checks that at least one sub fund is selected and stores the selection settings. If no sub fund is selected, an error message
412         * is displayed to the user.
413         * 
414         * @param subFundPickList - List of BudgetConstructionSubFundPick objects to check
415         * @return boolean - true if there was a selection and the list was saved, otherwise false
416         */
417        protected boolean storedSelectedSubFunds(List<BudgetConstructionSubFundPick> subFundPickList) {
418            boolean foundSelected = false;
419    
420            // check to see if at least one pullflag is set and store the reportflag settings for currently displayed set of sub-funds
421            for (BudgetConstructionSubFundPick budgetConstructionSubFundPick : subFundPickList) {
422                if (budgetConstructionSubFundPick.getReportFlag() > 0) {
423                    foundSelected = true;
424                }
425            }
426    
427            // if selection was found, save the sub-fund selections, otherwise build error message
428            if (foundSelected) {
429                SpringContext.getBean(BudgetReportsControlListService.class).updateSubFundSelectFlags(subFundPickList);
430            }
431            else {
432                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_SUBFUND_NOT_SELECTED);
433            }
434    
435            return foundSelected;
436        }
437    
438        /**
439         * Checks that at least one object code is selected and stores the selection settings. If no object code is selected, an error
440         * message is displayed to the user.
441         * 
442         * @param objectCodePickList - List of BudgetConstructionObjectPick objects to check
443         * @return boolean - true if there was a selection and the list was saved, otherwise false
444         */
445        protected boolean storedSelectedObjectCodes(List<BudgetConstructionObjectPick> objectCodePickList) {
446            boolean foundSelected = false;
447    
448            // check to see if at least one pullflag is set and store the selectFlag settings for currently displayed set of object
449            // codes
450            for (BudgetConstructionObjectPick budgetConstructionObjectPick : objectCodePickList) {
451                if (budgetConstructionObjectPick.getSelectFlag() > 0) {
452                    foundSelected = true;
453                }
454            }
455    
456            // if selection was found, save the object code selections, otherwise build error message
457            if (foundSelected) {
458                SpringContext.getBean(BudgetReportsControlListService.class).updateObjectCodeSelectFlags(objectCodePickList);
459            }
460            else {
461                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_OBJECT_CODE_NOT_SELECTED);
462            }
463    
464            return foundSelected;
465        }
466    
467        /**
468         * Checks that at least one reason code is selected and stores the selection settings. If no reason code is selected, an error
469         * message is displayed to the user.
470         * 
471         * @param reasonCodePickList - List of BudgetConstructionReasonCodePick objects to check
472         * @return boolean - true if there was a selection and the list was saved, otherwise false
473         */
474        protected boolean storedSelectedReasonCodes(List<BudgetConstructionReasonCodePick> reasonCodePickList) {
475            boolean foundSelected = false;
476    
477            // check to see if at least one pullflag is set and store the selectFlag settings for currently displayed set of reason
478            // codes
479            for (BudgetConstructionReasonCodePick budgetConstructionReasonCodePick : reasonCodePickList) {
480                if (budgetConstructionReasonCodePick.getSelectFlag() > 0) {
481                    foundSelected = true;
482                }
483            }
484    
485            // if selection was found, save the reason code selections, otherwise build error message
486            if (foundSelected) {
487                SpringContext.getBean(BudgetReportsControlListService.class).updateReasonCodeSelectFlags(reasonCodePickList);
488            }
489            else {
490                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, BCKeyConstants.ERROR_BUDGET_REASON_CODE_NOT_SELECTED);
491            }
492    
493            return foundSelected;
494        }
495    
496        /**
497         * When apply threshold is checked, and displays error if no percent change threshold value is set.  
498         * 
499         * @param thresholdSettings
500         * @return
501         */
502        protected boolean validThresholdSettings(BudgetConstructionReportThresholdSettings thresholdSettings){
503            Boolean thresholdSettingsValid = true;
504            if (thresholdSettings.isUseThreshold()){
505                if (thresholdSettings.getThresholdPercent() == null){
506                    thresholdSettingsValid = false;
507                    GlobalVariables.getMessageMap().putError(BCPropertyConstants.BUDGET_CONSTRUCTION_REPORT_THRESHOLD_SETTINGS+"."+BCPropertyConstants.THRESHOLD_PERCENT, BCKeyConstants.ERROR_BUDGET_THRESHOLD_PERCENT_NEEDED);
508                }
509            }
510            return thresholdSettingsValid;
511        }
512    }