KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > shipment > thirdparty > ups > UpsServices


1 /*
2  * $Id: UpsServices.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2003 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.shipment.thirdparty.ups;
25
26 import java.io.File JavaDoc;
27 import java.io.FileOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.TreeSet JavaDoc;
36
37 import javax.xml.parsers.ParserConfigurationException JavaDoc;
38
39 import org.ofbiz.base.util.Base64;
40 import org.ofbiz.base.util.Debug;
41 import org.ofbiz.base.util.GeneralException;
42 import org.ofbiz.base.util.HttpClient;
43 import org.ofbiz.base.util.HttpClientException;
44 import org.ofbiz.base.util.StringUtil;
45 import org.ofbiz.base.util.UtilMisc;
46 import org.ofbiz.base.util.UtilProperties;
47 import org.ofbiz.base.util.UtilValidate;
48 import org.ofbiz.base.util.UtilXml;
49 import org.ofbiz.entity.GenericDelegator;
50 import org.ofbiz.entity.GenericEntityException;
51 import org.ofbiz.entity.GenericValue;
52 import org.ofbiz.entity.util.EntityUtil;
53 import org.ofbiz.service.DispatchContext;
54 import org.ofbiz.service.ServiceUtil;
55 import org.ofbiz.product.store.ProductStoreWorker;
56
57 import org.w3c.dom.Document JavaDoc;
58 import org.w3c.dom.Element JavaDoc;
59 import org.xml.sax.SAXException JavaDoc;
60
61 /**
62  * UPS ShipmentServices
63  *
64  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
65  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
66  * @version $Rev: 5462 $
67  * @since 2.2
68  */

