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.external.kc.service.impl;
017    
018    import java.net.MalformedURLException;
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.Comparator;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    
026    import org.apache.commons.lang.StringUtils;
027    import org.kuali.kfs.coa.businessobject.Account;
028    import org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService;
029    import org.kuali.kfs.module.external.kc.KcConstants;
030    import org.kuali.kfs.module.external.kc.businessobject.AwardAccount;
031    import org.kuali.kfs.module.external.kc.webService.InstitutionalUnitService;
032    import org.kuali.kfs.module.external.kc.webService.InstitutionalUnitSoapService;
033    import org.kuali.kfs.sys.context.SpringContext;
034    import org.kuali.kfs.sys.service.NonTransactional;
035    import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
036    import org.kuali.rice.kim.bo.Person;
037    import org.kuali.rice.kns.service.BusinessObjectService;
038    import org.kuali.rice.kns.service.ParameterService;
039    import org.kuali.rice.kns.util.ObjectUtils;
040    
041    @NonTransactional
042    public class ContractsAndGrantsModuleServiceImpl implements ContractsAndGrantsModuleService {
043        private org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ContractsAndGrantsModuleServiceImpl.class);
044        private BusinessObjectService businessObjectService;
045        
046        protected List <AwardAccount> getAwardAccounts(String chartCode, String accountNumber) {
047            Map objectKeys = new HashMap();
048            if ((chartCode != null) && (!chartCode.isEmpty())) objectKeys.put(KcConstants.AccountCreationDefaults.CHART_OF_ACCOUNT_CODE, chartCode);
049            objectKeys.put(KcConstants.AccountCreationDefaults.ACCOUNT_NUMBER, accountNumber);
050                    
051            List <AwardAccount> awardAccountDTOs = (List<AwardAccount>)SpringContext.getBean(AwardAccountServiceImpl.class).findMatching(objectKeys);
052            
053            return awardAccountDTOs;
054        }
055    
056        protected InstitutionalUnitService getInstitutionalUnitWebService() {
057            InstitutionalUnitSoapService institutionalUnitSoapService = null;
058            try {
059                institutionalUnitSoapService = new InstitutionalUnitSoapService();
060            }
061            catch (MalformedURLException ex) {
062                LOG.error("Could not intialize InstitutionalUnitSoapService: " + ex.getMessage());
063                throw new RuntimeException("Could not intialize InstitutionalUnitSoapService: " + ex.getMessage());
064            }
065            InstitutionalUnitService port = institutionalUnitSoapService.getInstitutionalUnitServicePort();
066            return port;
067        }
068    
069        public List<String> getParentUnits(String unitNumber) {
070            List<String> parentUnits = this.getInstitutionalUnitWebService().getParentUnits(unitNumber);
071            return parentUnits;
072        }
073    
074        /**
075         * @see org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService#getProjectDirectorForAccount(java.lang.String,
076         *      java.lang.String)
077         */
078        public Person getProjectDirectorForAccount(String chartOfAccountsCode, String accountNumber) {
079            
080            List<AwardAccount> awardAccountDTOs = this.getAwardAccounts(chartOfAccountsCode, accountNumber);     
081            AwardAccount awardAccount = determineAwardAccountForProjectDirector(awardAccountDTOs);   
082            if (awardAccount == null)
083                return null;
084            
085            String projectDirectorId = awardAccount.getPrincipalId();
086            LOG.debug("getProjectDirectorForAccount Web Service sent " + chartOfAccountsCode + "/" + accountNumber + " got " + projectDirectorId);
087            if (projectDirectorId != null) {
088                Person projectDirector = SpringContext.getBean(org.kuali.rice.kim.service.PersonService.class).getPerson(projectDirectorId);
089                return projectDirector;
090            }
091            return null;
092        }
093        
094        /**
095         * Looks for first non-blank project director id within a list of award accounts sorted newest first
096         * and returns the award account object, otherwise returns null.
097         * 
098         * @param awardAccountDTOs
099         * @return
100         */
101        protected AwardAccount determineAwardAccountForProjectDirector(List<AwardAccount> awardAccounts){
102            AwardAccount awardAccountReturn = null;
103            
104            //sorts awards in reverse order, newest first
105            if(ObjectUtils.isNotNull(awardAccounts)){
106                Collections.sort(awardAccounts, new Comparator<AwardAccount>() {
107                    public int compare(AwardAccount o1, AwardAccount o2) {
108                        String awardId1 = String.valueOf(o1.getAward().getProposalNumber());
109                        String awardId2 = String.valueOf(o2.getAward().getProposalNumber());
110                        
111                        return awardId2.compareTo(awardId1);                                
112                    }
113                });
114            }
115            
116            if(ObjectUtils.isNotNull(awardAccounts) && !awardAccounts.isEmpty()){
117                
118                for(AwardAccount awardAccount : (List<AwardAccount>)awardAccounts){
119                    //break on first award account with a non-blank project director
120                    if(StringUtils.isNotBlank(awardAccount.getPrincipalId())){
121                        awardAccountReturn = awardAccount;
122                        break;
123                    }
124                }
125            }
126            
127            return awardAccountReturn;
128        }
129    
130        /**
131         * @see org.kuali.kfs.integration.service.ContractsAndGrantsModuleService#getProjectDirectorForAccount(org.kuali.kfs.coa.businessobject.Account)
132         */
133        public Person getProjectDirectorForAccount(Account account) {
134            if (account != null) {
135                String chartOfAccountsCode = account.getChartOfAccountsCode();
136                String accountNumber = account.getAccountNumber();
137                return this.getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
138            }
139            return null;
140        }
141    
142        /**
143         * @see org.kuali.kfs.integration.service.ContractsAndGrantsModuleService#isAwardedByFederalAgency(java.lang.String,
144         *      java.lang.String, java.util.List)
145         */
146        public boolean isAwardedByFederalAgency(String chartOfAccountsCode, String accountNumber, List<String> federalAgencyTypeCodes) {        
147            boolean _isFederalSponsor_return = false;
148            List<String> federalSponsorTypeCodes = null; 
149            List<AwardAccount> awardAccounts = this.getAwardAccounts(chartOfAccountsCode, accountNumber);           
150            AwardAccount awardAccount = determineAwardAccountForFederalAgency(awardAccounts);
151    
152            if(ObjectUtils.isNotNull(awardAccount)){
153                _isFederalSponsor_return = awardAccount.isFederalSponsor();
154            }
155            
156            LOG.debug("isAwardedByFederalAgency" + accountNumber + " got " + _isFederalSponsor_return);
157    
158            return _isFederalSponsor_return;
159        }
160    
161        /**
162         * Looks for the newest award account object, otherwise returns null.
163         * 
164         * @param awardAccounts
165         * @return
166         */
167        protected AwardAccount determineAwardAccountForFederalAgency(List<AwardAccount> awardAccounts){
168            AwardAccount awardAccountReturn = null;
169    
170            //sorts awards in reverse order, newest first
171            if(ObjectUtils.isNotNull(awardAccounts)){
172                Collections.sort(awardAccounts, new Comparator<AwardAccount>() {
173                    public int compare(AwardAccount o1, AwardAccount o2) {
174                        String awardId1 = String.valueOf(o1.getProposalNumber());
175                        String awardId2 = String.valueOf(o2.getProposalNumber());
176                        
177                        return awardId2.compareTo(awardId1);                                
178                    }
179                });
180            }
181        
182            if(ObjectUtils.isNotNull(awardAccounts) && !awardAccounts.isEmpty()){
183                
184                for(AwardAccount awardAccount : awardAccounts){
185                        awardAccountReturn = awardAccount;
186                        break;
187                }
188            }
189            
190            return awardAccountReturn;
191        }
192    
193        /**
194         * @see org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService#getAllAccountReponsiblityIds()
195         */
196        public List<Integer> getAllAccountReponsiblityIds() {
197            int maxResponsibilityId = this.getMaxiumAccountResponsibilityId();
198    
199            List<Integer> contractsAndGrantsReponsiblityIds = new ArrayList<Integer>();
200            for (int id = 1; id <= maxResponsibilityId; id++) {
201                contractsAndGrantsReponsiblityIds.add(id);
202            }
203    
204            return contractsAndGrantsReponsiblityIds;
205        }
206    
207        /**
208         * @see org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService#hasValidAccountReponsiblityIdIfExists(org.kuali.kfs.coa.businessobject.Account)
209         */
210        public boolean hasValidAccountReponsiblityIdIfNotNull(Account account) {
211            Integer accountResponsiblityId = account.getContractsAndGrantsAccountResponsibilityId();
212    
213            if (accountResponsiblityId == null) {
214                return true;
215            }
216    
217            return accountResponsiblityId >= 1 && accountResponsiblityId <= this.getMaxiumAccountResponsibilityId();
218        }
219    
220        public String getProposalNumberForAccountAndProjectDirector(String chartOfAccountsCode, String accountNumber, String projectDirectorId) {
221            String proposalNumber = null;
222            String awardProjectDirectorId = null;
223            
224            List<AwardAccount> awardAccountDTOs = this.getAwardAccounts(chartOfAccountsCode, accountNumber);     
225            AwardAccount awardAccount = determineAwardAccountForProjectDirector(awardAccountDTOs);   
226    
227            //if we have an award, then proceed
228            if (ObjectUtils.isNotNull(awardAccount)){
229                
230                awardProjectDirectorId = awardAccount.getPrincipalId();
231                
232                LOG.debug("getProjectDirectorForAccount Web Service sent " + chartOfAccountsCode + "/" + accountNumber + " got " + StringUtils.trimToEmpty(awardProjectDirectorId));
233                
234                //if what we passed in and what we found match, return Proposal Number (in kc this is award number)
235                if (StringUtils.equalsIgnoreCase(
236                        StringUtils.trimToEmpty(awardProjectDirectorId), 
237                        StringUtils.trimToEmpty(projectDirectorId))) {
238                    
239                    if(ObjectUtils.isNotNull(awardAccount.getAward())){
240                        proposalNumber = awardAccount.getAward().getAwardNumber();
241                    }
242                }
243            }
244            
245            return proposalNumber;
246        }
247    
248        /**
249         * retieve the maxium account responsiblity id from system parameter
250         * 
251         * @return the maxium account responsiblity id from system parameter
252         */
253        protected int getMaxiumAccountResponsibilityId() {
254            String maxResponsibilityId = getParameterService().getParameterValue(KfsParameterConstants.CONTRACTS_AND_GRANTS_ALL.class, KcConstants.MAXIMUM_ACCOUNT_RESPONSIBILITY_ID);
255            return Integer.valueOf(maxResponsibilityId);
256        }
257    
258        /**
259         * Returns an implementation of the parameterService
260         * 
261         * @return an implementation of the parameterService
262         */
263        public ParameterService getParameterService() {
264            return SpringContext.getBean(ParameterService.class);
265        }
266    
267        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
268            this.businessObjectService = businessObjectService;
269        }
270       
271    }