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.sec.businessobject.lookup;
017    
018    import java.util.ArrayList;
019    import java.util.Iterator;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.kuali.kfs.coa.service.ObjectTypeService;
025    import org.kuali.kfs.gl.GeneralLedgerConstants;
026    import org.kuali.kfs.gl.businessobject.AccountBalance;
027    import org.kuali.kfs.gl.businessobject.TransientBalanceInquiryAttributes;
028    import org.kuali.kfs.gl.businessobject.lookup.AccountBalanceByConsolidationLookupableHelperServiceImpl;
029    import org.kuali.kfs.gl.service.AccountBalanceService;
030    import org.kuali.kfs.sec.SecKeyConstants;
031    import org.kuali.kfs.sec.service.AccessSecurityService;
032    import org.kuali.kfs.sec.util.SecUtil;
033    import org.kuali.kfs.sys.KFSConstants;
034    import org.kuali.kfs.sys.KFSKeyConstants;
035    import org.kuali.kfs.sys.KFSPropertyConstants;
036    import org.kuali.kfs.sys.context.SpringContext;
037    import org.kuali.rice.kns.bo.BusinessObject;
038    import org.kuali.rice.kns.lookup.CollectionIncomplete;
039    import org.kuali.rice.kns.service.KualiConfigurationService;
040    import org.kuali.rice.kns.util.GlobalVariables;
041    
042    
043    /**
044     * Override of AccountBalanceByConsolidation lookup helper to integrate access security
045     */
046    public class AccessSecurityAccountBalanceByConsolidationLookupableHelperServiceImpl extends AccountBalanceByConsolidationLookupableHelperServiceImpl {
047        protected AccessSecurityService accessSecurityService;
048        protected ObjectTypeService objectTypeService;
049        protected KualiConfigurationService kualiConfigurationService;
050    
051        /**
052         * Checks security on the detail balance records, if user does not have access to view any of those records they are removed and total lines
053         * are updated
054         * 
055         * @see org.kuali.kfs.gl.businessobject.lookup.AccountBalanceByConsolidationLookupableHelperServiceImpl#getSearchResults(java.util.Map)
056         */
057        @Override
058        public List<? extends BusinessObject> getSearchResults(Map fieldValues) {
059            AccountBalanceByConsolidationLookupableHelperServiceImpl helperServiceImpl = new AccountBalanceByConsolidationLookupableHelperServiceImpl();
060            helperServiceImpl.setAccountBalanceService(SpringContext.getBean(AccountBalanceService.class));
061            List<? extends BusinessObject> results = helperServiceImpl.getSearchResults(fieldValues);
062    
063            // first 7 items of results are total lines, so we need to check any detail lines after than
064            if (results.size() > 7) {
065                List details = results.subList(7, results.size());
066    
067                int resultSizeBeforeRestrictions = details.size();
068                accessSecurityService.applySecurityRestrictionsForGLInquiry(details, GlobalVariables.getUserSession().getPerson());
069    
070                SecUtil.compareListSizeAndAddMessageIfChanged(resultSizeBeforeRestrictions, details, SecKeyConstants.MESSAGE_BALANCE_INQUIRY_RESULTS_RESTRICTED);
071    
072                // if details have changed we need to update totals
073                if (resultSizeBeforeRestrictions != details.size()) {
074                    String subAccountNumber = (String) fieldValues.get(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
075                    String fiscalYear = (String) fieldValues.get(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
076                    Integer universityFiscalYear = new Integer(Integer.parseInt(fiscalYear));
077    
078                    // Dashes means no sub account number
079                    if (KFSConstants.getDashSubAccountNumber().equals(subAccountNumber)) {
080                        subAccountNumber = "";
081                    }
082    
083                    TransientBalanceInquiryAttributes dbo = ((AccountBalance) results.get(0)).getDummyBusinessObject();
084    
085                    List totals = buildAccountBalanceTotals(details, universityFiscalYear, subAccountNumber, dbo);
086                    totals.addAll(details);
087    
088                    return new CollectionIncomplete(totals, new Long(totals.size()));
089                }
090            }
091    
092            return results;
093        }
094    
095        /**
096         * Rebuilds the account balance total lines, logic mostly duplicated from AccountBalanceServiceImpl:findAccountBalanceByConsolidation
097         * 
098         * @param balanceDetails List of AccountBalance detail lines
099         * @param universityFiscalYear Fiscal Year being searched
100         * @param subAccountNumber Sub Account number being searched 
101         * @param dbo TransientBalanceInquiryAttributes object that will be set on total lines
102         * @return List of AccountBalance total lines
103         */
104        protected List buildAccountBalanceTotals(List balanceDetails, Integer universityFiscalYear, String subAccountNumber, TransientBalanceInquiryAttributes dbo) {
105            List totals = new ArrayList();
106    
107            List incomeObjectTypes = objectTypeService.getBasicIncomeObjectTypes(universityFiscalYear);
108            String incomeTransferObjectType = objectTypeService.getIncomeTransferObjectType(universityFiscalYear);
109            List expenseObjectTypes = objectTypeService.getBasicExpenseObjectTypes(universityFiscalYear);
110            String expenseTransferObjectType = objectTypeService.getExpenseTransferObjectType(universityFiscalYear);
111    
112            AccountBalance income = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.INCOME));
113            AccountBalance incomeTransfers = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.INCOME_FROM_TRANSFERS));
114            AccountBalance incomeTotal = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.INCOME_TOTAL));
115            AccountBalance expense = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.EXPENSE));
116            AccountBalance expenseTransfers = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.EXPENSE_FROM_TRANSFERS));
117            AccountBalance expenseTotal = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.EXPENSE_TOTAL));
118            AccountBalance total = new AccountBalance(kualiConfigurationService.getPropertyString(KFSKeyConstants.AccountBalanceService.TOTAL));
119    
120            totals.add(income);
121            totals.add(incomeTransfers);
122            totals.add(incomeTotal);
123            totals.add(expense);
124            totals.add(expenseTransfers);
125            totals.add(expenseTotal);
126            totals.add(total);
127    
128            // set the dummy business object that was built in super lookupable
129            for (Iterator iterator = totals.iterator(); iterator.hasNext();) {
130                AccountBalance totalBalance = (AccountBalance) iterator.next();
131                total.setDummyBusinessObject(dbo);
132            }
133    
134            boolean subAccountBlank = StringUtils.isBlank(subAccountNumber);
135    
136            // iterate over details and update total line based on object type
137            for (Iterator iterator = balanceDetails.iterator(); iterator.hasNext();) {
138                AccountBalance detail = (AccountBalance) iterator.next();
139                String objectType = detail.getFinancialObject().getFinancialObjectTypeCode();
140    
141                if (incomeObjectTypes.contains(objectType)) {
142                    String transferExpenseCode = detail.getFinancialObject().getFinancialObjectLevel().getFinancialConsolidationObject().getFinConsolidationObjectCode();
143                    if (!subAccountBlank && transferExpenseCode.equals(GeneralLedgerConstants.INCOME_OR_EXPENSE_TRANSFER_CONSOLIDATION_CODE)) {
144                        incomeTransfers.add(detail);
145                    }
146                    else {
147                        income.add(detail);
148                    }
149    
150                    incomeTotal.add(detail);
151                }
152    
153                if (incomeTransferObjectType.equals(objectType)) {
154                    incomeTransfers.add(detail);
155                    incomeTotal.add(detail);
156                }
157    
158                if (expenseObjectTypes.contains(objectType)) {
159                    String transferExpenseCode = detail.getFinancialObject().getFinancialObjectLevel().getFinancialConsolidationObject().getFinConsolidationObjectCode();
160                    if (!subAccountBlank && transferExpenseCode.equals(GeneralLedgerConstants.INCOME_OR_EXPENSE_TRANSFER_CONSOLIDATION_CODE)) {
161                        expenseTransfers.add(detail);
162                    }
163                    else {
164                        expense.add(detail);
165                    }
166    
167                    expenseTotal.add(detail);
168                }
169    
170                if (expenseTransferObjectType.equals(objectType)) {
171                    expenseTransfers.add(detail);
172                    expenseTransfers.add(detail);
173                }
174            }
175    
176            // Add up variances
177            income.getDummyBusinessObject().setGenericAmount(income.getAccountLineActualsBalanceAmount().add(income.getAccountLineEncumbranceBalanceAmount()).subtract(income.getCurrentBudgetLineBalanceAmount()));
178            incomeTransfers.getDummyBusinessObject().setGenericAmount(incomeTransfers.getAccountLineActualsBalanceAmount().add(incomeTransfers.getAccountLineEncumbranceBalanceAmount()).subtract(incomeTransfers.getCurrentBudgetLineBalanceAmount()));
179            incomeTotal.getDummyBusinessObject().setGenericAmount(income.getDummyBusinessObject().getGenericAmount().add(incomeTransfers.getDummyBusinessObject().getGenericAmount()));
180    
181            expense.getDummyBusinessObject().setGenericAmount(expense.getCurrentBudgetLineBalanceAmount().subtract(expense.getAccountLineActualsBalanceAmount()).subtract(expense.getAccountLineEncumbranceBalanceAmount()));
182            expenseTransfers.getDummyBusinessObject().setGenericAmount(expenseTransfers.getCurrentBudgetLineBalanceAmount().subtract(expenseTransfers.getAccountLineActualsBalanceAmount()).subtract(expenseTransfers.getAccountLineEncumbranceBalanceAmount()));
183            expenseTotal.getDummyBusinessObject().setGenericAmount(expense.getDummyBusinessObject().getGenericAmount().add(expenseTransfers.getDummyBusinessObject().getGenericAmount()));
184    
185            total.getDummyBusinessObject().setGenericAmount(incomeTotal.getDummyBusinessObject().getGenericAmount().add(expenseTotal.getDummyBusinessObject().getGenericAmount()));
186    
187            return totals;
188        }
189    
190        /**
191         * Sets the accessSecurityService attribute value.
192         * 
193         * @param accessSecurityService The accessSecurityService to set.
194         */
195        public void setAccessSecurityService(AccessSecurityService accessSecurityService) {
196            this.accessSecurityService = accessSecurityService;
197        }
198    
199        /**
200         * Sets the objectTypeService attribute value.
201         * 
202         * @param objectTypeService The objectTypeService to set.
203         */
204        public void setObjectTypeService(ObjectTypeService objectTypeService) {
205            this.objectTypeService = objectTypeService;
206        }
207    
208        /**
209         * Sets the kualiConfigurationService attribute value.
210         * 
211         * @param kualiConfigurationService The kualiConfigurationService to set.
212         */
213        public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) {
214            this.kualiConfigurationService = kualiConfigurationService;
215        }
216    
217    }