69 public class UpsServices {
70     
71     public final static String JavaDoc module = UpsServices.class.getName();
72     
73     public static Map JavaDoc unitsUpsToOfbiz = new HashMap JavaDoc();
74     public static Map JavaDoc unitsOfbizToUps = new HashMap JavaDoc();
75     static {
76         unitsUpsToOfbiz.put("LBS", "WT_lb");
77         unitsUpsToOfbiz.put("KGS", "WT_kg");
78         
79         Iterator JavaDoc unitsUpsToOfbizIter = unitsUpsToOfbiz.entrySet().iterator();
80         while (unitsUpsToOfbizIter.hasNext()) {
81             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) unitsUpsToOfbizIter.next();
82             unitsOfbizToUps.put(entry.getValue(), entry.getKey());
83         }
84     }
85
86
87     public static Map JavaDoc upsShipmentConfirm(DispatchContext dctx, Map JavaDoc context) {
88         Map JavaDoc result = new HashMap JavaDoc();
89         GenericDelegator delegator = dctx.getDelegator();
90         String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
91         String JavaDoc shipmentRouteSegmentId = (String JavaDoc) context.get("shipmentRouteSegmentId");
92
93         boolean shipmentUpsSaveCertificationInfo = "true".equals(UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.info"));
94         String JavaDoc shipmentUpsSaveCertificationPath = UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.path");
95         File JavaDoc shipmentUpsSaveCertificationFile = null;
96         if (shipmentUpsSaveCertificationInfo) {
97             shipmentUpsSaveCertificationFile = new File JavaDoc(shipmentUpsSaveCertificationPath);
98             if (!shipmentUpsSaveCertificationFile.exists()) {
99                 shipmentUpsSaveCertificationFile.mkdirs();
100             }
101         }
102
103         String JavaDoc shipmentConfirmResponseString = null;
104         
105         try {
106             GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
107             if (shipment == null) {
108                 return ServiceUtil.returnError("Shipment not found with ID " + shipmentId);
109             }
110             GenericValue shipmentRouteSegment = delegator.findByPrimaryKey("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId));
111             if (shipmentRouteSegment == null) {
112                 return ServiceUtil.returnError("ShipmentRouteSegment not found with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
113             }
114             
115             if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
116                 return ServiceUtil.returnError("ERROR: The Carrier for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is not UPS.");
117             }
118             
119             // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services
120
if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("carrierServiceStatusId")) && !"SHRSCS_NOT_STARTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
121                 return ServiceUtil.returnError("ERROR: The Carrier Service Status for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is [" + shipmentRouteSegment.getString("carrierServiceStatusId") + "], but must be not-set or [SHRSCS_NOT_STARTED] to perform the UPS Shipment Confirm operation.");
122             }
123             
124             // Get Origin Info
125
GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress");
126             if (originPostalAddress == null) {
127                 return ServiceUtil.returnError("OriginPostalAddress not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
128             }
129             GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber");
130             if (originTelecomNumber == null) {
131                 return ServiceUtil.returnError("OriginTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
132             }
133             String JavaDoc originPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber");
134             // don't put on country code if not specified or is the US country code (UPS wants it this way)
135
if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !"001".equals(originTelecomNumber.getString("countryCode"))) {
136                 originPhoneNumber = originTelecomNumber.getString("countryCode") + originPhoneNumber;
137             }
138             originPhoneNumber = StringUtil.replaceString(originPhoneNumber, "-", "");
139             originPhoneNumber = StringUtil.replaceString(originPhoneNumber, " ", "");
140             // lookup the two letter country code (in the geoCode field)
141
GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo");
142             if (originCountryGeo == null) {
143                 return ServiceUtil.returnError("OriginCountryGeo not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
144             }
145
146             // Get Dest Info
147
GenericValue destPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress");
148             if (destPostalAddress == null) {
149                 return ServiceUtil.returnError("DestPostalAddress not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
150             }
151
152             GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber");
153             if (destTelecomNumber == null) {
154                 String JavaDoc missingErrMsg = "DestTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId;
155                 Debug.logError(missingErrMsg, module);
156                 // for now we won't require the dest phone number, but is it required?
157
//return ServiceUtil.returnError(missingErrMsg);
158
}
159             String JavaDoc destPhoneNumber = null;
160             if (destTelecomNumber != null) {
161                 destPhoneNumber = destTelecomNumber.getString("areaCode") + destTelecomNumber.getString("contactNumber");
162                 // don't put on country code if not specified or is the US country code (UPS wants it this way)
163
if (UtilValidate.isNotEmpty(destTelecomNumber.getString("countryCode")) && !"001".equals(destTelecomNumber.getString("countryCode"))) {
164                     destPhoneNumber = destTelecomNumber.getString("countryCode") + destPhoneNumber;
165                 }
166                 destPhoneNumber = StringUtil.replaceString(destPhoneNumber, "-", "");
167                 destPhoneNumber = StringUtil.replaceString(destPhoneNumber, " ", "");
168             }
169
170             // lookup the two letter country code (in the geoCode field)
171
GenericValue destCountryGeo = destPostalAddress.getRelatedOne("CountryGeo");
172             if (destCountryGeo == null) {
173                 return ServiceUtil.returnError("DestCountryGeo not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
174             }
175
176             Map JavaDoc findCarrierShipmentMethodMap = UtilMisc.toMap("partyId", shipmentRouteSegment.get("carrierPartyId"), "roleTypeId", "CARRIER", "shipmentMethodTypeId", shipmentRouteSegment.get("shipmentMethodTypeId"));
177             GenericValue carrierShipmentMethod = delegator.findByPrimaryKey("CarrierShipmentMethod", findCarrierShipmentMethodMap);
178             if (carrierShipmentMethod == null) {
179                 return ServiceUtil.returnError("CarrierShipmentMethod not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId + "; partyId is " + shipmentRouteSegment.get("carrierPartyId") + " and shipmentMethodTypeId is " + shipmentRouteSegment.get("shipmentMethodTypeId"));
180             }
181
182             List JavaDoc shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"));
183             if (shipmentPackageRouteSegs == null || shipmentPackageRouteSegs.size() == 0) {
184                 return ServiceUtil.returnError("No ShipmentPackageRouteSegs (ie No Packages) found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
185             }
186             
187             List JavaDoc itemIssuances = shipment.getRelated("ItemIssuance");
188             Set JavaDoc orderIdSet = new TreeSet JavaDoc();
189             Iterator JavaDoc itemIssuanceIter = itemIssuances.iterator();
190             while (itemIssuanceIter.hasNext()) {
191                 GenericValue itemIssuance = (GenericValue) itemIssuanceIter.next();
192                 orderIdSet.add(itemIssuance.get("orderId"));
193             }
194             String JavaDoc ordersDescription = "";
195             if (orderIdSet.size() > 1) {
196                 StringBuffer JavaDoc odBuf = new StringBuffer JavaDoc("Orders ");
197                 Iterator JavaDoc orderIdIter = orderIdSet.iterator();
198                 while (orderIdIter.hasNext()) {
199                     String JavaDoc orderId = (String JavaDoc) orderIdIter.next();
200                     odBuf.append(orderId);
201                     if (orderIdIter.hasNext()) {
202                         odBuf.append(", ");
203                     }
204                 }
205                 ordersDescription = odBuf.toString();
206             } else if (orderIdSet.size() > 0) {
207                 ordersDescription = "Order " + (String JavaDoc) orderIdSet.iterator().next();
208             }
209             
210             // Okay, start putting the XML together...
211
Document JavaDoc shipmentConfirmRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentConfirmRequest");
212             Element JavaDoc shipmentConfirmRequestElement = shipmentConfirmRequestDoc.getDocumentElement();
213             shipmentConfirmRequestElement.setAttribute("xml:lang", "en-US");
214
215             // Top Level Element: Request
216
Element JavaDoc requestElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Request", shipmentConfirmRequestDoc);
217
218             Element JavaDoc transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", shipmentConfirmRequestDoc);
219             UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Ship Confirm / nonvalidate", shipmentConfirmRequestDoc);
220             UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", shipmentConfirmRequestDoc);
221
222             UtilXml.addChildElementValue(requestElement, "RequestAction", "ShipConfirm", shipmentConfirmRequestDoc);
223             UtilXml.addChildElementValue(requestElement, "RequestOption", "nonvalidate", shipmentConfirmRequestDoc);
224
225             // Top Level Element: LabelSpecification
226
Element JavaDoc labelSpecificationElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "LabelSpecification", shipmentConfirmRequestDoc);
227             
228             Element JavaDoc labelPrintMethodElement = UtilXml.addChildElement(labelSpecificationElement, "LabelPrintMethod", shipmentConfirmRequestDoc);
229             UtilXml.addChildElementValue(labelPrintMethodElement, "Code", "GIF", shipmentConfirmRequestDoc);
230
231             UtilXml.addChildElementValue(labelSpecificationElement, "HTTPUserAgent", "Mozilla/5.0", shipmentConfirmRequestDoc);
232
233             Element JavaDoc labelImageFormatElement = UtilXml.addChildElement(labelSpecificationElement, "LabelImageFormat", shipmentConfirmRequestDoc);
234             UtilXml.addChildElementValue(labelImageFormatElement, "Code", "GIF", shipmentConfirmRequestDoc);
235             
236             // Top Level Element: Shipment
237
Element JavaDoc shipmentElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Shipment", shipmentConfirmRequestDoc);
238             UtilXml.addChildElementValue(shipmentElement, "Description", "Goods for Shipment " + shipment.get("shipmentId") + " from " + ordersDescription, shipmentConfirmRequestDoc);
239             
240             // Child of Shipment: Shipper
241
Element JavaDoc shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", shipmentConfirmRequestDoc);
242             UtilXml.addChildElementValue(shipperElement, "Name", originPostalAddress.getString("toName"), shipmentConfirmRequestDoc);
243             UtilXml.addChildElementValue(shipperElement, "AttentionName", originPostalAddress.getString("attnName"), shipmentConfirmRequestDoc);
244             UtilXml.addChildElementValue(shipperElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc);
245             UtilXml.addChildElementValue(shipperElement, "ShipperNumber", UtilProperties.getPropertyValue("shipment", "shipment.ups.shipper.number"), shipmentConfirmRequestDoc);
246
247             Element JavaDoc shipperAddressElement = UtilXml.addChildElement(shipperElement, "Address", shipmentConfirmRequestDoc);
248             UtilXml.addChildElementValue(shipperAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc);
249             if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) {
250                 UtilXml.addChildElementValue(shipperAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc);
251             }
252             //UtilXml.addChildElementValue(shipperAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc);
253
UtilXml.addChildElementValue(shipperAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc);
254             UtilXml.addChildElementValue(shipperAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc);
255             UtilXml.addChildElementValue(shipperAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc);
256             UtilXml.addChildElementValue(shipperAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc);
257             // How to determine this? Add to data model...? UtilXml.addChildElement(shipperAddressElement, "ResidentialAddress", shipmentConfirmRequestDoc);
258

259
260             // Child of Shipment: ShipTo
261
Element JavaDoc shipToElement = UtilXml.addChildElement(shipmentElement, "ShipTo", shipmentConfirmRequestDoc);
262             UtilXml.addChildElementValue(shipToElement, "CompanyName", destPostalAddress.getString("toName"), shipmentConfirmRequestDoc);
263             UtilXml.addChildElementValue(shipToElement, "AttentionName", destPostalAddress.getString("attnName"), shipmentConfirmRequestDoc);
264             if (UtilValidate.isNotEmpty(destPhoneNumber)) {
265                 UtilXml.addChildElementValue(shipToElement, "PhoneNumber", destPhoneNumber, shipmentConfirmRequestDoc);
266             }
267             Element JavaDoc shipToAddressElement = UtilXml.addChildElement(shipToElement, "Address", shipmentConfirmRequestDoc);
268             UtilXml.addChildElementValue(shipToAddressElement, "AddressLine1", destPostalAddress.getString("address1"), shipmentConfirmRequestDoc);
269             if (UtilValidate.isNotEmpty(destPostalAddress.getString("address2"))) {
270                 UtilXml.addChildElementValue(shipToAddressElement, "AddressLine2", destPostalAddress.getString("address2"), shipmentConfirmRequestDoc);
271             }
272             //UtilXml.addChildElementValue(shipToAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc);
273
UtilXml.addChildElementValue(shipToAddressElement, "City", destPostalAddress.getString("city"), shipmentConfirmRequestDoc);
274             UtilXml.addChildElementValue(shipToAddressElement, "StateProvinceCode", destPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc);
275             UtilXml.addChildElementValue(shipToAddressElement, "PostalCode", destPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc);
276             UtilXml.addChildElementValue(shipToAddressElement, "CountryCode", destCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc);
277
278             // Child of Shipment: ShipFrom
279
Element JavaDoc shipFromElement = UtilXml.addChildElement(shipmentElement, "ShipFrom", shipmentConfirmRequestDoc);
280             UtilXml.addChildElementValue(shipFromElement, "CompanyName", originPostalAddress.getString("toName"), shipmentConfirmRequestDoc);
281             UtilXml.addChildElementValue(shipFromElement, "AttentionName", originPostalAddress.getString("attnName"), shipmentConfirmRequestDoc);
282             UtilXml.addChildElementValue(shipFromElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc);
283             Element JavaDoc shipFromAddressElement = UtilXml.addChildElement(shipFromElement, "Address", shipmentConfirmRequestDoc);
284             UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc);
285             if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) {
286                 UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc);
287             }
288             //UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc);
289
UtilXml.addChildElementValue(shipFromAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc);
290             UtilXml.addChildElementValue(shipFromAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc);
291             UtilXml.addChildElementValue(shipFromAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc);
292             UtilXml.addChildElementValue(shipFromAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc);
293
294             // Child of Shipment: PaymentInformation
295
Element JavaDoc paymentInformationElement = UtilXml.addChildElement(shipmentElement, "PaymentInformation", shipmentConfirmRequestDoc);
296             Element JavaDoc prepaidElement = UtilXml.addChildElement(paymentInformationElement, "Prepaid", shipmentConfirmRequestDoc);
297             Element JavaDoc billShipperElement = UtilXml.addChildElement(prepaidElement, "BillShipper", shipmentConfirmRequestDoc);
298             // fill in BillShipper AccountNumber element from properties file
299
UtilXml.addChildElementValue(billShipperElement, "AccountNumber", UtilProperties.getPropertyValue("shipment", "shipment.ups.bill.shipper.account.number"), shipmentConfirmRequestDoc);
300
301             // Child of Shipment: Service
302
Element JavaDoc serviceElement = UtilXml.addChildElement(shipmentElement, "Service", shipmentConfirmRequestDoc);
303             UtilXml.addChildElementValue(serviceElement, "Code", carrierShipmentMethod.getString("carrierServiceCode"), shipmentConfirmRequestDoc);
304
305             // Child of Shipment: Package
306
Iterator JavaDoc shipmentPackageRouteSegIter = shipmentPackageRouteSegs.iterator();
307             while (shipmentPackageRouteSegIter.hasNext()) {
308                 GenericValue shipmentPackageRouteSeg = (GenericValue) shipmentPackageRouteSegIter.next();
309                 GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage");
310                 GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType");
311                 List JavaDoc carrierShipmentBoxTypes = shipmentPackage.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "UPS"), null);
312                 GenericValue carrierShipmentBoxType = null;
313                 if (carrierShipmentBoxTypes.size() > 0) {
314                     carrierShipmentBoxType = (GenericValue) carrierShipmentBoxTypes.get(0);
315                 }
316                  
317                 Element JavaDoc packageElement = UtilXml.addChildElement(shipmentElement, "Package", shipmentConfirmRequestDoc);
318                 Element JavaDoc packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", shipmentConfirmRequestDoc);
319                 if (carrierShipmentBoxType != null && carrierShipmentBoxType.get("packagingTypeCode") != null) {
320                     UtilXml.addChildElementValue(packagingTypeElement, "Code", carrierShipmentBoxType.getString("packagingTypeCode"), shipmentConfirmRequestDoc);
321                 } else {
322                     // default to "02", plain old Package
323
UtilXml.addChildElementValue(packagingTypeElement, "Code", "02", shipmentConfirmRequestDoc);
324                 }
325                 if (shipmentBoxType != null) {
326                     Element JavaDoc dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", shipmentConfirmRequestDoc);
327                     Element JavaDoc unitOfMeasurementElement = UtilXml.addChildElement(dimensionsElement, "UnitOfMeasurement", shipmentConfirmRequestDoc);
328                     GenericValue dimensionUom = shipmentBoxType.getRelatedOne("DimensionUom");
329                     if (dimensionUom != null) {
330                         UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", dimensionUom.getString("abbreviation"), shipmentConfirmRequestDoc);
331                     } else {
332                         // I guess we'll default to inches...
333
UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", "IN", shipmentConfirmRequestDoc);
334                     }
335                     UtilXml.addChildElementValue(dimensionsElement, "Length", shipmentBoxType.get("boxLength").toString(), shipmentConfirmRequestDoc);
336                     UtilXml.addChildElementValue(dimensionsElement, "Width", shipmentBoxType.get("boxWidth").toString(), shipmentConfirmRequestDoc);
337                     UtilXml.addChildElementValue(dimensionsElement, "Height", shipmentBoxType.get("boxHeight").toString(), shipmentConfirmRequestDoc);
338                 }
339                 
340                 Element JavaDoc packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", shipmentConfirmRequestDoc);
341                 Element JavaDoc packageWeightUnitOfMeasurementElement = UtilXml.addChildElement(packageElement, "UnitOfMeasurement", shipmentConfirmRequestDoc);
342                 String JavaDoc weightUomUps = (String JavaDoc) unitsOfbizToUps.get(shipmentPackage.get("weightUomId"));
343                 if (weightUomUps != null) {
344                     UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", weightUomUps, shipmentConfirmRequestDoc);
345                 } else {
346                     // might as well default to LBS
347
UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", "LBS", shipmentConfirmRequestDoc);
348                 }
349                 
350                 if (shipmentPackage.getString("weight") == null) {
351                     return ServiceUtil.returnError("Weight value not found for ShipmentRouteSegment with shipmentId " + shipmentId + ", shipmentRouteSegmentId " + shipmentRouteSegmentId + ", and shipmentPackageSeqId " + shipmentPackage.getString("shipmentPackageSeqId"));
352                 }
353                 UtilXml.addChildElementValue(packageWeightElement, "Weight", shipmentPackage.getString("weight"), shipmentConfirmRequestDoc);
354                 
355                 Element JavaDoc referenceNumberElement = UtilXml.addChildElement(packageElement, "ReferenceNumber", shipmentConfirmRequestDoc);
356                 UtilXml.addChildElementValue(referenceNumberElement, "Code", "MK", shipmentConfirmRequestDoc);
357                 UtilXml.addChildElementValue(referenceNumberElement, "Value", shipmentPackage.getString("shipmentPackageSeqId"), shipmentConfirmRequestDoc);
358
359                 if (carrierShipmentBoxType != null && carrierShipmentBoxType.get("oversizeCode") != null) {
360                     UtilXml.addChildElementValue(packageElement, "OversizePackage", carrierShipmentBoxType.getString("oversizeCode"), shipmentConfirmRequestDoc);
361                 }
362             }
363
364             String JavaDoc shipmentConfirmRequestString = null;
365             try {
366                 shipmentConfirmRequestString = UtilXml.writeXmlDocument(shipmentConfirmRequestDoc);
367             } catch (IOException JavaDoc e) {
368                 String JavaDoc ioeErrMsg = "Error writing the ShipmentConfirmRequest XML Document to a String: " + e.toString();
369                 Debug.logError(e, ioeErrMsg, module);
370                 return ServiceUtil.returnError(ioeErrMsg);
371             }
372             
373             // create AccessRequest XML doc
374
Document JavaDoc accessRequestDocument = createAccessRequestDocument();
375             String JavaDoc accessRequestString = null;
376             try {
377                 accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument);
378             } catch (IOException JavaDoc e) {
379                 String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString();
380                 Debug.logError(e, ioeErrMsg, module);
381                 return ServiceUtil.returnError(ioeErrMsg);
382             }
383             
384             // connect to UPS server, send AccessRequest to auth
385
// send ShipmentConfirmRequest String
386
// get ShipmentConfirmResponse String back
387
StringBuffer JavaDoc xmlString = new StringBuffer JavaDoc();
388             // TODO: note that we may have to append <?xml version="1.0"?> before each string
389
xmlString.append(accessRequestString);
390             xmlString.append(shipmentConfirmRequestString);
391
392             if (shipmentUpsSaveCertificationInfo) {
393                 String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentConfirmRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
394                 try {
395                     FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
396                     fileOut.write(xmlString.toString().getBytes());
397                     fileOut.flush();
398                     fileOut.close();
399                 } catch (IOException JavaDoc e) {
400                     Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
401                 }
402             }
403             
404             try {
405                 shipmentConfirmResponseString = sendUpsRequest("ShipConfirm", xmlString.toString());
406             } catch (UpsConnectException e) {
407                 String JavaDoc uceErrMsg = "Error sending UPS request for UPS Service ShipConfirm: " + e.toString();
408                 Debug.logError(e, uceErrMsg, module);
409                 return ServiceUtil.returnError(uceErrMsg);
410             }
411
412             if (shipmentUpsSaveCertificationInfo) {
413                 String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentConfirmResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
414                 try {
415                     FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
416                     fileOut.write(shipmentConfirmResponseString.getBytes());
417                     fileOut.flush();
418                     fileOut.close();
419                 } catch (IOException JavaDoc e) {
420                     Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
421                 }
422             }
423             
424             Document JavaDoc shipmentConfirmResponseDocument = null;
425             try {
426                 shipmentConfirmResponseDocument = UtilXml.readXmlDocument(shipmentConfirmResponseString, false);
427             } catch (SAXException JavaDoc e2) {
428                 String JavaDoc excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString();
429                 Debug.logError(e2, excErrMsg, module);
430                 return ServiceUtil.returnError(excErrMsg);
431             } catch (ParserConfigurationException JavaDoc e2) {
432                 String JavaDoc excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString();
433                 Debug.logError(e2, excErrMsg, module);
434                 return ServiceUtil.returnError(excErrMsg);
435             } catch (IOException JavaDoc e2) {
436                 String JavaDoc excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString();
437                 Debug.logError(e2, excErrMsg, module);
438                 return ServiceUtil.returnError(excErrMsg);
439             }
440
441             return handleUpsShipmentConfirmResponse(shipmentConfirmResponseDocument, shipmentRouteSegment);
442         } catch (GenericEntityException e) {
443             Debug.logError(e, module);
444             if (shipmentConfirmResponseString != null) {
445                 Debug.logError("Got XML ShipmentConfirmRespose: " + shipmentConfirmResponseString, module);
446                 return ServiceUtil.returnError(UtilMisc.toList(
447                             "Error reading or writing Shipment data for UPS Shipment Confirm: " + e.toString(),
448                             "A ShipmentConfirmRespose was received: " + shipmentConfirmResponseString));
449             } else {
450                 return ServiceUtil.returnError("Error reading or writing Shipment data for UPS Shipment Confirm: " + e.toString());
451             }
452         }
453     }
454
455     public static Map JavaDoc handleUpsShipmentConfirmResponse(Document JavaDoc shipmentConfirmResponseDocument, GenericValue shipmentRouteSegment) throws GenericEntityException {
456         // process ShipmentConfirmResponse, update data as needed
457
Element JavaDoc shipmentConfirmResponseElement = shipmentConfirmResponseDocument.getDocumentElement();
458             
459         // handle Response element info
460
Element JavaDoc responseElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "Response");
461         Element JavaDoc responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference");
462         String JavaDoc responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext");
463         String JavaDoc responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion");
464
465         String JavaDoc responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode");
466         String JavaDoc responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription");
467         List JavaDoc errorList = new LinkedList JavaDoc();
468         UpsServices.handleErrors(responseElement, errorList);
469
470         if ("1".equals(responseStatusCode)) {
471             // handle ShipmentCharges element info
472
Element JavaDoc shipmentChargesElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "ShipmentCharges");
473
474             Element JavaDoc transportationChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TransportationCharges");
475             String JavaDoc transportationCurrencyCode = UtilXml.childElementValue(transportationChargesElement, "CurrencyCode");
476             String JavaDoc transportationMonetaryValue = UtilXml.childElementValue(transportationChargesElement, "MonetaryValue");
477             
478             Element JavaDoc serviceOptionsChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "ServiceOptionsCharges");
479             String JavaDoc serviceOptionsCurrencyCode = UtilXml.childElementValue(serviceOptionsChargesElement, "CurrencyCode");
480             String JavaDoc serviceOptionsMonetaryValue = UtilXml.childElementValue(serviceOptionsChargesElement, "MonetaryValue");
481
482             Element JavaDoc totalChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TotalCharges");
483             String JavaDoc totalCurrencyCode = UtilXml.childElementValue(totalChargesElement, "CurrencyCode");
484             String JavaDoc totalMonetaryValue = UtilXml.childElementValue(totalChargesElement, "MonetaryValue");
485             
486             if (UtilValidate.isNotEmpty(totalCurrencyCode)) {
487                 if (UtilValidate.isEmpty(shipmentRouteSegment.getString("currencyUomId"))) {
488                     shipmentRouteSegment.set("currencyUomId", totalCurrencyCode);
489                 } else if(!totalCurrencyCode.equals(shipmentRouteSegment.getString("currencyUomId"))) {
490                     errorList.add("The Currency Unit of Measure returned [" + totalCurrencyCode + "] is not the same as the original [" + shipmentRouteSegment.getString("currencyUomId") + "], setting to the new one.");
491                     shipmentRouteSegment.set("currencyUomId", totalCurrencyCode);
492                 }
493             }
494             
495             try {
496                 shipmentRouteSegment.set("actualTransportCost", Double.valueOf(transportationMonetaryValue));
497             } catch (NumberFormatException JavaDoc e) {
498                 String JavaDoc excErrMsg = "Error parsing the transportationMonetaryValue [" + transportationMonetaryValue + "]: " + e.toString();
499                 Debug.logError(e, excErrMsg, module);
500                 errorList.add(excErrMsg);
501             }
502             try {
503                 shipmentRouteSegment.set("actualServiceCost", Double.valueOf(serviceOptionsMonetaryValue));
504             } catch (NumberFormatException JavaDoc e) {
505                 String JavaDoc excErrMsg = "Error parsing the serviceOptionsMonetaryValue [" + serviceOptionsMonetaryValue + "]: " + e.toString();
506                 Debug.logError(e, excErrMsg, module);
507                 errorList.add(excErrMsg);
508             }
509             try {
510                 shipmentRouteSegment.set("actualCost", Double.valueOf(totalMonetaryValue));
511             } catch (NumberFormatException JavaDoc e) {
512                 String JavaDoc excErrMsg = "Error parsing the totalMonetaryValue [" + totalMonetaryValue + "]: " + e.toString();
513                 Debug.logError(e, excErrMsg, module);
514                 errorList.add(excErrMsg);
515             }
516             
517             // handle BillingWeight element info
518
Element JavaDoc billingWeightElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "BillingWeight");
519             Element JavaDoc billingWeightUnitOfMeasurementElement = UtilXml.firstChildElement(billingWeightElement, "UnitOfMeasurement");
520             String JavaDoc billingWeightUnitOfMeasurement = UtilXml.childElementValue(billingWeightUnitOfMeasurementElement, "Code");
521             String JavaDoc billingWeight = UtilXml.childElementValue(billingWeightElement, "Weight");
522             try {
523                 shipmentRouteSegment.set("billingWeight", Double.valueOf(billingWeight));
524             } catch (NumberFormatException JavaDoc e) {
525                 String JavaDoc excErrMsg = "Error parsing the billingWeight [" + billingWeight + "]: " + e.toString();
526                 Debug.logError(e, excErrMsg, module);
527                 errorList.add(excErrMsg);
528             }
529             shipmentRouteSegment.set("billingWeightUomId", unitsUpsToOfbiz.get(billingWeightUnitOfMeasurement));
530
531             // store the ShipmentIdentificationNumber and ShipmentDigest
532
String JavaDoc shipmentIdentificationNumber = UtilXml.childElementValue(shipmentConfirmResponseElement, "ShipmentIdentificationNumber");
533             String JavaDoc shipmentDigest = UtilXml.childElementValue(shipmentConfirmResponseElement, "ShipmentDigest");
534             shipmentRouteSegment.set("trackingIdNumber", shipmentIdentificationNumber);
535             shipmentRouteSegment.set("trackingDigest", shipmentDigest);
536                 
537             // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable
538
shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_CONFIRMED");
539             
540             // write/store all modified value objects
541
shipmentRouteSegment.store();
542                 
543             // -=-=-=- Okay, now done with that, just return any extra info...
544

