1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.pdp.service.impl;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileNotFoundException;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.PrintStream;
24 import java.sql.Timestamp;
25 import java.text.MessageFormat;
26 import java.util.ArrayList;
27 import java.util.Calendar;
28 import java.util.List;
29
30 import org.apache.commons.io.IOUtils;
31 import org.apache.commons.lang.StringUtils;
32 import org.kuali.ole.pdp.businessobject.Batch;
33 import org.kuali.ole.pdp.businessobject.CustomerProfile;
34 import org.kuali.ole.pdp.businessobject.LoadPaymentStatus;
35 import org.kuali.ole.pdp.businessobject.PaymentFileLoad;
36 import org.kuali.ole.pdp.businessobject.PaymentGroup;
37 import org.kuali.ole.pdp.service.CustomerProfileService;
38 import org.kuali.ole.pdp.service.PaymentFileService;
39 import org.kuali.ole.pdp.service.PaymentFileValidationService;
40 import org.kuali.ole.pdp.service.PdpEmailService;
41 import org.kuali.ole.sys.OLEConstants;
42 import org.kuali.ole.sys.OLEKeyConstants;
43 import org.kuali.ole.sys.batch.BatchInputFileType;
44 import org.kuali.ole.sys.batch.InitiateDirectoryBase;
45 import org.kuali.ole.sys.batch.service.BatchInputFileService;
46 import org.kuali.ole.sys.exception.ParseException;
47 import org.kuali.rice.core.api.config.property.ConfigurationService;
48 import org.kuali.rice.core.api.datetime.DateTimeService;
49 import org.kuali.rice.core.api.util.type.KualiInteger;
50 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
51 import org.kuali.rice.krad.service.BusinessObjectService;
52 import org.kuali.rice.krad.util.ErrorMessage;
53 import org.kuali.rice.krad.util.GlobalVariables;
54 import org.kuali.rice.krad.util.MessageMap;
55 import org.springframework.transaction.annotation.Transactional;
56
57
58
59
60 @Transactional
61 public class PaymentFileServiceImpl extends InitiateDirectoryBase implements PaymentFileService {
62 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentFileServiceImpl.class);
63
64 private String outgoingDirectoryName;
65
66 private ParameterService parameterService;
67 private CustomerProfileService customerProfileService;
68 private BatchInputFileService batchInputFileService;
69 private PaymentFileValidationService paymentFileValidationService;
70 private BusinessObjectService businessObjectService;
71 private DateTimeService dateTimeService;
72 private PdpEmailService paymentFileEmailService;
73 private ConfigurationService kualiConfigurationService;
74
75 public PaymentFileServiceImpl() {
76 super();
77 }
78
79
80
81
82 public void processPaymentFiles(BatchInputFileType paymentInputFileType) {
83 List<String> fileNamesToLoad = batchInputFileService.listInputFileNamesWithDoneFile(paymentInputFileType);
84
85 for (String incomingFileName : fileNamesToLoad) {
86 try {
87 if (LOG.isDebugEnabled()) {
88 LOG.debug("processPaymentFiles() Processing " + incomingFileName);
89 }
90
91
92 LoadPaymentStatus status = new LoadPaymentStatus();
93 status.setMessageMap(new MessageMap());
94
95
96 PaymentFileLoad paymentFile = processPaymentFile(paymentInputFileType, incomingFileName, status.getMessageMap());
97 if (paymentFile != null && paymentFile.isPassedValidation()) {
98
99 loadPayments(paymentFile, status, incomingFileName);
100
101 createOutputFile(status, incomingFileName);
102 }else{
103
104
105 LOG.warn("Encounter a problem while processing payment file: " + incomingFileName + " . Removing the done file to stop re-process.");
106 removeDoneFile(incomingFileName);
107 }
108 }
109 catch (RuntimeException e) {
110 LOG.error("Caught exception trying to load payment file: " + incomingFileName, e);
111
112 }
113 }
114 }
115
116
117
118
119
120
121
122
123
124 protected PaymentFileLoad processPaymentFile(BatchInputFileType paymentInputFileType, String incomingFileName, MessageMap errorMap) {
125
126 PaymentFileLoad paymentFile = parsePaymentFile(paymentInputFileType, incomingFileName, errorMap);
127
128 if (errorMap.hasNoErrors()) {
129
130 doPaymentFileValidation(paymentFile, errorMap);
131 }
132
133 return paymentFile;
134 }
135
136
137
138
139
140 public void doPaymentFileValidation(PaymentFileLoad paymentFile, MessageMap errorMap) {
141 paymentFileValidationService.doHardEdits(paymentFile, errorMap);
142
143 if (errorMap.hasErrors()) {
144 paymentFileEmailService.sendErrorEmail(paymentFile, errorMap);
145 }
146
147 paymentFile.setPassedValidation(true);
148 }
149
150
151
152
153 public void loadPayments(PaymentFileLoad paymentFile, LoadPaymentStatus status, String incomingFileName) {
154 status.setChart(paymentFile.getChart());
155 status.setUnit(paymentFile.getUnit());
156 status.setSubUnit(paymentFile.getSubUnit());
157 status.setCreationDate(paymentFile.getCreationDate());
158 status.setDetailCount(paymentFile.getActualPaymentCount());
159 status.setDetailTotal(paymentFile.getCalculatedPaymentTotalAmount());
160
161
162 Batch batch = createNewBatch(paymentFile, getBaseFileName(incomingFileName));
163 businessObjectService.save(batch);
164
165 paymentFile.setBatchId(batch.getId());
166 status.setBatchId(batch.getId());
167
168
169 List<String> warnings = paymentFileValidationService.doSoftEdits(paymentFile);
170 status.setWarnings(warnings);
171
172
173 for (PaymentGroup paymentGroup : paymentFile.getPaymentGroups()) {
174 businessObjectService.save(paymentGroup);
175 }
176
177
178 paymentFileEmailService.sendLoadEmail(paymentFile, warnings);
179 if (paymentFile.isTaxEmailRequired()) {
180 paymentFileEmailService.sendTaxEmail(paymentFile);
181 }
182
183 removeDoneFile(incomingFileName);
184
185 LOG.debug("loadPayments() was successful");
186 status.setLoadStatus(LoadPaymentStatus.LoadStatus.SUCCESS);
187 }
188
189
190
191
192
193
194
195
196
197 protected PaymentFileLoad parsePaymentFile(BatchInputFileType paymentInputFileType, String incomingFileName, MessageMap errorMap) {
198 FileInputStream fileContents;
199 try {
200 fileContents = new FileInputStream(incomingFileName);
201 }
202 catch (FileNotFoundException e1) {
203 LOG.error("file to load not found " + incomingFileName, e1);
204 throw new RuntimeException("Cannot find the file requested to be loaded " + incomingFileName, e1);
205 }
206
207
208 PaymentFileLoad paymentFile = null;
209 try {
210 byte[] fileByteContent = IOUtils.toByteArray(fileContents);
211 paymentFile = (PaymentFileLoad) batchInputFileService.parse(paymentInputFileType, fileByteContent);
212 }
213 catch (IOException e) {
214 LOG.error("error while getting file bytes: " + e.getMessage(), e);
215 throw new RuntimeException("Error encountered while attempting to get file bytes: " + e.getMessage(), e);
216 }
217 catch (ParseException e1) {
218 LOG.error("Error parsing xml " + e1.getMessage());
219
220 errorMap.putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_PARSING_XML, new String[] { e1.getMessage() });
221
222
223 paymentFileEmailService.sendErrorEmail(paymentFile, errorMap);
224 }
225
226 return paymentFile;
227 }
228
229
230
231
232
233 public boolean createOutputFile(LoadPaymentStatus status, String inputFileName) {
234
235
236 prepareDirectories(getRequiredDirectoryNames());
237
238
239 String filename = outgoingDirectoryName + "/" + getBaseFileName(inputFileName);
240
241
242 String code;
243 String message;
244 if (LoadPaymentStatus.LoadStatus.SUCCESS.equals(status.getLoadStatus())) {
245 code = "SUCCESS";
246 message = "Successful Load";
247 }
248 else {
249 code = "FAIL";
250 message = "Load Failed: ";
251 List<ErrorMessage> errorMessages = status.getMessageMap().getMessages(OLEConstants.GLOBAL_ERRORS);
252 for (ErrorMessage errorMessage : errorMessages) {
253 String resourceMessage = kualiConfigurationService.getPropertyValueAsString(errorMessage.getErrorKey());
254 resourceMessage = MessageFormat.format(resourceMessage, (Object[]) errorMessage.getMessageParameters());
255 message += resourceMessage + ", ";
256 }
257 }
258
259 try {
260 FileOutputStream out = new FileOutputStream(filename);
261 PrintStream p = new PrintStream(out);
262
263 p.println("<pdp_load_status>");
264 p.println(" <input_file_name>" + inputFileName + "</input_file_name>");
265 p.println(" <code>" + code + "</code>");
266 p.println(" <count>" + status.getDetailCount() + "</count>");
267 if (status.getDetailTotal() != null) {
268 p.println(" <total>" + status.getDetailTotal() + "</total>");
269 }
270 else {
271 p.println(" <total>0</total>");
272 }
273
274 p.println(" <description>" + message + "</description>");
275 p.println(" <messages>");
276 for (String warning : status.getWarnings()) {
277 p.println(" <message>" + warning + "</message>");
278 }
279 p.println(" </messages>");
280 p.println("</pdp_load_status>");
281
282 p.close();
283 out.close();
284 }
285 catch (FileNotFoundException e) {
286 LOG.error("createOutputFile() Cannot create output file", e);
287 return false;
288 }
289 catch (IOException e) {
290 LOG.error("createOutputFile() Cannot write to output file", e);
291 return false;
292 }
293
294 return true;
295 }
296
297
298
299
300
301
302
303
304 protected Batch createNewBatch(PaymentFileLoad paymentFile, String fileName) {
305 Timestamp now = dateTimeService.getCurrentTimestamp();
306
307 Calendar nowPlus30 = Calendar.getInstance();
308 nowPlus30.setTime(now);
309 nowPlus30.add(Calendar.DATE, 30);
310
311 Calendar nowMinus30 = Calendar.getInstance();
312 nowMinus30.setTime(now);
313 nowMinus30.add(Calendar.DATE, -30);
314
315 Batch batch = new Batch();
316
317 CustomerProfile customer = customerProfileService.get(paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit());
318 batch.setCustomerProfile(customer);
319 batch.setCustomerFileCreateTimestamp(new Timestamp(paymentFile.getCreationDate().getTime()));
320 batch.setFileProcessTimestamp(now);
321 batch.setPaymentCount(new KualiInteger(paymentFile.getPaymentCount()));
322
323 if (fileName.length() > 30) {
324 batch.setPaymentFileName(fileName.substring(0, 30));
325 }
326 else {
327 batch.setPaymentFileName(fileName);
328 }
329
330 batch.setPaymentTotalAmount(paymentFile.getPaymentTotalAmount());
331 batch.setSubmiterUserId(GlobalVariables.getUserSession().getPerson().getPrincipalId());
332
333 return batch;
334 }
335
336
337
338
339
340 protected String getBaseFileName(String filename) {
341
342 filename = filename.replaceAll("\\\\", "/");
343
344 int startingPointer = filename.length() - 1;
345 while ((startingPointer > 0) && (filename.charAt(startingPointer) != '/')) {
346 startingPointer--;
347 }
348
349 return filename.substring(startingPointer + 1);
350 }
351
352
353
354
355
356
357 protected void removeDoneFile(String dataFileName) {
358 File doneFile = new File(StringUtils.substringBeforeLast(dataFileName, ".") + ".done");
359 if (doneFile.exists()) {
360 doneFile.delete();
361 }
362 }
363
364
365
366
367
368
369 public void setOutgoingDirectoryName(String outgoingDirectoryName) {
370 this.outgoingDirectoryName = outgoingDirectoryName;
371 }
372
373
374
375
376
377
378 public void setParameterService(ParameterService parameterService) {
379 this.parameterService = parameterService;
380 }
381
382
383
384
385
386
387 public void setCustomerProfileService(CustomerProfileService customerProfileService) {
388 this.customerProfileService = customerProfileService;
389 }
390
391
392
393
394
395
396 public void setBatchInputFileService(BatchInputFileService batchInputFileService) {
397 this.batchInputFileService = batchInputFileService;
398 }
399
400
401
402
403
404
405 public void setPaymentFileValidationService(PaymentFileValidationService paymentFileValidationService) {
406 this.paymentFileValidationService = paymentFileValidationService;
407 }
408
409
410
411
412
413
414 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
415 this.businessObjectService = businessObjectService;
416 }
417
418
419
420
421
422
423 public void setDateTimeService(DateTimeService dateTimeService) {
424 this.dateTimeService = dateTimeService;
425 }
426
427
428
429
430
431
432 public void setPaymentFileEmailService(PdpEmailService paymentFileEmailService) {
433 this.paymentFileEmailService = paymentFileEmailService;
434 }
435
436
437
438
439
440
441 public void setConfigurationService(ConfigurationService kualiConfigurationService) {
442 this.kualiConfigurationService = kualiConfigurationService;
443 }
444
445
446
447
448 @Override
449 public List<String> getRequiredDirectoryNames() {
450 return new ArrayList<String>() {{add(outgoingDirectoryName); }};
451 }
452
453 }
454