1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.gl.batch.service.impl;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.PrintStream;
21 import java.sql.Date;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.ole.gl.GeneralLedgerConstants;
30 import org.kuali.ole.gl.businessobject.Entry;
31 import org.kuali.ole.gl.businessobject.OriginEntryFull;
32 import org.kuali.ole.gl.businessobject.OriginEntryInformation;
33 import org.kuali.ole.gl.businessobject.PendingEntrySummary;
34 import org.kuali.ole.gl.report.LedgerSummaryReport;
35 import org.kuali.ole.gl.service.NightlyOutService;
36 import org.kuali.ole.gl.service.OriginEntryGroupService;
37 import org.kuali.ole.gl.service.OriginEntryService;
38 import org.kuali.ole.sys.OLEConstants;
39 import org.kuali.ole.sys.OLEPropertyConstants;
40 import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
41 import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
42 import org.kuali.ole.sys.service.ReportWriterService;
43 import org.kuali.rice.core.api.datetime.DateTimeService;
44 import org.kuali.rice.core.api.util.type.KualiDecimal;
45 import org.kuali.rice.core.web.format.CurrencyFormatter;
46 import org.kuali.rice.kns.service.DataDictionaryService;
47 import org.springframework.transaction.annotation.Transactional;
48
49
50
51
52 @Transactional
53 public class NightlyOutServiceImpl implements NightlyOutService {
54 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NightlyOutServiceImpl.class);
55
56 private GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
57 private OriginEntryService originEntryService;
58 private DateTimeService dateTimeService;
59 private OriginEntryGroupService originEntryGroupService;
60 private String batchFileDirectoryName;
61 private ReportWriterService pendingEntryListReportWriterService;
62 private ReportWriterService pendingEntrySummaryReportWriterService;
63 private DataDictionaryService dataDictionaryService;
64
65
66
67
68 public NightlyOutServiceImpl() {
69 }
70
71
72
73
74
75 public void deleteCopiedPendingLedgerEntries() {
76 LOG.debug("deleteCopiedPendingLedgerEntries() started");
77
78 generalLedgerPendingEntryService.deleteByFinancialDocumentApprovedCode(OLEConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.PROCESSED);
79 }
80
81
82
83
84
85 public void copyApprovedPendingLedgerEntries() {
86 if (LOG.isInfoEnabled()) {
87 LOG.info("copyApprovedPendingLedgerEntries() started");
88 }
89 Date today = new Date(dateTimeService.getCurrentTimestamp().getTime());
90
91 Iterator pendingEntries = generalLedgerPendingEntryService.findApprovedPendingLedgerEntries();
92 String outputFile = batchFileDirectoryName + File.separator + GeneralLedgerConstants.BatchFileSystem.NIGHTLY_OUT_FILE + GeneralLedgerConstants.BatchFileSystem.EXTENSION ;
93 PrintStream outputFilePs = null;
94
95 try {
96 outputFilePs = new PrintStream(outputFile);
97 }
98 catch (IOException ioe) {
99 throw new RuntimeException("Cannot open output file "+outputFile+" for writing", ioe);
100 }
101
102 EntryListReport entryListReport = new EntryListReport();
103 LedgerSummaryReport nightlyOutLedgerSummaryReport = new LedgerSummaryReport();
104
105 Collection<OriginEntryFull> group = new ArrayList<OriginEntryFull>();
106 while (pendingEntries.hasNext()) {
107
108 GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntries.next();
109
110 OriginEntryFull entry = new OriginEntryFull(pendingEntry);
111
112
113 entryListReport.writeEntry(entry, pendingEntryListReportWriterService);
114 nightlyOutLedgerSummaryReport.summarizeEntry(entry);
115
116 group.add(entry);
117
118
119 outputFilePs.printf("%s\n", entry.getLine());
120
121
122 pendingEntry.setFinancialDocumentApprovedCode(OLEConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.PROCESSED);
123 pendingEntry.setTransactionDate(today);
124
125 generalLedgerPendingEntryService.save(pendingEntry);
126 }
127
128 outputFilePs.close();
129
130
131 String doneFileName = outputFile.replace(GeneralLedgerConstants.BatchFileSystem.EXTENSION, GeneralLedgerConstants.BatchFileSystem.DONE_FILE_EXTENSION);
132 File doneFile = new File (doneFileName);
133 if (!doneFile.exists()){
134 try {
135 doneFile.createNewFile();
136 } catch (IOException e) {
137 throw new RuntimeException();
138 }
139 }
140
141
142 entryListReport.writeReportFooter(pendingEntryListReportWriterService);
143 nightlyOutLedgerSummaryReport.writeReport(pendingEntrySummaryReportWriterService);
144 }
145
146
147
148 public void setGeneralLedgerPendingEntryService(GeneralLedgerPendingEntryService generalLedgerPendingEntryService) {
149 this.generalLedgerPendingEntryService = generalLedgerPendingEntryService;
150 }
151
152 public void setOriginEntryService(OriginEntryService originEntryService) {
153 this.originEntryService = originEntryService;
154 }
155
156 public void setOriginEntryGroupService(OriginEntryGroupService originEntryGroupService) {
157 this.originEntryGroupService = originEntryGroupService;
158 }
159
160 public void setDateTimeService(DateTimeService dateTimeService) {
161 this.dateTimeService = dateTimeService;
162 }
163
164 public void setBatchFileDirectoryName(String batchFileDirectoryName) {
165 this.batchFileDirectoryName = batchFileDirectoryName;
166 }
167
168
169
170
171
172 public ReportWriterService getPendingEntryListReportWriterService() {
173 return pendingEntryListReportWriterService;
174 }
175
176
177
178
179
180 public void setPendingEntryListReportWriterService(ReportWriterService pendingEntryListReportWriterService) {
181 this.pendingEntryListReportWriterService = pendingEntryListReportWriterService;
182 }
183
184
185
186
187
188 public ReportWriterService getPendingEntrySummaryReportWriterService() {
189 return pendingEntrySummaryReportWriterService;
190 }
191
192
193
194
195
196 public void setPendingEntrySummaryReportWriterService(ReportWriterService pendingEntrySummaryReportWriterService) {
197 this.pendingEntrySummaryReportWriterService = pendingEntrySummaryReportWriterService;
198 }
199
200
201
202
203
204 public DataDictionaryService getDataDictionaryService() {
205 return dataDictionaryService;
206 }
207
208
209
210
211
212 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
213 this.dataDictionaryService = dataDictionaryService;
214 }
215
216
217
218
219 protected class EntryListReport {
220 private PendingEntrySummary pendingEntrySummary;
221 private EntryReportTotalLine totalLine;
222 private Map<String, EntryReportDocumentTypeTotalLine> documentTypeTotals;
223 private EntryReportDocumentNumberTotalLine documentNumberTotal;
224 private int entryCount = 0;
225 private String suppressKey = "";
226
227
228
229
230 public EntryListReport() {
231 pendingEntrySummary = new PendingEntrySummary();
232 totalLine = new EntryReportTotalLine();
233 documentTypeTotals = new LinkedHashMap<String, EntryReportDocumentTypeTotalLine>();
234 }
235
236
237
238
239
240
241 public void writeEntry(OriginEntryInformation entry, ReportWriterService reportWriterService) {
242 pendingEntrySummary.setOriginEntry(entry);
243 if (pendingEntrySummary.getSuppressableFieldsAsKey().equals(suppressKey)) {
244 pendingEntrySummary.suppressCommonFields(true);
245 }
246 else if (StringUtils.isNotBlank(suppressKey)) {
247 writeDocumentTotalLine(documentNumberTotal, reportWriterService);
248 documentNumberTotal = new EntryReportDocumentNumberTotalLine(pendingEntrySummary.getConstantDocumentNumber());
249 }
250
251 if (StringUtils.isBlank(suppressKey)) {
252 documentNumberTotal = new EntryReportDocumentNumberTotalLine(pendingEntrySummary.getConstantDocumentNumber());
253 reportWriterService.writeTableHeader(pendingEntrySummary);
254 }
255 suppressKey = pendingEntrySummary.getSuppressableFieldsAsKey();
256
257 reportWriterService.writeTableRow(pendingEntrySummary);
258
259 addPendingEntryToDocumentType(pendingEntrySummary, documentTypeTotals);
260 addSummaryToTotal(pendingEntrySummary, documentNumberTotal);
261 addSummaryToTotal(pendingEntrySummary, totalLine);
262 entryCount += 1;
263 }
264
265
266
267
268
269
270 protected void addPendingEntryToDocumentType(PendingEntrySummary pendingEntrySummary, Map<String, EntryReportDocumentTypeTotalLine> docTypeTotals) {
271 EntryReportDocumentTypeTotalLine docTypeTotal = docTypeTotals.get(pendingEntrySummary.getConstantDocumentTypeCode());
272 if (docTypeTotal == null) {
273 docTypeTotal = new EntryReportDocumentTypeTotalLine(pendingEntrySummary.getConstantDocumentTypeCode());
274 docTypeTotals.put(pendingEntrySummary.getConstantDocumentTypeCode(), docTypeTotal);
275 }
276 addSummaryToTotal(pendingEntrySummary, docTypeTotal);
277 }
278
279
280
281
282
283
284
285 protected void addSummaryToTotal(PendingEntrySummary pendingEntrySummary, EntryReportTotalLine totalLine) {
286 if (pendingEntrySummary.getDebitAmount() != null) {
287 totalLine.addDebitAmount(pendingEntrySummary.getDebitAmount());
288 }
289 if (pendingEntrySummary.getCreditAmount() != null) {
290 totalLine.addCreditAmount(pendingEntrySummary.getCreditAmount());
291 }
292 if (pendingEntrySummary.getBudgetAmount() != null) {
293 totalLine.addBudgetAmount(pendingEntrySummary.getBudgetAmount());
294 }
295 }
296
297
298
299
300
301
302
303 protected void writeDocumentTotalLine(EntryReportDocumentNumberTotalLine documentNumberTotal, ReportWriterService reportWriterService) {
304 final CurrencyFormatter formatter = new CurrencyFormatter();
305 final int amountLength = getDataDictionaryService().getAttributeMaxLength(Entry.class, OLEPropertyConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT);
306
307 reportWriterService.writeNewLines(1);
308 reportWriterService.writeFormattedMessageLine(" Total: %"+amountLength+"s %"+amountLength+"s %"+amountLength+"s", formatter.format(documentNumberTotal.getCreditAmount()), formatter.format(documentNumberTotal.getDebitAmount()), formatter.format(documentNumberTotal.getBudgetAmount()));
309 reportWriterService.writeNewLines(1);
310 }
311
312
313
314
315
316 public void writeReportFooter(ReportWriterService reportWriterService) {
317 final CurrencyFormatter formatter = new CurrencyFormatter();
318 final int amountLength = getDataDictionaryService().getAttributeMaxLength(Entry.class, OLEPropertyConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT);
319
320 reportWriterService.writeNewLines(1);
321 for (String documentTypeCode : documentTypeTotals.keySet()) {
322 final EntryReportDocumentTypeTotalLine docTypeTotal = documentTypeTotals.get(documentTypeCode);
323 reportWriterService.writeFormattedMessageLine(" Totals for Document Type %4s Cnt %6d: %"+amountLength+"s %"+amountLength+"s %"+amountLength+"s",documentTypeCode, docTypeTotal.getEntryCount(), formatter.format(docTypeTotal.getCreditAmount()), formatter.format(docTypeTotal.getDebitAmount()), formatter.format(docTypeTotal.getBudgetAmount()));
324 }
325
326 reportWriterService.writeNewLines(1);
327 reportWriterService.writeFormattedMessageLine(" Grand Totals Cnt %6d: %"+amountLength+"s %"+amountLength+"s %"+amountLength+"s", new Integer(entryCount), formatter.format(totalLine.getCreditAmount()), formatter.format(totalLine.getDebitAmount()), formatter.format(totalLine.getBudgetAmount()));
328 }
329
330
331
332
333 protected class EntryReportTotalLine {
334 private KualiDecimal debitAmount = new KualiDecimal("0");
335 private KualiDecimal creditAmount = new KualiDecimal("0");
336 private KualiDecimal budgetAmount = new KualiDecimal("0");
337
338
339
340
341 public KualiDecimal getDebitAmount() {
342 return debitAmount;
343 }
344
345
346
347
348 public KualiDecimal getCreditAmount() {
349 return creditAmount;
350 }
351
352
353
354
355 public KualiDecimal getBudgetAmount() {
356 return budgetAmount;
357 }
358
359
360
361
362
363 public void addDebitAmount(KualiDecimal debitAmount) {
364 this.debitAmount = this.debitAmount.add(debitAmount);
365 }
366
367
368
369
370
371 public void addCreditAmount(KualiDecimal creditAmount) {
372 this.creditAmount = this.creditAmount.add(creditAmount);
373 }
374
375
376
377
378
379 public void addBudgetAmount(KualiDecimal budgetAmount) {
380 this.budgetAmount = this.budgetAmount.add(budgetAmount);
381 }
382 }
383
384
385
386
387 protected class EntryReportDocumentTypeTotalLine extends EntryReportTotalLine {
388 private String documentTypeCode;
389 private int entryCount = 0;
390
391
392
393
394
395 public EntryReportDocumentTypeTotalLine(String documentTypeCode) {
396 this.documentTypeCode = documentTypeCode;
397 }
398
399
400
401
402 public String getDocumentTypeCode() {
403 return this.documentTypeCode;
404 }
405
406
407
408
409 public int getEntryCount() {
410 return this.entryCount;
411 }
412
413
414
415
416
417 @Override
418 public void addBudgetAmount(KualiDecimal budgetAmount) {
419 super.addBudgetAmount(budgetAmount);
420 entryCount += 1;
421 }
422
423
424
425
426
427 @Override
428 public void addCreditAmount(KualiDecimal creditAmount) {
429 super.addCreditAmount(creditAmount);
430 entryCount += 1;
431 }
432
433
434
435
436
437 @Override
438 public void addDebitAmount(KualiDecimal debitAmount) {
439 super.addDebitAmount(debitAmount);
440 entryCount += 1;
441 }
442 }
443
444
445
446
447 protected class EntryReportDocumentNumberTotalLine extends EntryReportTotalLine {
448 private String documentNumber;
449 private int entryCount = 0;
450
451
452
453
454
455 public EntryReportDocumentNumberTotalLine(String documentNumber) {
456 this.documentNumber = documentNumber;
457 }
458
459
460
461
462 public String getDocumentNumber() {
463 return this.documentNumber;
464 }
465
466
467
468
469 public int getEntryCount() {
470 return this.entryCount;
471 }
472
473
474
475
476
477 @Override
478 public void addBudgetAmount(KualiDecimal budgetAmount) {
479 super.addBudgetAmount(budgetAmount);
480 entryCount += 1;
481 }
482
483
484
485
486
487 @Override
488 public void addCreditAmount(KualiDecimal creditAmount) {
489 super.addCreditAmount(creditAmount);
490 entryCount += 1;
491 }
492
493
494
495
496
497 @Override
498 public void addDebitAmount(KualiDecimal debitAmount) {
499 super.addDebitAmount(debitAmount);
500 entryCount += 1;
501 }
502 }
503 }
504 }