545             StringBuffer JavaDoc successString = new StringBuffer JavaDoc("The UPS ShipmentConfirm succeeded");
546             if (errorList.size() > 0) {
547                 // this shouldn't happen much, but handle it anyway
548
successString.append(", but the following occurred: ");
549                 Iterator JavaDoc errorListIter = errorList.iterator();
550                 while (errorListIter.hasNext()) {
551                     String JavaDoc errorMsg = (String JavaDoc) errorListIter.next();
552                     successString.append(errorMsg);
553                     if (errorListIter.hasNext()) {
554                         successString.append(", ");
555                     }
556                 }
557             }
558             return ServiceUtil.returnSuccess(successString.toString());
559         } else {
560             errorList.add(0, "The UPS ShipmentConfirm failed");
561             return ServiceUtil.returnError(errorList);
562         }
563     }
564     
565     public static Map JavaDoc upsShipmentAccept(DispatchContext dctx, Map JavaDoc context) {
566         Map JavaDoc result = new HashMap JavaDoc();
567         GenericDelegator delegator = dctx.getDelegator();
568         String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
569         String JavaDoc shipmentRouteSegmentId = (String JavaDoc) context.get("shipmentRouteSegmentId");
570         
571         boolean shipmentUpsSaveCertificationInfo = "true".equals(UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.info"));
572         String JavaDoc shipmentUpsSaveCertificationPath = UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.path");
573         File JavaDoc shipmentUpsSaveCertificationFile = null;
574         if (shipmentUpsSaveCertificationInfo) {
575             shipmentUpsSaveCertificationFile = new File JavaDoc(shipmentUpsSaveCertificationPath);
576             if (!shipmentUpsSaveCertificationFile.exists()) {
577                 shipmentUpsSaveCertificationFile.mkdirs();
578             }
579         }
580
581         String JavaDoc shipmentAcceptResponseString = null;
582
583         try {
584             GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
585             GenericValue shipmentRouteSegment = delegator.findByPrimaryKey("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId));
586
587             if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
588                 return ServiceUtil.returnError("ERROR: The Carrier for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is not UPS.");
589             }
590             
591             // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services
592
if (!"SHRSCS_CONFIRMED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
593                 return ServiceUtil.returnError("ERROR: The Carrier Service Status for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is [" + shipmentRouteSegment.getString("carrierServiceStatusId") + "], but must be [SHRSCS_CONFIRMED] to perform the UPS Shipment Accept operation.");
594             }
595             
596             List JavaDoc shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"));
597             if (shipmentPackageRouteSegs == null || shipmentPackageRouteSegs.size() == 0) {
598                 return ServiceUtil.returnError("No ShipmentPackageRouteSegs found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
599             }
600             
601             if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingDigest"))) {
602                 return ServiceUtil.returnError("ERROR: The trackingDigest was not set for this Route Segment, meaning that a UPS shipment confirm has not been done.");
603             }
604
605             Document JavaDoc shipmentAcceptRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentAcceptRequest");
606             Element JavaDoc shipmentAcceptRequestElement = shipmentAcceptRequestDoc.getDocumentElement();
607             shipmentAcceptRequestElement.setAttribute("xml:lang", "en-US");
608
609             // Top Level Element: Request
610
Element JavaDoc requestElement = UtilXml.addChildElement(shipmentAcceptRequestElement, "Request", shipmentAcceptRequestDoc);
611
612             Element JavaDoc transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", shipmentAcceptRequestDoc);
613             UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "ShipAccept / 01", shipmentAcceptRequestDoc);
614             UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", shipmentAcceptRequestDoc);
615
616             UtilXml.addChildElementValue(requestElement, "RequestAction", "ShipAccept", shipmentAcceptRequestDoc);
617             UtilXml.addChildElementValue(requestElement, "RequestOption", "01", shipmentAcceptRequestDoc);
618
619             UtilXml.addChildElementValue(shipmentAcceptRequestElement, "ShipmentDigest", shipmentRouteSegment.getString("trackingDigest"), shipmentAcceptRequestDoc);
620             
621             
622             String JavaDoc shipmentAcceptRequestString = null;
623             try {
624                 shipmentAcceptRequestString = UtilXml.writeXmlDocument(shipmentAcceptRequestDoc);
625             } catch (IOException JavaDoc e) {
626                 String JavaDoc ioeErrMsg = "Error writing the ShipmentAcceptRequest XML Document to a String: " + e.toString();
627                 Debug.logError(e, ioeErrMsg, module);
628                 return ServiceUtil.returnError(ioeErrMsg);
629             }
630             
631             // create AccessRequest XML doc
632
Document JavaDoc accessRequestDocument = createAccessRequestDocument();
633             String JavaDoc accessRequestString = null;
634             try {
635                 accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument);
636             } catch (IOException JavaDoc e) {
637                 String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString();
638                 Debug.logError(e, ioeErrMsg, module);
639                 return ServiceUtil.returnError(ioeErrMsg);
640             }
641             
642             // connect to UPS server, send AccessRequest to auth
643
// send ShipmentConfirmRequest String
644
// get ShipmentConfirmResponse String back
645
StringBuffer JavaDoc xmlString = new StringBuffer JavaDoc();
646             // TODO: note that we may have to append <?xml version="1.0"?> before each string
647
xmlString.append(accessRequestString);
648             xmlString.append(shipmentAcceptRequestString);
649             
650             if (shipmentUpsSaveCertificationInfo) {
651                 String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentAcceptRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
652                 try {
653                     FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
654                     fileOut.write(xmlString.toString().getBytes());
655                     fileOut.flush();
656                     fileOut.close();
657                 } catch (IOException JavaDoc e) {
658                     Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
659                 }
660             }
661             
662             try {
663                 shipmentAcceptResponseString = sendUpsRequest("ShipAccept", xmlString.toString());
664             } catch (UpsConnectException e) {
665                 String JavaDoc uceErrMsg = "Error sending UPS request for UPS Service ShipAccept: " + e.toString();
666                 Debug.logError(e, uceErrMsg, module);
667                 return ServiceUtil.returnError(uceErrMsg);
668             }
669
670             if (shipmentUpsSaveCertificationInfo) {
671                 String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentAcceptResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
672                 try {
673                     FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
674                     fileOut.write(shipmentAcceptResponseString.getBytes());
675                     fileOut.flush();
676                     fileOut.close();
677                 } catch (IOException JavaDoc e) {
678                     Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
679                 }
680             }
681             
682             Document JavaDoc shipmentAcceptResponseDocument = null;
683             try {
684                 shipmentAcceptResponseDocument = UtilXml.readXmlDocument(shipmentAcceptResponseString, false);
685             } catch (SAXException JavaDoc e2) {
686                 String JavaDoc excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString();
687                 Debug.logError(e2, excErrMsg, module);
688                 return ServiceUtil.returnError(excErrMsg);
689             } catch (ParserConfigurationException JavaDoc e2) {
690                 String JavaDoc excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString();
691                 Debug.logError(e2, excErrMsg, module);
692                 return ServiceUtil.returnError(excErrMsg);
693             } catch (IOException JavaDoc e2) {
694                 String JavaDoc excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString();
695                 Debug.logError(e2, excErrMsg, module);
696                 return ServiceUtil.returnError(excErrMsg);
697             }
698
699             return handleUpsShipmentAcceptResponse(shipmentAcceptResponseDocument, shipmentRouteSegment, shipmentPackageRouteSegs);
700         } catch (GenericEntityException e) {
701             Debug.logError(e, module);
702             return ServiceUtil.returnError("Error reading or writing Shipment data for UPS Shipment Accept: " + e.toString());
703         }
704     }
705     
706     public static Map JavaDoc handleUpsShipmentAcceptResponse(Document JavaDoc shipmentAcceptResponseDocument, GenericValue shipmentRouteSegment, List JavaDoc shipmentPackageRouteSegs) throws GenericEntityException {
707         boolean shipmentUpsSaveCertificationInfo = "true".equals(UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.info"));
708         String JavaDoc shipmentUpsSaveCertificationPath = UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.path");
709         File JavaDoc shipmentUpsSaveCertificationFile = null;
710         if (shipmentUpsSaveCertificationInfo) {
711             shipmentUpsSaveCertificationFile = new File JavaDoc(shipmentUpsSaveCertificationPath);
712             if (!shipmentUpsSaveCertificationFile.exists()) {
713                 shipmentUpsSaveCertificationFile.mkdirs();
714             }
715         }
716
717         // process ShipmentAcceptResponse, update data as needed
718
Element JavaDoc shipmentAcceptResponseElement = shipmentAcceptResponseDocument.getDocumentElement();
719             
720         // handle Response element info
721
Element JavaDoc responseElement = UtilXml.firstChildElement(shipmentAcceptResponseElement, "Response");
722         Element JavaDoc responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference");
723         String JavaDoc responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext");
724         String JavaDoc responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion");
725
726         String JavaDoc responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode");
727         String JavaDoc responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription");
728         List JavaDoc errorList = new LinkedList JavaDoc();
729         UpsServices.handleErrors(responseElement, errorList);
730
731         if ("1".equals(responseStatusCode)) {
732             Element JavaDoc shipmentResultsElement = UtilXml.firstChildElement(shipmentAcceptResponseElement, "ShipmentResults");
733
734             // This information is returned in both the ShipmentConfirmResponse and
735
//the ShipmentAcceptResponse. So, we'll go ahead and store it here again
736
//and warn of changes or something...
737

738
739             // handle ShipmentCharges element info
740
Element JavaDoc shipmentChargesElement = UtilXml.firstChildElement(shipmentResultsElement, "ShipmentCharges");
741
742             Element JavaDoc transportationChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TransportationCharges");
743             String JavaDoc transportationCurrencyCode = UtilXml.childElementValue(transportationChargesElement, "CurrencyCode");
744             String JavaDoc transportationMonetaryValue = UtilXml.childElementValue(transportationChargesElement, "MonetaryValue");
745             
746             Element JavaDoc serviceOptionsChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "ServiceOptionsCharges");
747             String JavaDoc serviceOptionsCurrencyCode = UtilXml.childElementValue(serviceOptionsChargesElement, "CurrencyCode");
748             String JavaDoc serviceOptionsMonetaryValue = UtilXml.childElementValue(serviceOptionsChargesElement, "MonetaryValue");
749
750             Element JavaDoc totalChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TotalCharges");
751             String JavaDoc totalCurrencyCode = UtilXml.childElementValue(totalChargesElement, "CurrencyCode");
752             String JavaDoc totalMonetaryValue = UtilXml.childElementValue(totalChargesElement, "MonetaryValue");
753             
754             if (UtilValidate.isNotEmpty(totalCurrencyCode)) {
755                 if (UtilValidate.isEmpty(shipmentRouteSegment.getString("currencyUomId"))) {
756                     shipmentRouteSegment.set("currencyUomId", totalCurrencyCode);
757                 } else if(!totalCurrencyCode.equals(shipmentRouteSegment.getString("currencyUomId"))) {
758                     errorList.add("The Currency Unit of Measure returned [" + totalCurrencyCode + "] is not the same as the original [" + shipmentRouteSegment.getString("currencyUomId") + "], setting to the new one.");
759                     shipmentRouteSegment.set("currencyUomId", totalCurrencyCode);
760                 }
761             }
762             
763             try {
764                 shipmentRouteSegment.set("actualTransportCost", Double.valueOf(transportationMonetaryValue));
765             } catch (NumberFormatException JavaDoc e) {
766                 String JavaDoc excErrMsg = "Error parsing the transportationMonetaryValue [" + transportationMonetaryValue + "]: " + e.toString();
767                 Debug.logError(e, excErrMsg, module);
768                 errorList.add(excErrMsg);
769             }
770             try {
771                 shipmentRouteSegment.set("actualServiceCost", Double.valueOf(serviceOptionsMonetaryValue));
772             } catch (NumberFormatException JavaDoc e) {
773                 String JavaDoc excErrMsg = "Error parsing the serviceOptionsMonetaryValue [" + serviceOptionsMonetaryValue + "]: " + e.toString();
774                 Debug.logError(e, excErrMsg, module);
775                 errorList.add(excErrMsg);
776             }
777             try {
778                 shipmentRouteSegment.set("actualCost", Double.valueOf(totalMonetaryValue));
779             } catch (NumberFormatException JavaDoc e) {
780                 String JavaDoc excErrMsg = "Error parsing the totalMonetaryValue [" + totalMonetaryValue + "]: " + e.toString();
781                 Debug.logError(e, excErrMsg, module);
782                 errorList.add(excErrMsg);
783             }
784             
785             // handle BillingWeight element info
786
Element JavaDoc billingWeightElement = UtilXml.firstChildElement(shipmentResultsElement, "BillingWeight");
787             Element JavaDoc billingWeightUnitOfMeasurementElement = UtilXml.firstChildElement(billingWeightElement, "UnitOfMeasurement");
788             String JavaDoc billingWeightUnitOfMeasurement = UtilXml.childElementValue(billingWeightUnitOfMeasurementElement, "Code");
789             String JavaDoc billingWeight = UtilXml.childElementValue(billingWeightElement, "Weight");
790             try {
791                 shipmentRouteSegment.set("billingWeight", Double.valueOf(billingWeight));
792             } catch (NumberFormatException JavaDoc e) {
793                 String JavaDoc excErrMsg = "Error parsing the billingWeight [" + billingWeight + "]: " + e.toString();
794                 Debug.logError(e, excErrMsg, module);
795                 errorList.add(excErrMsg);
796             }
797             shipmentRouteSegment.set("billingWeightUomId", unitsUpsToOfbiz.get(billingWeightUnitOfMeasurement));
798
799             // store the ShipmentIdentificationNumber and ShipmentDigest
800
String JavaDoc shipmentIdentificationNumber = UtilXml.childElementValue(shipmentResultsElement, "ShipmentIdentificationNumber");
801             // should compare to trackingIdNumber, should always be the same right?
802
shipmentRouteSegment.set("trackingIdNumber", shipmentIdentificationNumber);
803
804             // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable
805
shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_ACCEPTED");
806             
807             // write/store modified value object
808
shipmentRouteSegment.store();
809                 
810             // now process the PackageResults elements
811
List JavaDoc packageResultsElements = UtilXml.childElementList(shipmentResultsElement, "PackageResults");
812             Iterator JavaDoc packageResultsElementIter = packageResultsElements.iterator();
813             Iterator JavaDoc shipmentPackageRouteSegIter = shipmentPackageRouteSegs.iterator();
814             while (packageResultsElementIter.hasNext()) {
815                 Element JavaDoc packageResultsElement = (Element JavaDoc) packageResultsElementIter.next();
816                     
817                 String JavaDoc trackingNumber = UtilXml.childElementValue(packageResultsElement, "TrackingNumber");
818
819                 Element JavaDoc packageServiceOptionsChargesElement = UtilXml.firstChildElement(packageResultsElement, "ServiceOptionsCharges");
820                 String JavaDoc packageServiceOptionsCurrencyCode = UtilXml.childElementValue(packageServiceOptionsChargesElement, "CurrencyCode");
821                 String JavaDoc packageServiceOptionsMonetaryValue = UtilXml.childElementValue(packageServiceOptionsChargesElement, "MonetaryValue");
822
823                 Element JavaDoc packageLabelImageElement = UtilXml.firstChildElement(packageResultsElement, "LabelImage");
824                 Element JavaDoc packageLabelImageFormatElement = UtilXml.firstChildElement(packageResultsElement, "LabelImageFormat");
825                 // will be EPL or GIF, should always be GIF since that is what we requested
826
String JavaDoc packageLabelImageFormatCode = UtilXml.childElementValue(packageLabelImageFormatElement, "Code");
827                 String JavaDoc packageLabelImageFormatDescription = UtilXml.childElementValue(packageLabelImageFormatElement, "Description");
828                 String JavaDoc packageLabelGraphicImageString = UtilXml.childElementValue(packageLabelImageElement, "GraphicImage");
829                 String JavaDoc packageLabelInternationalSignatureGraphicImageString = UtilXml.childElementValue(packageLabelImageElement, "InternationalSignatureGraphicImage");
830                 String JavaDoc packageLabelHTMLImageString = UtilXml.childElementValue(packageLabelImageElement, "HTMLImage");
831
832                 if (!shipmentPackageRouteSegIter.hasNext()) {
833                     errorList.add("Error: More PackageResults were returned than there are Packages on this Shipment; the TrackingNumber is [" + trackingNumber + "], the ServiceOptionsCharges were " + packageServiceOptionsMonetaryValue + packageServiceOptionsCurrencyCode);
834                     // NOTE: if this happens much we should just create a new package to store all of the info...
835
continue;
836                 }
837                     
838                 //NOTE: I guess they come back in the same order we sent them, so we'll get the packages in order and off we go...
839
GenericValue shipmentPackageRouteSeg = (GenericValue) shipmentPackageRouteSegIter.next();
840                 shipmentPackageRouteSeg.set("trackingCode", trackingNumber);
841                 shipmentPackageRouteSeg.set("boxNumber", "");
842                 shipmentPackageRouteSeg.set("currencyUomId", packageServiceOptionsCurrencyCode);
843                 try {
844                     shipmentPackageRouteSeg.set("packageServiceCost", Double.valueOf(packageServiceOptionsMonetaryValue));
845                 } catch (NumberFormatException JavaDoc e) {
846                     String JavaDoc excErrMsg = "Error parsing the packageServiceOptionsMonetaryValue [" + packageServiceOptionsMonetaryValue + "] for Package [" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + "]: " + e.toString();
847                     Debug.logError(e, excErrMsg, module);
848                     errorList.add(excErrMsg);
849                 }
850                     
851                 byte[] labelImageBytes = null;
852                 if (packageLabelGraphicImageString != null) {
853                     labelImageBytes = Base64.base64Decode(packageLabelGraphicImageString.getBytes());
854                     shipmentPackageRouteSeg.setBytes("labelImage", labelImageBytes);
855                 }
856                 byte[] labelInternationalSignatureGraphicImageBytes = null;
857                 if (packageLabelInternationalSignatureGraphicImageString != null) {
858                     labelInternationalSignatureGraphicImageBytes = Base64.base64Decode(packageLabelInternationalSignatureGraphicImageString.getBytes());
859                     shipmentPackageRouteSeg.set("labelIntlSignImage", labelInternationalSignatureGraphicImageBytes);
860                 }
861                 String JavaDoc packageLabelHTMLImageStringDecoded = Base64.base64Decode(packageLabelHTMLImageString);
862                 shipmentPackageRouteSeg.set("labelHtml", packageLabelHTMLImageStringDecoded);
863
864                 if (shipmentUpsSaveCertificationInfo) {
865                     if (labelImageBytes != null) {
866                         String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentLabelImage" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + "_" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + ".gif";
867                         try {
868                             FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
869                             fileOut.write(labelImageBytes);
870                             fileOut.flush();
871                             fileOut.close();
872                         } catch (IOException JavaDoc e) {
873                             Debug.log(e, "Could not save UPS LabelImage GIF file: [[[" + packageLabelGraphicImageString + "]]] to file: " + outFileName, module);
874                         }
875                     }
876                     if (labelInternationalSignatureGraphicImageBytes != null) {
877                         String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentLabelIntlSignImage" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + "_" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + ".gif";
878                         try {
879                             FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
880                             fileOut.write(labelInternationalSignatureGraphicImageBytes);
881                             fileOut.flush();
882                             fileOut.close();
883                         } catch (IOException JavaDoc e) {
884                             Debug.log(e, "Could not save UPS IntlSign LabelImage GIF file: [[[" + packageLabelInternationalSignatureGraphicImageString + "]]] to file: " + outFileName, module);
885                         }
886                     }
887                     if (packageLabelHTMLImageStringDecoded != null) {
888                         String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentLabelHTMLImage" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + "_" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + ".html";
889                         try {
890                             FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
891                             fileOut.write(packageLabelHTMLImageStringDecoded.getBytes());
892                             fileOut.flush();
893                             fileOut.close();
894                         } catch (IOException JavaDoc e) {
895                             Debug.log(e, "Could not save UPS LabelImage HTML file: [[[" + packageLabelHTMLImageStringDecoded + "]]] to file: " + outFileName, module);
896                         }
897                     }
898                 }
899             
900                 shipmentPackageRouteSeg.store();
901             }
902
903             if (shipmentPackageRouteSegIter.hasNext()) {
904                 errorList.add("Error: There are more Packages on this Shipment than there were PackageResults returned from UPS");
905                 while (shipmentPackageRouteSegIter.hasNext()) {
906                     GenericValue shipmentPackageRouteSeg = (GenericValue) shipmentPackageRouteSegIter.next();
907                     errorList.add("Error: No PackageResults were returned for the Package [" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + "]");
908                 }
909             }
910                 
911             // -=-=-=- Okay, now done with that, just return any extra info...
912
StringBuffer JavaDoc successString = new StringBuffer JavaDoc("The UPS ShipmentAccept succeeded");
913             if (errorList.size() > 0) {
914                 // this shouldn't happen much, but handle it anyway
915
successString.append(", but the following occurred: ");
916                 Iterator JavaDoc errorListIter = errorList.iterator();
917                 while (errorListIter.hasNext()) {
918                     String JavaDoc errorMsg = (String JavaDoc) errorListIter.next();
919                     successString.append(errorMsg);
920                     if (errorListIter.hasNext()) {
921                         successString.append(", ");
922                     }
923                 }
924             }
925             return ServiceUtil.returnSuccess(successString.toString());
926         } else {
927             errorList.add(0, "The UPS ShipmentConfirm failed");
928             return ServiceUtil.returnError(errorList);
929         }
930     }
931     
932     public static Map JavaDoc upsVoidShipment(DispatchContext dctx, Map JavaDoc context) {
933         Map JavaDoc result = new HashMap JavaDoc();
934         GenericDelegator delegator = dctx.getDelegator();
935         String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
936         String JavaDoc shipmentRouteSegmentId = (String JavaDoc) context.get("shipmentRouteSegmentId");
937
938         boolean shipmentUpsSaveCertificationInfo = "true".equals(UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.info"));
939         String JavaDoc shipmentUpsSaveCertificationPath = UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.path");
940         File JavaDoc shipmentUpsSaveCertificationFile = null;
941         if (shipmentUpsSaveCertificationInfo) {
942             shipmentUpsSaveCertificationFile = new File JavaDoc(shipmentUpsSaveCertificationPath);
943             if (!shipmentUpsSaveCertificationFile.exists()) {
944                 shipmentUpsSaveCertificationFile.mkdirs();
945             }
946         }
947
948         String JavaDoc voidShipmentResponseString = null;
949
950         try {
951             GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
952             GenericValue shipmentRouteSegment = delegator.findByPrimaryKey("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId));
953
954             if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
955                 return ServiceUtil.returnError("ERROR: The Carrier for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is not UPS.");
956             }
957             
958             // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services
959
if (!"SHRSCS_CONFIRMED".equals(shipmentRouteSegment.getString("carrierServiceStatusId")) &&
960                     !"SHRSCS_ACCEPTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
961                 return ServiceUtil.returnError("ERROR: The Carrier Service Status for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is [" + shipmentRouteSegment.getString("carrierServiceStatusId") + "], but must be [SHRSCS_CONFIRMED] or [SHRSCS_ACCEPTED] to perform the UPS Void Shipment operation.");
962             }
963             
964             if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingIdNumber"))) {
965                 return ServiceUtil.returnError("ERROR: The trackingIdNumber was not set for this Route Segment, meaning that a UPS shipment confirm has not been done.");
966             }
967
968             Document JavaDoc voidShipmentRequestDoc = UtilXml.makeEmptyXmlDocument("VoidShipmentRequest");
969             Element JavaDoc voidShipmentRequestElement = voidShipmentRequestDoc.getDocumentElement();
970             voidShipmentRequestElement.setAttribute("xml:lang", "en-US");
971
972             // Top Level Element: Request
973
Element JavaDoc requestElement = UtilXml.addChildElement(voidShipmentRequestElement, "Request", voidShipmentRequestDoc);
974
975             Element JavaDoc transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", voidShipmentRequestDoc);
976             UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Void / 1", voidShipmentRequestDoc);
977             UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", voidShipmentRequestDoc);
978
979             UtilXml.addChildElementValue(requestElement, "RequestAction", "Void", voidShipmentRequestDoc);
980             UtilXml.addChildElementValue(requestElement, "RequestOption", "1", voidShipmentRequestDoc);
981
982             UtilXml.addChildElementValue(voidShipmentRequestElement, "ShipmentIdentificationNumber", shipmentRouteSegment.getString("trackingIdNumber"), voidShipmentRequestDoc);
983
984             String JavaDoc voidShipmentRequestString = null;
985             try {
986                 voidShipmentRequestString = UtilXml.writeXmlDocument(voidShipmentRequestDoc);
987             } catch (IOException JavaDoc e) {
988                 String JavaDoc ioeErrMsg = "Error writing the VoidShipmentRequest XML Document to a String: " + e.toString();
989                 Debug.logError(e, ioeErrMsg, module);
990                 return ServiceUtil.returnError(ioeErrMsg);
991             }
992             
993             // create AccessRequest XML doc
994
Document JavaDoc accessRequestDocument = createAccessRequestDocument();
995             String JavaDoc accessRequestString = null;
996             try {
997                 accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument);
998             } catch (IOException JavaDoc e) {
999                 String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString();
1000                Debug.logError(e, ioeErrMsg, module);
1001                return ServiceUtil.returnError(ioeErrMsg);
1002            }
1003            
1004            // connect to UPS server, send AccessRequest to auth
1005
// send ShipmentConfirmRequest String
1006
// get ShipmentConfirmResponse String back
1007
StringBuffer JavaDoc xmlString = new StringBuffer JavaDoc();
1008            // TODO: note that we may have to append <?xml version="1.0"?> before each string
1009
xmlString.append(accessRequestString);
1010            xmlString.append(voidShipmentRequestString);
1011
1012            if (shipmentUpsSaveCertificationInfo) {
1013                String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsVoidShipmentRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
1014                try {
1015                    FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
1016                    fileOut.write(xmlString.toString().getBytes());
1017                    fileOut.flush();
1018                    fileOut.close();
1019                } catch (IOException JavaDoc e) {
1020                    Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
1021                }
1022            }
1023            
1024            try {
1025                voidShipmentResponseString = sendUpsRequest("Void", xmlString.toString());
1026            } catch (UpsConnectException e) {
1027                String JavaDoc uceErrMsg = "Error sending UPS request for UPS Service Void: " + e.toString();
1028                Debug.logError(e, uceErrMsg, module);
1029                return ServiceUtil.returnError(uceErrMsg);
1030            }
1031
1032            if (shipmentUpsSaveCertificationInfo) {
1033                String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsVoidShipmentResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
1034                try {
1035                    FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
1036                    fileOut.write(voidShipmentResponseString.getBytes());
1037                    fileOut.flush();
1038                    fileOut.close();
1039                } catch (IOException JavaDoc e) {
1040                    Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
1041                }
1042            }
1043            
1044            Document JavaDoc voidShipmentResponseDocument = null;
1045            try {
1046                voidShipmentResponseDocument = UtilXml.readXmlDocument(voidShipmentResponseString, false);
1047            } catch (SAXException JavaDoc e2) {
1048                String JavaDoc excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString();
1049                Debug.logError(e2, excErrMsg, module);
1050                return ServiceUtil.returnError(excErrMsg);
1051            } catch (ParserConfigurationException JavaDoc e2) {
1052                String JavaDoc excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString();
1053                Debug.logError(e2, excErrMsg, module);
1054                return ServiceUtil.returnError(excErrMsg);
1055            } catch (IOException JavaDoc e2) {
1056                String JavaDoc excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString();
1057                Debug.logError(e2, excErrMsg, module);
1058                return ServiceUtil.returnError(excErrMsg);
1059            }
1060
1061            return handleUpsVoidShipmentResponse(voidShipmentResponseDocument, shipmentRouteSegment);
1062        } catch (GenericEntityException e) {
1063            Debug.logError(e, module);
1064            return ServiceUtil.returnError("Error reading or writing Shipment data for UPS Void Shipment: " + e.toString());
1065        }
1066    }
1067
1068    public static Map JavaDoc handleUpsVoidShipmentResponse(Document JavaDoc voidShipmentResponseDocument, GenericValue shipmentRouteSegment) throws GenericEntityException {
1069        // process VoidShipmentResponse, update data as needed
1070
Element JavaDoc voidShipmentResponseElement = voidShipmentResponseDocument.getDocumentElement();
1071            
1072        // handle Response element info
1073
Element JavaDoc responseElement = UtilXml.firstChildElement(voidShipmentResponseElement, "Response");
1074        Element JavaDoc responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference");
1075        String JavaDoc responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext");
1076        String JavaDoc responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion");
1077
1078        String JavaDoc responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode");
1079        String JavaDoc responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription");
1080        List JavaDoc errorList = new LinkedList JavaDoc();
1081        UpsServices.handleErrors(responseElement, errorList);
1082
1083        // handle other response elements
1084
Element JavaDoc statusElement = UtilXml.firstChildElement(voidShipmentResponseElement, "Status");
1085
1086        Element JavaDoc statusTypeElement = UtilXml.firstChildElement(statusElement, "StatusType");
1087        String JavaDoc statusTypeCode = UtilXml.childElementValue(statusTypeElement, "Code");
1088        String JavaDoc statusTypeDescription = UtilXml.childElementValue(statusTypeElement, "Description");
1089
1090        Element JavaDoc statusCodeElement = UtilXml.firstChildElement(statusElement, "StatusCode");
1091        String JavaDoc statusCodeCode = UtilXml.childElementValue(statusCodeElement, "Code");
1092        String JavaDoc statusCodeDescription = UtilXml.childElementValue(statusCodeElement, "Description");
1093
1094        if ("1".equals(responseStatusCode)) {
1095            // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable
1096
shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_VOIDED");
1097            shipmentRouteSegment.store();
1098            
1099            // -=-=-=- Okay, now done with that, just return any extra info...
1100
StringBuffer JavaDoc successString = new StringBuffer JavaDoc("The UPS VoidShipment succeeded; the StatusType is: [" + statusTypeCode + ":" + statusTypeDescription + "], the StatusCode is: [" + statusCodeCode + ":" + statusCodeDescription + "]");
1101            if (errorList.size() > 0) {
1102                // this shouldn't happen much, but handle it anyway
1103
successString.append(", but the following occurred: ");
1104                Iterator JavaDoc errorListIter = errorList.iterator();
1105                while (errorListIter.hasNext()) {
1106                    String JavaDoc errorMsg = (String JavaDoc) errorListIter.next();
1107                    successString.append(errorMsg);
1108                    if (errorListIter.hasNext()) {
1109                        successString.append(", ");
1110                    }
1111                }
1112            }
1113            return ServiceUtil.returnSuccess(successString.toString());
1114        } else {
1115            errorList.add(0, "The UPS ShipmentConfirm failed; the StatusType is: [" + statusTypeCode + ":" + statusTypeDescription + "], the StatusCode is: [" + statusCodeCode + ":" + statusCodeDescription + "]");
1116            return ServiceUtil.returnError(errorList);
1117        }
1118    }
1119    
1120    public static Map JavaDoc upsTrackShipment(DispatchContext dctx, Map JavaDoc context) {
1121        Map JavaDoc result = new HashMap JavaDoc();
1122        GenericDelegator delegator = dctx.getDelegator();
1123        String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
1124        String JavaDoc shipmentRouteSegmentId = (String JavaDoc) context.get("shipmentRouteSegmentId");
1125
1126        boolean shipmentUpsSaveCertificationInfo = "true".equals(UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.info"));
1127        String JavaDoc shipmentUpsSaveCertificationPath = UtilProperties.getPropertyValue("shipment", "shipment.ups.save.certification.path");
1128        File JavaDoc shipmentUpsSaveCertificationFile = null;
1129        if (shipmentUpsSaveCertificationInfo) {
1130            shipmentUpsSaveCertificationFile = new File JavaDoc(shipmentUpsSaveCertificationPath);
1131            if (!shipmentUpsSaveCertificationFile.exists()) {
1132                shipmentUpsSaveCertificationFile.mkdirs();
1133            }
1134        }
1135
1136        String JavaDoc trackResponseString = null;
1137
1138        try {
1139            GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
1140            GenericValue shipmentRouteSegment = delegator.findByPrimaryKey("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId));
1141
1142            if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
1143                return ServiceUtil.returnError("ERROR: The Carrier for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is not UPS.");
1144            }
1145            
1146            // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services
1147
if (!"SHRSCS_ACCEPTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
1148                return ServiceUtil.returnError("ERROR: The Carrier Service Status for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is [" + shipmentRouteSegment.getString("carrierServiceStatusId") + "], but must be [SHRSCS_ACCEPTED] to perform the UPS Track Shipment operation.");
1149            }
1150            
1151            List JavaDoc shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"));
1152            if (shipmentPackageRouteSegs == null || shipmentPackageRouteSegs.size() == 0) {
1153                return ServiceUtil.returnError("No ShipmentPackageRouteSegs found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
1154            }
1155            
1156            if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingIdNumber"))) {
1157                return ServiceUtil.returnError("ERROR: The trackingIdNumber was not set for this Route Segment, meaning that a UPS shipment confirm has not been done.");
1158            }
1159
1160            Document JavaDoc trackRequestDoc = UtilXml.makeEmptyXmlDocument("TrackRequest");
1161            Element JavaDoc trackRequestElement = trackRequestDoc.getDocumentElement();
1162            trackRequestElement.setAttribute("xml:lang", "en-US");
1163
1164            // Top Level Element: Request
1165
Element JavaDoc requestElement = UtilXml.addChildElement(trackRequestElement, "Request", trackRequestDoc);
1166
1167            Element JavaDoc transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", trackRequestDoc);
1168            UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Track", trackRequestDoc);
1169            UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", trackRequestDoc);
1170
1171            UtilXml.addChildElementValue(requestElement, "RequestAction", "Track", trackRequestDoc);
1172
1173            UtilXml.addChildElementValue(trackRequestElement, "ShipmentIdentificationNumber", shipmentRouteSegment.getString("trackingIdNumber"), trackRequestDoc);
1174
1175            String JavaDoc trackRequestString = null;
1176            try {
1177                trackRequestString = UtilXml.writeXmlDocument(trackRequestDoc);
1178            } catch (IOException JavaDoc e) {
1179                String JavaDoc ioeErrMsg = "Error writing the TrackRequest XML Document to a String: " + e.toString();
1180                Debug.logError(e, ioeErrMsg, module);
1181                return ServiceUtil.returnError(ioeErrMsg);
1182            }
1183            
1184            // create AccessRequest XML doc
1185
Document JavaDoc accessRequestDocument = createAccessRequestDocument();
1186            String JavaDoc accessRequestString = null;
1187            try {
1188                accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument);
1189            } catch (IOException JavaDoc e) {
1190                String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString();
1191                Debug.logError(e, ioeErrMsg, module);
1192                return ServiceUtil.returnError(ioeErrMsg);
1193            }
1194            
1195            // connect to UPS server, send AccessRequest to auth
1196
// send ShipmentConfirmRequest String
1197
// get ShipmentConfirmResponse String back
1198
StringBuffer JavaDoc xmlString = new StringBuffer JavaDoc();
1199            // TODO: note that we may have to append <?xml version="1.0"?> before each string
1200
xmlString.append(accessRequestString);
1201            xmlString.append(trackRequestString);
1202
1203            if (shipmentUpsSaveCertificationInfo) {
1204                String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsTrackRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
1205                try {
1206                    FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
1207                    fileOut.write(xmlString.toString().getBytes());
1208                    fileOut.flush();
1209                    fileOut.close();
1210                } catch (IOException JavaDoc e) {
1211                    Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
1212                }
1213            }
1214            
1215            try {
1216                trackResponseString = sendUpsRequest("Track", xmlString.toString());
1217            } catch (UpsConnectException e) {
1218                String JavaDoc uceErrMsg = "Error sending UPS request for UPS Service Track: " + e.toString();
1219                Debug.logError(e, uceErrMsg, module);
1220                return ServiceUtil.returnError(uceErrMsg);
1221            }
1222
1223            if (shipmentUpsSaveCertificationInfo) {
1224                String JavaDoc outFileName = shipmentUpsSaveCertificationPath + "/UpsTrackResponseString" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml";
1225                try {
1226                    FileOutputStream JavaDoc fileOut = new FileOutputStream JavaDoc(outFileName);
1227                    fileOut.write(trackResponseString.getBytes());
1228                    fileOut.flush();
1229                    fileOut.close();
1230                } catch (IOException JavaDoc e) {
1231                    Debug.log(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module);
1232                }
1233            }
1234            
1235            Document JavaDoc trackResponseDocument = null;
1236            try {
1237                trackResponseDocument = UtilXml.readXmlDocument(trackResponseString, false);
1238            } catch (SAXException JavaDoc e2) {
1239                String JavaDoc excErrMsg = "Error parsing the TrackResponse: " + e2.toString();
1240                Debug.logError(e2, excErrMsg, module);
1241                return ServiceUtil.returnError(excErrMsg);
1242            } catch (ParserConfigurationException JavaDoc e2) {
1243                String JavaDoc excErrMsg = "Error parsing the TrackResponse: " + e2.toString();
1244                Debug.logError(e2, excErrMsg, module);
1245                return ServiceUtil.returnError(excErrMsg);
1246            } catch (IOException JavaDoc e2) {
1247                String JavaDoc excErrMsg = "Error parsing the TrackResponse: " + e2.toString();
1248                Debug.logError(e2, excErrMsg, module);
1249                return ServiceUtil.returnError(excErrMsg);
1250            }
1251
1252            return handleUpsTrackShipmentResponse(trackResponseDocument, shipmentRouteSegment, shipmentPackageRouteSegs);
1253        } catch (GenericEntityException e) {
1254            Debug.logError(e, module);
1255            return ServiceUtil.returnError("Error reading or writing Shipment data for UPS Track Shipment: " + e.toString());
1256        }
1257    }
1258
1259    public static Map JavaDoc handleUpsTrackShipmentResponse(Document JavaDoc trackResponseDocument, GenericValue shipmentRouteSegment, List JavaDoc shipmentPackageRouteSegs) throws GenericEntityException {
1260        // process TrackResponse, update data as needed
1261
Element JavaDoc trackResponseElement = trackResponseDocument.getDocumentElement();
1262            
1263        // handle Response element info
1264
Element JavaDoc responseElement = UtilXml.firstChildElement(trackResponseElement, "Response");
1265        Element JavaDoc responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference");
1266        String JavaDoc responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext");
1267        String JavaDoc responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion");
1268
1269        String JavaDoc responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode");
1270        String JavaDoc responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription");
1271        List JavaDoc errorList = new LinkedList JavaDoc();
1272        UpsServices.handleErrors(responseElement, errorList);
1273
1274        if ("1".equals(responseStatusCode)) {
1275            // TODO: handle other response elements
1276
Element JavaDoc shipmentElement = UtilXml.firstChildElement(trackResponseElement, "Shipment");
1277
1278            Element JavaDoc shipperElement = UtilXml.firstChildElement(shipmentElement, "Shipper");
1279            String JavaDoc shipperNumber = UtilXml.childElementValue(shipperElement, "ShipperNumber");
1280
1281            Element JavaDoc serviceElement = UtilXml.firstChildElement(shipmentElement, "Service");
1282            String JavaDoc serviceCode = UtilXml.childElementValue(serviceElement, "Code");
1283            String JavaDoc serviceDescription = UtilXml.childElementValue(serviceElement, "Description");
1284
1285            String JavaDoc shipmentIdentificationNumber = UtilXml.childElementValue(shipmentElement, "ShipmentIdentificationNumber");
1286                
1287            List JavaDoc packageElements = UtilXml.childElementList(shipmentElement, "Package");
1288            Iterator JavaDoc packageElementIter = packageElements.iterator();
1289            while (packageElementIter.hasNext()) {
1290                Element JavaDoc packageElement = (Element JavaDoc) packageElementIter.next();
1291            }
1292/*
1293        <Package>
1294            <TrackingNumber>1Z12345E1512345676</TrackingNumber>
1295            <Activity>
1296                <ActivityLocation>
1297                    <Address>
1298                        <City>CLAKVILLE</City>
1299                        <StateProvinceCode>AK</StateProvinceCode>
1300                        <PostalCode>99901</PostalCode>
1301                        <CountryCode>US</CountryCode>
1302                    </Address>
1303                    <Code>MG</Code>
1304                    <Description>MC MAN</Description>
1305                </ActivityLocation>
1306                <Status>
1307                    <StatusType>
1308                        <Code>D</Code>
1309                        <Description>DELIVERED</Description>
1310                    </StatusType>
1311                    <StatusCode>
1312                        <Code>FS</Code>
1313                    </StatusCode>
1314                </Status>
1315                <Date>20020930</Date>
1316                <Time>130900</Time>
1317            </Activity>
1318            <PackageWeight>
1319                <UnitOfMeasurement>
1320                    <Code>LBS</Code>
1321                </UnitOfMeasurement>
1322                <Weight>0.00</Weight>
1323            </PackageWeight>
1324        </Package>
1325 *
1326 */

1327
1328
1329            // -=-=-=- Okay, now done with that, just return any extra info...
1330
StringBuffer JavaDoc successString = new StringBuffer JavaDoc("The UPS TrackShipment succeeded");
1331            if (errorList.size() > 0) {
1332                // this shouldn't happen much, but handle it anyway
1333
successString.append(", but the following occurred: ");
1334                Iterator JavaDoc errorListIter = errorList.iterator();
1335                while (errorListIter.hasNext()) {
1336                    String JavaDoc errorMsg = (String JavaDoc) errorListIter.next();
1337                    successString.append(errorMsg);
1338                    if (errorListIter.hasNext()) {
1339                        successString.append(", ");
1340                    }
1341                }
1342            }
1343            return ServiceUtil.returnSuccess(successString.toString());
1344        } else {
1345            errorList.add(0, "The UPS ShipmentConfirm failed");
1346            return ServiceUtil.returnError(errorList);
1347        }
1348    }
1349
1350    public static Map JavaDoc upsRateInquire(DispatchContext dctx, Map JavaDoc context) {
1351        GenericDelegator delegator = dctx.getDelegator();
1352        // prepare the data
1353
String JavaDoc serviceConfigProps = (String JavaDoc) context.get("serviceConfigProps");
1354        String JavaDoc upsRateInquireMode = (String JavaDoc) context.get("upsRateInquireMode");
1355        String JavaDoc productStoreId = (String JavaDoc) context.get("productStoreId");
1356        String JavaDoc carrierRoleTypeId = (String JavaDoc) context.get("carrierRoleTypeId");
1357        String JavaDoc carrierPartyId = (String JavaDoc) context.get("carrierPartyId");
1358        String JavaDoc shipmentMethodTypeId = (String JavaDoc) context.get("shipmentMethodTypeId");
1359        String JavaDoc shippingContactMechId = (String JavaDoc) context.get("shippingContactMechId");
1360
1361        List JavaDoc shippableItemInfo = (List JavaDoc) context.get("shippableItemInfo");
1362        Double JavaDoc shippableTotal = (Double JavaDoc) context.get("shippableTotal");
1363        Double JavaDoc shippableQuantity = (Double JavaDoc) context.get("shippableQuantity");
1364        Double JavaDoc shippableWeight = (Double JavaDoc) context.get("shippableWeight");
1365
1366        if (shippableTotal == null) {
1367            shippableTotal = new Double JavaDoc(0.00);
1368        }
1369        if (shippableQuantity == null) {
1370            shippableQuantity = new Double JavaDoc(0.00);
1371        }
1372        if (shippableWeight == null) {
1373            shippableWeight = new Double JavaDoc(0.00);
1374        }
1375        if (serviceConfigProps == null) {
1376            serviceConfigProps = "shipment.properties";
1377        }
1378        if (upsRateInquireMode == null || !"Shop".equals(upsRateInquireMode)) {
1379            // can be either Rate || Shop
1380
Debug.logWarning("No upsRateInquireMode set, defaulting to 'Rate'", module);
1381            upsRateInquireMode = "Rate";
1382        }
1383
1384        // grab the pickup type; if none is defined we will assume daily pickup
1385
String JavaDoc pickupType = UtilProperties.getPropertyValue(serviceConfigProps, "shipment.ups.shipper.pickup.type", "01");
1386
1387        // locate the ship-from address based on the product store's default facility
1388
GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
1389        GenericValue shipFromAddress = null;
1390        if (productStore != null && productStore.get("inventoryFacilityId") != null) {
1391            List JavaDoc shipLocs = null;
1392            try {
1393                shipLocs = delegator.findByAnd("FacilityContactMechPurpose", UtilMisc.toMap("facilityId",
1394                        productStore.getString("inventoryFacilityId"), "contactMechPurposeTypeId",
1395                        "SHIP_ORIG_LOCATION"), UtilMisc.toList("-fromDate"));
1396            } catch (GenericEntityException e) {
1397                Debug.logError(e, module);
1398            }
1399            if (shipLocs != null) {
1400                shipLocs = EntityUtil.filterByDate(shipLocs);
1401                GenericValue purp = EntityUtil.getFirst(shipLocs);
1402                if (purp != null) {
1403                    try {
1404                        shipFromAddress = delegator.findByPrimaryKey("PostalAddress", UtilMisc.toMap("contactMechId", purp.getString("contactMechId")));
1405                    } catch (GenericEntityException e) {
1406                        Debug.logError(e, module);
1407                    }
1408                }
1409            }
1410        }
1411        if (shipFromAddress == null) {
1412            return ServiceUtil.returnError("Unable to determine ship-from address");
1413        }
1414
1415        // obtain the ship-to address
1416
GenericValue shipToAddress = null;
1417        if (shippingContactMechId != null) {
1418            try {
1419                shipToAddress = delegator.findByPrimaryKey("PostalAddress", UtilMisc.toMap("contactMechId", shippingContactMechId));
1420            } catch (GenericEntityException e) {
1421                Debug.logError(e, module);
1422            }
1423        }
1424        if (shipToAddress == null) {
1425            return ServiceUtil.returnError("Unable to determine ship-to address");
1426        }
1427
1428        // locate the service code
1429
String JavaDoc serviceCode = null;
1430        if (!"Shop".equals(upsRateInquireMode)) {
1431            // locate the CarrierShipmentMethod record
1432
GenericValue carrierShipmentMethod = null;
1433            try {
1434                carrierShipmentMethod = delegator.findByPrimaryKey("CarrierShipmentMethod", UtilMisc.toMap("shipmentMethodTypeId",
1435                        shipmentMethodTypeId, "partyId", carrierPartyId, "roleTypeId", carrierRoleTypeId));
1436            } catch (GenericEntityException e) {
1437                Debug.logError(e, module);
1438            }
1439            if (carrierShipmentMethod == null) {
1440                return ServiceUtil.returnError("Unable to locate the shipping method requested");
1441            }
1442
1443            // service code is 'carrierServiceCode'
1444
serviceCode = carrierShipmentMethod.getString("carrierServiceCode");
1445        }
1446
1447        // prepare the XML Document
1448
Document JavaDoc rateRequestDoc = UtilXml.makeEmptyXmlDocument("RatingServiceSelectionRequest");
1449        Element JavaDoc rateRequestElement = rateRequestDoc.getDocumentElement();
1450        rateRequestElement.setAttribute("xml:lang", "en-US");
1451
1452        // XML request header
1453
Element JavaDoc requestElement = UtilXml.addChildElement(rateRequestElement, "Request", rateRequestDoc);
1454        Element JavaDoc transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", rateRequestDoc);
1455        UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Rating and Service", rateRequestDoc);
1456        UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", rateRequestDoc);
1457
1458        // RequestAction is always Rate, but RequestOption can be Rate to get a single rate or Shop for all shipping methods
1459
UtilXml.addChildElementValue(requestElement, "RequestAction", "Rate", rateRequestDoc);
1460        UtilXml.addChildElementValue(requestElement, "RequestOption", upsRateInquireMode, rateRequestDoc);
1461
1462        // set the pickup type
1463
Element JavaDoc pickupElement = UtilXml.addChildElement(rateRequestElement, "PickupType", rateRequestDoc);
1464        UtilXml.addChildElementValue(pickupElement, "Code", pickupType, rateRequestDoc);
1465
1466        // shipment info
1467
Element JavaDoc shipmentElement = UtilXml.addChildElement(rateRequestElement, "Shipment", rateRequestDoc);
1468
1469        // shipper info - (sub of shipment)
1470
Element JavaDoc shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", rateRequestDoc);
1471        Element JavaDoc shipperAddrElement = UtilXml.addChildElement(shipperElement, "Address", rateRequestDoc);
1472        UtilXml.addChildElementValue(shipperAddrElement, "PostalCode", shipFromAddress.getString("postalCode"), rateRequestDoc);
1473
1474        // ship-to info - (sub of shipment)
1475
Element JavaDoc shiptoElement = UtilXml.addChildElement(shipmentElement, "ShipTo", rateRequestDoc);
1476        Element JavaDoc shiptoAddrElement = UtilXml.addChildElement(shiptoElement, "Address", rateRequestDoc);
1477        UtilXml.addChildElementValue(shiptoAddrElement, "PostalCode", shipToAddress.getString("postalCode"), rateRequestDoc);
1478
1479        // requested service (code) - not used when in Shop mode
1480
if (serviceCode != null) {
1481            Element JavaDoc serviceElement = UtilXml.addChildElement(shipmentElement, "Service", rateRequestDoc);
1482            UtilXml.addChildElementValue(serviceElement, "Code", serviceCode, rateRequestDoc);
1483        }
1484
1485        // package info
1486
String JavaDoc maxWeightStr = UtilProperties.getPropertyValue(serviceConfigProps, "shipment.ups.max.estimate.weight", "99");
1487        double maxWeight = 99;
1488        try {
1489            maxWeight = Double.parseDouble(maxWeightStr);
1490        } catch (NumberFormatException JavaDoc e) {
1491            maxWeight = 99;
1492        }
1493
1494        splitEstimatePackages(rateRequestDoc, shipmentElement, shippableItemInfo, maxWeight);
1495
1496        // service options
1497
UtilXml.addChildElement(shipmentElement, "ShipmentServiceOptions", rateRequestDoc);
1498
1499        String JavaDoc rateRequestString = null;
1500        try {
1501            rateRequestString = UtilXml.writeXmlDocument(rateRequestDoc);
1502        } catch (IOException JavaDoc e) {
1503            String JavaDoc ioeErrMsg = "Error writing the RatingServiceSelectionRequest XML Document to a String: " + e.toString();
1504            Debug.logError(e, ioeErrMsg, module);
1505            return ServiceUtil.returnError(ioeErrMsg);
1506        }
1507
1508        // create AccessRequest XML doc
1509
Document JavaDoc accessRequestDocument = createAccessRequestDocument(serviceConfigProps);
1510        String JavaDoc accessRequestString = null;
1511        try {
1512            accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument);
1513        } catch (IOException JavaDoc e) {
1514            String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString();
1515            Debug.logError(e, ioeErrMsg, module);
1516            return ServiceUtil.returnError(ioeErrMsg);
1517        }
1518
1519        // prepare the access/inquire request string
1520
StringBuffer JavaDoc xmlString = new StringBuffer JavaDoc();
1521        xmlString.append(accessRequestString);
1522        xmlString.append(rateRequestString);
1523
1524        // send the request
1525
String JavaDoc rateResponseString = null;
1526        try {
1527            rateResponseString = sendUpsRequest("Rate", xmlString.toString());
1528        } catch (UpsConnectException e) {
1529            String JavaDoc uceErrMsg = "Error sending UPS request for UPS Service Rate: " + e.toString();
1530            Debug.logError(e, uceErrMsg, module);
1531            return ServiceUtil.returnError(uceErrMsg);
1532        }
1533
1534        Document JavaDoc rateResponseDocument = null;
1535        try {
1536            rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false);
1537        } catch (SAXException JavaDoc e2) {
1538            String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
1539            Debug.logError(e2, excErrMsg, module);
1540            return ServiceUtil.returnError(excErrMsg);
1541        } catch (ParserConfigurationException JavaDoc e2) {
1542            String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
1543            Debug.logError(e2, excErrMsg, module);
1544            return ServiceUtil.returnError(excErrMsg);
1545        } catch (IOException JavaDoc e2) {
1546            String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
1547            Debug.logError(e2, excErrMsg, module);
1548            return ServiceUtil.returnError(excErrMsg);
1549        }
1550
1551        return handleUpsRateInquireResponse(rateResponseDocument);
1552
1553    }
1554
1555    private static void splitEstimatePackages(Document JavaDoc requestDoc, Element JavaDoc shipmentElement, List JavaDoc shippableItemInfo, double maxWeight) {
1556        List JavaDoc packages = getPackageSplit(shippableItemInfo, maxWeight);
1557        Iterator JavaDoc i = packages.iterator();
1558        while (i.hasNext()) {
1559            Map JavaDoc packageMap = (Map JavaDoc) i.next();
1560            double packageWeight = calcPackageWeight(packageMap, shippableItemInfo, 0);
1561
1562            // package info
1563
Element JavaDoc packageElement = UtilXml.addChildElement(shipmentElement, "Package", requestDoc);
1564            Element JavaDoc packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", requestDoc);
1565            UtilXml.addChildElementValue(packagingTypeElement, "Code", "00", requestDoc);
1566            UtilXml.addChildElementValue(packagingTypeElement, "Description", "Unknown PackagingType", requestDoc);
1567            UtilXml.addChildElementValue(packageElement, "Description", "Package Description", requestDoc);
1568            Element JavaDoc packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", requestDoc);
1569            UtilXml.addChildElementValue(packageWeightElement, "Weight", new Double JavaDoc(packageWeight).toString(), requestDoc);
1570        }
1571    }
1572
1573    private static List JavaDoc getPackageSplit(List JavaDoc shippableItemInfo, double maxWeight) {
1574        // create the package list w/ the first pacakge
1575
List JavaDoc packages = new LinkedList JavaDoc();
1576
1577        if (shippableItemInfo != null) {
1578            Iterator JavaDoc sii = shippableItemInfo.iterator();
1579            while (sii.hasNext()) {
1580                Map JavaDoc itemInfo = (Map JavaDoc) sii.next();
1581                long pieces = ((Long JavaDoc) itemInfo.get("piecesIncluded")).longValue();
1582                double totalQuantity = ((Double JavaDoc) itemInfo.get("quantity")).doubleValue();
1583                double totalWeight = ((Double JavaDoc) itemInfo.get("weight")).doubleValue();
1584                String JavaDoc productId = (String JavaDoc) itemInfo.get("productId");
1585
1586                // sanity check
1587
if (pieces < 1) {
1588                    pieces = 1; // can NEVER be less than one
1589
}
1590                double weight = totalWeight / pieces;
1591
1592                for (int z = 1; z <= totalQuantity; z++) {
1593                    double partialQty = pieces > 1 ? 1.000 / pieces : 1;
1594                    for (long x = 0; x < pieces; x++) {
1595                        if (weight >= maxWeight) {
1596                            Map JavaDoc newPackage = new HashMap JavaDoc();
1597                            newPackage.put(productId, new Double JavaDoc(partialQty));
1598                            packages.add(newPackage);
1599                        } else if (totalWeight > 0) {
1600                            // create the first package
1601
if (packages.size() == 0) {
1602                                packages.add(new HashMap JavaDoc());
1603                            }
1604
1605                            // package loop
1606
int packageSize = packages.size();
1607                            boolean addedToPackage = false;
1608                            for (int pi = 0; pi < packageSize; pi++) {
1609                                if (!addedToPackage) {
1610                                    Map JavaDoc packageMap = (Map JavaDoc) packages.get(pi);
1611                                    double packageWeight = calcPackageWeight(packageMap, shippableItemInfo, weight);
1612                                    if (packageWeight <= maxWeight) {
1613                                        Double JavaDoc qtyD = (Double JavaDoc) packageMap.get(productId);
1614                                        double qty = qtyD == null ? 0 : qtyD.doubleValue();
1615                                        packageMap.put(productId, new Double JavaDoc(qty + partialQty));
1616                                        addedToPackage = true;
1617                                    }
1618                                }
1619                            }
1620                            if (!addedToPackage) {
1621                                Map JavaDoc packageMap = new HashMap JavaDoc();
1622                                packageMap.put(productId, new Double JavaDoc(partialQty));
1623                                packages.add(packageMap);
1624                            }
1625                        }
1626                    }
1627                }
1628            }
1629        }
1630        return packages;
1631    }
1632
1633    private static double calcPackageWeight(Map JavaDoc packageMap, List JavaDoc shippableItemInfo, double additionalWeight) {
1634        double totalWeight = 0.00;
1635        Iterator JavaDoc i = packageMap.keySet().iterator();
1636        while (i.hasNext()) {
1637            String JavaDoc productId = (String JavaDoc) i.next();
1638            Map JavaDoc productInfo = getProductItemInfo(shippableItemInfo, productId);
1639            double productWeight = ((Double JavaDoc) productInfo.get("weight")).doubleValue();
1640            double quantity = ((Double JavaDoc) packageMap.get(productId)).doubleValue();
1641            totalWeight += (productWeight * quantity);
1642        }
1643        return totalWeight + additionalWeight;
1644    }
1645
1646    private static Map JavaDoc getProductItemInfo(List JavaDoc shippableItemInfo, String JavaDoc productId) {
1647        if (shippableItemInfo != null) {
1648            Iterator JavaDoc i = shippableItemInfo.iterator();
1649            while (i.hasNext()) {
1650                Map JavaDoc testMap = (Map JavaDoc) i.next();
1651                String JavaDoc id = (String JavaDoc) testMap.get("productId");
1652                if (productId.equals(id)) {
1653                    return testMap;
1654                }
1655            }
1656        }
1657        return null;
1658    }
1659
1660    public static Map JavaDoc handleUpsRateInquireResponse(Document JavaDoc rateResponseDocument) {
1661        // process TrackResponse, update data as needed
1662
Element JavaDoc rateResponseElement = rateResponseDocument.getDocumentElement();
1663
1664        // handle Response element info
1665
Element JavaDoc responseElement = UtilXml.firstChildElement(rateResponseElement, "Response");
1666        Element JavaDoc responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference");
1667        String JavaDoc responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext");
1668        String JavaDoc responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion");
1669
1670        String JavaDoc responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode");
1671        String JavaDoc responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription");
1672        List JavaDoc errorList = new LinkedList JavaDoc();
1673        UpsServices.handleErrors(responseElement, errorList);
1674
1675        if ("1".equals(responseStatusCode)) {
1676            List JavaDoc rates = UtilXml.childElementList(rateResponseElement, "RatedShipment");
1677            Map JavaDoc rateMap = new HashMap JavaDoc();
1678            Double JavaDoc firstRate = null;
1679            if (rates == null || rates.size() == 0) {
1680                return ServiceUtil.returnError("No rates available at this time");
1681            } else {
1682                Iterator JavaDoc i = rates.iterator();
1683                while (i.hasNext()) {
1684                    Element JavaDoc element = (Element JavaDoc) i.next();
1685
1686                    // get service
1687
Element JavaDoc service = UtilXml.firstChildElement(element, "Service");
1688                    String JavaDoc serviceCode = UtilXml.childElementValue(service, "Code");
1689
1690                    // get total
1691
Element JavaDoc totalCharges = UtilXml.firstChildElement(element, "TotalCharges");
1692                    String JavaDoc totalString = UtilXml.childElementValue(totalCharges, "MonetaryValue");
1693
1694                    rateMap.put(serviceCode, new Double JavaDoc(totalString));
1695                    if (firstRate == null) {
1696                        firstRate = (Double JavaDoc) rateMap.get(serviceCode);
1697                    }
1698                }
1699            }
1700
1701            Debug.log("UPS Rate Map : " + rateMap, module);
1702
1703            Map JavaDoc resp = ServiceUtil.returnSuccess();
1704            resp.put("upsRateCodeMap", rateMap);
1705            resp.put("shippingEstimateAmount", firstRate);
1706            return resp;
1707        } else {
1708            errorList.add("Error status code : " + responseStatusCode);
1709            return ServiceUtil.returnError(errorList);
1710        }
1711    }
1712
1713    public static Document JavaDoc createAccessRequestDocument() {
1714        return createAccessRequestDocument("shipment.properties");
1715    }
1716
1717    public static Document JavaDoc createAccessRequestDocument(String JavaDoc props) {
1718        Document JavaDoc accessRequestDocument = UtilXml.makeEmptyXmlDocument("AccessRequest");
1719        Element JavaDoc accessRequestElement = accessRequestDocument.getDocumentElement();
1720        UtilXml.addChildElementValue(accessRequestElement, "AccessLicenseNumber", UtilProperties.getPropertyValue(props, "shipment.ups.access.license.number"), accessRequestDocument);
1721        UtilXml.addChildElementValue(accessRequestElement, "UserId", UtilProperties.getPropertyValue(props, "shipment.ups.access.user.id"), accessRequestDocument);
1722        UtilXml.addChildElementValue(accessRequestElement, "Password", UtilProperties.getPropertyValue(props, "shipment.ups.access.password"), accessRequestDocument);
1723        return accessRequestDocument;
1724    }
1725
1726    public static void handleErrors(Element JavaDoc responseElement, List JavaDoc errorList) {
1727        List JavaDoc errorElements = UtilXml.childElementList(responseElement, "Error");
1728        Iterator JavaDoc errorElementIter = errorElements.iterator();
1729        while (errorElementIter.hasNext()) {
1730            StringBuffer JavaDoc errorMessageBuf = new StringBuffer JavaDoc();
1731            Element JavaDoc errorElement = (Element JavaDoc) errorElementIter.next();
1732
1733            String JavaDoc errorSeverity = UtilXml.childElementValue(errorElement, "ErrorSeverity");
1734            String JavaDoc errorCode = UtilXml.childElementValue(errorElement, "ErrorCode");
1735            String JavaDoc errorDescription = UtilXml.childElementValue(errorElement, "ErrorDescription");
1736            String JavaDoc minimumRetrySeconds = UtilXml.childElementValue(errorElement, "MinimumRetrySeconds");
1737
1738            errorMessageBuf.append("An error occurred [code:");
1739            errorMessageBuf.append(errorCode);
1740            errorMessageBuf.append("] with severity ");
1741            errorMessageBuf.append(errorSeverity);
1742            errorMessageBuf.append(": ");
1743            errorMessageBuf.append(errorDescription);
1744            if (UtilValidate.isNotEmpty(minimumRetrySeconds)) {
1745                errorMessageBuf.append("; you should wait ");
1746                errorMessageBuf.append(minimumRetrySeconds);
1747                errorMessageBuf.append(" seconds before retrying. ");
1748            } else {
1749                errorMessageBuf.append(". ");
1750            }
1751
1752            List JavaDoc errorLocationElements = UtilXml.childElementList(errorElement, "ErrorLocation");
1753            Iterator JavaDoc errorLocationElementIter = errorLocationElements.iterator();
1754            while (errorLocationElementIter.hasNext()) {
1755                Element JavaDoc errorLocationElement = (Element JavaDoc) errorLocationElementIter.next();
1756                String JavaDoc errorLocationElementName = UtilXml.childElementValue(errorLocationElement, "ErrorLocationElementName");
1757                String JavaDoc errorLocationAttributeName = UtilXml.childElementValue(errorLocationElement, "ErrorLocationAttributeName");
1758
1759                errorMessageBuf.append("The error was at Element [");
1760                errorMessageBuf.append(errorLocationElementName);
1761                errorMessageBuf.append("]");
1762
1763                if (UtilValidate.isNotEmpty(errorLocationAttributeName)) {
1764                    errorMessageBuf.append(" in the attribute [");
1765                    errorMessageBuf.append(errorLocationAttributeName);
1766                    errorMessageBuf.append("]");
1767                }
1768
1769                List JavaDoc errorDigestElements = UtilXml.childElementList(errorLocationElement, "ErrorDigest");
1770                Iterator JavaDoc errorDigestElementIter = errorDigestElements.iterator();
1771                while (errorDigestElementIter.hasNext()) {
1772                    Element JavaDoc errorDigestElement = (Element JavaDoc) errorDigestElementIter.next();
1773                    errorMessageBuf.append(" full text: [");
1774                    errorMessageBuf.append(UtilXml.elementValue(errorDigestElement));
1775                    errorMessageBuf.append("]");
1776                }
1777            }
1778
1779            errorList.add(errorMessageBuf.toString());
1780        }
1781    }
1782
1783    /**
1784     * Opens a URL to UPS and makes a request.
1785     * @param upsService Name of the UPS service to invoke
1786     * @param xmlString XML message to send
1787     * @return XML string response from UPS
1788     * @throws UpsConnectException
1789     */

