| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.ofbiz.shipment.thirdparty.ups; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.math.BigDecimal; |
| import java.math.MathContext; |
| import java.text.SimpleDateFormat; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import javolution.util.FastList; |
| import javolution.util.FastMap; |
| |
| import org.ofbiz.base.util.Base64; |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.GeneralException; |
| import org.ofbiz.base.util.HttpClient; |
| import org.ofbiz.base.util.HttpClientException; |
| import org.ofbiz.base.util.StringUtil; |
| import org.ofbiz.base.util.UtilGenerics; |
| import org.ofbiz.base.util.UtilMisc; |
| import org.ofbiz.base.util.UtilNumber; |
| import org.ofbiz.base.util.UtilProperties; |
| import org.ofbiz.base.util.UtilValidate; |
| import org.ofbiz.base.util.UtilXml; |
| import org.ofbiz.base.util.string.FlexibleStringExpander; |
| import org.ofbiz.entity.Delegator; |
| import org.ofbiz.entity.GenericEntityException; |
| import org.ofbiz.entity.GenericValue; |
| import org.ofbiz.entity.condition.EntityCondition; |
| import org.ofbiz.entity.condition.EntityOperator; |
| import org.ofbiz.entity.util.EntityQuery; |
| import org.ofbiz.entity.util.EntityUtil; |
| import org.ofbiz.entity.util.EntityUtilProperties; |
| import org.ofbiz.party.contact.ContactMechWorker; |
| import org.ofbiz.product.store.ProductStoreWorker; |
| import org.ofbiz.service.DispatchContext; |
| import org.ofbiz.service.GenericServiceException; |
| import org.ofbiz.service.LocalDispatcher; |
| import org.ofbiz.service.ModelService; |
| import org.ofbiz.service.ServiceUtil; |
| import org.ofbiz.shipment.shipment.ShipmentServices; |
| import org.ofbiz.shipment.shipment.ShipmentWorker; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * UPS ShipmentServices |
| */ |
| public class UpsServices { |
| |
| public final static String module = UpsServices.class.getName(); |
| |
| public static Map<String, String> unitsUpsToOfbiz = FastMap.newInstance(); |
| public static Map<String, String> unitsOfbizToUps = FastMap.newInstance(); |
| static { |
| unitsUpsToOfbiz.put("LBS", "WT_lb"); |
| unitsUpsToOfbiz.put("KGS", "WT_kg"); |
| |
| for (Map.Entry<String, String> entry: unitsUpsToOfbiz.entrySet()) { |
| unitsOfbizToUps.put(entry.getValue(), entry.getKey()); |
| } |
| } |
| public static final int decimals = UtilNumber.getBigDecimalScale("order.decimals"); |
| public static final int rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding"); |
| public static final MathContext generalRounding = new MathContext(10); |
| public static final int returnServiceCode = 8; |
| public static final String dateFormatString = "yyyyMMdd"; |
| public static final String resourceError = "ProductUiLabels"; |
| public static final String resourceOrder = "OrderUiLabels"; |
| |
| public static Map<String, Object> upsShipmentConfirm(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| LocalDispatcher dispatcher = dctx.getDispatcher(); |
| GenericValue userLogin = (GenericValue) context.get("userLogin"); |
| Locale locale = (Locale) context.get("locale"); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| String shipmentConfirmResponseString = null; |
| |
| try { |
| GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne(); |
| if (shipment == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "ProductShipmentNotFoundId", locale) + " " + shipmentId); |
| } |
| GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| if (shipmentRouteSegment == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "ProductShipmentRouteSegmentNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", |
| UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("carrierServiceStatusId")) && !"SHRSCS_NOT_STARTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentStatusNotStarted", |
| UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId, "shipmentRouteSegmentStatus", shipmentRouteSegment.getString("carrierServiceStatusId")), locale)); |
| } |
| |
| // Get Origin Info |
| GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false); |
| if (originPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentRouteSegmentOriginPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber", false); |
| if (originTelecomNumber == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentRouteSegmentOriginTelecomNumberNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| String originPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !"001".equals(originTelecomNumber.getString("countryCode"))) { |
| originPhoneNumber = originTelecomNumber.getString("countryCode") + originPhoneNumber; |
| } |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, "-", ""); |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, " ", ""); |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo", false); |
| if (originCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentRouteSegmentOriginCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| // Get Dest Info |
| GenericValue destPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false); |
| if (destPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentRouteSegmentDestPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false); |
| if (destTelecomNumber == null) { |
| String missingErrMsg = "DestTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId; |
| Debug.logError(missingErrMsg, module); |
| // for now we won't require the dest phone number, but is it required? |
| //return ServiceUtil.returnError(missingErrMsg); |
| } |
| String destPhoneNumber = null; |
| if (destTelecomNumber != null) { |
| destPhoneNumber = destTelecomNumber.getString("areaCode") + destTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(destTelecomNumber.getString("countryCode")) && !"001".equals(destTelecomNumber.getString("countryCode"))) { |
| destPhoneNumber = destTelecomNumber.getString("countryCode") + destPhoneNumber; |
| } |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, "-", ""); |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, " ", ""); |
| } |
| |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue destCountryGeo = destPostalAddress.getRelatedOne("CountryGeo", false); |
| if (destCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentRouteSegmentDestCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod").where("partyId", shipmentRouteSegment.get("carrierPartyId"), "roleTypeId", "CARRIER", "shipmentMethodTypeId", shipmentRouteSegment.get("shipmentMethodTypeId")).queryOne(); |
| if (carrierShipmentMethod == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentCarrierShipmentMethodNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "carrierPartyId", shipmentRouteSegment.get("carrierPartyId"), "shipmentMethodTypeId", shipmentRouteSegment.get("shipmentMethodTypeId")), locale)); |
| } |
| |
| List<GenericValue> shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false); |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentPackageRouteSegsNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| List<GenericValue> itemIssuances = shipment.getRelated("ItemIssuance", null, null, false); |
| Set<String> orderIdSet = new TreeSet<String>(); |
| for (GenericValue itemIssuance: itemIssuances) { |
| orderIdSet.add(itemIssuance.getString("orderId")); |
| } |
| String ordersDescription = ""; |
| if (orderIdSet.size() > 1) { |
| |
| StringBuilder odBuf = new StringBuilder(UtilProperties.getMessage(resourceOrder, "OrderOrders", locale) + " "); |
| for (String orderId: orderIdSet) { |
| if (odBuf.length() > 0) { |
| odBuf.append(", "); |
| } |
| odBuf.append(orderId); |
| } |
| ordersDescription = odBuf.toString(); |
| } else if (orderIdSet.size() > 0) { |
| ordersDescription = UtilProperties.getMessage(resourceOrder, "OrderOrder", locale) + " " + orderIdSet.iterator().next(); |
| } |
| |
| // COD Support |
| boolean allowCOD = "true".equalsIgnoreCase(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "codAllowCod", resource, "shipment.ups.cod.allowCOD", "true")); |
| |
| // COD only applies if all orders involved with the shipment were paid only with EXT_COD - anything else becomes too complicated |
| if (allowCOD) { |
| |
| // Get the paymentMethodTypeIds of all the orderPaymentPreferences involved with the shipment |
| List<GenericValue> opps = EntityQuery.use(delegator).from("OrderPaymentPreference") |
| .where(EntityCondition.makeCondition("orderId", EntityOperator.IN, orderIdSet)).queryList(); |
| List<String> paymentMethodTypeIds = EntityUtil.getFieldListFromEntityList(opps, "paymentMethodTypeId", true); |
| |
| if (paymentMethodTypeIds.size() > 1 || ! paymentMethodTypeIds.contains("EXT_COD")) { |
| allowCOD = false; |
| } |
| } |
| |
| String codSurchargeAmount = null; |
| String codSurchargeCurrencyUomId = null; |
| String codFundsCode = null; |
| |
| boolean codSurchargeApplyToFirstPackage = false; |
| boolean codSurchargeApplyToAllPackages = false; |
| boolean codSurchargeSplitBetweenPackages = false; |
| boolean codSurchargeApplyToNoPackages = false; |
| |
| BigDecimal codSurchargePackageAmount = null; |
| |
| if (allowCOD) { |
| codSurchargeAmount = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "codSurchargeAmount", resource, "shipment.ups.cod.surcharge.amount", ""); |
| if (UtilValidate.isEmpty(codSurchargeAmount)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsSurchargeAmountIsNotConfigurated", locale)); |
| } |
| codSurchargeCurrencyUomId = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "codSurchargeCurrencyUomId", resource, "shipment.ups.cod.surcharge.currencyUomId", ""); |
| if (UtilValidate.isEmpty(codSurchargeCurrencyUomId)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsSurchargeCurrencyIsNotConfigurated", locale)); |
| } |
| String codSurchargeApplyToPackages = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "codSurchargeApplyToPackage", resource, "shipment.ups.cod.surcharge.applyToPackages", ""); |
| if (UtilValidate.isEmpty(codSurchargeApplyToPackages)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsApplyToPackagesIsNotConfigured", locale)); |
| } |
| codFundsCode = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "codFundsCode", resource, "shipment.ups.cod.codFundsCode", ""); |
| if (UtilValidate.isEmpty(codFundsCode)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsCodFundsCodeIsNotConfigured", locale)); |
| } |
| |
| codSurchargeApplyToFirstPackage = "first".equalsIgnoreCase(codSurchargeApplyToPackages); |
| codSurchargeApplyToAllPackages = "all".equalsIgnoreCase(codSurchargeApplyToPackages); |
| codSurchargeSplitBetweenPackages = "split".equalsIgnoreCase(codSurchargeApplyToPackages); |
| codSurchargeApplyToNoPackages = "none".equalsIgnoreCase(codSurchargeApplyToPackages); |
| |
| if (codSurchargeApplyToNoPackages) { |
| codSurchargeAmount = "0"; |
| } |
| codSurchargePackageAmount = new BigDecimal(codSurchargeAmount).setScale(decimals, rounding); |
| if (codSurchargeSplitBetweenPackages) { |
| codSurchargePackageAmount = codSurchargePackageAmount.divide(new BigDecimal(shipmentPackageRouteSegs.size()), decimals, rounding); |
| } |
| |
| if (UtilValidate.isEmpty(destTelecomNumber)) { |
| Debug.logInfo("Voice notification service will not be requested for COD shipmentId " + shipmentId + ", shipmentRouteSegmentId " + shipmentRouteSegmentId + " - missing destination phone number", module); |
| } |
| if (UtilValidate.isEmpty(shipmentRouteSegment.get("homeDeliveryType"))) { |
| Debug.logInfo("Voice notification service will not be requested for COD shipmentId " + shipmentId + ", shipmentRouteSegmentId " + shipmentRouteSegmentId + " - destination address is not residential", module); |
| } |
| } |
| |
| // Determine the currency by trying the shipmentRouteSegment, then the Shipment, then the framework's default currency, and finally default to USD |
| String currencyCode = null; |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("currencyUomId"))) { |
| currencyCode = shipmentRouteSegment.getString("currencyUomId"); |
| } else if (UtilValidate.isNotEmpty(shipment.getString("currencyUomId"))) { |
| currencyCode = shipment.getString("currencyUomId"); |
| } else { |
| currencyCode = EntityUtilProperties.getPropertyValue("general.properties", "currency.uom.id.default", "USD", delegator); |
| } |
| |
| // Okay, start putting the XML together... |
| Document shipmentConfirmRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentConfirmRequest"); |
| Element shipmentConfirmRequestElement = shipmentConfirmRequestDoc.getDocumentElement(); |
| shipmentConfirmRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element requestElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Request", shipmentConfirmRequestDoc); |
| |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Ship Confirm / nonvalidate", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", shipmentConfirmRequestDoc); |
| |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "ShipConfirm", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", "nonvalidate", shipmentConfirmRequestDoc); |
| |
| // Top Level Element: LabelSpecification |
| Element labelSpecificationElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "LabelSpecification", shipmentConfirmRequestDoc); |
| |
| Element labelPrintMethodElement = UtilXml.addChildElement(labelSpecificationElement, "LabelPrintMethod", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(labelPrintMethodElement, "Code", "GIF", shipmentConfirmRequestDoc); |
| |
| UtilXml.addChildElementValue(labelSpecificationElement, "HTTPUserAgent", "Mozilla/5.0", shipmentConfirmRequestDoc); |
| |
| Element labelImageFormatElement = UtilXml.addChildElement(labelSpecificationElement, "LabelImageFormat", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(labelImageFormatElement, "Code", "GIF", shipmentConfirmRequestDoc); |
| |
| // Top Level Element: Shipment |
| Element shipmentElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Shipment", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipmentElement, "Description", "Goods for Shipment " + shipment.get("shipmentId") + " from " + ordersDescription, shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: Shipper |
| String shipperNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "shipperNumber", resource, "shipment.ups.shipper.number", ""); |
| Element shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "Name", UtilValidate.isNotEmpty(originPostalAddress.getString("toName")) ? originPostalAddress.getString("toName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "AttentionName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "ShipperNumber", shipperNumber, shipmentConfirmRequestDoc); |
| |
| Element shipperAddressElement = UtilXml.addChildElement(shipperElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| //UtilXml.addChildElementValue(shipperAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| // How to determine this? Add to data model...? UtilXml.addChildElement(shipperAddressElement, "ResidentialAddress", shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: ShipTo |
| Element shipToElement = UtilXml.addChildElement(shipmentElement, "ShipTo", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "CompanyName", UtilValidate.isNotEmpty(destPostalAddress.getString("toName")) ? destPostalAddress.getString("toName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "AttentionName", UtilValidate.isNotEmpty(destPostalAddress.getString("attnName")) ? destPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPhoneNumber)) { |
| UtilXml.addChildElementValue(shipToElement, "PhoneNumber", destPhoneNumber, shipmentConfirmRequestDoc); |
| } |
| Element shipToAddressElement = UtilXml.addChildElement(shipToElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine1", destPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine2", destPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| //UtilXml.addChildElementValue(shipToAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "City", destPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "StateProvinceCode", destPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "PostalCode", destPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "CountryCode", destCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("homeDeliveryType"))) { |
| UtilXml.addChildElement(shipToAddressElement, "ResidentialAddress", shipmentConfirmRequestDoc); |
| } |
| |
| // Child of Shipment: ShipFrom |
| Element shipFromElement = UtilXml.addChildElement(shipmentElement, "ShipFrom", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "CompanyName", originPostalAddress.getString("toName"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "AttentionName", originPostalAddress.getString("attnName"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc); |
| Element shipFromAddressElement = UtilXml.addChildElement(shipFromElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| //UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine3", "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: SoldTo |
| Element soldToElement = UtilXml.addChildElement(shipmentElement, "SoldTo", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToElement, "CompanyName", UtilValidate.isNotEmpty(destPostalAddress.getString("toName")) ? destPostalAddress.getString("toName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToElement, "AttentionName", UtilValidate.isNotEmpty(destPostalAddress.getString("attnName")) ? destPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPhoneNumber)) { |
| UtilXml.addChildElementValue(soldToElement, "PhoneNumber", destPhoneNumber, shipmentConfirmRequestDoc); |
| } |
| Element soldToAddressElement = UtilXml.addChildElement(soldToElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToAddressElement, "AddressLine1", destPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(soldToAddressElement, "AddressLine2", destPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| UtilXml.addChildElementValue(soldToAddressElement, "City", destPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToAddressElement, "StateProvinceCode", destPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToAddressElement, "PostalCode", destPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(soldToAddressElement, "CountryCode", destCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: PaymentInformation |
| Element paymentInformationElement = UtilXml.addChildElement(shipmentElement, "PaymentInformation", shipmentConfirmRequestDoc); |
| |
| String thirdPartyAccountNumber = shipmentRouteSegment.getString("thirdPartyAccountNumber"); |
| |
| if (UtilValidate.isEmpty(thirdPartyAccountNumber)) { |
| |
| // Paid by shipper |
| Element prepaidElement = UtilXml.addChildElement(paymentInformationElement, "Prepaid", shipmentConfirmRequestDoc); |
| Element billShipperElement = UtilXml.addChildElement(prepaidElement, "BillShipper", shipmentConfirmRequestDoc); |
| |
| // fill in BillShipper AccountNumber element |
| String billShipperAccountNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "billShipperAccountNumber", resource, "shipment.ups.bill.shipper.account.number", ""); |
| UtilXml.addChildElementValue(billShipperElement, "AccountNumber", billShipperAccountNumber, shipmentConfirmRequestDoc); |
| } else { |
| |
| // Paid by another shipper (may be receiver or not) |
| |
| // UPS requires the postal code and country code of the third party |
| String thirdPartyPostalCode = shipmentRouteSegment.getString("thirdPartyPostalCode"); |
| if (UtilValidate.isEmpty(thirdPartyPostalCode)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentThirdPartyPostalCodeNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| String thirdPartyCountryGeoCode = shipmentRouteSegment.getString("thirdPartyCountryGeoCode"); |
| if (UtilValidate.isEmpty(thirdPartyCountryGeoCode)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentThirdPartyCountryNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| Element billThirdPartyElement = UtilXml.addChildElement(paymentInformationElement, "BillThirdParty", shipmentConfirmRequestDoc); |
| Element billThirdPartyShipperElement = UtilXml.addChildElement(billThirdPartyElement, "BillThirdPartyShipper", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(billThirdPartyShipperElement, "AccountNumber", thirdPartyAccountNumber, shipmentConfirmRequestDoc); |
| Element thirdPartyElement = UtilXml.addChildElement(billThirdPartyShipperElement, "ThirdParty", shipmentConfirmRequestDoc); |
| Element addressElement = UtilXml.addChildElement(thirdPartyElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(addressElement, "PostalCode", thirdPartyPostalCode, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(addressElement, "CountryCode", thirdPartyCountryGeoCode, shipmentConfirmRequestDoc); |
| } |
| |
| // Child of Shipment: Service |
| Element serviceElement = UtilXml.addChildElement(shipmentElement, "Service", shipmentConfirmRequestDoc); |
| String carrierServiceCode = carrierShipmentMethod.getString("carrierServiceCode"); |
| UtilXml.addChildElementValue(serviceElement, "Code", carrierServiceCode, shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: ShipmentServiceOptions |
| List<String> internationalServiceCodes = UtilMisc.toList("07", "08", "54", "65"); |
| if (internationalServiceCodes.contains(carrierServiceCode)) { |
| Element shipmentServiceOptionsElement = UtilXml.addChildElement(shipmentElement, "ShipmentServiceOptions", shipmentConfirmRequestDoc); |
| Element internationalFormsElement = UtilXml.addChildElement(shipmentServiceOptionsElement, "InternationalForms", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(internationalFormsElement, "FormType", "01", shipmentConfirmRequestDoc); |
| List<GenericValue> shipmentItems = shipment.getRelated("ShipmentItem", null, null, false); |
| for (GenericValue shipmentItem :shipmentItems) { |
| Element productElement = UtilXml.addChildElement(internationalFormsElement, "Product", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(productElement, "Description", "Product Description", shipmentConfirmRequestDoc); |
| Element unitElement = UtilXml.addChildElement(productElement, "Unit", shipmentConfirmRequestDoc); |
| BigDecimal productQuantity = shipmentItem.getBigDecimal("quantity").setScale(decimals, rounding); |
| UtilXml.addChildElementValue(unitElement, "Number", String.valueOf(productQuantity.intValue()), shipmentConfirmRequestDoc); |
| List<GenericValue> shipmentItemIssuances = shipmentItem.getRelated("ItemIssuance", null, null, false); |
| GenericValue orderItem = EntityUtil.getFirst(shipmentItemIssuances).getRelatedOne("OrderItem", false); |
| UtilXml.addChildElementValue(unitElement, "Value", orderItem.getBigDecimal("unitPrice").toString(), shipmentConfirmRequestDoc); |
| Element unitOfMeasurElement = UtilXml.addChildElement(unitElement, "UnitOfMeasurement", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(unitOfMeasurElement, "Code", "EA", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(productElement, "OriginCountryCode", "US", shipmentConfirmRequestDoc); |
| } |
| SimpleDateFormat formatter = new SimpleDateFormat(dateFormatString); |
| String invoiceDate = formatter.format(shipment.getTimestamp("createdDate")); |
| UtilXml.addChildElementValue(internationalFormsElement, "InvoiceDate", invoiceDate, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(internationalFormsElement, "ReasonForExport","SALE", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(internationalFormsElement, "CurrencyCode", currencyCode, shipmentConfirmRequestDoc); |
| } |
| |
| // Child of Shipment: Package |
| ListIterator<GenericValue> shipmentPackageRouteSegIter = shipmentPackageRouteSegs.listIterator(); |
| while (shipmentPackageRouteSegIter.hasNext()) { |
| GenericValue shipmentPackageRouteSeg = shipmentPackageRouteSegIter.next(); |
| GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false); |
| GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType", false); |
| List<GenericValue> carrierShipmentBoxTypes = shipmentPackage.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "UPS"), null, false); |
| GenericValue carrierShipmentBoxType = null; |
| if (carrierShipmentBoxTypes.size() > 0) { |
| carrierShipmentBoxType = carrierShipmentBoxTypes.get(0); |
| } |
| |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", shipmentConfirmRequestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", shipmentConfirmRequestDoc); |
| if (carrierShipmentBoxType != null && carrierShipmentBoxType.get("packagingTypeCode") != null) { |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", carrierShipmentBoxType.getString("packagingTypeCode"), shipmentConfirmRequestDoc); |
| } else { |
| // default to "02", plain old Package |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "02", shipmentConfirmRequestDoc); |
| } |
| if (shipmentBoxType != null) { |
| Element dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", shipmentConfirmRequestDoc); |
| Element unitOfMeasurementElement = UtilXml.addChildElement(dimensionsElement, "UnitOfMeasurement", shipmentConfirmRequestDoc); |
| GenericValue dimensionUom = shipmentBoxType.getRelatedOne("DimensionUom", false); |
| if (dimensionUom != null) { |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", dimensionUom.getString("abbreviation").toUpperCase(), shipmentConfirmRequestDoc); |
| } else { |
| // I guess we'll default to inches... |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", "IN", shipmentConfirmRequestDoc); |
| } |
| BigDecimal boxLength = shipmentBoxType.getBigDecimal("boxLength"); |
| BigDecimal boxWidth = shipmentBoxType.getBigDecimal("boxWidth"); |
| BigDecimal boxHeight = shipmentBoxType.getBigDecimal("boxHeight"); |
| UtilXml.addChildElementValue(dimensionsElement, "Length", UtilValidate.isNotEmpty(boxLength) ? ""+boxLength.intValue() : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Width", UtilValidate.isNotEmpty(boxWidth) ? ""+boxWidth.intValue() : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Height", UtilValidate.isNotEmpty(boxHeight) ? ""+boxHeight.intValue() : "", shipmentConfirmRequestDoc); |
| } else if (UtilValidate.isNotEmpty(shipmentPackage) && UtilValidate.isNotEmpty(shipmentPackage.getBigDecimal("boxLength")) |
| && UtilValidate.isNotEmpty(shipmentPackage.getBigDecimal("boxWidth")) |
| && UtilValidate.isNotEmpty(shipmentPackage.getBigDecimal("boxHeight"))) { |
| Element dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", shipmentConfirmRequestDoc); |
| Element unitOfMeasurementElement = UtilXml.addChildElement(dimensionsElement, "UnitOfMeasurement", shipmentConfirmRequestDoc); |
| GenericValue dimensionUom = shipmentPackage.getRelatedOne("DimensionUom", false); |
| if (UtilValidate.isNotEmpty(dimensionUom)) { |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", dimensionUom.getString("abbreviation").toUpperCase(), shipmentConfirmRequestDoc); |
| } else { |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", "IN", shipmentConfirmRequestDoc); |
| } |
| UtilXml.addChildElementValue(dimensionsElement, "Length", ""+shipmentPackage.getBigDecimal("boxLength").intValue(), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Width", ""+shipmentPackage.getBigDecimal("boxWidth").intValue(), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Height", ""+shipmentPackage.getBigDecimal("boxHeight").intValue(), shipmentConfirmRequestDoc); |
| } |
| |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", shipmentConfirmRequestDoc); |
| Element packageWeightUnitOfMeasurementElement = UtilXml.addChildElement(packageElement, "UnitOfMeasurement", shipmentConfirmRequestDoc); |
| String weightUomUps = null; |
| if (shipmentPackage.get("weightUomId") != null) { |
| weightUomUps = unitsOfbizToUps.get(shipmentPackage.get("weightUomId")); |
| } |
| if (weightUomUps != null) { |
| UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", weightUomUps, shipmentConfirmRequestDoc); |
| } else { |
| // might as well default to LBS |
| UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", "LBS", shipmentConfirmRequestDoc); |
| } |
| |
| if (shipmentPackage.getString("weight") == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsWeightValueNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId")), locale)); |
| } |
| BigDecimal boxWeight = shipmentPackage.getBigDecimal("weight"); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", UtilValidate.isNotEmpty(boxWeight) ? ""+ boxWeight.setScale(0, BigDecimal.ROUND_CEILING) : "", shipmentConfirmRequestDoc); |
| // Adding only when order is not an international order |
| if (!internationalServiceCodes.contains(carrierServiceCode)) { |
| Element referenceNumberElement = UtilXml.addChildElement(packageElement, "ReferenceNumber", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(referenceNumberElement, "Code", "MK", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(referenceNumberElement, "Value", shipmentPackage.getString("shipmentPackageSeqId"), shipmentConfirmRequestDoc); |
| } |
| if (carrierShipmentBoxType != null && carrierShipmentBoxType.get("oversizeCode") != null) { |
| UtilXml.addChildElementValue(packageElement, "OversizePackage", carrierShipmentBoxType.getString("oversizeCode"), shipmentConfirmRequestDoc); |
| } |
| |
| Element packageServiceOptionsElement = UtilXml.addChildElement(packageElement, "PackageServiceOptions", shipmentConfirmRequestDoc); |
| |
| // Package insured value |
| BigDecimal insuredValue = shipmentPackage.getBigDecimal("insuredValue"); |
| if (! UtilValidate.isEmpty(insuredValue)) { |
| |
| Element insuredValueElement = UtilXml.addChildElement(packageServiceOptionsElement, "InsuredValue", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(insuredValueElement, "MonetaryValue", insuredValue.setScale(2, BigDecimal.ROUND_HALF_UP).toString(), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(insuredValueElement, "CurrencyCode", currencyCode, shipmentConfirmRequestDoc); |
| } |
| |
| if (allowCOD) { |
| Element codElement = UtilXml.addChildElement(packageServiceOptionsElement, "COD", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(codElement, "CODCode", "3", shipmentConfirmRequestDoc); // "3" is the only valid value for package-level COD |
| UtilXml.addChildElementValue(codElement, "CODFundsCode", codFundsCode, shipmentConfirmRequestDoc); |
| Element codAmountElement = UtilXml.addChildElement(codElement, "CODAmount", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(codAmountElement, "CurrencyCode", currencyCode, shipmentConfirmRequestDoc); |
| |
| // Get the value of the package by going back to the orderItems |
| Map<String, Object> getPackageValueResult = dispatcher.runSync("getShipmentPackageValueFromOrders", UtilMisc.toMap("shipmentId", shipmentId, "shipmentPackageSeqId", shipmentPackage.get("shipmentPackageSeqId"), "currencyUomId", currencyCode, "userLogin", userLogin, "locale", locale)); |
| if (ServiceUtil.isError(getPackageValueResult)) return getPackageValueResult; |
| BigDecimal packageValue = (BigDecimal) getPackageValueResult.get("packageValue"); |
| |
| // Convert the value of the COD surcharge to the shipment currency, if necessary |
| Map<String, Object> convertUomResult = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", codSurchargeCurrencyUomId, "uomIdTo", currencyCode, "originalValue", codSurchargePackageAmount)); |
| if (ServiceUtil.isError(convertUomResult)) return convertUomResult; |
| if (convertUomResult.containsKey("convertedValue")) { |
| codSurchargePackageAmount = ((BigDecimal) convertUomResult.get("convertedValue")).setScale(decimals, rounding); |
| } |
| |
| // Add the amount of the surcharge for the package, if the surcharge should be on all packages or the first and this is the first package |
| if (codSurchargeApplyToAllPackages || codSurchargeSplitBetweenPackages || (codSurchargeApplyToFirstPackage && shipmentPackageRouteSegIter.previousIndex() <= 0)) { |
| packageValue = packageValue.add(codSurchargePackageAmount); |
| } |
| |
| UtilXml.addChildElementValue(codAmountElement, "MonetaryValue", packageValue.setScale(decimals, rounding).toString(), shipmentConfirmRequestDoc); |
| } |
| } |
| |
| String shipmentConfirmRequestString = null; |
| try { |
| shipmentConfirmRequestString = UtilXml.writeXmlDocument(shipmentConfirmRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the ShipmentConfirmRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorShipmentConfirmRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| // send ShipmentConfirmRequest String |
| // get ShipmentConfirmResponse String back |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(shipmentConfirmRequestString); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentConfirmRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(xmlString.toString().getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| try { |
| shipmentConfirmResponseString = sendUpsRequest("ShipConfirm", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service ShipConfirm: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingShipConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentConfirmResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(shipmentConfirmResponseString.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| Document shipmentConfirmResponseDocument = null; |
| try { |
| shipmentConfirmResponseDocument = UtilXml.readXmlDocument(shipmentConfirmResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return handleUpsShipmentConfirmResponse(shipmentConfirmResponseDocument, shipmentRouteSegment, locale); |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| if (shipmentConfirmResponseString != null) { |
| Debug.logError("Got XML ShipmentConfirmRespose: " + shipmentConfirmResponseString, module); |
| return ServiceUtil.returnError(UtilMisc.toList( |
| UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale), |
| UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentConfirmResposeWasReceived", |
| UtilMisc.toMap("shipmentConfirmResponseString", shipmentConfirmResponseString), locale))); |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| } |
| |
| public static Map<String, Object> handleUpsShipmentConfirmResponse(Document shipmentConfirmResponseDocument, GenericValue shipmentRouteSegment, Locale locale) throws GenericEntityException { |
| // process ShipmentConfirmResponse, update data as needed |
| Element shipmentConfirmResponseElement = shipmentConfirmResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "Response"); |
| //Element responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference"); |
| //String responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext"); |
| //String responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion"); |
| |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| //String responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| if ("1".equals(responseStatusCode)) { |
| // handle ShipmentCharges element info |
| Element shipmentChargesElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "ShipmentCharges"); |
| |
| Element transportationChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TransportationCharges"); |
| //String transportationCurrencyCode = UtilXml.childElementValue(transportationChargesElement, "CurrencyCode"); |
| String transportationMonetaryValue = UtilXml.childElementValue(transportationChargesElement, "MonetaryValue"); |
| |
| Element serviceOptionsChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "ServiceOptionsCharges"); |
| //String serviceOptionsCurrencyCode = UtilXml.childElementValue(serviceOptionsChargesElement, "CurrencyCode"); |
| String serviceOptionsMonetaryValue = UtilXml.childElementValue(serviceOptionsChargesElement, "MonetaryValue"); |
| |
| Element totalChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TotalCharges"); |
| String totalCurrencyCode = UtilXml.childElementValue(totalChargesElement, "CurrencyCode"); |
| String totalMonetaryValue = UtilXml.childElementValue(totalChargesElement, "MonetaryValue"); |
| |
| if (UtilValidate.isNotEmpty(totalCurrencyCode)) { |
| if (UtilValidate.isEmpty(shipmentRouteSegment.getString("currencyUomId"))) { |
| shipmentRouteSegment.set("currencyUomId", totalCurrencyCode); |
| } else if (!totalCurrencyCode.equals(shipmentRouteSegment.getString("currencyUomId"))) { |
| shipmentRouteSegment.set("currencyUomId", totalCurrencyCode); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsCurrencyDoesNotMatch", |
| UtilMisc.toMap("currency1", totalCurrencyCode, "currency2", shipmentRouteSegment.getString("currencyUomId")), locale)); |
| } |
| } |
| |
| try { |
| shipmentRouteSegment.set("actualTransportCost", new BigDecimal(transportationMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the transportationMonetaryValue [" + transportationMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTransportationMonetaryValue", |
| UtilMisc.toMap("transportationMonetaryValue", transportationMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| try { |
| shipmentRouteSegment.set("actualServiceCost", new BigDecimal(serviceOptionsMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the serviceOptionsMonetaryValue [" + serviceOptionsMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingServiceOptionsMonetaryValue", |
| UtilMisc.toMap("serviceOptionsMonetaryValue", serviceOptionsMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| try { |
| shipmentRouteSegment.set("actualCost", new BigDecimal(totalMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the totalMonetaryValue [" + totalMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTotalMonetaryValue", |
| UtilMisc.toMap("totalMonetaryValue", totalMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| |
| // handle BillingWeight element info |
| Element billingWeightElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "BillingWeight"); |
| Element billingWeightUnitOfMeasurementElement = UtilXml.firstChildElement(billingWeightElement, "UnitOfMeasurement"); |
| String billingWeightUnitOfMeasurement = UtilXml.childElementValue(billingWeightUnitOfMeasurementElement, "Code"); |
| String billingWeight = UtilXml.childElementValue(billingWeightElement, "Weight"); |
| try { |
| shipmentRouteSegment.set("billingWeight", new BigDecimal(billingWeight)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the billingWeight [" + billingWeight + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingBillingWeight", |
| UtilMisc.toMap("billingWeight", billingWeight, "errorString", e.toString()), locale)); |
| } |
| shipmentRouteSegment.set("billingWeightUomId", unitsUpsToOfbiz.get(billingWeightUnitOfMeasurement)); |
| |
| // store the ShipmentIdentificationNumber and ShipmentDigest |
| String shipmentIdentificationNumber = UtilXml.childElementValue(shipmentConfirmResponseElement, "ShipmentIdentificationNumber"); |
| String shipmentDigest = UtilXml.childElementValue(shipmentConfirmResponseElement, "ShipmentDigest"); |
| shipmentRouteSegment.set("trackingIdNumber", shipmentIdentificationNumber); |
| shipmentRouteSegment.set("trackingDigest", shipmentDigest); |
| |
| // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable |
| shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_CONFIRMED"); |
| |
| // write/store all modified value objects |
| shipmentRouteSegment.store(); |
| |
| // -=-=-=- Okay, now done with that, just return any extra info... |
| StringBuilder successString = new StringBuilder(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsShipmentConfirmSucceeded", locale)); |
| |
| if (errorList.size() > 0) { |
| // this shouldn't happen much, but handle it anyway |
| successString.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentConfirmError", locale)); |
| Iterator<Object> errorListIter = errorList.iterator(); |
| while (errorListIter.hasNext()) { |
| successString.append(errorListIter.next()); |
| if (errorListIter.hasNext()) { |
| successString.append(", "); |
| } |
| } |
| } |
| return ServiceUtil.returnSuccess(successString.toString()); |
| } else { |
| errorList.add(0, UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentConfirmFailed", locale)); |
| return ServiceUtil.returnError(errorList); |
| } |
| } |
| |
| public static Map<String, Object> upsShipmentAccept(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| Locale locale = (Locale) context.get("locale"); |
| |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| String shipmentAcceptResponseString = null; |
| |
| try { |
| //GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne(); |
| GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services |
| if (!"SHRSCS_CONFIRMED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentStatusNotConfirmed", |
| UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId, "shipmentRouteSegmentStatus", shipmentRouteSegment.getString("carrierServiceStatusId")), locale)); |
| } |
| |
| List<GenericValue> shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false); |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsPackageRouteSegsNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingDigest"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsTrackingDigestWasNotSet", locale)); |
| } |
| |
| Document shipmentAcceptRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentAcceptRequest"); |
| Element shipmentAcceptRequestElement = shipmentAcceptRequestDoc.getDocumentElement(); |
| shipmentAcceptRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element requestElement = UtilXml.addChildElement(shipmentAcceptRequestElement, "Request", shipmentAcceptRequestDoc); |
| |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "ShipAccept / 01", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", shipmentAcceptRequestDoc); |
| |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "ShipAccept", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", "01", shipmentAcceptRequestDoc); |
| |
| UtilXml.addChildElementValue(shipmentAcceptRequestElement, "ShipmentDigest", shipmentRouteSegment.getString("trackingDigest"), shipmentAcceptRequestDoc); |
| |
| |
| String shipmentAcceptRequestString = null; |
| try { |
| shipmentAcceptRequestString = UtilXml.writeXmlDocument(shipmentAcceptRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the ShipmentAcceptRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorShipmentAcceptRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| // send ShipmentConfirmRequest String |
| // get ShipmentConfirmResponse String back |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(shipmentAcceptRequestString); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentAcceptRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(xmlString.toString().getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| try { |
| shipmentAcceptResponseString = sendUpsRequest("ShipAccept", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service ShipAccept: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingShipAccept", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentAcceptResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(shipmentAcceptResponseString.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| Document shipmentAcceptResponseDocument = null; |
| try { |
| shipmentAcceptResponseDocument = UtilXml.readXmlDocument(shipmentAcceptResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentAcceptResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentAcceptResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the ShipmentAcceptResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentAcceptResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return handleUpsShipmentAcceptResponse(shipmentAcceptResponseDocument, shipmentRouteSegment, shipmentPackageRouteSegs, delegator, |
| shipmentGatewayConfigId, resource, context, locale); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentAccept", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| |
| public static Map<String, Object> handleUpsShipmentAcceptResponse(Document shipmentAcceptResponseDocument, GenericValue shipmentRouteSegment, List<GenericValue> shipmentPackageRouteSegs, |
| Delegator delegator, String shipmentGatewayConfigId, String resource, Map<String, ? extends Object> context, Locale locale) throws GenericEntityException { |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| // process ShipmentAcceptResponse, update data as needed |
| Element shipmentAcceptResponseElement = shipmentAcceptResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(shipmentAcceptResponseElement, "Response"); |
| //Element responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference"); |
| //String responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext"); |
| //String responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion"); |
| |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| //String responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| if ("1".equals(responseStatusCode)) { |
| Element shipmentResultsElement = UtilXml.firstChildElement(shipmentAcceptResponseElement, "ShipmentResults"); |
| |
| // This information is returned in both the ShipmentConfirmResponse and |
| //the ShipmentAcceptResponse. So, we'll go ahead and store it here again |
| //and warn of changes or something... |
| |
| |
| // handle ShipmentCharges element info |
| Element shipmentChargesElement = UtilXml.firstChildElement(shipmentResultsElement, "ShipmentCharges"); |
| |
| Element transportationChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TransportationCharges"); |
| //String transportationCurrencyCode = UtilXml.childElementValue(transportationChargesElement, "CurrencyCode"); |
| String transportationMonetaryValue = UtilXml.childElementValue(transportationChargesElement, "MonetaryValue"); |
| |
| Element serviceOptionsChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "ServiceOptionsCharges"); |
| //String serviceOptionsCurrencyCode = UtilXml.childElementValue(serviceOptionsChargesElement, "CurrencyCode"); |
| String serviceOptionsMonetaryValue = UtilXml.childElementValue(serviceOptionsChargesElement, "MonetaryValue"); |
| |
| Element totalChargesElement = UtilXml.firstChildElement(shipmentChargesElement, "TotalCharges"); |
| String totalCurrencyCode = UtilXml.childElementValue(totalChargesElement, "CurrencyCode"); |
| String totalMonetaryValue = UtilXml.childElementValue(totalChargesElement, "MonetaryValue"); |
| |
| if (UtilValidate.isNotEmpty(totalCurrencyCode)) { |
| if (UtilValidate.isEmpty(shipmentRouteSegment.getString("currencyUomId"))) { |
| shipmentRouteSegment.set("currencyUomId", totalCurrencyCode); |
| } else if (!totalCurrencyCode.equals(shipmentRouteSegment.getString("currencyUomId"))) { |
| shipmentRouteSegment.set("currencyUomId", totalCurrencyCode); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsCurrencyDoesNotMatch", |
| UtilMisc.toMap("currency1", totalCurrencyCode, "currency2", shipmentRouteSegment.getString("currencyUomId")), locale)); |
| } |
| } |
| |
| try { |
| shipmentRouteSegment.set("actualTransportCost", new BigDecimal(transportationMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the transportationMonetaryValue [" + transportationMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTransportationMonetaryValue", |
| UtilMisc.toMap("transportationMonetaryValue", transportationMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| try { |
| shipmentRouteSegment.set("actualServiceCost", new BigDecimal(serviceOptionsMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the serviceOptionsMonetaryValue [" + serviceOptionsMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingServiceOptionsMonetaryValue", |
| UtilMisc.toMap("serviceOptionsMonetaryValue", serviceOptionsMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| try { |
| shipmentRouteSegment.set("actualCost", new BigDecimal(totalMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the totalMonetaryValue [" + totalMonetaryValue + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTotalMonetaryValue", |
| UtilMisc.toMap("totalMonetaryValue", totalMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| |
| // handle BillingWeight element info |
| Element billingWeightElement = UtilXml.firstChildElement(shipmentResultsElement, "BillingWeight"); |
| Element billingWeightUnitOfMeasurementElement = UtilXml.firstChildElement(billingWeightElement, "UnitOfMeasurement"); |
| String billingWeightUnitOfMeasurement = UtilXml.childElementValue(billingWeightUnitOfMeasurementElement, "Code"); |
| String billingWeight = UtilXml.childElementValue(billingWeightElement, "Weight"); |
| try { |
| shipmentRouteSegment.set("billingWeight", new BigDecimal(billingWeight)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the billingWeight [" + billingWeight + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingBillingWeight", |
| UtilMisc.toMap("billingWeight", billingWeight, "errorString", e.toString()), locale)); |
| } |
| shipmentRouteSegment.set("billingWeightUomId", unitsUpsToOfbiz.get(billingWeightUnitOfMeasurement)); |
| |
| // store the ShipmentIdentificationNumber and ShipmentDigest |
| String shipmentIdentificationNumber = UtilXml.childElementValue(shipmentResultsElement, "ShipmentIdentificationNumber"); |
| // should compare to trackingIdNumber, should always be the same right? |
| shipmentRouteSegment.set("trackingIdNumber", shipmentIdentificationNumber); |
| |
| // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable |
| shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_ACCEPTED"); |
| |
| // write/store modified value object |
| shipmentRouteSegment.store(); |
| |
| // now process the PackageResults elements |
| List<? extends Element> packageResultsElements = UtilXml.childElementList(shipmentResultsElement, "PackageResults"); |
| Iterator<GenericValue> shipmentPackageRouteSegIter = shipmentPackageRouteSegs.iterator(); |
| for (Element packageResultsElement: packageResultsElements) { |
| String trackingNumber = UtilXml.childElementValue(packageResultsElement, "TrackingNumber"); |
| |
| Element packageServiceOptionsChargesElement = UtilXml.firstChildElement(packageResultsElement, "ServiceOptionsCharges"); |
| String packageServiceOptionsCurrencyCode = UtilXml.childElementValue(packageServiceOptionsChargesElement, "CurrencyCode"); |
| String packageServiceOptionsMonetaryValue = UtilXml.childElementValue(packageServiceOptionsChargesElement, "MonetaryValue"); |
| |
| Element packageLabelImageElement = UtilXml.firstChildElement(packageResultsElement, "LabelImage"); |
| //Element packageLabelImageFormatElement = UtilXml.firstChildElement(packageResultsElement, "LabelImageFormat"); |
| // will be EPL or GIF, should always be GIF since that is what we requested |
| //String packageLabelImageFormatCode = UtilXml.childElementValue(packageLabelImageFormatElement, "Code"); |
| //String packageLabelImageFormatDescription = UtilXml.childElementValue(packageLabelImageFormatElement, "Description"); |
| String packageLabelGraphicImageString = UtilXml.childElementValue(packageLabelImageElement, "GraphicImage"); |
| String packageLabelInternationalSignatureGraphicImageString = UtilXml.childElementValue(packageLabelImageElement, "InternationalSignatureGraphicImage"); |
| String packageLabelHTMLImageString = UtilXml.childElementValue(packageLabelImageElement, "HTMLImage"); |
| |
| if (!shipmentPackageRouteSegIter.hasNext()) { |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorMorePackageResultsWereReturned", |
| UtilMisc.toMap("trackingNumber", trackingNumber, "ServiceOptionsCharges", packageServiceOptionsMonetaryValue + packageServiceOptionsCurrencyCode), locale)); |
| // NOTE: if this happens much we should just create a new package to store all of the info... |
| continue; |
| } |
| |
| //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... |
| GenericValue shipmentPackageRouteSeg = shipmentPackageRouteSegIter.next(); |
| shipmentPackageRouteSeg.set("trackingCode", trackingNumber); |
| shipmentPackageRouteSeg.set("boxNumber", ""); |
| shipmentPackageRouteSeg.set("currencyUomId", packageServiceOptionsCurrencyCode); |
| try { |
| shipmentPackageRouteSeg.set("packageServiceCost", new BigDecimal(packageServiceOptionsMonetaryValue)); |
| } catch (NumberFormatException e) { |
| String excErrMsg = "Error parsing the packageServiceOptionsMonetaryValue [" + packageServiceOptionsMonetaryValue + "] for Package [" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + "]: " + e.toString(); |
| Debug.logError(e, excErrMsg, module); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingServiceOptionsMonetaryValue", |
| UtilMisc.toMap("serviceOptionsMonetaryValue", serviceOptionsMonetaryValue, "errorString", e.toString()), locale)); |
| } |
| byte[] labelImageBytes = null; |
| if (packageLabelGraphicImageString != null) { |
| labelImageBytes = Base64.base64Decode(packageLabelGraphicImageString.getBytes()); |
| shipmentPackageRouteSeg.setBytes("labelImage", labelImageBytes); |
| } |
| byte[] labelInternationalSignatureGraphicImageBytes = null; |
| if (packageLabelInternationalSignatureGraphicImageString != null) { |
| labelInternationalSignatureGraphicImageBytes = Base64.base64Decode(packageLabelInternationalSignatureGraphicImageString.getBytes()); |
| shipmentPackageRouteSeg.set("labelIntlSignImage", labelInternationalSignatureGraphicImageBytes); |
| } |
| String packageLabelHTMLImageStringDecoded = Base64.base64Decode(packageLabelHTMLImageString); |
| shipmentPackageRouteSeg.set("labelHtml", packageLabelHTMLImageStringDecoded); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| if (labelImageBytes != null) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/label" + trackingNumber + ".gif"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(labelImageBytes); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS LabelImage GIF file: [[[" + packageLabelGraphicImageString + "]]] to file: " + outFileName, module); |
| } |
| } |
| if (labelInternationalSignatureGraphicImageBytes != null) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentLabelIntlSignImage" + "label" + trackingNumber + ".gif"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(labelInternationalSignatureGraphicImageBytes); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS IntlSign LabelImage GIF file: [[[" + packageLabelInternationalSignatureGraphicImageString + "]]] to file: " + outFileName, module); |
| } |
| } |
| if (packageLabelHTMLImageStringDecoded != null) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentLabelHTMLImage" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + "_" + shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + ".html"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(packageLabelHTMLImageStringDecoded.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS LabelImage HTML file: [[[" + packageLabelHTMLImageStringDecoded + "]]] to file: " + outFileName, module); |
| } |
| } |
| } |
| |
| //save International Invoice image if it exists (upscie is not returning this at this moment) |
| //Commenting because it might be useful in the future as there are other types of forms that may be returned |
| /* Element formElement = UtilXml.firstChildElement(packageResultsElement, "Form"); |
| if (formElement != null) { |
| String code = UtilXml.childElementValue(formElement, "Code"); |
| String description = UtilXml.childElementValue(formElement, "Description"); |
| |
| Element imageElement = UtilXml.firstChildElement(formElement, "Image"); |
| Element imageFormatElement = UtilXml.firstChildElement(imageElement, "ImageFormat"); |
| String formatCode = UtilXml.childElementValue(imageFormatElement, "Code"); |
| String imgString = UtilXml.childElementValue(imageElement, "GraphicImage"); |
| String imgStringDecoded = Base64.base64Decode(imgString); |
| shipmentPackageRouteSeg.set("internationalInvoice", imgStringDecoded); |
| shipmentPackageRouteSeg.store(); |
| String outFile = shipmentUpsSaveCertificationPath + "/InternationalInvoice" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".html"; |
| try { |
| FileOutputStream file = new FileOutputStream(outFile); |
| file.write(imgStringDecoded.getBytes()); |
| file.flush(); |
| file.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS International Invoice: [[[" + imgStringDecoded + "]]] to file: " + outFile, module); |
| } |
| } |
| String formGroupId = UtilXml.childElementValue(formElement, "FormGroupId"); |
| */ |
| shipmentPackageRouteSeg.store(); |
| } |
| |
| if (shipmentPackageRouteSegIter.hasNext()) { |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorMorePackageOnThisShipment", locale)); |
| |
| while (shipmentPackageRouteSegIter.hasNext()) { |
| GenericValue shipmentPackageRouteSeg = shipmentPackageRouteSegIter.next(); |
| errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorNoPackageResultsWereReturned", |
| UtilMisc.toMap("shipmentPackageSeqId", shipmentPackageRouteSeg.getString("shipmentPackageSeqId")), locale)); |
| } |
| } |
| |
| // save the High Value Report image if it exists |
| Element controlLogReceiptElement = UtilXml.firstChildElement(shipmentResultsElement, "ControlLogReceipt"); |
| if (controlLogReceiptElement != null) { |
| String fileString = UtilXml.childElementValue(controlLogReceiptElement, "GraphicImage"); |
| String fileStringDecoded = Base64.base64Decode(fileString); |
| if (fileStringDecoded != null) { |
| shipmentRouteSegment.set("upsHighValueReport", fileStringDecoded); |
| shipmentRouteSegment.store(); |
| String outFileName = shipmentUpsSaveCertificationPath + "/HighValueReport" + shipmentRouteSegment.getString("shipmentId") + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".html"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(fileStringDecoded.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS High Value Report data: [[[" + fileStringDecoded + "]]] to file: " + outFileName, module); |
| } |
| } |
| } |
| |
| // -=-=-=- Okay, now done with that, just return any extra info... |
| StringBuilder successString = new StringBuilder(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsShipmentAcceptSucceeded", locale)); |
| if (errorList.size() > 0) { |
| // this shouldn't happen much, but handle it anyway |
| successString.append(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsShipmentAcceptError", locale)); |
| Iterator<Object> errorListIter = errorList.iterator(); |
| while (errorListIter.hasNext()) { |
| successString.append(errorListIter.next()); |
| if (errorListIter.hasNext()) { |
| successString.append(", "); |
| } |
| } |
| } |
| return ServiceUtil.returnSuccess(successString.toString()); |
| } else { |
| errorList.add(0, UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentAcceptFailed", locale)); |
| return ServiceUtil.returnError(errorList); |
| } |
| } |
| |
| public static Map<String, Object> upsVoidShipment(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| Locale locale = (Locale) context.get("locale"); |
| |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| String voidShipmentResponseString = null; |
| |
| try { |
| //GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne(); |
| GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services |
| if (!"SHRSCS_CONFIRMED".equals(shipmentRouteSegment.getString("carrierServiceStatusId")) && |
| !"SHRSCS_ACCEPTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentStatusMustBeConfirmedOrAccepted", |
| UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId, "shipmentRouteSegmentStatus", |
| shipmentRouteSegment.getString("carrierServiceStatusId")), locale)); |
| } |
| |
| if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingIdNumber"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsTrackingIdNumberWasNotSet", locale)); |
| } |
| |
| Document voidShipmentRequestDoc = UtilXml.makeEmptyXmlDocument("VoidShipmentRequest"); |
| Element voidShipmentRequestElement = voidShipmentRequestDoc.getDocumentElement(); |
| voidShipmentRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element requestElement = UtilXml.addChildElement(voidShipmentRequestElement, "Request", voidShipmentRequestDoc); |
| |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", voidShipmentRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Void / 1", voidShipmentRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", voidShipmentRequestDoc); |
| |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "Void", voidShipmentRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", "1", voidShipmentRequestDoc); |
| |
| UtilXml.addChildElementValue(voidShipmentRequestElement, "ShipmentIdentificationNumber", shipmentRouteSegment.getString("trackingIdNumber"), voidShipmentRequestDoc); |
| |
| String voidShipmentRequestString = null; |
| try { |
| voidShipmentRequestString = UtilXml.writeXmlDocument(voidShipmentRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the VoidShipmentRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorVoidShipmentRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| // send ShipmentConfirmRequest String |
| // get ShipmentConfirmResponse String back |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(voidShipmentRequestString); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsVoidShipmentRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(xmlString.toString().getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| try { |
| voidShipmentResponseString = sendUpsRequest("Void", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service Void: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingVoid", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsVoidShipmentResponse" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(voidShipmentResponseString.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| Document voidShipmentResponseDocument = null; |
| try { |
| voidShipmentResponseDocument = UtilXml.readXmlDocument(voidShipmentResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingVoidShipmentResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingVoidShipmentResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the VoidShipmentResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingVoidShipmentResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return handleUpsVoidShipmentResponse(voidShipmentResponseDocument, shipmentRouteSegment, locale); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentVoid", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| |
| public static Map<String, Object> handleUpsVoidShipmentResponse(Document voidShipmentResponseDocument, GenericValue shipmentRouteSegment, Locale locale) throws GenericEntityException { |
| // process VoidShipmentResponse, update data as needed |
| Element voidShipmentResponseElement = voidShipmentResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(voidShipmentResponseElement, "Response"); |
| //Element responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference"); |
| //String responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext"); |
| //String responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion"); |
| |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| //String responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| // handle other response elements |
| Element statusElement = UtilXml.firstChildElement(voidShipmentResponseElement, "Status"); |
| |
| Element statusTypeElement = UtilXml.firstChildElement(statusElement, "StatusType"); |
| String statusTypeCode = UtilXml.childElementValue(statusTypeElement, "Code"); |
| String statusTypeDescription = UtilXml.childElementValue(statusTypeElement, "Description"); |
| |
| Element statusCodeElement = UtilXml.firstChildElement(statusElement, "StatusCode"); |
| String statusCodeCode = UtilXml.childElementValue(statusCodeElement, "Code"); |
| String statusCodeDescription = UtilXml.childElementValue(statusCodeElement, "Description"); |
| |
| if ("1".equals(responseStatusCode)) { |
| // set ShipmentRouteSegment carrierServiceStatusId after each UPS service applicable |
| shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_VOIDED"); |
| shipmentRouteSegment.store(); |
| |
| // -=-=-=- Okay, now done with that, just return any extra info... |
| StringBuilder successString = new StringBuilder(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentVoidSucceeded", |
| UtilMisc.toMap("statusTypeCode", statusTypeCode, "statusTypeDescription", statusTypeDescription, |
| "statusCodeCode", statusCodeCode, "statusCodeDescription", statusCodeDescription), locale)); |
| if (errorList.size() > 0) { |
| // this shouldn't happen much, but handle it anyway |
| successString.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentVoidError", locale)); |
| Iterator<Object> errorListIter = errorList.iterator(); |
| while (errorListIter.hasNext()) { |
| successString.append(errorListIter.next()); |
| if (errorListIter.hasNext()) { |
| successString.append(", "); |
| } |
| } |
| } |
| return ServiceUtil.returnSuccess(successString.toString()); |
| } else { |
| errorList.add(0, UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentVoidFailed", |
| UtilMisc.toMap("statusTypeCode", statusTypeCode, "statusTypeDescription", statusTypeDescription, |
| "statusCodeCode", statusCodeCode, "statusCodeDescription", statusCodeDescription), locale)); |
| return ServiceUtil.returnError(errorList); |
| } |
| } |
| |
| public static Map<String, Object> upsTrackShipment(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| Locale locale = (Locale) context.get("locale"); |
| |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| String trackResponseString = null; |
| |
| try { |
| //GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne(); |
| GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // add ShipmentRouteSegment carrierServiceStatusId, check before all UPS services |
| if (!"SHRSCS_ACCEPTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentStatusNotAccepted", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId, "shipmentRouteSegmentStatus", shipmentRouteSegment.getString("carrierServiceStatusId")), locale)); |
| } |
| |
| List<GenericValue> shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false); |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsPackageRouteSegsNotFound", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| if (UtilValidate.isEmpty(shipmentRouteSegment.getString("trackingIdNumber"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsTrackingIdNumberWasNotSet", locale)); |
| } |
| |
| Document trackRequestDoc = UtilXml.makeEmptyXmlDocument("TrackRequest"); |
| Element trackRequestElement = trackRequestDoc.getDocumentElement(); |
| trackRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element requestElement = UtilXml.addChildElement(trackRequestElement, "Request", trackRequestDoc); |
| |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", trackRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Track", trackRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", trackRequestDoc); |
| |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "Track", trackRequestDoc); |
| |
| UtilXml.addChildElementValue(trackRequestElement, "ShipmentIdentificationNumber", shipmentRouteSegment.getString("trackingIdNumber"), trackRequestDoc); |
| |
| String trackRequestString = null; |
| try { |
| trackRequestString = UtilXml.writeXmlDocument(trackRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the TrackRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorTrackRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| // send ShipmentConfirmRequest String |
| // get ShipmentConfirmResponse String back |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(trackRequestString); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsTrackRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(xmlString.toString().getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| try { |
| trackResponseString = sendUpsRequest("Track", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service Track: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingTrack", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsTrackResponseString" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(trackResponseString.getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| |
| Document trackResponseDocument = null; |
| try { |
| trackResponseDocument = UtilXml.readXmlDocument(trackResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the TrackResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTrackResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the TrackResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTrackResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the TrackResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingTrackResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return handleUpsTrackShipmentResponse(trackResponseDocument, shipmentRouteSegment, shipmentPackageRouteSegs, locale); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentTrack", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| |
| public static Map<String, Object> handleUpsTrackShipmentResponse(Document trackResponseDocument, GenericValue shipmentRouteSegment, |
| List<GenericValue> shipmentPackageRouteSegs, Locale locale) throws GenericEntityException { |
| // process TrackResponse, update data as needed |
| Element trackResponseElement = trackResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(trackResponseElement, "Response"); |
| //Element responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference"); |
| //String responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext"); |
| //String responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion"); |
| |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| //String responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| if ("1".equals(responseStatusCode)) { |
| // TODO: handle other response elements |
| //Element shipmentElement = UtilXml.firstChildElement(trackResponseElement, "Shipment"); |
| |
| //Element shipperElement = UtilXml.firstChildElement(shipmentElement, "Shipper"); |
| //String shipperNumber = UtilXml.childElementValue(shipperElement, "ShipperNumber"); |
| |
| //Element serviceElement = UtilXml.firstChildElement(shipmentElement, "Service"); |
| //String serviceCode = UtilXml.childElementValue(serviceElement, "Code"); |
| //String serviceDescription = UtilXml.childElementValue(serviceElement, "Description"); |
| |
| //String shipmentIdentificationNumber = UtilXml.childElementValue(shipmentElement, "ShipmentIdentificationNumber"); |
| |
| /* |
| List<? extends Element> packageElements = UtilXml.childElementList(shipmentElement, "Package"); |
| for (Element packageElement: packageElements) { |
| } |
| */ |
| /* |
| <Package> |
| <TrackingNumber>1Z12345E1512345676</TrackingNumber> |
| <Activity> |
| <ActivityLocation> |
| <Address> |
| <City>CLAKVILLE</City> |
| <StateProvinceCode>AK</StateProvinceCode> |
| <PostalCode>99901</PostalCode> |
| <CountryCode>US</CountryCode> |
| </Address> |
| <Code>MG</Code> |
| <Description>MC MAN</Description> |
| </ActivityLocation> |
| <Status> |
| <StatusType> |
| <Code>D</Code> |
| <Description>DELIVERED</Description> |
| </StatusType> |
| <StatusCode> |
| <Code>FS</Code> |
| </StatusCode> |
| </Status> |
| <Date>20020930</Date> |
| <Time>130900</Time> |
| </Activity> |
| <PackageWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>0.00</Weight> |
| </PackageWeight> |
| </Package> |
| * |
| */ |
| |
| |
| // -=-=-=- Okay, now done with that, just return any extra info... |
| StringBuilder successString = new StringBuilder(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentTrackSucceeded", locale)); |
| |
| if (errorList.size() > 0) { |
| // this shouldn't happen much, but handle it anyway |
| successString.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentTrackError", locale)); |
| Iterator<Object> errorListIter = errorList.iterator(); |
| while (errorListIter.hasNext()) { |
| successString.append(errorListIter.next()); |
| if (errorListIter.hasNext()) { |
| successString.append(", "); |
| } |
| } |
| } |
| return ServiceUtil.returnSuccess(successString.toString()); |
| } else { |
| errorList.add(0, UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentTrackFailed", locale)); |
| return ServiceUtil.returnError(errorList); |
| } |
| } |
| |
| public static Map<String, Object> upsRateInquire(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| Locale locale = (Locale) context.get("locale"); |
| // prepare the data |
| String shippingContactMechId = (String) context.get("shippingContactMechId"); |
| String shippingOriginContactMechId = (String) context.get("shippingOriginContactMechId"); |
| // obtain the ship-to address |
| GenericValue shipToAddress = null; |
| if (shippingContactMechId != null) { |
| try { |
| shipToAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", shippingContactMechId).queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } |
| if (shipToAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUnableFoundShipToAddresss", locale)); |
| } |
| |
| // obtain the ship from address if provided |
| GenericValue shipFromAddress = null; |
| if (shippingOriginContactMechId != null) { |
| try { |
| shipFromAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", shippingOriginContactMechId).queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUnableFoundShipToAddresssForDropShipping", locale)); |
| } |
| } |
| |
| GenericValue destCountryGeo = null; |
| try { |
| destCountryGeo = shipToAddress.getRelatedOne("CountryGeo", false); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| if (UtilValidate.isEmpty(destCountryGeo)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipToAddresssNoDestionationCountry", locale)); |
| } |
| Map<String, Object> cxt = UtilMisc.toMap("serviceConfigProps", context.get("serviceConfigProps"), "upsRateInquireMode", context.get("upsRateInquireMode"), |
| "productStoreId", context.get("productStoreId"), "carrierRoleTypeId", context.get("carrierRoleTypeId")); |
| cxt.put("carrierPartyId", context.get("carrierPartyId")); |
| cxt.put("shipmentMethodTypeId", context.get("shipmentMethodTypeId")); |
| cxt.put("shippingPostalCode", shipToAddress.getString("postalCode")); |
| cxt.put("shippingCountryCode",destCountryGeo.getString("geoCode")); |
| cxt.put("packageWeights", context.get("packageWeights")); |
| cxt.put("shippableItemInfo", context.get("shippableItemInfo")); |
| cxt.put("shippableTotal", context.get("shippableTotal")); |
| cxt.put("shippableQuantity", context.get("shippableQuantity")); |
| cxt.put("shippableWeight", context.get("shippableWeight")); |
| cxt.put("isResidentialAddress", context.get("isResidentialAddress")); |
| cxt.put("shipFromAddress", shipFromAddress); |
| cxt.put("shipmentGatewayConfigId", context.get("shipmentGatewayConfigId")); |
| try { |
| return dctx.getDispatcher().runSync("upsRateEstimateByPostalCode", cxt); |
| |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRateEstimateError", |
| UtilMisc.toMap("errorString", e.getMessage()), locale)); |
| } |
| } |
| |
| private static void splitEstimatePackages(DispatchContext dctx, Document requestDoc, Element shipmentElement, List<Map<String, Object>> shippableItemInfo, |
| BigDecimal maxWeight, BigDecimal minWeight, String totalWeightStr) { |
| List<Map<String, BigDecimal>> packages = ShipmentWorker.getPackageSplit(dctx, shippableItemInfo, maxWeight); |
| if (UtilValidate.isNotEmpty(packages)) { |
| for (Map<String, BigDecimal> packageMap: packages) { |
| addPackageElement(dctx, requestDoc, shipmentElement, shippableItemInfo, packageMap, minWeight); |
| } |
| } else { |
| // Add a dummy package |
| BigDecimal packageWeight = BigDecimal.ONE; |
| try { |
| packageWeight = new BigDecimal(totalWeightStr); |
| } catch (NumberFormatException e) { |
| Debug.logError(e, module); |
| } |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", requestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", requestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "00", requestDoc); |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", requestDoc); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", "" + packageWeight, requestDoc); |
| } |
| } |
| |
| private static void addPackageElement(DispatchContext dctx, Document requestDoc, Element shipmentElement, List<Map<String, Object>> shippableItemInfo, Map<String, BigDecimal> packageMap, BigDecimal minWeight) { |
| BigDecimal packageWeight = checkForDefaultPackageWeight(ShipmentWorker.calcPackageWeight(dctx,packageMap, shippableItemInfo, BigDecimal.ZERO), minWeight); |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", requestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", requestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "00", requestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Description", "Unknown PackagingType", requestDoc); |
| UtilXml.addChildElementValue(packageElement, "Description", "Package Description", requestDoc); |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", requestDoc); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", packageWeight.toPlainString(), requestDoc); |
| //If product is in shippable Package then it we should have one product per packagemap |
| if (packageMap.size() ==1) { |
| Iterator<String> i = packageMap.keySet().iterator(); |
| String productId = i.next(); |
| Map<String, Object> productInfo = ShipmentWorker.getProductItemInfo(shippableItemInfo, productId); |
| if (productInfo.get("inShippingBox") != null && ((String) productInfo.get("inShippingBox")).equalsIgnoreCase("Y") |
| && productInfo.get("shippingDepth") !=null && productInfo.get("shippingWidth") !=null && productInfo.get("shippingHeight") !=null) { |
| Element dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", requestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Length", productInfo.get("shippingDepth").toString(), requestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Width", productInfo.get("shippingWidth").toString(), requestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Height", productInfo.get("shippingHeight").toString(), requestDoc); |
| } |
| } |
| } |
| |
| private static void addPackageElement(Document requestDoc, Element shipmentElement, BigDecimal packageWeight) { |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", requestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", requestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "00", requestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Description", "Unknown PackagingType", requestDoc); |
| UtilXml.addChildElementValue(packageElement, "Description", "Package Description", requestDoc); |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", requestDoc); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", packageWeight.toString(), requestDoc); |
| } |
| |
| |
| private static BigDecimal checkForDefaultPackageWeight(BigDecimal weight, BigDecimal minWeight) { |
| return (weight.compareTo(BigDecimal.ZERO) > 0 && weight.compareTo(minWeight) > 0 ? weight : minWeight); |
| } |
| |
| public static Map<String, Object> handleUpsRateInquireResponse(Document rateResponseDocument, Locale locale) { |
| // process TrackResponse, update data as needed |
| Element rateResponseElement = rateResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(rateResponseElement, "Response"); |
| //Element responseTransactionReferenceElement = UtilXml.firstChildElement(responseElement, "TransactionReference"); |
| //String responseTransactionReferenceCustomerContext = UtilXml.childElementValue(responseTransactionReferenceElement, "CustomerContext"); |
| //String responseTransactionReferenceXpciVersion = UtilXml.childElementValue(responseTransactionReferenceElement, "XpciVersion"); |
| |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| //String responseStatusDescription = UtilXml.childElementValue(responseElement, "ResponseStatusDescription"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| if ("1".equals(responseStatusCode)) { |
| List<? extends Element> rates = UtilXml.childElementList(rateResponseElement, "RatedShipment"); |
| Map<String, BigDecimal> rateMap = FastMap.newInstance(); |
| BigDecimal firstRate = null; |
| if (UtilValidate.isEmpty(rates)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentRateNotAvailable", locale)); |
| } else { |
| for (Element element: rates) { |
| // get service |
| Element service = UtilXml.firstChildElement(element, "Service"); |
| String serviceCode = UtilXml.childElementValue(service, "Code"); |
| |
| // get total |
| Element totalCharges = UtilXml.firstChildElement(element, "TotalCharges"); |
| String totalString = UtilXml.childElementValue(totalCharges, "MonetaryValue"); |
| |
| rateMap.put(serviceCode, new BigDecimal(totalString)); |
| if (firstRate == null) { |
| firstRate = rateMap.get(serviceCode); |
| } |
| } |
| } |
| |
| Debug.logInfo("UPS Rate Map : " + rateMap, module); |
| |
| Map<String, Object> resp = ServiceUtil.returnSuccess(); |
| resp.put("upsRateCodeMap", rateMap); |
| resp.put("shippingEstimateAmount", firstRate); |
| return resp; |
| } else { |
| errorList.add(ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorStatusCode", |
| UtilMisc.toMap("responseStatusCode", responseStatusCode), locale))); |
| return ServiceUtil.returnFailure(errorList); |
| } |
| } |
| |
| public static Document createAccessRequestDocument(Delegator delegator, String shipmentGatewayConfigId, |
| String serviceConfigProps) { |
| Document accessRequestDocument = UtilXml.makeEmptyXmlDocument("AccessRequest"); |
| Element accessRequestElement = accessRequestDocument.getDocumentElement(); |
| String accessLicenseNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessLicenseNumber", serviceConfigProps, "shipment.ups.access.license.number", ""); |
| String userId = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessUserId", serviceConfigProps, "shipment.ups.access.user.id", ""); |
| String password = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessPassword", serviceConfigProps, "shipment.ups.access.password", ""); |
| UtilXml.addChildElementValue(accessRequestElement, "AccessLicenseNumber",accessLicenseNumber, accessRequestDocument); |
| UtilXml.addChildElementValue(accessRequestElement, "UserId", userId, accessRequestDocument); |
| UtilXml.addChildElementValue(accessRequestElement, "Password", password, accessRequestDocument); |
| return accessRequestDocument; |
| } |
| |
| public static void handleErrors(Element responseElement, List<Object> errorList, Locale locale) { |
| List<? extends Element> errorElements = UtilXml.childElementList(responseElement, "Error"); |
| for (Element errorElement: errorElements) { |
| StringBuilder errorMessageBuf = new StringBuilder(); |
| |
| String errorSeverity = UtilXml.childElementValue(errorElement, "ErrorSeverity"); |
| String errorCode = UtilXml.childElementValue(errorElement, "ErrorCode"); |
| String errorDescription = UtilXml.childElementValue(errorElement, "ErrorDescription"); |
| String minimumRetrySeconds = UtilXml.childElementValue(errorElement, "MinimumRetrySeconds"); |
| |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorMessage", |
| UtilMisc.toMap("errorCode", errorCode, "errorSeverity", errorSeverity, "errorDescription", errorDescription), locale)); |
| if (UtilValidate.isNotEmpty(minimumRetrySeconds)) { |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorMessageMinimumRetrySeconds", |
| UtilMisc.toMap("minimumRetrySeconds", minimumRetrySeconds), locale)); |
| } else { |
| errorMessageBuf.append(". "); |
| } |
| |
| List<? extends Element> errorLocationElements = UtilXml.childElementList(errorElement, "ErrorLocation"); |
| for (Element errorLocationElement: errorLocationElements) { |
| String errorLocationElementName = UtilXml.childElementValue(errorLocationElement, "ErrorLocationElementName"); |
| String errorLocationAttributeName = UtilXml.childElementValue(errorLocationElement, "ErrorLocationAttributeName"); |
| |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorWasAtElement", |
| UtilMisc.toMap("errorLocationElementName", errorLocationElementName), locale)); |
| |
| if (UtilValidate.isNotEmpty(errorLocationAttributeName)) { |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorWasAtElementAttribute", |
| UtilMisc.toMap("errorLocationAttributeName", errorLocationAttributeName), locale)); |
| } |
| |
| List<? extends Element> errorDigestElements = UtilXml.childElementList(errorLocationElement, "ErrorDigest"); |
| for (Element errorDigestElement: errorDigestElements) { |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorWasAtElementFullText", |
| UtilMisc.toMap("fullText", UtilXml.elementValue(errorDigestElement)), locale)); |
| } |
| } |
| |
| errorList.add(errorMessageBuf.toString()); |
| } |
| } |
| |
| /** |
| * Opens a URL to UPS and makes a request. |
| * @param upsService Name of the UPS service to invoke |
| * @param xmlString XML message to send |
| * @return XML string response from UPS |
| * @throws UpsConnectException |
| */ |
| public static String sendUpsRequest(String upsService, String xmlString, String shipmentGatewayConfigId, |
| String resource, Delegator delegator, Locale locale) throws UpsConnectException { |
| String conStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectUrl", resource, "shipment.ups.connect.url"); |
| if (conStr == null) { |
| throw new UpsConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsIncompleteConnectionURL", locale)); |
| } |
| |
| // need a ups service to call |
| if (upsService == null) { |
| throw new UpsConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsServiceNameCannotBeNull", locale)); |
| } |
| |
| // xmlString should contain the auth document at the beginning |
| // all documents require an <?xml version="1.0"?> header |
| if (xmlString == null) { |
| throw new UpsConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsXmlMessageCannotBeNull", locale)); |
| } |
| |
| // prepare the connect string |
| conStr = conStr.trim(); |
| if (!conStr.endsWith("/")) { |
| conStr = conStr + "/"; |
| } |
| conStr = conStr + upsService; |
| |
| String timeOutStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectTimeout", resource, "shipment.ups.connect.timeout", "60"); |
| int timeout = 60; |
| try { |
| timeout = Integer.parseInt(timeOutStr); |
| } catch (NumberFormatException e) { |
| Debug.logError(e, "Unable to set timeout to " + timeOutStr + " using default " + timeout); |
| } |
| |
| //Debug.logInfo("UPS Connect URL : " + conStr, module); |
| //Debug.logInfo("UPS XML String : " + xmlString, module); |
| |
| HttpClient http = new HttpClient(conStr); |
| http.setTimeout(timeout * 1000); |
| http.setAllowUntrusted(true); |
| String response = null; |
| try { |
| response = http.post(xmlString); |
| } catch (HttpClientException e) { |
| Debug.logError(e, "Problem connecting with UPS server [" + conStr + "]", module); |
| throw new UpsConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsURLConnectionProblem", |
| UtilMisc.toMap("exception", e), locale)); |
| } |
| |
| if (response == null) { |
| throw new UpsConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsReceivedNullResponse", locale)); |
| } |
| if (Debug.verboseOn()) Debug.logVerbose("UPS Response : " + response, module); |
| |
| return response; |
| } |
| |
| public static Map<String, Object> upsRateInquireByPostalCode(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| Locale locale = (Locale) context.get("locale"); |
| // prepare the data |
| String serviceConfigProps = (String) context.get("serviceConfigProps"); |
| String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId"); |
| String upsRateInquireMode = (String) context.get("upsRateInquireMode"); |
| String productStoreId = (String) context.get("productStoreId"); |
| String carrierRoleTypeId = (String) context.get("carrierRoleTypeId"); |
| String carrierPartyId = (String) context.get("carrierPartyId"); |
| String shipmentMethodTypeId = (String) context.get("shipmentMethodTypeId"); |
| // String shippingContactMechId = (String) context.get("shippingContactMechId"); |
| String shippingPostalCode = (String) context.get("shippingPostalCode"); |
| String shippingCountryCode = (String) context.get("shippingCountryCode"); |
| List<BigDecimal> packageWeights = UtilGenerics.checkList(context.get("packageWeights")); |
| List<Map<String, Object>> shippableItemInfo = UtilGenerics.checkList(context.get("shippableItemInfo")); |
| BigDecimal shippableTotal = (BigDecimal) context.get("shippableTotal"); |
| BigDecimal shippableQuantity = (BigDecimal) context.get("shippableQuantity"); |
| BigDecimal shippableWeight = (BigDecimal) context.get("shippableWeight"); |
| String isResidentialAddress = (String)context.get("isResidentialAddress"); |
| |
| // Important: DO NOT returnError here or you could trigger a transaction rollback and break other services. |
| if (UtilValidate.isEmpty(shippingPostalCode)) { |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsCannotRateEstimatePostalCodeMissing", locale)); |
| } |
| |
| if (shippableTotal == null) { |
| shippableTotal = BigDecimal.ZERO; |
| } |
| if (shippableQuantity == null) { |
| shippableQuantity = BigDecimal.ZERO; |
| } |
| if (shippableWeight == null) { |
| shippableWeight = BigDecimal.ZERO; |
| } |
| if (serviceConfigProps == null) { |
| serviceConfigProps = "shipment.properties"; |
| } |
| if (upsRateInquireMode == null || !"Shop".equals(upsRateInquireMode)) { |
| // can be either Rate || Shop |
| Debug.logWarning("No upsRateInquireMode set, defaulting to 'Rate'", module); |
| upsRateInquireMode = "Rate"; |
| } |
| |
| // grab the pickup type; if none is defined we will assume daily pickup |
| String pickupType = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "shipperPickupType", serviceConfigProps, "shipment.ups.shipper.pickup.type", "01"); |
| |
| // if we're drop shipping from a supplier, then the address is given to us |
| GenericValue shipFromAddress = (GenericValue) context.get("shipFromAddress"); |
| if (shipFromAddress == null) { |
| |
| // locate the ship-from address based on the product store's default facility |
| GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator); |
| if (productStore != null && productStore.get("inventoryFacilityId") != null) { |
| GenericValue facilityContactMech = ContactMechWorker.getFacilityContactMechByPurpose(delegator, productStore.getString("inventoryFacilityId"), UtilMisc.toList("SHIP_ORIG_LOCATION", "PRIMARY_LOCATION")); |
| if (facilityContactMech != null) { |
| try { |
| shipFromAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", facilityContactMech.getString("contactMechId")).queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } |
| } |
| } |
| if (shipFromAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUnableFoundShipToAddresss", locale)); |
| } |
| |
| // locate the service code |
| String serviceCode = null; |
| if (!"Shop".equals(upsRateInquireMode)) { |
| // locate the CarrierShipmentMethod record |
| GenericValue carrierShipmentMethod = null; |
| try { |
| carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod") |
| .where("shipmentMethodTypeId", shipmentMethodTypeId, "partyId", carrierPartyId, "roleTypeId", carrierRoleTypeId) |
| .queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| if (carrierShipmentMethod == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsUnableToLocateShippingMethodRequested", locale)); |
| } |
| |
| // service code is 'carrierServiceCode' |
| serviceCode = carrierShipmentMethod.getString("carrierServiceCode"); |
| |
| } |
| |
| // prepare the XML Document |
| Document rateRequestDoc = UtilXml.makeEmptyXmlDocument("RatingServiceSelectionRequest"); |
| Element rateRequestElement = rateRequestDoc.getDocumentElement(); |
| rateRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // XML request header |
| Element requestElement = UtilXml.addChildElement(rateRequestElement, "Request", rateRequestDoc); |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", rateRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Rating and Service", rateRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", rateRequestDoc); |
| |
| // RequestAction is always Rate, but RequestOption can be Rate to get a single rate or Shop for all shipping methods |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "Rate", rateRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", upsRateInquireMode, rateRequestDoc); |
| |
| // set the pickup type |
| Element pickupElement = UtilXml.addChildElement(rateRequestElement, "PickupType", rateRequestDoc); |
| UtilXml.addChildElementValue(pickupElement, "Code", pickupType, rateRequestDoc); |
| |
| // shipment info |
| Element shipmentElement = UtilXml.addChildElement(rateRequestElement, "Shipment", rateRequestDoc); |
| |
| // shipper info - (sub of shipment) |
| Element shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", rateRequestDoc); |
| Element shipperAddrElement = UtilXml.addChildElement(shipperElement, "Address", rateRequestDoc); |
| UtilXml.addChildElementValue(shipperAddrElement, "PostalCode", shipFromAddress.getString("postalCode"), rateRequestDoc); |
| try { |
| //If the warehouse you are shipping from its located in a country other than US, you need to supply its country code to UPS |
| UtilXml.addChildElementValue(shipperAddrElement, "CountryCode", shipFromAddress.getRelatedOne("CountryGeo", true).getString("geoCode"), rateRequestDoc); |
| } catch (GenericEntityException e) { |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| // ship-to info - (sub of shipment) |
| Element shiptoElement = UtilXml.addChildElement(shipmentElement, "ShipTo", rateRequestDoc); |
| Element shiptoAddrElement = UtilXml.addChildElement(shiptoElement, "Address", rateRequestDoc); |
| UtilXml.addChildElementValue(shiptoAddrElement, "PostalCode", shippingPostalCode, rateRequestDoc); |
| if (shippingCountryCode != null && !shippingCountryCode.equals("")) { |
| UtilXml.addChildElementValue(shiptoAddrElement, "CountryCode", shippingCountryCode, rateRequestDoc); |
| } |
| |
| if (isResidentialAddress != null && isResidentialAddress.equals("Y")) { |
| UtilXml.addChildElement(shiptoAddrElement, "ResidentialAddress", rateRequestDoc); |
| } |
| // requested service (code) - not used when in Shop mode |
| if (serviceCode != null) { |
| Element serviceElement = UtilXml.addChildElement(shipmentElement, "Service", rateRequestDoc); |
| UtilXml.addChildElementValue(serviceElement, "Code", serviceCode, rateRequestDoc); |
| } |
| |
| // package info |
| String maxWeightStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "maxEstimateWeight", serviceConfigProps, "shipment.ups.max.estimate.weight", "99"); |
| BigDecimal maxWeight = new BigDecimal("99"); |
| try { |
| maxWeight = new BigDecimal(maxWeightStr); |
| } catch (NumberFormatException e) { |
| maxWeight = new BigDecimal("99"); |
| } |
| String minWeightStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "minEstimateWeight", serviceConfigProps, "shipment.ups.min.estimate.weight", ".1"); |
| BigDecimal minWeight = new BigDecimal("0.1"); |
| try { |
| minWeight = new BigDecimal(minWeightStr); |
| } catch (NumberFormatException e) { |
| minWeight = new BigDecimal("0.1"); |
| } |
| |
| // Passing in a list of package weights overrides the calculation of same via shippableItemInfo |
| if (UtilValidate.isEmpty(packageWeights)) { |
| String totalWeightStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "minEstimateWeight", serviceConfigProps, "shipment.ups.min.estimate.weight", "1"); |
| splitEstimatePackages(dctx, rateRequestDoc, shipmentElement, shippableItemInfo, maxWeight, minWeight, totalWeightStr); |
| } else { |
| for (BigDecimal packageWeight: packageWeights) { |
| addPackageElement(rateRequestDoc, shipmentElement, packageWeight); |
| } |
| } |
| |
| // service options |
| UtilXml.addChildElement(shipmentElement, "ShipmentServiceOptions", rateRequestDoc); |
| |
| String rateRequestString = null; |
| try { |
| rateRequestString = UtilXml.writeXmlDocument(rateRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the RatingServiceSelectionRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorRatingServiceSelectionRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, serviceConfigProps); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // prepare the access/inquire request string |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(rateRequestString); |
| if (Debug.verboseOn()) Debug.logVerbose(xmlString.toString(), module); |
| // send the request |
| String rateResponseString = null; |
| try { |
| rateResponseString = sendUpsRequest("Rate", xmlString.toString(), shipmentGatewayConfigId, serviceConfigProps, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service Rate: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingRate", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| Debug.logVerbose(rateResponseString, module); |
| Document rateResponseDocument = null; |
| try { |
| rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| return handleUpsRateInquireResponse(rateResponseDocument, locale); |
| } |
| |
| public static Map<String, Object> upsAddressValidation(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| Locale locale = (Locale) context.get("locale"); |
| String city = (String) context.get("city"); |
| String stateProvinceGeoId = (String) context.get("stateProvinceGeoId"); |
| String postalCode = (String) context.get("postalCode"); |
| |
| String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId"); |
| String resource = (String) context.get("serviceConfigProps"); |
| |
| if (UtilValidate.isEmpty(city) && UtilValidate.isEmpty(postalCode)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsAddressValidationRequireCityOrPostalCode", locale)); |
| } |
| |
| // prepare the XML Document |
| Document avRequestDoc = UtilXml.makeEmptyXmlDocument("AddressValidationRequest"); |
| Element avRequestElement = avRequestDoc.getDocumentElement(); |
| avRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // XML request header |
| Element requestElement = UtilXml.addChildElement(avRequestElement, "Request", avRequestDoc); |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", avRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Rating and Service", avRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", avRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "AV", avRequestDoc); |
| |
| // Address |
| Element addressElement = UtilXml.addChildElement(avRequestElement, "Address", avRequestDoc); |
| if (UtilValidate.isNotEmpty(city)) { |
| UtilXml.addChildElementValue(addressElement, "City", city, avRequestDoc); |
| } |
| if (UtilValidate.isNotEmpty(stateProvinceGeoId)) { |
| UtilXml.addChildElementValue(addressElement, "StateProvinceCode", stateProvinceGeoId, avRequestDoc); |
| } |
| if (UtilValidate.isNotEmpty(postalCode)) { |
| UtilXml.addChildElementValue(addressElement, "PostalCode", postalCode, avRequestDoc); |
| } |
| |
| String avRequestString = null; |
| try { |
| avRequestString = UtilXml.writeXmlDocument(avRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AddressValidationRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorAddressValidationRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorShipmentAcceptRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // prepare the request string |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(avRequestString); |
| Debug.logInfo(xmlString.toString(), module); |
| |
| // send the request |
| String avResponseString = null; |
| try { |
| avResponseString = sendUpsRequest("AV", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorSendingAddressVerification", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| Debug.logInfo(avResponseString, module); |
| |
| Document avResponseDocument = null; |
| try { |
| avResponseDocument = UtilXml.readXmlDocument(avResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the UPS response: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorParsingAddressVerificationResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the UPS response: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorParsingAddressVerificationResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the UPS response: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorParsingAddressVerificationResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return handleUpsAddressValidationResponse(avResponseDocument, locale); |
| |
| } |
| |
| public static Map<String, Object> handleUpsAddressValidationResponse(Document rateResponseDocument, Locale locale) { |
| Element avResponseElement = rateResponseDocument.getDocumentElement(); |
| Element responseElement = UtilXml.firstChildElement(avResponseElement, "Response"); |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| |
| if ("1".equals(responseStatusCode)) { |
| List<Map<String, String>> matches = FastList.newInstance(); |
| |
| List<? extends Element> avResultList = UtilXml.childElementList(avResponseElement, "AddressValidationResult"); |
| // TODO: return error if there are no matches? |
| if (UtilValidate.isNotEmpty(avResultList)) { |
| for (Element avResultElement: avResultList) { |
| Map<String, String> match = FastMap.newInstance(); |
| |
| match.put("Rank", UtilXml.childElementValue(avResultElement, "Rank")); |
| match.put("Quality", UtilXml.childElementValue(avResultElement, "Quality")); |
| |
| Element addressElement = UtilXml.firstChildElement(avResultElement, "Address"); |
| match.put("City", UtilXml.childElementValue(addressElement, "City")); |
| match.put("StateProvinceCode", UtilXml.childElementValue(addressElement, "StateProvinceCode")); |
| |
| match.put("PostalCodeLowEnd", UtilXml.childElementValue(avResultElement, "PostalCodeLowEnd")); |
| match.put("PostalCodeHighEnd", UtilXml.childElementValue(avResultElement, "PostalCodeHighEnd")); |
| |
| matches.add(match); |
| } |
| } |
| |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| result.put("matches", matches); |
| return result; |
| } else { |
| errorList.add(ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorStatusCode", |
| UtilMisc.toMap("responseStatusCode", responseStatusCode), locale))); |
| return ServiceUtil.returnError(errorList); |
| } |
| } |
| |
| public static Map<String, Object> upsEmailReturnLabel(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| LocalDispatcher dispatcher = dctx.getDispatcher(); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| Locale locale = (Locale) context.get("locale"); |
| GenericValue userLogin = (GenericValue) context.get("userLogin"); |
| |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| boolean shipmentUpsSaveCertificationInfo = "true".equals(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertInfo", resource, "shipment.ups.save.certification.info", "true")); |
| String shipmentUpsSaveCertificationPath = FlexibleStringExpander.expandString(getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "saveCertPath", resource, "shipment.ups.save.certification.path", ""), context); |
| File shipmentUpsSaveCertificationFile = null; |
| if (shipmentUpsSaveCertificationInfo) { |
| shipmentUpsSaveCertificationFile = new File(shipmentUpsSaveCertificationPath); |
| if (!shipmentUpsSaveCertificationFile.exists()) { |
| shipmentUpsSaveCertificationFile.mkdirs(); |
| } |
| } |
| |
| //Shipment Confirm request |
| String shipmentConfirmResponseString = null; |
| |
| try { |
| GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne(); |
| if (shipment == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "ProductShipmentNotFoundId", locale) + " " + shipmentId); |
| } |
| GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| if (shipmentRouteSegment == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "ProductShipmentRouteSegmentNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // Get Origin Info |
| GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false); |
| if (originPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber", false); |
| if (originTelecomNumber == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginTelecomNumberNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| String originPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !"001".equals(originTelecomNumber.getString("countryCode"))) { |
| originPhoneNumber = originTelecomNumber.getString("countryCode") + originPhoneNumber; |
| } |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, "-", ""); |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, " ", ""); |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo", false); |
| if (originCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| // Get Dest Info |
| GenericValue destPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false); |
| if (destPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentDestPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false); |
| if (destTelecomNumber == null) { |
| String missingErrMsg = "DestTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId; |
| Debug.logError(missingErrMsg, module); |
| } |
| String destPhoneNumber = null; |
| if (destTelecomNumber != null) { |
| destPhoneNumber = destTelecomNumber.getString("areaCode") + destTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(destTelecomNumber.getString("countryCode")) && !"001".equals(destTelecomNumber.getString("countryCode"))) { |
| destPhoneNumber = destTelecomNumber.getString("countryCode") + destPhoneNumber; |
| } |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, "-", ""); |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, " ", ""); |
| } |
| |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue destCountryGeo = destPostalAddress.getRelatedOne("CountryGeo", false); |
| if (destCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentDestCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod") |
| .where("partyId", shipmentRouteSegment.get("carrierPartyId"), "roleTypeId", "CARRIER", "shipmentMethodTypeId", shipmentRouteSegment.get("shipmentMethodTypeId")) |
| .queryOne(); |
| if (carrierShipmentMethod == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentCarrierShipmentMethodNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "carrierPartyId", shipmentRouteSegment.get("carrierPartyId"), "shipmentMethodTypeId", shipmentRouteSegment.get("shipmentMethodTypeId")), locale)); |
| } |
| |
| Map<String, Object> destEmail = dispatcher.runSync("getPartyEmail", UtilMisc.toMap("partyId", shipment.get("partyIdTo"), "userLogin", userLogin)); |
| String recipientEmail = null; |
| if (UtilValidate.isNotEmpty(destEmail.get("emailAddress"))) { |
| recipientEmail = (String) destEmail.get("emailAddress"); |
| } |
| String senderEmail = null; |
| Map<String, Object> originEmail = dispatcher.runSync("getPartyEmail", UtilMisc.toMap("partyId", shipment.get("partyIdFrom"), "userLogin", userLogin)); |
| if (UtilValidate.isNotEmpty(originEmail.get("emailAddress"))) { |
| senderEmail = (String) originEmail.get("emailAddress"); |
| } |
| |
| List<GenericValue> shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false); |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsPackageRouteSegsNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| // Okay, start putting the XML together... |
| Document shipmentConfirmRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentConfirmRequest"); |
| Element shipmentConfirmRequestElement = shipmentConfirmRequestDoc.getDocumentElement(); |
| shipmentConfirmRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element requestElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Request", shipmentConfirmRequestDoc); |
| |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "ShipConfirm", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", "nonvalidate", shipmentConfirmRequestDoc); |
| |
| // Top Level Element: Shipment |
| Element shipmentElement = UtilXml.addChildElement(shipmentConfirmRequestElement, "Shipment", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipmentElement, "Description", "Goods for Shipment " + shipment.get("shipmentId"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: ReturnService |
| Element returnServiceElement = UtilXml.addChildElement(shipmentElement, "ReturnService", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(returnServiceElement, "Code", String.valueOf(returnServiceCode), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: Shipper |
| String shipperNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "shipperNumber", resource, "shipment.ups.shipper.number", ""); |
| Element shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "Name", UtilValidate.isNotEmpty(originPostalAddress.getString("toName")) ? originPostalAddress.getString("toName"): "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "AttentionName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "ShipperNumber", shipperNumber, shipmentConfirmRequestDoc); |
| |
| Element shipperAddressElement = UtilXml.addChildElement(shipperElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| UtilXml.addChildElementValue(shipperAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: ShipTo |
| Element shipToElement = UtilXml.addChildElement(shipmentElement, "ShipTo", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "CompanyName", UtilValidate.isNotEmpty(destPostalAddress.getString("toName")) ? destPostalAddress.getString("toName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "AttentionName", UtilValidate.isNotEmpty(destPostalAddress.getString("attnName")) ? destPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPhoneNumber)) { |
| UtilXml.addChildElementValue(shipToElement, "PhoneNumber", destPhoneNumber, shipmentConfirmRequestDoc); |
| } |
| Element shipToAddressElement = UtilXml.addChildElement(shipToElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine1", destPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(destPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine2", destPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| UtilXml.addChildElementValue(shipToAddressElement, "City", destPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "StateProvinceCode", destPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "PostalCode", destPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "CountryCode", destCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("homeDeliveryType"))) { |
| UtilXml.addChildElement(shipToAddressElement, "ResidentialAddress", shipmentConfirmRequestDoc); |
| } |
| |
| // Child of Shipment: ShipFrom |
| Element shipFromElement = UtilXml.addChildElement(shipmentElement, "ShipFrom", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "CompanyName", UtilValidate.isNotEmpty(originPostalAddress.getString("toName")) ? originPostalAddress.getString("toName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "AttentionName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "PhoneNumber", originPhoneNumber, shipmentConfirmRequestDoc); |
| Element shipFromAddressElement = UtilXml.addChildElement(shipFromElement, "Address", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine1", originPostalAddress.getString("address1"), shipmentConfirmRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine2", originPostalAddress.getString("address2"), shipmentConfirmRequestDoc); |
| } |
| UtilXml.addChildElementValue(shipFromAddressElement, "City", originPostalAddress.getString("city"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: PaymentInformation |
| Element paymentInformationElement = UtilXml.addChildElement(shipmentElement, "PaymentInformation", shipmentConfirmRequestDoc); |
| |
| String thirdPartyAccountNumber = shipmentRouteSegment.getString("thirdPartyAccountNumber"); |
| |
| if (UtilValidate.isEmpty(thirdPartyAccountNumber)) { |
| // Paid by shipper |
| Element prepaidElement = UtilXml.addChildElement(paymentInformationElement, "Prepaid", shipmentConfirmRequestDoc); |
| Element billShipperElement = UtilXml.addChildElement(prepaidElement, "BillShipper", shipmentConfirmRequestDoc); |
| |
| // fill in BillShipper AccountNumber element from properties file |
| String billShipperAccountNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "billShipperAccountNumber", resource, "shipment.ups.bill.shipper.account.number", ""); |
| UtilXml.addChildElementValue(billShipperElement, "AccountNumber", billShipperAccountNumber, shipmentConfirmRequestDoc); |
| } |
| |
| // Child of Shipment: Service |
| Element serviceElement = UtilXml.addChildElement(shipmentElement, "Service", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(serviceElement, "Code", carrierShipmentMethod.getString("carrierServiceCode"), shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: ShipmentServiceOptions |
| String defaultReturnLabelMemo = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "defaultReturnLabelMemo", resource, "shipment.ups.default.returnLabel.memo", ""); |
| String defaultReturnLabelSubject = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "defaultReturnLabelSubject", resource, "shipment.ups.default.returnLabel.subject", ""); |
| Element shipmentServiceOptionsElement = UtilXml.addChildElement(shipmentElement, "ShipmentServiceOptions", shipmentConfirmRequestDoc); |
| Element labelDeliveryElement = UtilXml.addChildElement(shipmentServiceOptionsElement, "LabelDelivery", shipmentConfirmRequestDoc); |
| Element emailMessageElement = UtilXml.addChildElement(labelDeliveryElement, "EMailMessage", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(emailMessageElement, "EMailAddress", recipientEmail, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(emailMessageElement, "FromEMailAddress", senderEmail, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(emailMessageElement, "FromName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(emailMessageElement, "Memo", defaultReturnLabelMemo, shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(emailMessageElement, "Subject", defaultReturnLabelSubject, shipmentConfirmRequestDoc); |
| |
| // Child of Shipment: Package |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", shipmentConfirmRequestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "02", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(packageElement, "Description", "Package Description", shipmentConfirmRequestDoc); |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", shipmentConfirmRequestDoc); |
| Element packageWeightUnitOfMeasurementElement = UtilXml.addChildElement(packageElement, "UnitOfMeasurement", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", "LBS", shipmentConfirmRequestDoc); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", EntityUtilProperties.getPropertyValue("shipment", "shipment.default.weight.value", delegator), shipmentConfirmRequestDoc); |
| |
| String shipmentConfirmRequestString = null; |
| try { |
| shipmentConfirmRequestString = UtilXml.writeXmlDocument(shipmentConfirmRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the ShipmentConfirmRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorShipmentConfirmRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| // send ShipmentConfirmRequest String |
| // get ShipmentConfirmResponse String back |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(shipmentConfirmRequestString); |
| try { |
| shipmentConfirmResponseString = sendUpsRequest("ShipConfirm", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service ShipConfirm: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingShipConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| Document shipmentConfirmResponseDocument = null; |
| try { |
| shipmentConfirmResponseDocument = UtilXml.readXmlDocument(shipmentConfirmResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the ShipmentConfirmResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingShipmentConfirm", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| Element shipmentConfirmResponseElement = shipmentConfirmResponseDocument.getDocumentElement(); |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(shipmentConfirmResponseElement, "Response"); |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| if (!"1".equals(responseStatusCode)) { |
| errorList.add(0, UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentConfirmFailedForReturnShippingLabel", locale)); |
| return ServiceUtil.returnError(errorList); |
| } |
| |
| //Shipment Accept Request follows |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsPackageRouteSegsNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| String shipmentDigest = UtilXml.childElementValue(shipmentConfirmResponseElement, "ShipmentDigest"); |
| if (UtilValidate.isEmpty(shipmentDigest)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsTrackingDigestWasNotSet", locale)); |
| } |
| |
| Document shipmentAcceptRequestDoc = UtilXml.makeEmptyXmlDocument("ShipmentAcceptRequest"); |
| Element shipmentAcceptRequestElement = shipmentAcceptRequestDoc.getDocumentElement(); |
| shipmentAcceptRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // Top Level Element: Request |
| Element acceptRequestElement = UtilXml.addChildElement(shipmentAcceptRequestElement, "Request", shipmentAcceptRequestDoc); |
| |
| Element acceptTransactionReferenceElement = UtilXml.addChildElement(acceptRequestElement, "TransactionReference", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(acceptTransactionReferenceElement, "CustomerContext", "ShipAccept / 01", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(acceptTransactionReferenceElement, "XpciVersion", "1.0001", shipmentAcceptRequestDoc); |
| |
| UtilXml.addChildElementValue(acceptRequestElement, "RequestAction", "ShipAccept", shipmentAcceptRequestDoc); |
| UtilXml.addChildElementValue(acceptRequestElement, "RequestOption", "01", shipmentAcceptRequestDoc); |
| |
| UtilXml.addChildElementValue(shipmentAcceptRequestElement, "ShipmentDigest", shipmentDigest, shipmentAcceptRequestDoc); |
| |
| String shipmentAcceptRequestString = null; |
| try { |
| shipmentAcceptRequestString = UtilXml.writeXmlDocument(shipmentAcceptRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the ShipmentAcceptRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorShipmentAcceptRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document acceptAccessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String acceptAccessRequestString = null; |
| try { |
| acceptAccessRequestString = UtilXml.writeXmlDocument(acceptAccessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // connect to UPS server, send AccessRequest to auth |
| StringBuilder acceptXmlString = new StringBuilder(); |
| acceptXmlString.append(acceptAccessRequestString); |
| acceptXmlString.append(shipmentAcceptRequestString); |
| |
| if (shipmentUpsSaveCertificationInfo) { |
| String outFileName = shipmentUpsSaveCertificationPath + "/UpsShipmentAcceptRequest" + shipmentId + "_" + shipmentRouteSegment.getString("shipmentRouteSegmentId") + ".xml"; |
| try { |
| FileOutputStream fileOut = new FileOutputStream(outFileName); |
| fileOut.write(xmlString.toString().getBytes()); |
| fileOut.flush(); |
| fileOut.close(); |
| } catch (IOException e) { |
| Debug.logInfo(e, "Could not save UPS XML file: [[[" + xmlString.toString() + "]]] to file: " + outFileName, module); |
| } |
| } |
| try { |
| sendUpsRequest("ShipAccept", acceptXmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service ShipAccept: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingShipAccept", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentAccept", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentConfirm", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| return ServiceUtil.returnSuccess(UtilProperties.getMessage("OrderUiLabels", "OrderReturnLabelEmailSuccessful", locale)); |
| } |
| |
| public static Map<String, Object> upsShipmentAlternateRatesInquiry(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| |
| // prepare the data |
| String upsRateInquireMode = (String) context.get("upsRateInquireMode"); |
| String shipmentId = (String) context.get("shipmentId"); |
| String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId"); |
| Locale locale = (Locale) context.get("locale"); |
| String rateResponseString = null; |
| String productStoreId = (String) context.get("productStoreId"); |
| List<Map<String, Object>> shippingRates = FastList.newInstance(); |
| GenericValue shipmentRouteSegment = null; |
| Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale); |
| String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId"); |
| String resource = (String) shipmentGatewayConfig.get("configProps"); |
| if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsGatewayNotAvailable", locale)); |
| } |
| |
| try { |
| if (shipmentRouteSegmentId != null) { |
| shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne(); |
| } else { |
| shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where(EntityCondition.makeCondition("shipmentId", EntityOperator.EQUALS, shipmentId)).queryFirst(); |
| } |
| |
| if (shipmentRouteSegment == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "ProductShipmentRouteSegmentNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| shipmentRouteSegmentId = shipmentRouteSegment.getString("shipmentRouteSegmentId"); |
| |
| if (!"UPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNotRouteSegmentCarrier", UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // Get Origin Info |
| GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false); |
| if (originPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber", false); |
| if (originTelecomNumber == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginTelecomNumberNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| String originPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !"001".equals(originTelecomNumber.getString("countryCode"))) { |
| originPhoneNumber = originTelecomNumber.getString("countryCode") + originPhoneNumber; |
| } |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, "-", ""); |
| originPhoneNumber = StringUtil.replaceString(originPhoneNumber, " ", ""); |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo", false); |
| if (originCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentOriginCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| // Get Dest Info |
| GenericValue destPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false); |
| if (destPostalAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentDestPostalAddressNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false); |
| if (destTelecomNumber == null) { |
| String missingErrMsg = "DestTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId; |
| Debug.logError(missingErrMsg, module); |
| // for now we won't require the dest phone number, but is it required? |
| //return ServiceUtil.returnError(missingErrMsg); |
| } |
| String destPhoneNumber = null; |
| if (destTelecomNumber != null) { |
| destPhoneNumber = destTelecomNumber.getString("areaCode") + destTelecomNumber.getString("contactNumber"); |
| // don't put on country code if not specified or is the US country code (UPS wants it this way) |
| if (UtilValidate.isNotEmpty(destTelecomNumber.getString("countryCode")) && !"001".equals(destTelecomNumber.getString("countryCode"))) { |
| destPhoneNumber = destTelecomNumber.getString("countryCode") + destPhoneNumber; |
| } |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, "-", ""); |
| destPhoneNumber = StringUtil.replaceString(destPhoneNumber, " ", ""); |
| } |
| |
| // lookup the two letter country code (in the geoCode field) |
| GenericValue destCountryGeo = destPostalAddress.getRelatedOne("CountryGeo", false); |
| if (destCountryGeo == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsRouteSegmentDestCountryGeoNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| |
| // grab the pickup type; if none is defined we will assume daily pickup |
| String pickupType = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "shipperPickupType", resource, "shipment.ups.shipper.pickup.type", "01"); |
| |
| // grab the customer classification; if none is defined we will assume daily pickup |
| String customerClassification = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "customerClassification", resource, "shipment.ups.customerclassification", "01"); |
| |
| // should be shop to get estimates for all the possible shipping method of UPS |
| upsRateInquireMode = "Shop"; |
| |
| // prepare the XML Document |
| Document rateRequestDoc = UtilXml.makeEmptyXmlDocument("RatingServiceSelectionRequest"); |
| Element rateRequestElement = rateRequestDoc.getDocumentElement(); |
| rateRequestElement.setAttribute("xml:lang", "en-US"); |
| |
| // XML request header |
| Element requestElement = UtilXml.addChildElement(rateRequestElement, "Request", rateRequestDoc); |
| Element transactionReferenceElement = UtilXml.addChildElement(requestElement, "TransactionReference", rateRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "CustomerContext", "Rating and Service", rateRequestDoc); |
| UtilXml.addChildElementValue(transactionReferenceElement, "XpciVersion", "1.0001", rateRequestDoc); |
| |
| // RequestAction is always Rate, but RequestOption can be Rate to get a single rate or Shop for all shipping methods |
| UtilXml.addChildElementValue(requestElement, "RequestAction", "Rate", rateRequestDoc); |
| UtilXml.addChildElementValue(requestElement, "RequestOption", upsRateInquireMode, rateRequestDoc); |
| |
| // set the pickup type |
| Element pickupElement = UtilXml.addChildElement(rateRequestElement, "PickupType", rateRequestDoc); |
| UtilXml.addChildElementValue(pickupElement, "Code", pickupType, rateRequestDoc); |
| |
| Element customerClassificationElement = UtilXml.addChildElement(rateRequestElement, "CustomerClassification", rateRequestDoc); |
| UtilXml.addChildElementValue(customerClassificationElement, "Code", customerClassification, rateRequestDoc); |
| |
| // shipment info |
| Element shipmentElement = UtilXml.addChildElement(rateRequestElement, "Shipment", rateRequestDoc); |
| //Element rateInformationElement = UtilXml.addChildElement(shipmentElement, "RateInformation", rateRequestDoc); |
| //Element negotiatedRatesIndicatorElement = UtilXml.addChildElement(rateInformationElement, "NegotiatedRatesIndicator", rateRequestDoc); |
| |
| Element shipperElement = UtilXml.addChildElement(shipmentElement, "Shipper", rateRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "Name", UtilValidate.isNotEmpty(originPostalAddress.getString("toName")) ? originPostalAddress.getString("toName") : "", rateRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "AttentionName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", rateRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "PhoneNumber", originPhoneNumber, rateRequestDoc); |
| UtilXml.addChildElementValue(shipperElement, "ShipperNumber", EntityUtilProperties.getPropertyValue("shipment", "shipment.ups.shipper.number", delegator), rateRequestDoc); |
| |
| Element shipperAddressElement = UtilXml.addChildElement(shipperElement, "Address", rateRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine1", originPostalAddress.getString("address1"), rateRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipperAddressElement, "AddressLine2", originPostalAddress.getString("address2"), rateRequestDoc); |
| } |
| |
| UtilXml.addChildElementValue(shipperAddressElement, "City", originPostalAddress.getString("city"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipperAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), rateRequestDoc); |
| |
| // Child of Shipment: ShipTo |
| Element shipToElement = UtilXml.addChildElement(shipmentElement, "ShipTo", rateRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "CompanyName", UtilValidate.isNotEmpty(destPostalAddress.getString("toName")) ? destPostalAddress.getString("toName") : "", rateRequestDoc); |
| UtilXml.addChildElementValue(shipToElement, "AttentionName", UtilValidate.isNotEmpty(destPostalAddress.getString("attnName")) ? destPostalAddress.getString("attnName") : "", rateRequestDoc); |
| if (UtilValidate.isNotEmpty(destPhoneNumber)) { |
| UtilXml.addChildElementValue(shipToElement, "PhoneNumber", destPhoneNumber, rateRequestDoc); |
| } |
| Element shipToAddressElement = UtilXml.addChildElement(shipToElement, "Address", rateRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine1", destPostalAddress.getString("address1"), rateRequestDoc); |
| if (UtilValidate.isNotEmpty(destPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipToAddressElement, "AddressLine2", destPostalAddress.getString("address2"), rateRequestDoc); |
| } |
| |
| UtilXml.addChildElementValue(shipToAddressElement, "City", destPostalAddress.getString("city"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "StateProvinceCode", destPostalAddress.getString("stateProvinceGeoId"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "PostalCode", destPostalAddress.getString("postalCode"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipToAddressElement, "CountryCode", destCountryGeo.getString("geoCode"), rateRequestDoc); |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("homeDeliveryType"))) { |
| UtilXml.addChildElement(shipToAddressElement, "ResidentialAddress", rateRequestDoc); |
| } |
| |
| // Child of Shipment: ShipFrom |
| Element shipFromElement = UtilXml.addChildElement(shipmentElement, "ShipFrom", rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "CompanyName", UtilValidate.isNotEmpty(originPostalAddress.getString("toName")) ? originPostalAddress.getString("toName") : "", rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "AttentionName", UtilValidate.isNotEmpty(originPostalAddress.getString("attnName")) ? originPostalAddress.getString("attnName") : "", rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromElement, "PhoneNumber", originPhoneNumber, rateRequestDoc); |
| Element shipFromAddressElement = UtilXml.addChildElement(shipFromElement, "Address", rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine1", originPostalAddress.getString("address1"), rateRequestDoc); |
| if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) { |
| UtilXml.addChildElementValue(shipFromAddressElement, "AddressLine2", originPostalAddress.getString("address2"), rateRequestDoc); |
| } |
| UtilXml.addChildElementValue(shipFromAddressElement, "City", originPostalAddress.getString("city"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "StateProvinceCode", originPostalAddress.getString("stateProvinceGeoId"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "PostalCode", originPostalAddress.getString("postalCode"), rateRequestDoc); |
| UtilXml.addChildElementValue(shipFromAddressElement, "CountryCode", originCountryGeo.getString("geoCode"), rateRequestDoc); |
| |
| List<GenericValue> shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false); |
| if (UtilValidate.isEmpty(shipmentPackageRouteSegs)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsPackageRouteSegsNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale)); |
| } |
| for (GenericValue shipmentPackageRouteSeg :shipmentPackageRouteSegs) { |
| |
| GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false); |
| GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType", false); |
| List<GenericValue> carrierShipmentBoxTypes = shipmentPackage.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "UPS"), null, false); |
| GenericValue carrierShipmentBoxType = null; |
| if (carrierShipmentBoxTypes.size() > 0) { |
| carrierShipmentBoxType = carrierShipmentBoxTypes.get(0); |
| } |
| |
| Element packageElement = UtilXml.addChildElement(shipmentElement, "Package", rateRequestDoc); |
| Element packagingTypeElement = UtilXml.addChildElement(packageElement, "PackagingType", rateRequestDoc); |
| if (carrierShipmentBoxType != null && carrierShipmentBoxType.get("packagingTypeCode") != null) { |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", carrierShipmentBoxType.getString("packagingTypeCode"), rateRequestDoc); |
| } else { |
| // default to "02", plain old Package |
| UtilXml.addChildElementValue(packagingTypeElement, "Code", "02", rateRequestDoc); |
| } |
| if (shipmentBoxType != null) { |
| Element dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", rateRequestDoc); |
| Element unitOfMeasurementElement = UtilXml.addChildElement(dimensionsElement, "UnitOfMeasurement", rateRequestDoc); |
| GenericValue dimensionUom = shipmentBoxType.getRelatedOne("DimensionUom", false); |
| if (dimensionUom != null) { |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", dimensionUom.getString("abbreviation").toUpperCase(), rateRequestDoc); |
| } else { |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", "IN", rateRequestDoc); |
| } |
| BigDecimal boxLength = shipmentBoxType.getBigDecimal("boxLength"); |
| BigDecimal boxWidth = shipmentBoxType.getBigDecimal("boxWidth"); |
| BigDecimal boxHeight = shipmentBoxType.getBigDecimal("boxHeight"); |
| UtilXml.addChildElementValue(dimensionsElement, "Length", UtilValidate.isNotEmpty(boxLength) ? ""+boxLength.intValue() : "", rateRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Width", UtilValidate.isNotEmpty(boxWidth) ? ""+boxWidth.intValue() : "", rateRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Height", UtilValidate.isNotEmpty(boxHeight) ? ""+boxHeight.intValue() : "", rateRequestDoc); |
| } |
| else if |
| (UtilValidate.isNotEmpty(shipmentPackage.get("boxLength")) && UtilValidate.isNotEmpty(shipmentPackage.get("boxWidth")) && |
| UtilValidate.isNotEmpty(shipmentPackage.get("boxHeight"))) { |
| Element dimensionsElement = UtilXml.addChildElement(packageElement, "Dimensions", rateRequestDoc); |
| Element unitOfMeasurementElement = UtilXml.addChildElement(dimensionsElement, "UnitOfMeasurement", rateRequestDoc); |
| UtilXml.addChildElementValue(unitOfMeasurementElement, "Code", "IN", rateRequestDoc); |
| BigDecimal length = (BigDecimal) shipmentPackage.get("boxLength"); |
| BigDecimal width = (BigDecimal) shipmentPackage.get("boxWidth"); |
| BigDecimal height = (BigDecimal) shipmentPackage.get("boxHeight"); |
| UtilXml.addChildElementValue(dimensionsElement, "Length", length.setScale(decimals, rounding).toString(), rateRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Width", width.setScale(decimals, rounding).toString(), rateRequestDoc); |
| UtilXml.addChildElementValue(dimensionsElement, "Height", height.setScale(decimals, rounding).toString(), rateRequestDoc); |
| } |
| |
| Element packageWeightElement = UtilXml.addChildElement(packageElement, "PackageWeight", rateRequestDoc); |
| Element packageWeightUnitOfMeasurementElement = UtilXml.addChildElement(packageElement, "UnitOfMeasurement", rateRequestDoc); |
| String weightUomUps = unitsOfbizToUps.get(shipmentPackage.get("weightUomId")); |
| if (weightUomUps != null) { |
| UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", weightUomUps, rateRequestDoc); |
| } else { |
| // might as well default to LBS |
| UtilXml.addChildElementValue(packageWeightUnitOfMeasurementElement, "Code", "LBS", rateRequestDoc); |
| } |
| |
| if (shipmentPackage.getString("weight") == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsWeightValueNotFound", |
| UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId")), locale)); |
| } |
| BigDecimal boxWeight = shipmentPackage.getBigDecimal("weight"); |
| UtilXml.addChildElementValue(packageWeightElement, "Weight", UtilValidate.isNotEmpty(boxWeight) ? ""+boxWeight.intValue() : "", rateRequestDoc); |
| } |
| |
| // service options |
| UtilXml.addChildElement(shipmentElement, "ShipmentServiceOptions", rateRequestDoc); |
| String rateRequestString = null; |
| try { |
| rateRequestString = UtilXml.writeXmlDocument(rateRequestDoc); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the RatingServiceSelectionRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorRatingServiceSelectionRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // create AccessRequest XML doc |
| Document accessRequestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String accessRequestString = null; |
| try { |
| accessRequestString = UtilXml.writeXmlDocument(accessRequestDocument); |
| } catch (IOException e) { |
| String ioeErrMsg = "Error writing the AccessRequest XML Document to a String: " + e.toString(); |
| Debug.logError(e, ioeErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUpsErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| // prepare the access/inquire request string |
| StringBuilder xmlString = new StringBuilder(); |
| xmlString.append(accessRequestString); |
| xmlString.append(rateRequestString); |
| if (Debug.verboseOn()) Debug.logVerbose(xmlString.toString(), module); |
| // send the request |
| try { |
| rateResponseString = sendUpsRequest("Rate", xmlString.toString(), shipmentGatewayConfigId, resource, delegator, locale); |
| } catch (UpsConnectException e) { |
| String uceErrMsg = "Error sending UPS request for UPS Service Rate: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorSendingRate", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| Debug.logVerbose(rateResponseString, module); |
| Document rateResponseDocument = null; |
| try { |
| rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorParsingRatingServiceSelectionResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| Map<String,Object> upsResponse = handleUpsAlternateRatesInquireResponse(rateResponseDocument, locale); |
| Map<String,BigDecimal> upsRateCodeMap = UtilGenerics.cast(upsResponse.get("upsRateCodeMap")); |
| GenericValue carrierShipmentMethod = null; |
| // Filtering out rates of shipping methods which are not configured in ProductStoreShipmentMeth entity. |
| try { |
| List <GenericValue> productStoreShipmentMethods = EntityQuery.use(delegator).from("ProductStoreShipmentMethView").where("productStoreId", productStoreId).queryList(); |
| for (GenericValue productStoreShipmentMethod :productStoreShipmentMethods) { |
| if ("UPS".equals(productStoreShipmentMethod.get("partyId"))) { |
| Map<String,Object> thisUpsRateCodeMap = FastMap.newInstance(); |
| carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod") |
| .where("shipmentMethodTypeId", productStoreShipmentMethod.getString("shipmentMethodTypeId"), "partyId", productStoreShipmentMethod.getString("partyId"), "roleTypeId", productStoreShipmentMethod.getString("roleTypeId")) |
| .queryOne(); |
| String serviceCode = carrierShipmentMethod.getString("carrierServiceCode"); |
| for (String thisServiceCode : upsRateCodeMap.keySet()) { |
| if (serviceCode.equals(thisServiceCode)) { |
| BigDecimal newRate = upsRateCodeMap.get(serviceCode); |
| thisUpsRateCodeMap.put(serviceCode,newRate); |
| shippingRates.add(thisUpsRateCodeMap); |
| } |
| } |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| return UtilMisc.toMap("shippingRates", shippingRates, |
| ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| if (rateResponseString != null) { |
| Debug.logError("Got XML ShipmentAlternateRatesInquiryResponse: " + rateResponseString, module); |
| return ServiceUtil.returnError(UtilMisc.toList( |
| UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentAccept", |
| UtilMisc.toMap("errorString", e.toString()), locale), |
| UtilProperties.getMessage(resourceError, "FacilityShipmentUpsShipmentAlternateRatesInquiryResponse", |
| UtilMisc.toMap("rateResponseString", rateResponseString), locale))); |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorDataShipmentAlternateRate", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| } |
| |
| public static Map<String, Object> handleUpsAlternateRatesInquireResponse(Document rateResponseDocument, Locale locale) { |
| Element rateResponseElement = rateResponseDocument.getDocumentElement(); |
| |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(rateResponseElement, "Response"); |
| String responseStatusCode = UtilXml.childElementValue(responseElement, "ResponseStatusCode"); |
| List<Object> errorList = FastList.newInstance(); |
| UpsServices.handleErrors(responseElement, errorList, locale); |
| String totalRates = null; |
| |
| if ("1".equals(responseStatusCode)) { |
| List<? extends Element> rates = UtilXml.childElementList(rateResponseElement, "RatedShipment"); |
| Map<String, BigDecimal> rateMap = FastMap.newInstance(); |
| if (UtilValidate.isEmpty(rates)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsNoRateAvailable", locale)); |
| } else { |
| for (Element element: rates) { |
| // get service |
| Element service = UtilXml.firstChildElement(element, "Service"); |
| String serviceCode = UtilXml.childElementValue(service, "Code"); |
| |
| // get negotiated rates |
| Element negotiatedRates = UtilXml.firstChildElement(element, "NegotiatedRates"); |
| if (negotiatedRates !=null) { |
| Element netSummaryCharges = UtilXml.firstChildElement(negotiatedRates, "NetSummaryCharges"); |
| Element grandTotal = UtilXml.firstChildElement(netSummaryCharges, "GrandTotal"); |
| totalRates = UtilXml.childElementValue(grandTotal, "MonetaryValue"); |
| } |
| else { |
| // get total rates |
| Element totalCharges = UtilXml.firstChildElement(element, "TotalCharges"); |
| totalRates = UtilXml.childElementValue(totalCharges, "MonetaryValue"); |
| } |
| rateMap.put(serviceCode, new BigDecimal(totalRates)); |
| } |
| } |
| Debug.logInfo("UPS Rate Map : " + rateMap, module); |
| Map<String, Object> resp = ServiceUtil.returnSuccess(); |
| resp.put("upsRateCodeMap", rateMap); |
| return resp; |
| } else { |
| errorList.add(ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "FacilityShipmentUpsErrorStatusCode", |
| UtilMisc.toMap("responseStatusCode", responseStatusCode), locale))); |
| return ServiceUtil.returnFailure(errorList); |
| } |
| } |
| |
| private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, |
| String resource, String parameterName) { |
| String returnValue = ""; |
| if (UtilValidate.isNotEmpty(shipmentGatewayConfigId)) { |
| try { |
| GenericValue ups = EntityQuery.use(delegator).from("ShipmentGatewayUps").where("shipmentGatewayConfigId", shipmentGatewayConfigId).queryOne(); |
| if (UtilValidate.isNotEmpty(ups)) { |
| Object upsField = ups.get(shipmentGatewayConfigParameterName); |
| if (upsField != null) { |
| returnValue = upsField.toString().trim(); |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } else { |
| String value = EntityUtilProperties.getPropertyValue(resource, parameterName, delegator); |
| if (value != null) { |
| returnValue = value.trim(); |
| } |
| } |
| return returnValue; |
| } |
| |
| private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, |
| String resource, String parameterName, String defaultValue) { |
| String returnValue = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, shipmentGatewayConfigParameterName, resource, parameterName); |
| if (UtilValidate.isEmpty(returnValue)) { |
| returnValue = defaultValue; |
| } |
| return returnValue; |
| } |
| } |
| |
| @SuppressWarnings("serial") |
| class UpsConnectException extends GeneralException { |
| UpsConnectException() { |
| super(); |
| } |
| |
| UpsConnectException(String msg) { |
| super(msg); |
| } |
| |
| UpsConnectException(Throwable t) { |
| super(t); |
| } |
| |
| UpsConnectException(String msg, Throwable t) { |
| super(msg, t); |
| } |
| } |
| |
| |
| /* |
| * UPS Code Reference |
| |
| UPS Service IDs |
| ShipConfirm |
| ShipAccept |
| Void |
| Track |
| Rate |
| |
| Package Type Code |
| 00 Unknown |
| 01 UPS Letter |
| 02 Package |
| 03 UPS Tube |
| 04 UPS Pak |
| 21 UPS Express Box |
| 24 UPS 25KG Box |
| 25 UPS 10KG Box |
| |
| Pickup Types |
| 01 Daily Pickup |
| 03 Customer Counter |
| 06 One Time Pickup |
| 07 On Call Air Pickup |
| 19 Letter Center |
| 20 Air Service Center |
| |
| UPS Service Codes |
| US Origin |
| 01 UPS Next Day Air |
| 02 UPS 2nd Day Air |
| 03 UPS Ground |
| 07 UPS Worldwide Express |
| 08 UPS Worldwide Expedited |
| 11 UPS Standard |
| 12 UPS 3-Day Select |
| 13 UPS Next Day Air Saver |
| 14 UPS Next Day Air Early AM |
| 54 UPS Worldwide Express Plus |
| 59 UPS 2nd Day Air AM |
| 64 N/A |
| 65 UPS Express Saver |
| |
| Reference Number Codes |
| AJ Acct. Rec. Customer Acct. |
| AT Appropriation Number |
| BM Bill of Lading Number |
| 9V COD Number |
| ON Dealer Order Number |
| DP Department Number |
| EI Employer's ID Number |
| 3Q FDA Product Code |
| TJ Federal Taxpayer ID Number |
| IK Invoice Number |
| MK Manifest Key Number |
| MJ Model Number |
| PM Part Number |
| PC Production Code |
| PO Purchase Order No. |
| RQ Purchase Request No. |
| RZ Return Authorization No. |
| SA Salesperson No. |
| SE Serial No. |
| SY Social Security No. |
| ST Store No. |
| TN Transaction Ref. No. |
| |
| Error Codes |
| First note that in the ref guide there are about 21 pages of error codes |
| Here are some overalls: |
| 1 Success (no error) |
| 01xxxx XML Error |
| 02xxxx Architecture Error |
| 15xxxx Tracking Specific Error |
| |
| */ |
| |
| |
| /* |
| * Sample XML documents: |
| * |
| <?xml version="1.0"?> |
| <AccessRequest xml:lang="en-US"> |
| <AccessLicenseNumber>TEST262223144CAT</AccessLicenseNumber> |
| <UserId>REG111111</UserId> |
| <Password>REG111111</Password> |
| </AccessRequest> |
| |
| ======================================= |
| Shipment Confirm Request/Response |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <ShipmentConfirmRequest xml:lang="en-US"> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>Ship Confirm / nonvalidate</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <RequestAction>ShipConfirm</RequestAction> |
| <RequestOption>nonvalidate</RequestOption> |
| </Request> |
| <LabelSpecification> |
| <LabelPrintMethod> |
| <Code>GIF</Code> |
| </LabelPrintMethod> |
| <HTTPUserAgent>Mozilla/5.0</HTTPUserAgent> |
| <LabelImageFormat> |
| <Code>GIF</Code> |
| </LabelImageFormat> |
| </LabelSpecification> |
| <Shipment> |
| <Description>DescriptionofGoodsTest</Description> |
| <Shipper> |
| <Name>ShipperName</Name> |
| <AttentionName>ShipperName</AttentionName> |
| <PhoneNumber>2226267227</PhoneNumber> |
| <ShipperNumber>12345E</ShipperNumber> |
| <Address> |
| <AddressLine1>123 ShipperStreet</AddressLine1> |
| <AddressLine2>123 ShipperStreet</AddressLine2> |
| <AddressLine3>123 ShipperStreet</AddressLine3> |
| <City>ShipperCity</City> |
| <StateProvinceCode>foo</StateProvinceCode> |
| <PostalCode>03570</PostalCode> |
| <CountryCode>DE</CountryCode> |
| </Address> |
| </Shipper> |
| <ShipTo> |
| <CompanyName>ShipToCompanyName</CompanyName> |
| <AttentionName>ShipToAttnName</AttentionName> |
| <PhoneNumber>3336367336</PhoneNumber> |
| <Address> |
| <AddressLine1>123 ShipToStreet</AddressLine1> |
| <PostalCode>DT09</PostalCode> |
| <City>Trent</City> |
| <CountryCode>GB</CountryCode> |
| </Address> |
| </ShipTo> |
| <ShipFrom> |
| <CompanyName>ShipFromCompanyName</CompanyName> |
| <AttentionName>ShipFromAttnName</AttentionName> |
| <PhoneNumber>7525565064</PhoneNumber> |
| <Address> |
| <AddressLine1>123 ShipFromStreet</AddressLine1> |
| <City>Berlin</City> |
| <PostalCode>03570</PostalCode> |
| <CountryCode>DE</CountryCode> |
| </Address> |
| </ShipFrom> |
| <PaymentInformation> |
| <Prepaid> |
| <BillShipper> |
| <AccountNumber>12345E</AccountNumber> |
| </BillShipper> |
| </Prepaid> |
| </PaymentInformation> |
| <Service> |
| <Code>07</Code> |
| </Service> |
| <Package> |
| <PackagingType> |
| <Code>02</Code> |
| </PackagingType> |
| <Dimensions> |
| <UnitOfMeasurement> |
| <Code>CM</Code> |
| </UnitOfMeasurement> |
| <Length>60</Length> |
| <Width>7</Width> |
| <Height>5</Height> |
| </Dimensions> |
| <PackageWeight> |
| <UnitOfMeasurement> |
| <Code>KGS</Code> |
| </UnitOfMeasurement> |
| <Weight>3.0</Weight> |
| </PackageWeight> |
| <ReferenceNumber> |
| <Code>MK</Code> |
| <Value>00001</Value> |
| </ReferenceNumber> |
| </Package> |
| </Shipment> |
| </ShipmentConfirmRequest> |
| |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <ShipmentConfirmResponse> |
| <Response> |
| <TransactionReference> |
| <CustomerContext>ShipConfirmUS</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <ShipmentCharges> |
| <TransportationCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>31.38</MonetaryValue> |
| </TransportationCharges> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>7.75</MonetaryValue> |
| </ServiceOptionsCharges> |
| <TotalCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>39.13</MonetaryValue> |
| </TotalCharges> |
| </ShipmentCharges> |
| <BillingWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>4.0</Weight> |
| </BillingWeight> |
| <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber> |
| <ShipmentDigest>INSERT SHIPPING DIGEST HERE</ShipmentDigest> |
| </ShipmentConfirmResponse> |
| |
| ======================================= |
| Shipment Accept Request/Response |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <ShipmentAcceptRequest> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>TR01</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <RequestAction>ShipAccept</RequestAction> |
| <RequestOption>01</RequestOption> |
| </Request> |
| <ShipmentDigest>INSERT SHIPPING DIGEST HERE</ShipmentDigest> |
| </ShipmentAcceptRequest> |
| |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <ShipmentAcceptResponse> |
| <Response> |
| <TransactionReference> |
| <CustomerContext>TR01</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <ShipmentResults> |
| <ShipmentCharges> |
| <TransportationCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>31.38</MonetaryValue> |
| </TransportationCharges> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>7.75</MonetaryValue> |
| </ServiceOptionsCharges> |
| <TotalCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>39.13</MonetaryValue> |
| </TotalCharges> |
| </ShipmentCharges> |
| <BillingWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>4.0</Weight> |
| </BillingWeight> |
| <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber> |
| <PackageResults> |
| <TrackingNumber>1Z12345E1512345676</TrackingNumber> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>0.00</MonetaryValue> |
| </ServiceOptionsCharges> |
| <LabelImage> |
| <LabelImageFormat> |
| <Code>epl</Code> |
| </LabelImageFormat> |
| <GraphicImage>INSERT GRAPHIC IMAGE HERE</GraphicImage> |
| </LabelImage> |
| </PackageResults> |
| <PackageResults> |
| <TrackingNumber>1Z12345E1512345686</TrackingNumber> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>7.75</MonetaryValue> |
| </ServiceOptionsCharges> |
| <LabelImage> |
| <LabelImageFormat> |
| <Code>epl</Code> |
| </LabelImageFormat> |
| <GraphicImage>INSERT GRAPHIC IMAGE HERE</GraphicImage> |
| </LabelImage> |
| </PackageResults> |
| </ShipmentResults> |
| </ShipmentAcceptResponse> |
| |
| ======================================= |
| Void Shipment Request/Response |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <VoidShipmentRequest> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>Void</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <RequestAction>Void</RequestAction> |
| <RequestOption>1</RequestOption> |
| </Request> |
| <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber> |
| </VoidShipmentRequest> |
| |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <VoidShipmentResponse> |
| <Response> |
| <TransactionReference> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <Status> |
| <StatusType> |
| <Code>1</Code> |
| <Description>Success</Description> |
| </StatusType> |
| <StatusCode> |
| <Code>1</Code> |
| <Description>Success</Description> |
| </StatusCode> |
| </Status> |
| </VoidShipmentResponse> |
| |
| ======================================= |
| Track Shipment Request/Response |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <TrackRequest xml:lang="en-US"> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>sample</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <RequestAction>Track</RequestAction> |
| </Request> |
| <TrackingNumber>1Z12345E1512345676</TrackingNumber> |
| </TrackRequest> |
| |
| ======================================= |
| |
| <?xml version="1.0" encoding="UTF-8"?> |
| <TrackResponse> |
| <Response> |
| <TransactionReference> |
| <CustomerContext>sample</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <Shipment> |
| <Shipper> |
| <ShipperNumber>12345E</ShipperNumber> |
| </Shipper> |
| <Service> |
| <Code>15</Code> |
| <Description>NDA EAM/EXP EAM</Description> |
| </Service> |
| <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber> |
| <Package> |
| <TrackingNumber>1Z12345E1512345676</TrackingNumber> |
| <Activity> |
| <ActivityLocation> |
| <Address> |
| <City>CLAKVILLE</City> |
| <StateProvinceCode>AK</StateProvinceCode> |
| <PostalCode>99901</PostalCode> |
| <CountryCode>US</CountryCode> |
| </Address> |
| <Code>MG</Code> |
| <Description>MC MAN</Description> |
| </ActivityLocation> |
| <Status> |
| <StatusType> |
| <Code>D</Code> |
| <Description>DELIVERED</Description> |
| </StatusType> |
| <StatusCode> |
| <Code>FS</Code> |
| </StatusCode> |
| </Status> |
| <Date>20020930</Date> |
| <Time>130900</Time> |
| </Activity> |
| <PackageWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>0.00</Weight> |
| </PackageWeight> |
| </Package> |
| </Shipment> |
| </TrackResponse> |
| |
| ======================================= |
| Rates & Service Request/Response |
| ======================================= |
| |
| <?xml version="1.0"?> |
| <RatingServiceSelectionRequest xml:lang="en-US"> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>Bare Bones Rate Request</CustomerContext> |
| <XpciVersion>1.0</XpciVersion> |
| </TransactionReference> |
| <RequestAction>Rate</RequestAction> |
| <RequestOption>Rate</RequestOption> |
| </Request> |
| <PickupType> |
| <Code>01</Code> |
| </PickupType> |
| <Shipment> |
| <Shipper> |
| <Address> |
| <PostalCode>44129</PostalCode> |
| <CountryCode>US</CountryCode> |
| </Address> |
| </Shipper> |
| <ShipTo> |
| <Address> |
| <PostalCode>44129</PostalCode> |
| <CountryCode>US</CountryCode> |
| </Address> |
| </ShipTo> |
| <ShipFrom> |
| <Address> |
| <PostalCode>32779</PostalCode> |
| <CountryCode>US</CountryCode> |
| </Address> |
| </ShipFrom> |
| <Service> |
| <Code>01</Code> |
| </Service> |
| <Package> |
| <PackagingType> |
| <Code>02</Code> |
| </PackagingType> |
| <Dimensions> |
| <UnitOfMeasurement> |
| <Code>IN</Code> |
| </UnitOfMeasurement> |
| <Length>20</Length> |
| <Width>20</Width> |
| <Height>20</Height> |
| </Dimensions> |
| <PackageWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>23</Weight> |
| </PackageWeight> |
| </Package> |
| </Shipment> |
| </RatingServiceSelectionRequest> |
| |
| ======================================= |
| |
| <?xml version="1.0" encoding="UTF-8"?> |
| <RatingServiceSelectionResponse> |
| <Response> |
| <TransactionReference> |
| <CustomerContext>Bare Bones Rate Request</CustomerContext> |
| <XpciVersion>1.0</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <RatedShipment> |
| <Service> |
| <Code>01</Code> |
| </Service> |
| <BillingWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>42.0</Weight> |
| </BillingWeight> |
| <TransportationCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>108.61</MonetaryValue> |
| </TransportationCharges> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>0.00</MonetaryValue> |
| </ServiceOptionsCharges> |
| <TotalCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>108.61</MonetaryValue> |
| </TotalCharges> |
| <GuaranteedDaysToDelivery>1</GuaranteedDaysToDelivery> |
| <ScheduledDeliveryTime>10:30 A.M.</ScheduledDeliveryTime> |
| <RatedPackage> |
| <TransportationCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>108.61</MonetaryValue> |
| </TransportationCharges> |
| <ServiceOptionsCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>0.00</MonetaryValue> |
| </ServiceOptionsCharges> |
| <TotalCharges> |
| <CurrencyCode>USD</CurrencyCode> |
| <MonetaryValue>108.61</MonetaryValue> |
| </TotalCharges> |
| <Weight>23.0</Weight> |
| <BillingWeight> |
| <UnitOfMeasurement> |
| <Code>LBS</Code> |
| </UnitOfMeasurement> |
| <Weight>42.0</Weight> |
| </BillingWeight> |
| </RatedPackage> |
| </RatedShipment> |
| </RatingServiceSelectionResponse> |
| |
| ======================================= |
| Address Validation Request/Response |
| ======================================= |
| |
| <AddressValidationRequest xml:lang="en-US"> |
| <Request> |
| <TransactionReference> |
| <CustomerContext>Maryam Dennis-Customer Data</CustomerContext> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <RequestAction>AV</RequestAction> |
| </Request> |
| <Address> |
| <City>MIAMI</City> |
| <StateProvinceCode>FL</StateProvinceCode> |
| </Address> |
| </AddressValidationRequest> |
| |
| ======================================= |
| |
| <AddressValidationResponse> |
| <Response> |
| <TransactionReference> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <AddressValidationResult> |
| <Rank>1</Rank> |
| <Quality>1.0</Quality> |
| <Address> |
| <City>TIMONIUM</City> |
| <StateProvinceCode>MD</StateProvinceCode> |
| </Address> |
| <PostalCodeLowEnd>21093</PostalCodeLowEnd> |
| <PostalCodeHighEnd>21094</PostalCodeHighEnd> |
| </AddressValidationResult> |
| </AddressValidationResponse> |
| |
| ======================================= |
| |
| <AddressValidationResponse> |
| <Response> |
| <TransactionReference> |
| <XpciVersion>1.0001</XpciVersion> |
| </TransactionReference> |
| <ResponseStatusCode>1</ResponseStatusCode> |
| <ResponseStatusDescription>Success</ResponseStatusDescription> |
| </Response> |
| <AddressValidationResult> |
| <Rank>1</Rank> |
| <Quality>0.9975000023841858</Quality> |
| <Address> |
| <City>TIMONIUM</City> |
| <StateProvinceCode>MD</StateProvinceCode> |
| </Address> |
| <PostalCodeLowEnd>21093</PostalCodeLowEnd> |
| <PostalCodeHighEnd>21094</PostalCodeHighEnd> |
| </AddressValidationResult> |
| <AddressValidationResult> |
| <Rank>2</Rank> |
| <Quality>0.8299999833106995</Quality> |
| <Address> |
| <City>LUTHERVILLE TIMONIUM</City> |
| <StateProvinceCode>MD</StateProvinceCode> |
| </Address> |
| <PostalCodeLowEnd>21093</PostalCodeLowEnd> |
| <PostalCodeHighEnd>21094</PostalCodeHighEnd> |
| </AddressValidationResult> |
| <AddressValidationResult> |
| <Rank>3</Rank> |
| <Quality>0.8299999833106995</Quality> |
| <Address> |
| <City>LUTHERVILLE</City> |
| <StateProvinceCode>MD</StateProvinceCode> |
| </Address> |
| <PostalCodeLowEnd>21093</PostalCodeLowEnd> |
| <PostalCodeHighEnd>21094</PostalCodeHighEnd> |
| </AddressValidationResult> |
| </AddressValidationResponse> |
| |
| */ |