View Javadoc
1   /*
2    * Copyright 2007 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.module.purap.edi;
17  
18  import com.lowagie.text.DocumentException;
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.kuali.ole.module.purap.PurapConstants;
22  import org.kuali.ole.module.purap.businessobject.PurApItem;
23  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
24  import org.kuali.ole.module.purap.exception.PurError;
25  import org.kuali.ole.module.purap.util.PurApDateFormatUtils;
26  import org.kuali.ole.select.businessobject.OlePurchaseOrderItem;
27  import org.kuali.ole.select.lookup.DocLookupSearch;
28  import org.kuali.ole.select.lookup.DocLookupServiceImpl;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.rice.core.api.datetime.DateTimeService;
31  import org.kuali.rice.krad.util.ObjectUtils;
32  
33  import java.io.*;
34  import java.text.SimpleDateFormat;
35  import java.util.*;
36  
37  /**
38   * Base class to handle Edi for purchase order documents.
39   */
40  public class PurchaseOrderEdi {
41      private static Log LOG = LogFactory.getLog(PurchaseOrderEdi.class);
42  
43      private DateTimeService dateTimeService;
44  
45  
46      public PurchaseOrderEdi() {
47      }
48  
49  
50      /**
51       * Invokes the createEdiFile method to create a EDI document and saves it into a file
52       * which name and location are specified in the file.
53       *
54       * @param po           The PurchaseOrderDocument to be used to create the EDI.
55       * @param file         The file containing some of the parameters information needed by the EDI for example, the EDI file name and EDI file location, purchasing director name, etc.
56       * @param isRetransmit The boolean to indicate whether this is for a retransmit purchase order document.
57       * @param environment  The current environment used (e.g. DEV if it is a development environment).
58       */
59      public boolean saveEdi(PurchaseOrderDocument po, PurApItem item, String file) {
60          if (LOG.isInfoEnabled()) {
61              LOG.info("saveEdi() started for po number " + po.getPurapDocumentIdentifier());
62          }
63  
64          try {
65              createEdiFile(po, item, file);
66              if (LOG.isDebugEnabled()) {
67                  LOG.debug("saveEdi() completed for po number " + po.getPurapDocumentIdentifier());
68              }
69          } catch (DocumentException de) {
70              LOG.error("saveEdi() DocumentException: " + de.getMessage(), de);
71              throw new PurError("Document Exception when trying to save a Purchase Order EDI", de);
72          } catch (FileNotFoundException f) {
73              LOG.error("saveEdi() FileNotFoundException: " + f.getMessage(), f);
74              throw new PurError("FileNotFound Exception when trying to save a Purchase Order EDI", f);
75          } catch (IOException i) {
76              LOG.error("saveEdi() IOException: " + i.getMessage(), i);
77              throw new PurError("IO Exception when trying to save a Purchase Order EDI", i);
78          } catch (Exception t) {
79              LOG.error("saveEdi() EXCEPTION: " + t.getMessage(), t);
80              throw new PurError("Exception when trying to save a Purchase Order EDI", t);
81          }
82          return true;
83      }
84  
85  
86      /**
87       * This method is for generate a unique reference number for a PO
88       *
89       * @return String
90       * @throws Exception
91       */
92      private String generateReferenceNumber() throws Exception {
93          UUID referenceNumber = UUID.randomUUID();
94          return referenceNumber.toString();
95      }
96  
97  
98      /**
99       * Create an EDI file using the given input parameters.
100      *
101      * @param po   The PurchaseOrderDocument to be used to create the EDI.
102      * @param file The EDI document whose margins have already been set.
103      * @throws Exception
104      */
105     private void createEdiFile(PurchaseOrderDocument po, PurApItem item, String file) throws Exception {
106         Writer writer = null;
107         StringBuffer text = new StringBuffer();
108         try {
109 
110             LOG.debug("EDI File creation started");
111             List<OlePurchaseOrderItem> purchaseOrderItemList = new ArrayList<OlePurchaseOrderItem>();
112             String itemIdentifier = item.getItemIdentifier().toString();
113             Map map = new HashMap();
114             map.put("itemIdentifier", itemIdentifier);
115             DocLookupServiceImpl impl = SpringContext.getBean(DocLookupServiceImpl.class, "docLookupService");
116             OlePurchaseOrderItem olePurchaseOrderItem = null;
117             impl.setLookupDao(new DocLookupSearch());
118             try {
119                 List<OlePurchaseOrderItem> searchResults = (List) impl.findCollectionBySearchHelper(OlePurchaseOrderItem.class, map, true);
120                 for (OlePurchaseOrderItem poItem : searchResults) {
121                     purchaseOrderItemList.add(poItem);
122                 }
123                 olePurchaseOrderItem = purchaseOrderItemList.get(0);
124             } catch (Exception exception) {
125                 LOG.error("*****Exception in createEdiFile()******: No matching data found in the docstore " + exception.getMessage());
126             }
127 
128             int lineCount = 0;
129             String uniqueRefNumber = generateReferenceNumber();
130             text.append("UNH+" + uniqueRefNumber + "ORDERS:D:96A:UN:EAN008'");
131             text.append(System.getProperty("line.separator"));
132             lineCount++;
133             String statusCode = "220";
134             if (po.getApplicationDocumentStatus() != null && po.getApplicationDocumentStatus().equalsIgnoreCase(PurapConstants.PurchaseOrderStatuses.APPDOC_RETIRED_VERSION)) {
135                 statusCode = "230";
136             }
137             text.append("BGM+" + statusCode + "+" + po.getPurapDocumentIdentifier().toString() + "+9'");
138             text.append(System.getProperty("line.separator"));
139             lineCount++;
140             String orderDate = "";
141 
142             SimpleDateFormat sdf = PurApDateFormatUtils.getSimpleDateFormat(PurapConstants.NamedDateFormats.KUALI_SIMPLE_DATE_FORMAT_2);
143             if (po.getPurchaseOrderInitialOpenTimestamp() != null) {
144                 orderDate = sdf.format(po.getPurchaseOrderInitialOpenTimestamp());
145             } else {
146                 // This date isn't set until the first time this document is printed, so will be null the first time; use today's date.
147                 orderDate = sdf.format(getDateTimeService().getCurrentSqlDate());
148             }
149 
150             SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy");
151             Date date = formatter.parse(orderDate);
152             String formattedDate = formatter.format(date);
153 
154             Date newDate = formatter.parse(formattedDate);
155             formatter = new SimpleDateFormat("yyMMdd");
156             formattedDate = formatter.format(newDate);
157 
158             Calendar calendar = Calendar.getInstance();
159             calendar.setTime(date);
160             int century = (calendar.get(Calendar.YEAR) / 100) + 1;
161 
162             text.append("DTM+137:" + century + formattedDate + ":102'");
163             text.append(System.getProperty("line.separator"));
164             lineCount++;
165             text.append("NAD+SU+++" + getSupplierDetails(po) + "'");
166             text.append(System.getProperty("line.separator"));
167             lineCount++;
168             text.append("NAD+BY+++" + getBillingDetails(po) + "'");
169             text.append(System.getProperty("line.separator"));
170             lineCount++;
171             text.append("NAD+DP+++" + getDeliveryDetails(po) + "'");
172             text.append(System.getProperty("line.separator"));
173             lineCount++;
174             if (po.getVendorCustomerNumber() != null && po.getVendorCustomerNumber().length() > 0) {
175                 text.append("RFF+API:" + po.getVendorCustomerNumber() + "'");
176                 text.append(System.getProperty("line.separator"));
177                 lineCount++;
178             }
179 
180             //text.append("CUX+2:"+"USD"+":9'");
181             //text.append(System.getProperty("line.separator"));
182             text.append("LIN+" + "1'");
183             text.append(System.getProperty("line.separator"));
184             lineCount++;
185             text.append("PIA+5+" + "9781444334609" + ":IB'");
186             text.append(System.getProperty("line.separator"));
187             lineCount++;
188             if (olePurchaseOrderItem != null && olePurchaseOrderItem.getDocData() != null) {
189                 if (olePurchaseOrderItem.getDocData().getTitle() != null && olePurchaseOrderItem.getDocData().getTitle().length() > 0) {
190                     text.append("IMD+L+050+:::" + olePurchaseOrderItem.getDocData().getTitle() + "'");
191                     text.append(System.getProperty("line.separator"));
192                     lineCount++;
193                 }
194                 if (olePurchaseOrderItem.getDocData().getPlaceOfPublication() != null && olePurchaseOrderItem.getDocData().getPlaceOfPublication().length() > 0) {
195                     text.append("IMD+L+110+:::" + olePurchaseOrderItem.getDocData().getPlaceOfPublication() + "'");
196                     text.append(System.getProperty("line.separator"));
197                     lineCount++;
198                 }
199                 if (olePurchaseOrderItem.getDocData().getAuthor() != null && olePurchaseOrderItem.getDocData().getAuthor().length() > 0) {
200                     text.append("IMD+L+009+:::" + olePurchaseOrderItem.getDocData().getAuthor() + "'");
201                     text.append(System.getProperty("line.separator"));
202                     lineCount++;
203                 }
204                 if (olePurchaseOrderItem.getDocData().getPublicationDate() != null && olePurchaseOrderItem.getDocData().getPublicationDate().length() > 0) {
205                     text.append("IMD+L+170+:::" + olePurchaseOrderItem.getDocData().getPublicationDate() + "'");
206                     text.append(System.getProperty("line.separator"));
207                     lineCount++;
208                 }
209                 if (olePurchaseOrderItem.getDocData().getPublisher() != null && olePurchaseOrderItem.getDocData().getPublisher().length() > 0) {
210                     text.append("IMD+L+109+:::" + olePurchaseOrderItem.getDocData().getPublisher() + "'");
211                     text.append(System.getProperty("line.separator"));
212                     lineCount++;
213                 }
214             }
215 
216             text.append("QTY+21:" + item.getItemQuantity() + "'");
217             text.append(System.getProperty("line.separator"));
218             lineCount++;
219             text.append("PRI+AAE:" + "33" + ":SRP'");
220             text.append(System.getProperty("line.separator"));
221             lineCount++;
222             text.append("UNS+S'");
223             text.append(System.getProperty("line.separator"));
224             lineCount++;
225             text.append("CNT+2:1'");
226             text.append(System.getProperty("line.separator"));
227             lineCount++;
228             lineCount++;
229             text.append("UNT+" + lineCount + "+" + uniqueRefNumber + ":'");
230 
231             File filePath = new File(file);
232             writer = new BufferedWriter(new FileWriter(filePath));
233             writer.write(text.toString());
234             LOG.debug("EDI File created");
235         } finally {
236             try {
237                 if (writer != null) {
238                     writer.close();
239                 }
240             } catch (IOException e) {
241                 e.printStackTrace();
242             }
243         }
244 
245     }
246 
247 
248     /**
249      * This method is to get the Supplier details
250      *
251      * @param po
252      * @return String
253      */
254     public String getSupplierDetails(PurchaseOrderDocument po) {
255         String str = (po.getVendorName() != null && po.getVendorName().length() > 0 ? po.getVendorName() + "+" : "") +
256                 (po.getVendorAttentionName() != null && po.getVendorAttentionName().length() > 0 ? "ATTN: " + po.getVendorAttentionName() + "+" : "") +
257                 (po.getVendorLine1Address() != null && po.getVendorLine1Address().length() > 0 ? po.getVendorLine1Address() + "+" : "") +
258                 (po.getVendorCityName() != null && po.getVendorCityName().length() > 0 ? po.getVendorCityName() + "+" : "") +
259                 (po.getVendorStateCode() != null && po.getVendorStateCode().length() > 0 ? po.getVendorStateCode() + "+" : "") +
260                 (po.getVendorPostalCode() != null && po.getVendorPostalCode().length() > 0 ? po.getVendorPostalCode() + "+" : "") +
261                 (po.getVendorCountryCode() != null && po.getVendorCountryCode().length() > 0 ? po.getVendorCountryCode() : "");
262         return str;
263 
264     }
265 
266 
267     /**
268      * This method is to get the billing details
269      *
270      * @param po
271      * @return String
272      */
273     public String getBillingDetails(PurchaseOrderDocument po) {
274         String str = (po.getBillingName() != null && po.getBillingName().length() > 0 ? po.getBillingName() + "+" : "") +
275                 (po.getBillingLine1Address() != null && po.getBillingLine1Address().length() > 0 ? po.getBillingLine1Address() + "+" : "") +
276                 (po.getBillingLine2Address() != null && po.getBillingLine2Address().length() > 0 ? po.getBillingLine2Address() + "+" : "") +
277                 (po.getBillingCityName() != null && po.getBillingCityName().length() > 0 ? po.getBillingCityName() + "+" : "") +
278                 (po.getBillingStateCode() != null && po.getBillingStateCode().length() > 0 ? po.getBillingStateCode() + "+" : "") +
279                 (po.getBillingPhoneNumber() != null && po.getBillingPhoneNumber().length() > 0 ? po.getBillingPhoneNumber() + "+" : "") +
280                 (po.getBillingPostalCode() != null && po.getBillingPostalCode().length() > 0 ? po.getBillingPostalCode() + "+" : "") +
281                 (po.getBillingCountryCode() != null && po.getBillingCountryCode().length() > 0 ? po.getBillingCountryCode() : "");
282         return str;
283 
284     }
285 
286 
287     /**
288      * This method is to get the delivery details
289      *
290      * @param po
291      * @return String
292      */
293     public String getDeliveryDetails(PurchaseOrderDocument po) {
294         String str = (po.getDeliveryToName() != null && po.getDeliveryToName().length() > 0 ? po.getDeliveryToName() + "+" : "") +
295                 (po.getDeliveryBuildingRoomNumber() != null && po.getDeliveryBuildingRoomNumber().length() > 0 ? "Room # " + po.getDeliveryBuildingRoomNumber() + "+" : "") +
296                 (po.getDeliveryBuildingLine1Address() != null && po.getDeliveryBuildingLine1Address().length() > 0 ? po.getDeliveryBuildingLine1Address() + "+" : "") +
297                 (po.getDeliveryCityName() != null && po.getDeliveryCityName().length() > 0 ? po.getDeliveryCityName() + "+" : "") +
298                 (po.getDeliveryStateCode() != null && po.getDeliveryStateCode().length() > 0 ? po.getDeliveryStateCode() + "+" : "") +
299                 (po.getDeliveryPostalCode() != null && po.getDeliveryPostalCode().length() > 0 ? po.getDeliveryPostalCode() + "+" : "") +
300                 (po.getDeliveryCountryCode() != null && po.getDeliveryCountryCode().length() > 0 ? po.getDeliveryCountryCode() : "");
301         return str;
302 
303     }
304 
305 
306     public DateTimeService getDateTimeService() {
307         if (ObjectUtils.isNull(dateTimeService)) {
308             this.dateTimeService = SpringContext.getBean(DateTimeService.class);
309         }
310         return this.dateTimeService;
311     }
312 
313 }