1790    public static String JavaDoc sendUpsRequest(String JavaDoc upsService, String JavaDoc xmlString) throws UpsConnectException {
1791        String JavaDoc conStr = UtilProperties.getPropertyValue("shipment.properties", "shipment.ups.connect.url");
1792        if (conStr == null) {
1793            throw new UpsConnectException("Incomplete connection URL; check your UPS configuration");
1794        }
1795        
1796        // need a ups service to call
1797
if (upsService == null) {
1798            throw new UpsConnectException("UPS service name cannot be null");
1799        }
1800        
1801        // xmlString should contain the auth document at the beginning
1802
// all documents require an <?xml version="1.0"?> header
1803
if (xmlString == null) {
1804            throw new UpsConnectException("XML message cannot be null");
1805        }
1806        
1807        // prepare the connect string
1808
conStr = conStr.trim();
1809        if (!conStr.endsWith("/")) {
1810            conStr = conStr + "/";
1811        }
1812        conStr = conStr + upsService;
1813
1814        String JavaDoc timeOutStr = UtilProperties.getPropertyValue("shipment.properties", "shipment.ups.connect.timeout", "60");
1815        int timeout = 60;
1816        try {
1817            timeout = Integer.parseInt(timeOutStr);
1818        } catch (NumberFormatException JavaDoc e) {
1819            Debug.logError(e, "Unable to set timeout to " + timeOutStr + " using default " + timeout);
1820        }
1821
1822        //Debug.log("UPS Connect URL : " + conStr, module);
1823
//Debug.log("UPS XML String : " + xmlString, module);
1824

1825        HttpClient http = new HttpClient(conStr);
1826        http.setTimeout(timeout * 1000);
1827        String JavaDoc response = null;
1828        try {
1829            response = http.post(xmlString);
1830        } catch (HttpClientException e) {
1831            Debug.logError(e, "Problem connecting with UPS server", module);
1832            throw new UpsConnectException("URL Connection problem", e);
1833        }
1834        
1835        if (response == null) {
1836            throw new UpsConnectException("Received a null response");
1837        }
1838        if (Debug.verboseOn()) Debug.logVerbose("UPS Response : " + response, module);
1839        
1840        return response;
1841    }
1842}
1843
1844class UpsConnectException extends GeneralException {
1845    UpsConnectException() {
1846        super();
1847    }
1848    
1849    UpsConnectException(String JavaDoc msg) {
1850        super(msg);
1851    }
1852    
1853    UpsConnectException(Throwable JavaDoc t) {
1854        super(t);
1855    }
1856    
1857    UpsConnectException(String JavaDoc msg, Throwable JavaDoc t) {
1858        super(msg, t);
1859    }
1860}
1861
1862
1863/*
1864 * UPS Code Reference
1865
1866UPS Service IDs
1867ShipConfirm
1868ShipAccept
1869Void
1870Track
1871Rate
1872
1873Package Type Code
187400 Unknown
187501 UPS Letter
187602 Package
187703 UPS Tube
187804 UPS Pak
187921 UPS Express Box
188024 UPS 25KG Box
188125 UPS 10KG Box
1882
1883Pickup Types
188401 Daily Pickup
188503 Customer Counter
188606 One Time Pickup
188707 On Call Air Pickup
188819 Letter Center
188920 Air Service Center
1890
1891UPS Service Codes
1892US Origin
189301 UPS Next Day Air
189402 UPS 2nd Day Air
189503 UPS Ground
189607 UPS Worldwide Express
189708 UPS Worldwide Expedited
189811 UPS Standard
189912 UPS 3-Day Select
190013 UPS Next Day Air Saver
190114 UPS Next Day Air Early AM
190254 UPS Worldwide Express Plus
190359 UPS 2nd Day Air AM
190464 N/A
190565 UPS Express Saver
1906
1907Reference Number Codes
1908AJ Acct. Rec. Customer Acct.
1909AT Appropriation Number
1910BM Bill of Lading Number
19119V COD Number
1912ON Dealer Order Number
1913DP Department Number
1914EI Employer's ID Number
19153Q FDA Product Code
1916TJ Federal Taxpayer ID Number
1917IK Invoice Number
1918MK Manifest Key Number
1919MJ Model Number
1920PM Part Number
1921PC Production Code
1922PO Purchase Order No.
1923RQ Purchase Request No.
1924RZ Return Authorization No.
1925SA Salesperson No.
1926SE Serial No.
1927SY Social Security No.
1928ST Store No.
1929TN Transaction Ref. No.
1930
1931Error Codes
1932First note that in the ref guide there are about 21 pages of error codes
1933Here are some overalls:
19341 Success (no error)
193501xxxx XML Error
193602xxxx Architecture Error
193715xxxx Tracking Specific Error
1938
1939 */

