1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.gl.service.impl;
17
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.LinkedHashMap;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
26 import java.util.TreeSet;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.ole.coa.businessobject.Account;
30 import org.kuali.ole.coa.service.AccountService;
31 import org.kuali.ole.gl.GeneralLedgerConstants;
32 import org.kuali.ole.gl.report.PreScrubberReportData;
33 import org.kuali.ole.gl.service.PreScrubberService;
34 import org.kuali.ole.sys.OLEConstants.SystemGroupParameterNames;
35 import org.kuali.ole.sys.context.SpringContext;
36 import org.kuali.ole.sys.service.impl.OleParameterConstants;
37 import org.kuali.ole.sys.util.TransactionalServiceUtils;
38 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
39
40
41
42
43
44 public class PreScrubberServiceImpl implements PreScrubberService {
45 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PreScrubberServiceImpl.class);
46
47 private int maxCacheSize = 10000;
48 private ParameterService parameterService;
49
50 public PreScrubberReportData preprocessOriginEntries(Iterator<String> inputOriginEntries, String outputFileName) throws IOException {
51 PrintStream outputStream = new PrintStream(outputFileName);
52
53 Map<String, String> chartCodeCache = new LinkedHashMap<String, String>() {
54 @Override
55 protected boolean removeEldestEntry(Entry<String, String> eldest) {
56 return size() > getMaxCacheSize();
57 }
58 };
59
60 Set<String> nonExistentAccountCache = new TreeSet<String>();
61 Set<String> multipleAccountCache = new TreeSet<String>();
62
63 AccountService accountService = SpringContext.getBean(AccountService.class);
64 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
65 boolean fillInChartCodesIfSpaces = deriveChartOfAccountsCodeIfSpaces();
66
67 int inputLines = 0;
68 int outputLines = 0;
69
70 try {
71 while (inputOriginEntries.hasNext()) {
72 inputLines++;
73
74 String originEntry = inputOriginEntries.next();
75 String outputLine = originEntry;
76 if (fillInChartCodesIfSpaces && originEntry.length() >= getExclusiveAccountNumberEndPosition()) {
77 String chartOfAccountsCode = originEntry.substring(getInclusiveChartOfAccountsCodeStartPosition(), getExclusiveChartOfAccountsCodeEndPosition());
78 if (GeneralLedgerConstants.getSpaceChartOfAccountsCode().equals(chartOfAccountsCode)) {
79
80 String accountNumber = originEntry.substring(getInclusiveAccountNumberStartPosition(), getExclusiveAccountNumberEndPosition());
81 if (StringUtils.isNotEmpty(accountNumber)) {
82 String replacementChartOfAccountsCode = null;
83 boolean nonExistent = false;
84 boolean multipleFound = false;
85
86 if (chartCodeCache.containsKey(accountNumber))
87 replacementChartOfAccountsCode = chartCodeCache.get(accountNumber);
88 else if (nonExistentAccountCache.contains(accountNumber))
89 nonExistent = true;
90 else if (multipleAccountCache.contains(accountNumber))
91 multipleFound = true;
92 else {
93 Collection<Account> results = accountService.getAccountsForAccountNumber(accountNumber);
94
95 if (results.isEmpty()) {
96 nonExistent = true;
97 nonExistentAccountCache.add(accountNumber);
98 LOG.warn("Could not find account record for account number " + accountNumber);
99 }
100 else {
101 Iterator<Account> accounts = results.iterator();
102 Account account = accounts.next();
103 if (accounts.hasNext()) {
104 LOG.warn("Multiple chart codes found for account number " + accountNumber + ", not filling in chart code for this account");
105 TransactionalServiceUtils.exhaustIterator(accounts);
106 multipleAccountCache.add(accountNumber);
107 multipleFound = true;
108 }
109 else {
110 replacementChartOfAccountsCode = account.getChartOfAccountsCode();
111 chartCodeCache.put(accountNumber, replacementChartOfAccountsCode);
112 }
113 }
114 }
115
116 if (!nonExistent && !multipleFound) {
117 StringBuilder buf = new StringBuilder(originEntry.length());
118 buf.append(originEntry.substring(0, getInclusiveChartOfAccountsCodeStartPosition()));
119 buf.append(replacementChartOfAccountsCode);
120 buf.append(originEntry.subSequence(getExclusiveChartOfAccountsCodeEndPosition(), originEntry.length()));
121 outputLine = buf.toString();
122 }
123 }
124 }
125 }
126 outputStream.printf("%s\n", outputLine);
127 outputLines++;
128 }
129 }
130 finally {
131 outputStream.close();
132 }
133 return new PreScrubberReportData(inputLines, outputLines, nonExistentAccountCache, multipleAccountCache);
134 }
135
136
137
138
139
140 protected int getInclusiveChartOfAccountsCodeStartPosition() {
141 return 4;
142 }
143
144
145
146
147
148 protected int getExclusiveChartOfAccountsCodeEndPosition() {
149 return 6;
150 }
151
152
153
154
155
156 protected int getInclusiveAccountNumberStartPosition() {
157 return 6;
158 }
159
160
161
162
163
164 protected int getExclusiveAccountNumberEndPosition() {
165 return 13;
166 }
167
168 public int getMaxCacheSize() {
169 return maxCacheSize;
170 }
171
172 public void setMaxCacheSize(int maxCacheSize) {
173 this.maxCacheSize = maxCacheSize;
174 }
175
176
177
178
179 public boolean deriveChartOfAccountsCodeIfSpaces() {
180 return !parameterService.getParameterValueAsBoolean(OleParameterConstants.FINANCIAL_SYSTEM_ALL.class, SystemGroupParameterNames.ACCOUNTS_CAN_CROSS_CHARTS_IND);
181 }
182
183
184
185
186
187 public void setParameterService(ParameterService parameterService) {
188 this.parameterService = parameterService;
189 }
190 }