1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.coa.service.impl;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.ole.coa.businessobject.Account;
27 import org.kuali.ole.coa.businessobject.Organization;
28 import org.kuali.ole.coa.service.ChartService;
29 import org.kuali.ole.coa.service.OrganizationService;
30 import org.kuali.ole.sys.OLEConstants.ChartApcParms;
31 import org.kuali.ole.sys.OLEPropertyConstants;
32 import org.kuali.ole.sys.businessobject.ChartOrgHolderImpl;
33 import org.kuali.ole.sys.service.NonTransactional;
34 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
35 import org.kuali.rice.krad.service.BusinessObjectService;
36 import org.springframework.cache.annotation.Cacheable;
37
38
39
40
41
42 @NonTransactional
43 public class OrganizationServiceImpl implements OrganizationService {
44 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrganizationServiceImpl.class);
45
46 protected ParameterService parameterService;
47 protected ChartService chartService;
48 protected BusinessObjectService boService;
49
50 protected Map<ChartOrgHolderImpl,ChartOrgHolderImpl> parentOrgCache = null;
51
52
53
54
55
56 @Override
57 public Organization getByPrimaryId(String chartOfAccountsCode, String organizationCode) {
58 Map<String, Object> keys = new HashMap<String, Object>();
59 keys.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
60 keys.put(OLEPropertyConstants.ORGANIZATION_CODE, organizationCode);
61 return boService.findByPrimaryKey(Organization.class, keys);
62 }
63
64
65
66
67
68
69
70 @Override
71 @Cacheable(value=Organization.CACHE_NAME, key="#p0+'-'+#p1")
72 public Organization getByPrimaryIdWithCaching(String chartOfAccountsCode, String organizationCode) {
73 return getByPrimaryId(chartOfAccountsCode, organizationCode);
74 }
75
76
77
78
79 @Override
80 public List<Account> getActiveAccountsByOrg(String chartOfAccountsCode, String organizationCode) {
81
82 if (StringUtils.isBlank(chartOfAccountsCode)) {
83 throw new IllegalArgumentException("String parameter chartOfAccountsCode was null or blank.");
84 }
85 if (StringUtils.isBlank(organizationCode)) {
86 throw new IllegalArgumentException("String parameter organizationCode was null or blank.");
87 }
88
89 Map<String, Object> criteria = new HashMap<String, Object>();
90 criteria.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
91 criteria.put(OLEPropertyConstants.ORGANIZATION_CODE, organizationCode);
92 criteria.put(OLEPropertyConstants.ACTIVE, Boolean.TRUE);
93 return new ArrayList<Account>( boService.findMatching(Account.class, criteria) );
94 }
95
96
97
98
99 @Override
100 public List<Organization> getActiveChildOrgs(String chartOfAccountsCode, String organizationCode) {
101 if (StringUtils.isBlank(chartOfAccountsCode)) {
102 throw new IllegalArgumentException("String parameter chartOfAccountsCode was null or blank.");
103 }
104 if (StringUtils.isBlank(organizationCode)) {
105 throw new IllegalArgumentException("String parameter organizationCode was null or blank.");
106 }
107
108 Map<String, Object> criteria = new HashMap<String, Object>();
109 criteria.put(OLEPropertyConstants.REPORTS_TO_CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
110 criteria.put(OLEPropertyConstants.REPORTS_TO_ORGANIZATION_CODE, organizationCode);
111 criteria.put(OLEPropertyConstants.ACTIVE, Boolean.TRUE);
112
113 return new ArrayList<Organization>( boService.findMatching(Organization.class, criteria) );
114 }
115
116 protected void loadParentOrgCache() {
117 LOG.debug( "START - Initializing parent organization cache" );
118 Map<ChartOrgHolderImpl,ChartOrgHolderImpl> temp = new HashMap<ChartOrgHolderImpl, ChartOrgHolderImpl>();
119
120 Collection<Organization> orgs = boService.findMatching(Organization.class, Collections.singletonMap(OLEPropertyConstants.ACTIVE, true));
121 for ( Organization org : orgs ) {
122 ChartOrgHolderImpl keyOrg = new ChartOrgHolderImpl(org);
123 if ( StringUtils.isNotBlank( org.getReportsToChartOfAccountsCode() )
124 && StringUtils.isNotBlank( org.getReportsToOrganizationCode() ) ) {
125 ChartOrgHolderImpl parentorg = new ChartOrgHolderImpl( org.getReportsToChartOfAccountsCode(), org.getReportsToOrganizationCode());
126 temp.put(keyOrg, parentorg);
127 }
128 }
129
130 parentOrgCache = temp;
131 if ( LOG.isDebugEnabled() ) {
132 LOG.debug( "COMPLETE - Initializing parent organization cache - " + temp.size() + " organizations loaded" );
133 }
134 }
135
136 @Override
137 public void flushParentOrgCache() {
138 LOG.debug( "Flushing parent organization cache" );
139 parentOrgCache = null;
140 }
141
142 @Override
143 public boolean isParentOrganization( String childChartOfAccountsCode, String childOrganizationCode, String parentChartOfAccountsCode, String parentOrganizationCode ) {
144 if (StringUtils.isBlank(childChartOfAccountsCode)
145 || StringUtils.isBlank(childOrganizationCode)
146 || StringUtils.isBlank(parentChartOfAccountsCode)
147 || StringUtils.isBlank(parentOrganizationCode) ) {
148 return false;
149 }
150
151 if ( parentOrgCache == null ) {
152 loadParentOrgCache();
153 }
154
155 ChartOrgHolderImpl currOrg = new ChartOrgHolderImpl( childChartOfAccountsCode, childOrganizationCode );
156 ChartOrgHolderImpl desiredParentOrg = new ChartOrgHolderImpl( parentChartOfAccountsCode, parentOrganizationCode );
157
158
159 if ( currOrg.equals( desiredParentOrg ) ) {
160 return true;
161 }
162
163 return isParentOrganization_Internal(currOrg, desiredParentOrg, new ArrayList<ChartOrgHolderImpl>() );
164 }
165
166
167
168
169
170 protected boolean isParentOrganization_Internal( ChartOrgHolderImpl currOrg, ChartOrgHolderImpl desiredParentOrg, List<ChartOrgHolderImpl> traversedOrgs ) {
171
172 if ( traversedOrgs.contains(currOrg) ) {
173 LOG.error( "THERE IS A LOOP IN THE ORG DATA: " + currOrg + " found a second time after traversing the following orgs: " + traversedOrgs );
174 return false;
175 }
176
177 ChartOrgHolderImpl parentOrg = parentOrgCache.get(currOrg);
178
179
180 if ( parentOrg == null ) {
181 return false;
182 }
183
184 if ( parentOrg.equals(currOrg) ) {
185 return false;
186 }
187
188 if ( parentOrg.equals( desiredParentOrg ) ) {
189 return true;
190 }
191
192 traversedOrgs.add( currOrg );
193 return isParentOrganization_Internal(parentOrg, desiredParentOrg, traversedOrgs);
194 }
195
196
197
198
199
200 @Override
201 public List<Organization> getActiveOrgsByType(String organizationTypeCode) {
202 if (StringUtils.isBlank(organizationTypeCode)) {
203 throw new IllegalArgumentException("String parameter organizationTypeCode was null or blank.");
204 }
205 Map<String, Object> criteria = new HashMap<String, Object>();
206 criteria.put(OLEPropertyConstants.ORGANIZATION_TYPE_CODE, organizationTypeCode);
207 criteria.put(OLEPropertyConstants.ACTIVE, Boolean.TRUE);
208
209 return new ArrayList<Organization>( boService.findMatching(Organization.class, criteria) );
210 }
211
212
213
214
215
216 @Override
217 public List<Organization> getActiveFinancialOrgs() {
218 Map<String, Object> criteria = new HashMap<String, Object>();
219 criteria.put(OLEPropertyConstants.ORGANIZATION_IN_FINANCIAL_PROCESSING_INDICATOR, Boolean.TRUE);
220 criteria.put(OLEPropertyConstants.ACTIVE, Boolean.TRUE);
221 return new ArrayList<Organization>( boService.findMatching(Organization.class, criteria) );
222 }
223
224
225
226
227
228
229
230 @Override
231 public String[] getRootOrganizationCode() {
232 String rootChart = chartService.getUniversityChart().getChartOfAccountsCode();
233 String selfReportsOrgType = parameterService.getParameterValueAsString(Organization.class, ChartApcParms.ORG_MUST_REPORT_TO_SELF_ORG_TYPES);
234 String[] returnValues = { null, null };
235
236 Map<String, Object> criteria = new HashMap<String, Object>();
237 criteria.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, rootChart);
238 criteria.put(OLEPropertyConstants.ORGANIZATION_TYPE_CODE, selfReportsOrgType);
239 criteria.put(OLEPropertyConstants.ACTIVE, Boolean.TRUE);
240
241 Collection<Organization> results = boService.findMatching(Organization.class, criteria);
242 if (results != null && !results.isEmpty()) {
243 Organization org = results.iterator().next();
244 returnValues[0] = org.getChartOfAccountsCode();
245 returnValues[1] = org.getOrganizationCode();
246 }
247
248 return returnValues;
249 }
250
251 public void setParameterService(ParameterService parameterService) {
252 this.parameterService = parameterService;
253 }
254 public void setBusinessObjectService(BusinessObjectService boService) {
255 this.boService = boService;
256 }
257 public void setChartService(ChartService chartService) {
258 this.chartService = chartService;
259 }
260
261 }