1940
1941
1942/*
1943 * Sample XML documents:
1944 *
1945<?xml version="1.0"?>
1946<AccessRequest xml:lang="en-US">
1947   <AccessLicenseNumber>TEST262223144CAT</AccessLicenseNumber>
1948   <UserId>REG111111</UserId>
1949   <Password>REG111111</Password>
1950</AccessRequest>
1951
1952=======================================
1953Shipment Confirm Request/Response
1954=======================================
1955
1956<?xml version="1.0"?>
1957<ShipmentConfirmRequest xml:lang="en-US">
1958    <Request>
1959        <TransactionReference>
1960            <CustomerContext>Ship Confirm / nonvalidate</CustomerContext>
1961            <XpciVersion>1.0001</XpciVersion>
1962        </TransactionReference>
1963        <RequestAction>ShipConfirm</RequestAction>
1964        <RequestOption>nonvalidate</RequestOption>
1965    </Request>
1966    <LabelSpecification>
1967        <LabelPrintMethod>
1968            <Code>GIF</Code>
1969        </LabelPrintMethod>
1970        <HTTPUserAgent>Mozilla/5.0</HTTPUserAgent>
1971        <LabelImageFormat>
1972            <Code>GIF</Code>
1973        </LabelImageFormat>
1974    </LabelSpecification>
1975    <Shipment>
1976        <Description>DescriptionofGoodsTest</Description>
1977        <Shipper>
1978            <Name>ShipperName</Name>
1979            <AttentionName>ShipperName</AttentionName>
1980            <PhoneNumber>2226267227</PhoneNumber>
1981            <ShipperNumber>12345E</ShipperNumber>
1982            <Address>
1983                <AddressLine1>123 ShipperStreet</AddressLine1>
1984                <AddressLine2>123 ShipperStreet</AddressLine2>
1985                <AddressLine3>123 ShipperStreet</AddressLine3>
1986                <City>ShipperCity</City>
1987                <StateProvinceCode>foo</StateProvinceCode>
1988                <PostalCode>03570</PostalCode>
1989                <CountryCode>DE</CountryCode>
1990            </Address>
1991        </Shipper>
1992        <ShipTo>
1993            <CompanyName>ShipToCompanyName</CompanyName>
1994            <AttentionName>ShipToAttnName</AttentionName>
1995            <PhoneNumber>3336367336</PhoneNumber>
1996            <Address>
1997                <AddressLine1>123 ShipToStreet</AddressLine1>
1998                <PostalCode>DT09</PostalCode>
1999                <City>Trent</City>
2000                <CountryCode>GB</CountryCode>
2001            </Address>
2002        </ShipTo>
2003        <ShipFrom>
2004            <CompanyName>ShipFromCompanyName</CompanyName>
2005            <AttentionName>ShipFromAttnName</AttentionName>
2006            <PhoneNumber>7525565064</PhoneNumber>
2007            <Address>
2008                <AddressLine1>123 ShipFromStreet</AddressLine1>
2009                <City>Berlin</City>
2010                <PostalCode>03570</PostalCode>
2011                <CountryCode>DE</CountryCode>
2012            </Address>
2013        </ShipFrom>
2014        <PaymentInformation>
2015            <Prepaid>
2016                <BillShipper>
2017                    <AccountNumber>12345E</AccountNumber>
2018                </BillShipper>
2019            </Prepaid>
2020        </PaymentInformation>
2021        <Service>
2022            <Code>07</Code>
2023        </Service>
2024        <Package>
2025            <PackagingType>
2026                <Code>02</Code>
2027            </PackagingType>
2028            <Dimensions>
2029                <UnitOfMeasurement>
2030                    <Code>CM</Code>
2031                </UnitOfMeasurement>
2032                <Length>60</Length>
2033                <Width>7</Width>
2034                <Height>5</Height>
2035            </Dimensions>
2036            <PackageWeight>
2037                <UnitOfMeasurement>
2038                    <Code>KGS</Code>
2039                </UnitOfMeasurement>
2040                <Weight>3.0</Weight>
2041            </PackageWeight>
2042            <ReferenceNumber>
2043                <Code>MK</Code>
2044                <Value>00001</Value>
2045            </ReferenceNumber>
2046        </Package>
2047    </Shipment>
2048</ShipmentConfirmRequest>
2049
2050=======================================
2051
2052<?xml version="1.0"?>
2053<ShipmentConfirmResponse>
2054    <Response>
2055        <TransactionReference>
2056            <CustomerContext>ShipConfirmUS</CustomerContext>
2057            <XpciVersion>1.0001</XpciVersion>
2058        </TransactionReference>
2059        <ResponseStatusCode>1</ResponseStatusCode>
2060        <ResponseStatusDescription>Success</ResponseStatusDescription>
2061    </Response>
2062    <ShipmentCharges>
2063        <TransportationCharges>
2064            <CurrencyCode>USD</CurrencyCode>
2065            <MonetaryValue>31.38</MonetaryValue>
2066        </TransportationCharges>
2067        <ServiceOptionsCharges>
2068            <CurrencyCode>USD</CurrencyCode>
2069            <MonetaryValue>7.75</MonetaryValue>
2070        </ServiceOptionsCharges>
2071        <TotalCharges>
2072            <CurrencyCode>USD</CurrencyCode>
2073            <MonetaryValue>39.13</MonetaryValue>
2074        </TotalCharges>
2075    </ShipmentCharges>
2076    <BillingWeight>
2077        <UnitOfMeasurement>
2078            <Code>LBS</Code>
2079        </UnitOfMeasurement>
2080        <Weight>4.0</Weight>
2081    </BillingWeight>
2082    <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber>
2083    <ShipmentDigest>INSERT SHIPPING DIGEST HERE</ShipmentDigest>
2084</ShipmentConfirmResponse>
2085
2086=======================================
2087Shipment Accept Request/Response
2088=======================================
2089
2090<?xml version="1.0"?>
2091<ShipmentAcceptRequest>
2092    <Request>
2093        <TransactionReference>
2094            <CustomerContext>TR01</CustomerContext>
2095            <XpciVersion>1.0001</XpciVersion>
2096        </TransactionReference>
2097        <RequestAction>ShipAccept</RequestAction>
2098        <RequestOption>01</RequestOption>
2099    </Request>
2100    <ShipmentDigest>INSERT SHIPPING DIGEST HERE</ShipmentDigest>
2101</ShipmentAcceptRequest>
2102
2103=======================================
2104
2105<?xml version="1.0"?>
2106<ShipmentAcceptResponse>
2107    <Response>
2108        <TransactionReference>
2109            <CustomerContext>TR01</CustomerContext>
2110            <XpciVersion>1.0001</XpciVersion>
2111        </TransactionReference>
2112        <ResponseStatusCode>1</ResponseStatusCode>
2113        <ResponseStatusDescription>Success</ResponseStatusDescription>
2114    </Response>
2115    <ShipmentResults>
2116        <ShipmentCharges>
2117            <TransportationCharges>
2118                <CurrencyCode>USD</CurrencyCode>
2119                <MonetaryValue>31.38</MonetaryValue>
2120            </TransportationCharges>
2121            <ServiceOptionsCharges>
2122                <CurrencyCode>USD</CurrencyCode>
2123                <MonetaryValue>7.75</MonetaryValue>
2124            </ServiceOptionsCharges>
2125            <TotalCharges>
2126                <CurrencyCode>USD</CurrencyCode>
2127                <MonetaryValue>39.13</MonetaryValue>
2128            </TotalCharges>
2129        </ShipmentCharges>
2130        <BillingWeight>
2131            <UnitOfMeasurement>
2132                <Code>LBS</Code>
2133            </UnitOfMeasurement>
2134            <Weight>4.0</Weight>
2135        </BillingWeight>
2136        <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber>
2137        <PackageResults>
2138            <TrackingNumber>1Z12345E1512345676</TrackingNumber>
2139            <ServiceOptionsCharges>
2140                <CurrencyCode>USD</CurrencyCode>
2141                <MonetaryValue>0.00</MonetaryValue>
2142            </ServiceOptionsCharges>
2143            <LabelImage>
2144                <LabelImageFormat>
2145                    <Code>epl</Code>
2146                </LabelImageFormat>
2147                <GraphicImage>INSERT GRAPHIC IMAGE HERE</GraphicImage>
2148            </LabelImage>
2149        </PackageResults>
2150        <PackageResults>
2151            <TrackingNumber>1Z12345E1512345686</TrackingNumber>
2152            <ServiceOptionsCharges>
2153                <CurrencyCode>USD</CurrencyCode>
2154                <MonetaryValue>7.75</MonetaryValue>
2155            </ServiceOptionsCharges>
2156            <LabelImage>
2157                <LabelImageFormat>
2158                    <Code>epl</Code>
2159                </LabelImageFormat>
2160                <GraphicImage>INSERT GRAPHIC IMAGE HERE</GraphicImage>
2161            </LabelImage>
2162        </PackageResults>
2163    </ShipmentResults>
2164</ShipmentAcceptResponse>
2165
2166=======================================
2167Void Shipment Request/Response
2168=======================================
2169
2170<?xml version="1.0"?>
2171<VoidShipmentRequest>
2172    <Request>
2173        <TransactionReference>
2174            <CustomerContext>Void</CustomerContext>
2175            <XpciVersion>1.0001</XpciVersion>
2176        </TransactionReference>
2177        <RequestAction>Void</RequestAction>
2178        <RequestOption>1</RequestOption>
2179    </Request>
2180    <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber>
2181</VoidShipmentRequest>
2182
2183=======================================
2184
2185<?xml version="1.0"?>
2186<VoidShipmentResponse>
2187    <Response>
2188        <TransactionReference>
2189            <XpciVersion>1.0001</XpciVersion>
2190        </TransactionReference>
2191        <ResponseStatusCode>1</ResponseStatusCode>
2192        <ResponseStatusDescription>Success</ResponseStatusDescription>
2193    </Response>
2194    <Status>
2195        <StatusType>
2196            <Code>1</Code>
2197            <Description>Success</Description>
2198        </StatusType>
2199        <StatusCode>
2200            <Code>1</Code>
2201            <Description>Success</Description>
2202        </StatusCode>
2203    </Status>
2204</VoidShipmentResponse>
2205
2206=======================================
2207Track Shipment Request/Response
2208=======================================
2209
2210<?xml version="1.0"?>
2211<TrackRequest xml:lang="en-US">
2212    <Request>
2213        <TransactionReference>
2214            <CustomerContext>sample</CustomerContext>
2215            <XpciVersion>1.0001</XpciVersion>
2216        </TransactionReference>
2217        <RequestAction>Track</RequestAction>
2218    </Request>
2219    <TrackingNumber>1Z12345E1512345676</TrackingNumber>
2220</TrackRequest>
2221
2222=======================================
2223
2224<?xml version="1.0" encoding="UTF-8"?>
2225<TrackResponse>
2226    <Response>
2227        <TransactionReference>
2228            <CustomerContext>sample</CustomerContext>
2229            <XpciVersion>1.0001</XpciVersion>
2230        </TransactionReference>
2231        <ResponseStatusCode>1</ResponseStatusCode>
2232        <ResponseStatusDescription>Success</ResponseStatusDescription>
2233    </Response>
2234    <Shipment>
2235        <Shipper>
2236            <ShipperNumber>12345E</ShipperNumber>
2237        </Shipper>
2238        <Service>
2239            <Code>15</Code>
2240            <Description>NDA EAM/EXP EAM</Description>
2241        </Service>
2242        <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber>
2243        <Package>
2244            <TrackingNumber>1Z12345E1512345676</TrackingNumber>
2245            <Activity>
2246                <ActivityLocation>
2247                    <Address>
2248                        <City>CLAKVILLE</City>
2249                        <StateProvinceCode>AK</StateProvinceCode>
2250                        <PostalCode>99901</PostalCode>
2251                        <CountryCode>US</CountryCode>
2252                    </Address>
2253                    <Code>MG</Code>
2254                    <Description>MC MAN</Description>
2255                </ActivityLocation>
2256                <Status>
2257                    <StatusType>
2258                        <Code>D</Code>
2259                        <Description>DELIVERED</Description>
2260                    </StatusType>
2261                    <StatusCode>
2262                        <Code>FS</Code>
2263                    </StatusCode>
2264                </Status>
2265                <Date>20020930</Date>
2266                <Time>130900</Time>
2267            </Activity>
2268            <PackageWeight>
2269                <UnitOfMeasurement>
2270                    <Code>LBS</Code>
2271                </UnitOfMeasurement>
2272                <Weight>0.00</Weight>
2273            </PackageWeight>
2274        </Package>
2275    </Shipment>
2276</TrackResponse>
2277
2278=======================================
2279Rates & Service Request/Response
2280=======================================
2281
2282<?xml version="1.0"?>
2283<RatingServiceSelectionRequest xml:lang="en-US">
2284  <Request>
2285    <TransactionReference>
2286      <CustomerContext>Bare Bones Rate Request</CustomerContext>
2287      <XpciVersion>1.0</XpciVersion>
2288    </TransactionReference>
2289    <RequestAction>Rate</RequestAction>
2290    <RequestOption>Rate</RequestOption>
2291  </Request>
2292  <PickupType>
2293    <Code>01</Code>
2294  </PickupType>
2295  <Shipment>
2296    <Shipper>
2297        <Address>
2298            <PostalCode>44129</PostalCode>
2299            <CountryCode>US</CountryCode>
2300        </Address>
2301    </Shipper>
2302    <ShipTo>
2303        <Address>
2304            <PostalCode>44129</PostalCode>
2305            <CountryCode>US</CountryCode>
2306        </Address>
2307    </ShipTo>
2308    <ShipFrom>
2309        <Address>
2310            <PostalCode>32779</PostalCode>
2311            <CountryCode>US</CountryCode>
2312        </Address>
2313    </ShipFrom>
2314    <Service>
2315            <Code>01</Code>
2316    </Service>
2317    <Package>
2318        <PackagingType>
2319            <Code>02</Code>
2320        </PackagingType>
2321            <Dimensions>
2322                <UnitOfMeasurement>
2323                  <Code>IN</Code>
2324                </UnitOfMeasurement>
2325                <Length>20</Length>
2326                <Width>20</Width>
2327                <Height>20</Height>
2328            </Dimensions>
2329        <PackageWeight>
2330            <UnitOfMeasurement>
2331                 <Code>LBS</Code>
2332            </UnitOfMeasurement>
2333            <Weight>23</Weight>
2334        </PackageWeight>
2335    </Package>
2336  </Shipment>
2337</RatingServiceSelectionRequest>
2338
2339=======================================
2340
2341<?xml version="1.0" encoding="UTF-8"?>
2342<RatingServiceSelectionResponse>
2343    <Response>
2344        <TransactionReference>
2345            <CustomerContext>Bare Bones Rate Request</CustomerContext>
2346            <XpciVersion>1.0</XpciVersion>
2347        </TransactionReference>
2348        <ResponseStatusCode>1</ResponseStatusCode>
2349        <ResponseStatusDescription>Success</ResponseStatusDescription>
2350    </Response>
2351    <RatedShipment>
2352        <Service>
2353            <Code>01</Code>
2354        </Service>
2355        <BillingWeight>
2356            <UnitOfMeasurement>
2357                <Code>LBS</Code>
2358            </UnitOfMeasurement>
2359            <Weight>42.0</Weight>
2360        </BillingWeight>
2361        <TransportationCharges>
2362            <CurrencyCode>USD</CurrencyCode>
2363            <MonetaryValue>108.61</MonetaryValue>
2364        </TransportationCharges>
2365        <ServiceOptionsCharges>
2366            <CurrencyCode>USD</CurrencyCode>
2367            <MonetaryValue>0.00</MonetaryValue>
2368        </ServiceOptionsCharges>
2369        <TotalCharges>
2370            <CurrencyCode>USD</CurrencyCode>
2371            <MonetaryValue>108.61</MonetaryValue>
2372        </TotalCharges>
2373        <GuaranteedDaysToDelivery>1</GuaranteedDaysToDelivery>
2374        <ScheduledDeliveryTime>10:30 A.M.</ScheduledDeliveryTime>
2375        <RatedPackage>
2376            <TransportationCharges>
2377                <CurrencyCode>USD</CurrencyCode>
2378                <MonetaryValue>108.61</MonetaryValue>
2379            </TransportationCharges>
2380            <ServiceOptionsCharges>
2381                <CurrencyCode>USD</CurrencyCode>
2382                <MonetaryValue>0.00</MonetaryValue>
2383            </ServiceOptionsCharges>
2384            <TotalCharges>
2385                <CurrencyCode>USD</CurrencyCode>
2386                <MonetaryValue>108.61</MonetaryValue>
2387            </TotalCharges>
2388            <Weight>23.0</Weight>
2389            <BillingWeight>
2390                <UnitOfMeasurement>
2391                    <Code>LBS</Code>
2392                </UnitOfMeasurement>
2393                <Weight>42.0</Weight>
2394            </BillingWeight>
2395        </RatedPackage>
2396    </RatedShipment>
2397</RatingServiceSelectionResponse>
2398
2399 */

2400
2401 
2402 
Popular Tags