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