| /******************************************************************************* |
| * 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.apache.ofbiz.shipment.thirdparty.dhl; |
| |
| import java.io.IOException; |
| import java.io.StringWriter; |
| import java.math.BigDecimal; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.apache.ofbiz.base.util.Base64; |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.GeneralException; |
| import org.apache.ofbiz.base.util.HttpClient; |
| import org.apache.ofbiz.base.util.HttpClientException; |
| import org.apache.ofbiz.base.util.StringUtil; |
| import org.apache.ofbiz.base.util.UtilDateTime; |
| import org.apache.ofbiz.base.util.UtilMisc; |
| import org.apache.ofbiz.base.util.UtilProperties; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.base.util.UtilXml; |
| import org.apache.ofbiz.content.content.ContentWorker; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.entity.util.EntityUtilProperties; |
| import org.apache.ofbiz.service.DispatchContext; |
| import org.apache.ofbiz.service.GenericServiceException; |
| import org.apache.ofbiz.service.LocalDispatcher; |
| import org.apache.ofbiz.service.ModelService; |
| import org.apache.ofbiz.service.ServiceUtil; |
| import org.apache.ofbiz.shipment.shipment.ShipmentServices; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * DHL ShipmentServices |
| * |
| * <p>Implementation of DHL US domestic shipment interface using DHL ShipIT XML APi.</p> |
| * |
| * Shipment services not supported in DHL ShipIT 1.1 |
| * <ul> |
| * <li>Multiple Piece shipping (Shipment must not have more than one |
| * ShipmentPackage)</li> |
| * <li>Dynamic editing of previously submitted shipment (void first then |
| * resubmit instead)</li> |
| * <li>Label size 4"x6"</li> |
| * <li>Out of origin shipping</li> |
| * </ul> |
| * |
| * TODO: International |
| */ |
| public class DhlServices { |
| |
| public final static String module = DhlServices.class.getName(); |
| public final static String shipmentPropertiesFile = "shipment.properties"; |
| public final static String DHL_WEIGHT_UOM_ID = "WT_lb"; // weight Uom used by DHL |
| public static final String resourceError = "ProductUiLabels"; |
| |
| /** |
| * Opens a URL to DHL and makes a request. |
| * |
| * @param xmlString Name of the DHL service to invoke |
| * @param delegator the delegator |
| * @param shipmentGatewayConfigId the shipment gateway config id |
| * @param resource the resource file (i.e. shipment.properties) |
| * @param locale locale in use |
| * @return XML string response from DHL |
| * @throws DhlConnectException |
| */ |
| public static String sendDhlRequest(String xmlString, Delegator delegator, String shipmentGatewayConfigId, |
| String resource, Locale locale) throws DhlConnectException { |
| String conStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectUrl", resource, "shipment.dhl.connect.url"); |
| if (conStr == null) { |
| throw new DhlConnectException(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlConnectUrlIncomplete", locale)); |
| } |
| |
| // xmlString should contain the auth document at the beginning |
| // all documents require an <?xml version="1.0"?> header |
| if (xmlString == null) { |
| throw new DhlConnectException(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlXmlCannotBeNull", locale)); |
| } |
| |
| // prepare the connect string |
| conStr = conStr.trim(); |
| |
| String timeOutStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectTimeout", |
| resource, "shipment.dhl.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); |
| } |
| |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("DHL Connect URL : " + conStr, module); |
| Debug.logVerbose("DHL XML String : " + xmlString, module); |
| } |
| |
| HttpClient http = new HttpClient(conStr); |
| http.setTimeout(timeout * 1000); |
| String response = null; |
| try { |
| response = http.post(xmlString); |
| } catch (HttpClientException e) { |
| Debug.logError(e, "Problem connecting with DHL server", module); |
| throw new DhlConnectException(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlConnectUrlProblem", UtilMisc.toMap("errorString", e), locale), e); |
| } |
| |
| if (response == null) { |
| throw new DhlConnectException(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlReceivedNullResponse", locale)); |
| } |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("DHL Response : " + response, module); |
| } |
| |
| return response; |
| } |
| |
| |
| /* |
| * Service to obtain a rate estimate from DHL for a shipment. Notes: Only one package per shipment currently supported by DHL ShipIT. |
| * If this service returns a null shippingEstimateAmount, then the shipment has not been processed |
| */ |
| public static Map<String, Object> dhlRateEstimate(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| LocalDispatcher dispatcher = dctx.getDispatcher(); |
| Locale locale = (Locale) context.get("locale"); |
| |
| // some of these can be refactored |
| String carrierPartyId = (String) context.get("carrierPartyId"); |
| String shipmentMethodTypeId = (String) context.get("shipmentMethodTypeId"); |
| String shippingContactMechId = (String) context.get("shippingContactMechId"); |
| BigDecimal shippableWeight = (BigDecimal) context.get("shippableWeight"); |
| |
| if (shipmentMethodTypeId.equals("NO_SHIPPING")) { |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| result.put("shippingEstimateAmount", null); |
| return result; |
| } |
| |
| // translate shipmentMethodTypeId to DHL service code |
| String dhlShipmentDetailCode = null; |
| try { |
| GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod") |
| .where("shipmentMethodTypeId", shipmentMethodTypeId, "partyId", carrierPartyId, "roleTypeId", "CARRIER") |
| .queryOne(); |
| if (carrierShipmentMethod == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlNoCarrierShipmentMethod", |
| UtilMisc.toMap("carrierPartyId", carrierPartyId, "shipmentMethodTypeId", shipmentMethodTypeId), locale)); |
| } |
| dhlShipmentDetailCode = carrierShipmentMethod.getString("carrierServiceCode"); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Failed to get rate estimate: " + e.getMessage(), module); |
| } |
| |
| String resource = (String) context.get("serviceConfigProps"); |
| String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId"); |
| |
| // shipping credentials (configured in properties) |
| String userid = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessUserId", resource, "shipment.dhl.access.userid"); |
| String password = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessPassword", resource, "shipment.dhl.access.password"); |
| String shippingKey = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessShippingKey", resource, "shipment.dhl.access.shippingKey"); |
| String accountNbr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessAccountNbr", resource, "shipment.dhl.access.accountNbr"); |
| if ((shippingKey == null) || (accountNbr == null) || (shippingKey.length() == 0) || (accountNbr.length() == 0)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlGatewayNotAvailable", locale)); |
| } |
| |
| // obtain the ship-to address |
| GenericValue shipToAddress = null; |
| if (shippingContactMechId != null) { |
| try { |
| shipToAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", shippingContactMechId).queryOne(); |
| if (shipToAddress == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentUnableFoundShipToAddresss", locale)); |
| } |
| } |
| catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } |
| |
| if ((shippableWeight == null) || (shippableWeight.compareTo(BigDecimal.ZERO) <= 0)) { |
| String tmpValue = EntityUtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.weight.value", delegator); |
| if (tmpValue != null) { |
| try { |
| shippableWeight = new BigDecimal(tmpValue); |
| } catch (Exception e) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlDefaultShippableWeightNotConfigured", locale)); |
| } |
| } |
| } |
| |
| // TODO: if a weight UOM is passed in, use convertUom service to convert it here |
| if (shippableWeight.compareTo(BigDecimal.ONE) < 0) { |
| Debug.logWarning("DHL Estimate: Weight is less than 1 lb, submitting DHL minimum of 1 lb for estimate.", module); |
| shippableWeight = BigDecimal.ONE; |
| } |
| if ((dhlShipmentDetailCode.equals("G") && shippableWeight.compareTo(new BigDecimal("999")) > 0) || (shippableWeight.compareTo(new BigDecimal("150")) > 0)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShippableWeightExceed", locale)); |
| } |
| String weight = (Integer.valueOf((int) shippableWeight.longValue())).toString(); |
| |
| // create AccessRequest XML doc using FreeMarker template |
| String templateName = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "rateEstimateTemplate", resource, "shipment.dhl.template.rate.estimate"); |
| if ((templateName == null) || (templateName.trim().length() == 0)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShipmentTemplateLocationNotFound", locale)); |
| } |
| StringWriter outWriter = new StringWriter(); |
| Map<String, Object> inContext = new HashMap<String, Object>(); |
| inContext.put("action", "RateEstimate"); |
| inContext.put("userid", userid); |
| inContext.put("password", password); |
| inContext.put("accountNbr", accountNbr); |
| inContext.put("shippingKey", shippingKey); |
| inContext.put("shipDate", UtilDateTime.nowTimestamp()); |
| inContext.put("dhlShipmentDetailCode", dhlShipmentDetailCode); |
| inContext.put("weight", weight); |
| inContext.put("state", shipToAddress.getString("stateProvinceGeoId")); |
| // DHL ShipIT API does not accept ZIP+4 |
| if ((shipToAddress.getString("postalCode") != null) && (shipToAddress.getString("postalCode").length() > 5)) { |
| inContext.put("postalCode", shipToAddress.getString("postalCode").substring(0,5)); |
| } else { |
| inContext.put("postalCode", shipToAddress.getString("postalCode")); |
| } |
| try { |
| ContentWorker.renderContentAsText(dispatcher, delegator, templateName, outWriter, inContext, locale, "text/plain", null, null, false); |
| } catch (Exception e) { |
| Debug.logError(e, "Cannot get DHL Estimate: Failed to render DHL XML Request.", module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShipmentTemplateError", locale)); |
| } |
| String requestString = outWriter.toString(); |
| if (Debug.verboseOn()) { |
| Debug.logVerbose(requestString, module); |
| } |
| |
| // send the request |
| String rateResponseString = null; |
| try { |
| rateResponseString = sendDhlRequest(requestString, delegator, shipmentGatewayConfigId, resource, locale); |
| if (Debug.verboseOn()) { |
| Debug.logVerbose(rateResponseString, module); |
| } |
| } |
| catch (DhlConnectException e) { |
| String uceErrMsg = "Error sending DHL request for DHL Service Rate: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShipmentTemplateSendingError", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| Document rateResponseDocument = null; |
| try { |
| rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false); |
| return handleDhlRateResponse(rateResponseDocument, locale); |
| } |
| catch (SAXException e2) { |
| String excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexShipmentTemplateParsingError", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexShipmentTemplateParsingError", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| catch (IOException e2) { |
| String excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexShipmentTemplateParsingError", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| } |
| |
| /* |
| * Parses an XML document from DHL to get the rate estimate |
| */ |
| public static Map<String, Object> handleDhlRateResponse(Document rateResponseDocument, Locale locale) { |
| List<Object> errorList = new LinkedList<Object>(); |
| Map<String, Object> dhlRateCodeMap = new HashMap<String, Object>(); |
| // process RateResponse |
| Element rateResponseElement = rateResponseDocument.getDocumentElement(); |
| DhlServices.handleErrors(rateResponseElement, errorList, locale); |
| if (UtilValidate.isNotEmpty(errorList)) { |
| return ServiceUtil.returnError(errorList); |
| } |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(rateResponseElement, "Shipment"); |
| Element responseEstimateDetailElement = UtilXml.firstChildElement(responseElement, "EstimateDetail"); |
| |
| DhlServices.handleErrors(responseElement, errorList, locale); |
| if (UtilValidate.isNotEmpty(errorList)) { |
| return ServiceUtil.returnError(errorList); |
| } |
| |
| String dateGenerated = UtilXml.childElementValue( |
| responseEstimateDetailElement, "DateGenerated"); |
| |
| Element responseServiceLevelCommitmentElement = UtilXml |
| .firstChildElement(responseEstimateDetailElement, |
| "ServiceLevelCommitment"); |
| String responseServiceLevelCommitmentDescription = UtilXml |
| .childElementValue(responseServiceLevelCommitmentElement, |
| "Desc"); |
| |
| Element responseRateEstimateElement = UtilXml.firstChildElement( |
| responseEstimateDetailElement, "RateEstimate"); |
| String responseTotalChargeEstimate = UtilXml.childElementValue( |
| responseRateEstimateElement, "TotalChargeEstimate"); |
| Element responseChargesElement = UtilXml.firstChildElement( |
| responseRateEstimateElement, "Charges"); |
| List<? extends Element> chargeNodeList = UtilXml.childElementList(responseChargesElement, |
| "Charge"); |
| |
| List<Map<String, String>> chargeList = new LinkedList<Map<String,String>>(); |
| if (UtilValidate.isNotEmpty(chargeNodeList)) { |
| for (Element responseChargeElement: chargeNodeList) { |
| Map<String, String> charge = new HashMap<String, String>(); |
| |
| Element responseChargeTypeElement = UtilXml.firstChildElement( |
| responseChargeElement, "Type"); |
| |
| String responseChargeTypeCode = UtilXml.childElementValue( |
| responseChargeTypeElement, "Code"); |
| String responseChargeTypeDesc = UtilXml.childElementValue( |
| responseChargeTypeElement, "Desc"); |
| String responseChargeValue = UtilXml.childElementValue( |
| responseChargeElement, "Value"); |
| |
| charge.put("chargeTypeCode", responseChargeTypeCode); |
| charge.put("chargeTypeDesc", responseChargeTypeDesc); |
| charge.put("chargeValue", responseChargeValue); |
| chargeList.add(charge); |
| } |
| } |
| BigDecimal shippingEstimateAmount = new BigDecimal(responseTotalChargeEstimate); |
| dhlRateCodeMap.put("dateGenerated", dateGenerated); |
| dhlRateCodeMap.put("serviceLevelCommitment", |
| responseServiceLevelCommitmentDescription); |
| dhlRateCodeMap.put("totalChargeEstimate", responseTotalChargeEstimate); |
| dhlRateCodeMap.put("chargeList", chargeList); |
| |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| result.put("shippingEstimateAmount", shippingEstimateAmount); |
| result.put("dhlRateCodeMap", dhlRateCodeMap); |
| return result; |
| } |
| |
| /* |
| * Register a DHL account for shipping by obtaining the DHL shipping key |
| */ |
| public static Map<String, Object> dhlRegisterInquire(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| String resource = (String) context.get("serviceConfigProps"); |
| String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId"); |
| Locale locale = (Locale) context.get("locale"); |
| Map<String, Object> result = new HashMap<String, Object>(); |
| String postalCode = (String) context.get("postalCode"); |
| String accountNbr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessAccountNbr", |
| resource, "shipment.dhl.access.accountNbr"); |
| if (accountNbr == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlAccessAccountNbrMandotoryForRegisterAccount", locale)); |
| } |
| // create AccessRequest XML doc |
| Document requestDocument = createAccessRequestDocument(delegator, shipmentGatewayConfigId, resource); |
| String requestString = null; |
| Element requesElement = requestDocument.getDocumentElement(); |
| |
| Element registerRequestElement = UtilXml.addChildElement(requesElement, "Register", requestDocument); |
| registerRequestElement.setAttribute("version", "1.0"); |
| registerRequestElement.setAttribute("action", "ShippingKey"); |
| UtilXml.addChildElementValue(registerRequestElement, "AccountNbr", accountNbr, requestDocument); |
| UtilXml.addChildElementValue(registerRequestElement, "PostalCode", postalCode, requestDocument); |
| |
| try { |
| requestString = UtilXml.writeXmlDocument(requestDocument); |
| Debug.logInfo("AccessRequest XML Document:" + requestString, module); |
| } 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, |
| "FacilityShipmentDhlErrorAccessRequestXmlToString", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| // send the request |
| String registerResponseString = null; |
| try { |
| registerResponseString = sendDhlRequest(requestString, delegator, shipmentGatewayConfigId, resource, locale); |
| Debug.logInfo("DHL request for DHL Register Account:" + registerResponseString, module); |
| } catch (DhlConnectException e) { |
| String uceErrMsg = "Error sending DHL request for DHL Register Account: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlErrorSendingRequestRegisterAccount", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| Document registerResponseDocument = null; |
| try { |
| registerResponseDocument = UtilXml.readXmlDocument(registerResponseString, false); |
| result = handleDhlRegisterResponse(registerResponseDocument, locale); |
| Debug.logInfo("DHL response for DHL Register Account:" + registerResponseString, module); |
| } catch (SAXException e2) { |
| String excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlErrorParsingRegisterAccountResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlErrorParsingRegisterAccountResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlErrorParsingRegisterAccountResponse", |
| UtilMisc.toMap("errorString", e2.toString()), locale)); |
| } |
| |
| return result; |
| } |
| |
| /* |
| * Parse response from DHL registration request to get shipping key |
| */ |
| public static Map<String, Object> handleDhlRegisterResponse(Document registerResponseDocument, Locale locale) { |
| List<Object> errorList = new LinkedList<Object>(); |
| // process RegisterResponse |
| Element registerResponseElement = registerResponseDocument.getDocumentElement(); |
| DhlServices.handleErrors(registerResponseElement, errorList, locale); |
| if (UtilValidate.isNotEmpty(errorList)) { |
| return ServiceUtil.returnError(errorList); |
| } |
| // handle Response element info |
| Element responseElement = UtilXml.firstChildElement(registerResponseElement, "Register"); |
| DhlServices.handleErrors(responseElement, errorList, locale); |
| if (UtilValidate.isNotEmpty(errorList)) { |
| return ServiceUtil.returnError(errorList); |
| } |
| String responseShippingKey = UtilXml.childElementValue(responseElement,"ShippingKey"); |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| result.put("shippingKey", responseShippingKey); |
| return result; |
| } |
| |
| /* |
| * Pass a shipment request to DHL via ShipIT and get a tracking number and a label back, among other things |
| */ |
| |
| public static Map<String, Object> dhlShipmentConfirm(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Delegator delegator = dctx.getDelegator(); |
| LocalDispatcher dispatcher = dctx.getDispatcher(); |
| Locale locale = (Locale) context.get("locale"); |
| |
| GenericValue userLogin = (GenericValue) context.get("userLogin"); |
| 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, |
| "FacilityShipmentDhlGatewayNotAvailable", locale)); |
| } |
| |
| 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 (!"DHL".equals(shipmentRouteSegment.getString("carrierPartyId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlNotRouteSegmentCarrier", |
| UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale)); |
| } |
| |
| // add ShipmentRouteSegment carrierServiceStatusId, check before all DHL services |
| if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("carrierServiceStatusId")) && !"SHRSCS_NOT_STARTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlRouteSegmentStatusNotStarted", |
| 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 and assuming DHL will accept this) |
| 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)); |
| } |
| |
| // DHL requires destination phone number, default to sender # if no customer number |
| String destPhoneNumber = originPhoneNumber; |
| GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false); |
| 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, " ", ""); |
| } |
| |
| String recipientEmail = null; |
| Map<String, Object> results = dispatcher.runSync("getPartyEmail", UtilMisc.toMap("partyId", shipment.get("partyIdTo"), "userLogin", userLogin)); |
| if (results.get("emailAddress") != null) { |
| recipientEmail = (String) results.get("emailAddress"); |
| } |
| |
| // 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)); |
| } |
| |
| 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)); |
| } |
| if (shipmentPackageRouteSegs.size() != 1) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlMultiplePackagesNotSupported", locale)); |
| } |
| |
| // get the weight from the ShipmentRouteSegment first, which overrides all later weight computations |
| boolean hasBillingWeight = false; // for later overrides |
| BigDecimal billingWeight = shipmentRouteSegment.getBigDecimal("billingWeight"); |
| String billingWeightUomId = shipmentRouteSegment.getString("billingWeightUomId"); |
| if ((billingWeight != null) && (billingWeight.compareTo(BigDecimal.ZERO) > 0)) { |
| hasBillingWeight = true; |
| if (billingWeightUomId == null) { |
| Debug.logWarning("Shipment Route Segment missing billingWeightUomId in shipmentId " + shipmentId, module); |
| billingWeightUomId = "WT_lb"; // TODO: this should be specified in a properties file |
| } |
| // convert |
| results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", billingWeightUomId, "uomIdTo", DHL_WEIGHT_UOM_ID, "originalValue", billingWeight)); |
| if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) { |
| Debug.logWarning("Unable to convert billing weights for shipmentId " + shipmentId , module); |
| // try getting the weight from package instead |
| hasBillingWeight = false; |
| } else { |
| billingWeight = (BigDecimal) results.get("convertedValue"); |
| } |
| } |
| |
| // loop through Shipment segments (NOTE: only one supported, loop is here for future refactoring reference) |
| BigDecimal packageWeight = null; |
| for (GenericValue shipmentPackageRouteSeg: shipmentPackageRouteSegs) { |
| GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false); |
| GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType", false); |
| |
| if (shipmentBoxType != null) { |
| // TODO: determine what default UoM is (assuming inches) - there should be a defaultDimensionUomId in Facility |
| } |
| |
| // next step is weight determination, so skip if we have a billing weight |
| if (hasBillingWeight) continue; |
| |
| // compute total packageWeight (for now, just one package) |
| if (shipmentPackage.getString("weight") != null) { |
| packageWeight = new BigDecimal(shipmentPackage.getString("weight")); |
| } else { |
| // use default weight if available |
| try { |
| packageWeight = EntityUtilProperties.getPropertyAsBigDecimal(shipmentPropertiesFile, "shipment.default.weight.value", BigDecimal.ZERO); |
| } catch (NumberFormatException ne) { |
| Debug.logWarning("Default shippable weight not configured (shipment.default.weight.value)", module); |
| packageWeight = BigDecimal.ONE; |
| } |
| } |
| // convert weight |
| String weightUomId = (String) shipmentPackage.get("weightUomId"); |
| if (weightUomId == null) { |
| Debug.logWarning("Shipment Route Segment missing weightUomId in shipmentId " + shipmentId, module); |
| weightUomId = "WT_lb"; // TODO: this should be specified in a properties file |
| } |
| results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", weightUomId, "uomIdTo", DHL_WEIGHT_UOM_ID, "originalValue", packageWeight)); |
| if ((results == null) || (results.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_ERROR)) || (results.get("convertedValue") == null)) { |
| Debug.logWarning("Unable to convert weights for shipmentId " + shipmentId , module); |
| packageWeight = BigDecimal.ONE; |
| } else { |
| packageWeight = (BigDecimal) results.get("convertedValue"); |
| } |
| } |
| |
| // pick which weight to use and round it |
| BigDecimal weight = null; |
| if (hasBillingWeight) { |
| weight = billingWeight; |
| } else { |
| weight = packageWeight; |
| } |
| // want the rounded weight as a string, so we use the "" + int shortcut |
| String roundedWeight = weight.setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString(); |
| |
| // translate shipmentMethodTypeId to DHL service code |
| String shipmentMethodTypeId = shipmentRouteSegment.getString("shipmentMethodTypeId"); |
| String dhlShipmentDetailCode = null; |
| GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod") |
| .where("shipmentMethodTypeId", shipmentMethodTypeId, "partyId", "DHL", "roleTypeId", "CARRIER") |
| .queryOne(); |
| if (carrierShipmentMethod == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlNoCarrierShipmentMethod", |
| UtilMisc.toMap("carrierPartyId", "DHL", "shipmentMethodTypeId", shipmentMethodTypeId), locale)); |
| } |
| dhlShipmentDetailCode = carrierShipmentMethod.getString("carrierServiceCode"); |
| |
| // shipping credentials (configured in properties) |
| String userid = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessUserId", resource, "shipment.dhl.access.userid"); |
| String password = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessPassword", resource, "shipment.dhl.access.password"); |
| String shippingKey = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessShippingKey", resource, "shipment.dhl.access.shippingKey"); |
| String accountNbr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessAccountNbr", resource, "shipment.dhl.access.accountNbr"); |
| if ((shippingKey == null) || (accountNbr == null) || (shippingKey.length() == 0) || (accountNbr.length() == 0)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlGatewayNotAvailable", locale)); |
| } |
| |
| // label image preference (PNG or GIF) |
| String labelImagePreference = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "labelImageFormat", resource, "shipment.dhl.label.image.format"); |
| if (labelImagePreference == null) { |
| Debug.logInfo("shipment.dhl.label.image.format not specified, assuming PNG", module); |
| labelImagePreference="PNG"; |
| } else if (!(labelImagePreference.equals("PNG") || labelImagePreference.equals("GIF"))) { |
| Debug.logError("Illegal shipment.dhl.label.image.format: " + labelImagePreference, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlUnknownLabelImageFormat", |
| UtilMisc.toMap("labelImagePreference", labelImagePreference), locale)); |
| } |
| |
| // create AccessRequest XML doc using FreeMarker template |
| String templateName = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "rateEstimateTemplate", resource, "shipment.dhl.template.rate.estimate"); |
| if ((templateName == null) || (templateName.trim().length() == 0)) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlRateEstimateTemplateNotConfigured", locale)); |
| } |
| StringWriter outWriter = new StringWriter(); |
| Map<String, Object> inContext = new HashMap<String, Object>(); |
| inContext.put("action", "GenerateLabel"); |
| inContext.put("userid", userid); |
| inContext.put("password", password); |
| inContext.put("accountNbr", accountNbr); |
| inContext.put("shippingKey", shippingKey); |
| inContext.put("shipDate", UtilDateTime.nowTimestamp()); |
| inContext.put("dhlShipmentDetailCode", dhlShipmentDetailCode); |
| inContext.put("weight", roundedWeight); |
| inContext.put("senderPhoneNbr", originPhoneNumber); |
| inContext.put("companyName", destPostalAddress.getString("toName")); |
| inContext.put("attnTo", destPostalAddress.getString("attnName")); |
| inContext.put("street", destPostalAddress.getString("address1")); |
| inContext.put("streetLine2", destPostalAddress.getString("address2")); |
| inContext.put("city", destPostalAddress.getString("city")); |
| inContext.put("state", destPostalAddress.getString("stateProvinceGeoId")); |
| |
| // DHL ShipIT API does not accept ZIP+4 |
| if ((destPostalAddress.getString("postalCode") != null) && (destPostalAddress.getString("postalCode").length() > 5)) { |
| inContext.put("postalCode", destPostalAddress.getString("postalCode").substring(0,5)); |
| } else { |
| inContext.put("postalCode", destPostalAddress.getString("postalCode")); |
| } |
| inContext.put("phoneNbr", destPhoneNumber); |
| inContext.put("labelImageType", labelImagePreference); |
| inContext.put("shipperReference", shipment.getString("primaryOrderId") + "-" + shipment.getString("primaryShipGroupSeqId")); |
| inContext.put("notifyEmailAddress", recipientEmail); |
| |
| try { |
| ContentWorker.renderContentAsText(dispatcher, delegator, templateName, outWriter, inContext, locale, "text/plain", null, null, false); |
| } catch (Exception e) { |
| Debug.logError(e, "Cannot confirm DHL shipment: Failed to render DHL XML Request.", module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexRateTemplateRenderingError", locale)); |
| } |
| String requestString = outWriter.toString(); |
| if (Debug.verboseOn()) { |
| Debug.logVerbose(requestString, module); |
| } |
| |
| // send the request |
| String responseString = null; |
| try { |
| responseString = sendDhlRequest(requestString, delegator, shipmentGatewayConfigId, resource, locale); |
| if (Debug.verboseOn()) { |
| Debug.logVerbose(responseString, module); |
| } |
| } catch (DhlConnectException e) { |
| String uceErrMsg = "Error sending DHL request for DHL Service Rate: " + e.toString(); |
| Debug.logError(e, uceErrMsg, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexRateTemplateSendingError", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| // pass to handler method |
| return handleDhlShipmentConfirmResponse(responseString, shipmentRouteSegment, shipmentPackageRouteSegs, locale); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexRateTemplateReadingError", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentFedexRateTemplateReadingError", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| |
| // NOTE: Must VOID shipments on errors |
| public static Map<String, Object> handleDhlShipmentConfirmResponse(String rateResponseString, GenericValue shipmentRouteSegment, |
| List<GenericValue> shipmentPackageRouteSegs, Locale locale) throws GenericEntityException { |
| GenericValue shipmentPackageRouteSeg = shipmentPackageRouteSegs.get(0); |
| |
| // TODO: figure out how to handle validation on return XML, which can be mangled |
| // Ideas: try again right away, let user try again, etc. |
| 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); |
| // TODO: VOID |
| } catch (ParserConfigurationException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| // TODO VOID |
| } catch (IOException e2) { |
| String excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString(); |
| Debug.logError(e2, excErrMsg, module); |
| // TODO VOID |
| } |
| |
| // tracking number: Shipment/ShipmentDetail/AirbillNbr |
| Element rootElement = rateResponseDocument.getDocumentElement(); |
| Element shipmentElement = UtilXml.firstChildElement(rootElement, "Shipment"); |
| Element shipmentDetailElement = UtilXml.firstChildElement(shipmentElement, "ShipmentDetail"); |
| String trackingNumber = UtilXml.childElementValue(shipmentDetailElement, "AirbillNbr"); |
| |
| // label: Shipment/Label/Image |
| Element labelElement = UtilXml.firstChildElement(shipmentElement, "Label"); |
| String encodedImageString = UtilXml.childElementValue(labelElement, "Image"); |
| if (encodedImageString == null) { |
| Debug.logError("Cannot find response DHL shipment label. Rate response document is: " + rateResponseString, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShipmentLabelError", |
| UtilMisc.toMap("shipmentPackageRouteSeg", shipmentPackageRouteSeg, |
| "rateResponseString", rateResponseString), locale)); |
| } |
| |
| // TODO: this is a temporary hack to replace the newlines so that Base64 likes the input This is NOT platform independent |
| int size = encodedImageString.length(); |
| StringBuilder sb = new StringBuilder(); |
| for (int i = 0; i < size; i++) { |
| if (encodedImageString.charAt(i) == '\n') |
| continue; |
| sb.append(encodedImageString.charAt(i)); |
| } |
| byte[] labelBytes = Base64.base64Decode(sb.toString().getBytes()); |
| |
| if (labelBytes != null) { |
| // store in db blob |
| shipmentPackageRouteSeg.setBytes("labelImage", labelBytes); |
| } else { |
| Debug.logInfo("Failed to either decode returned DHL label or no data found in eCommerce/Shipment/Label/Image.", module); |
| // TODO: VOID |
| } |
| |
| shipmentPackageRouteSeg.set("trackingCode", trackingNumber); |
| shipmentPackageRouteSeg.set("labelHtml", sb.toString()); |
| shipmentPackageRouteSeg.store(); |
| |
| shipmentRouteSegment.set("trackingIdNumber", trackingNumber); |
| shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_CONFIRMED"); |
| shipmentRouteSegment.store(); |
| |
| return ServiceUtil.returnSuccess(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlShipmentConfirmed", locale)); |
| } |
| |
| |
| public static Document createAccessRequestDocument(Delegator delegator, String shipmentGatewayConfigId, String resource) { |
| Document eCommerceRequestDocument = UtilXml.makeEmptyXmlDocument("eCommerce"); |
| Element eCommerceRequesElement = eCommerceRequestDocument.getDocumentElement(); |
| eCommerceRequesElement.setAttribute("version", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "headVersion", resource, "shipment.dhl.head.version")); |
| eCommerceRequesElement.setAttribute("action", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "headAction", resource, "shipment.dhl.head.action")); |
| Element requestorRequestElement = UtilXml.addChildElement(eCommerceRequesElement, "Requestor", eCommerceRequestDocument); |
| UtilXml.addChildElementValue(requestorRequestElement, "ID", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessUserId", resource, "shipment.dhl.access.userid"), |
| eCommerceRequestDocument); |
| UtilXml.addChildElementValue(requestorRequestElement, "Password", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessPassword", resource, "shipment.dhl.access.password"), |
| eCommerceRequestDocument); |
| return eCommerceRequestDocument; |
| } |
| |
| public static void handleErrors(Element responseElement, List<Object> errorList, Locale locale) { |
| Element faultsElement = UtilXml.firstChildElement(responseElement, |
| "Faults"); |
| List<? extends Element> faultElements = UtilXml.childElementList(faultsElement, "Fault"); |
| if (UtilValidate.isNotEmpty(faultElements)) { |
| for (Element errorElement: faultElements) { |
| StringBuilder errorMessageBuf = new StringBuilder(); |
| |
| String errorCode = UtilXml.childElementValue(errorElement, "Code"); |
| String errorDescription = UtilXml.childElementValue(errorElement, "Desc"); |
| String errorSource = UtilXml.childElementValue(errorElement, "Source"); |
| if (UtilValidate.isEmpty(errorSource)) { |
| errorSource = UtilXml.childElementValue(errorElement, "Context"); |
| } |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, "FacilityShipmentDhlErrorMessage", |
| UtilMisc.toMap("errorCode", errorCode, "errorDescription", errorDescription), locale)); |
| if (UtilValidate.isNotEmpty(errorSource)) { |
| errorMessageBuf.append(UtilProperties.getMessage(resourceError, |
| "FacilityShipmentDhlErrorMessageElement", |
| UtilMisc.toMap("errorSource", errorSource), locale)); |
| } |
| errorList.add(errorMessageBuf.toString()); |
| } |
| } |
| } |
| |
| private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, |
| String resource, String parameterName) { |
| String returnValue = ""; |
| if (UtilValidate.isNotEmpty(shipmentGatewayConfigId)) { |
| try { |
| GenericValue dhl = EntityQuery.use(delegator).from("ShipmentGatewayDhl").where("shipmentGatewayConfigId", shipmentGatewayConfigId).queryOne(); |
| if (UtilValidate.isNotEmpty(dhl)) { |
| Object dhlField = dhl.get(shipmentGatewayConfigParameterName); |
| if (dhlField != null) { |
| returnValue = dhlField.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 DhlConnectException extends GeneralException { |
| DhlConnectException() { |
| super(); |
| } |
| |
| DhlConnectException(String msg) { |
| super(msg); |
| } |
| |
| DhlConnectException(Throwable t) { |
| super(t); |
| } |
| |
| DhlConnectException(String msg, Throwable t) { |
| super(msg, t); |
| } |
| } |