/*
 * 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.fedex;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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.UtilDateTime;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.template.FreeMarkerWorker;
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.party.PartyHelper;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.shipment.shipment.ShipmentServices;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Fedex Shipment Services
 *
 * Implementation of Fedex shipment interface using Ship Manager Direct API
 *
 * TODO: FDXShipDeleteRequest/Reply (on error and via service call)
 * TODO: FDXCloseRequest/Reply
 * TODO: FDXRateRequest/Reply
 * TODO: FDXTrackRequest/Reply
 * TODO: International shipments
 * TODO: Multi-piece shipments
 * TODO: Freight shipments
 */
public class FedexServices {

    public final static String module = FedexServices.class.getName();
    public final static String shipmentPropertiesFile = "shipment.properties";
    public static final String resourceError = "ProductUiLabels";
    
    /**
     * Opens a URL to Fedex and makes a request.
     *
     * @param xmlString XML message to send
     * @param delegator the delegator
     * @param shipmentGatewayConfigId the shipmentGatewayConfigId
     * @param resource resource file name
     * @return XML string response from FedEx
     * @throws FedexConnectException
     */
    public static String sendFedexRequest(String xmlString, Delegator delegator, String shipmentGatewayConfigId, 
            String resource, Locale locale) throws FedexConnectException {
        String url = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectUrl", resource, "shipment.fedex.connect.url");
        if (UtilValidate.isEmpty(url)) {
            throw new FedexConnectException(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexConnectUrlIncomplete", locale));
        }

        // xmlString should contain the auth document at the beginning
        // all documents require an <?xml version="1.0" encoding="UTF-8" ?> header
        if (! xmlString.matches("^(?s)<\\?xml\\s+version=\"1\\.0\"\\s+encoding=\"UTF-8\"\\s*\\?>.*")) {
            throw new FedexConnectException(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexXmlHeaderMalformed", locale));
        }

        // prepare the connect string
        url = url.trim();

        String timeOutStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectTimeout", resource, "shipment.fedex.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("Fedex Connect URL : " + url, module);
            Debug.logVerbose("Fedex XML String : " + xmlString, module);
        }

        HttpClient http = new HttpClient(url);
        http.setTimeout(timeout * 1000);
        String response = null;
        try {
            response = http.post(xmlString);
        } catch (HttpClientException e) {
            Debug.logError(e, "Problem connecting to Fedex server", module);
            throw new FedexConnectException(UtilProperties.getMessage(resourceError, "FacilityShipmentFedexConnectUrlProblem",
                    UtilMisc.toMap("errorString", e.toString()), locale));
        }

        if (response == null) {
            throw new FedexConnectException(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexReceivedNullResponse", locale));
        }
        if (Debug.verboseOn()) {
            Debug.logVerbose("Fedex Response : " + response, module);
        }

        return response;
    }

    /*
    * Register a Fedex account for shipping by obtaining the meter number
    */
    public static Map<String, Object> fedexSubscriptionRequest(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");
        List<Object> errorList = FastList.newInstance();

        Boolean replaceMeterNumber = (Boolean) context.get("replaceMeterNumber");

        if (! replaceMeterNumber.booleanValue()) {
            String meterNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessMeterNumber", resource, "shipment.fedex.access.meterNumber");
            if (UtilValidate.isNotEmpty(meterNumber)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexMeterNumberAlreadyExists", 
                        UtilMisc.toMap("meterNumber", meterNumber), locale));
            }
        }

        String companyPartyId = (String) context.get("companyPartyId");
        String contactPartyName = (String) context.get("contactPartyName");

        Map<String, Object> result = FastMap.newInstance();

        String accountNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessAccountNbr", resource, "shipment.fedex.access.accountNbr");
        if (UtilValidate.isEmpty(accountNumber)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexAccountNumberNotFound", locale));
        }

        if (UtilValidate.isEmpty(contactPartyName)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexContactNameCannotBeEmpty", locale));
        }

        String companyName = null;
        GenericValue postalAddress = null;
        String phoneNumber = null;
        String faxNumber = null;
        String emailAddress = null;
        try {
            // Make sure the company exists
            GenericValue companyParty = EntityQuery.use(delegator).from("Party").where("partyId", companyPartyId).cache().queryOne();
            if (companyParty == null) {
                String errorMessage = "Party with partyId " + companyPartyId + " does not exist";
                Debug.logError(errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexCompanyPartyDoesNotExists", 
                        UtilMisc.toMap("companyPartyId", companyPartyId), locale));
            }

            // Get the company name (required by Fedex)
            companyName = PartyHelper.getPartyName(companyParty);
            if (UtilValidate.isEmpty(companyName)) {
                String errorMessage = "Party with partyId " + companyPartyId + " has no name";
                Debug.logError(errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexCompanyPartyHasNoName", 
                        UtilMisc.toMap("companyPartyId", companyPartyId), locale));
            }

            // Get the contact information for the company
            List<GenericValue> partyContactDetails = EntityQuery.use(delegator).from("PartyContactDetailByPurpose")
                    .where("partyId", companyPartyId)
                    .filterByDate(UtilDateTime.nowTimestamp(), "fromDate", "thruDate", "purposeFromDate", "purposeThruDate")
                    .queryList();

            // Get the first valid postal address (address1, city, postalCode and countryGeoId are required by Fedex)
            List<EntityCondition> postalAddressConditions = FastList.newInstance();
            postalAddressConditions.add(EntityCondition.makeCondition("contactMechTypeId", EntityOperator.EQUALS, "POSTAL_ADDRESS"));
            postalAddressConditions.add(EntityCondition.makeCondition("address1", EntityOperator.NOT_EQUAL, null));
            postalAddressConditions.add(EntityCondition.makeCondition("address1", EntityOperator.NOT_EQUAL, ""));
            postalAddressConditions.add(EntityCondition.makeCondition("city", EntityOperator.NOT_EQUAL, null));
            postalAddressConditions.add(EntityCondition.makeCondition("city", EntityOperator.NOT_EQUAL, ""));
            postalAddressConditions.add(EntityCondition.makeCondition("postalCode", EntityOperator.NOT_EQUAL, null));
            postalAddressConditions.add(EntityCondition.makeCondition("postalCode", EntityOperator.NOT_EQUAL, ""));
            postalAddressConditions.add(EntityCondition.makeCondition("countryGeoId", EntityOperator.NOT_EQUAL, null));
            postalAddressConditions.add(EntityCondition.makeCondition("countryGeoId", EntityOperator.NOT_EQUAL, ""));
            List<GenericValue> postalAddresses = EntityUtil.filterByCondition(partyContactDetails, EntityCondition.makeCondition(postalAddressConditions, EntityOperator.AND));

            // Fedex requires USA or Canada addresses to have a state/province ID, so filter out the ones without
            postalAddressConditions.clear();
            postalAddressConditions.add(EntityCondition.makeCondition("countryGeoId", EntityOperator.IN, UtilMisc.toList("CAN", "USA")));
            postalAddressConditions.add(EntityCondition.makeCondition("stateProvinceGeoId", EntityOperator.EQUALS, null));
            postalAddresses = EntityUtil.filterOutByCondition(postalAddresses, EntityCondition.makeCondition(postalAddressConditions, EntityOperator.AND));
            postalAddressConditions.clear();
            postalAddressConditions.add(EntityCondition.makeCondition("countryGeoId", EntityOperator.IN, UtilMisc.toList("CAN", "USA")));
            postalAddressConditions.add(EntityCondition.makeCondition("stateProvinceGeoId", EntityOperator.EQUALS, ""));
            postalAddresses = EntityUtil.filterOutByCondition(postalAddresses, EntityCondition.makeCondition(postalAddressConditions, EntityOperator.AND));

            postalAddress = EntityUtil.getFirst(postalAddresses);
            if (UtilValidate.isEmpty(postalAddress)) {
                String errorMessage = "Party with partyId " + companyPartyId + " does not have a current, fully populated postal address";
                Debug.logError(errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexCompanyPartyHasNotPostalAddress", 
                        UtilMisc.toMap("companyPartyId", companyPartyId), locale));
            }
            GenericValue countryGeo = EntityQuery.use(delegator).from("Geo").where("geoId", postalAddress.getString("countryGeoId")).cache().queryOne();
            String countryCode = countryGeo.getString("geoCode");
            String stateOrProvinceCode = null;
            // Only add the StateOrProvinceCode element if the address is in USA or Canada
            if (countryCode.equals("CA") || countryCode.equals("US")) {
                GenericValue stateProvinceGeo = EntityQuery.use(delegator).from("Geo").where("geoId", postalAddress.getString("stateProvinceGeoId")).cache().queryOne();
                stateOrProvinceCode = stateProvinceGeo.getString("geoCode");
            }

            // Get the first valid primary phone number (required by Fedex)
            List<EntityCondition> phoneNumberConditions = FastList.newInstance();
            phoneNumberConditions.add(EntityCondition.makeCondition("contactMechTypeId", EntityOperator.EQUALS, "TELECOM_NUMBER"));
            phoneNumberConditions.add(EntityCondition.makeCondition("contactMechPurposeTypeId", EntityOperator.EQUALS, "PRIMARY_PHONE"));
            phoneNumberConditions.add(EntityCondition.makeCondition("areaCode", EntityOperator.NOT_EQUAL, null));
            phoneNumberConditions.add(EntityCondition.makeCondition("areaCode", EntityOperator.NOT_EQUAL, ""));
            phoneNumberConditions.add(EntityCondition.makeCondition("contactNumber", EntityOperator.NOT_EQUAL, null));
            phoneNumberConditions.add(EntityCondition.makeCondition("contactNumber", EntityOperator.NOT_EQUAL, ""));
            List<GenericValue> phoneNumbers = EntityUtil.filterByCondition(partyContactDetails, EntityCondition.makeCondition(phoneNumberConditions, EntityOperator.AND));
            GenericValue phoneNumberValue = EntityUtil.getFirst(phoneNumbers);
            if (UtilValidate.isEmpty(phoneNumberValue)) {
                String errorMessage = "Party with partyId " + companyPartyId + " does not have a current, fully populated primary phone number";
                Debug.logError(errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexCompanyPartyHasNotPrimaryPhoneNumber", 
                        UtilMisc.toMap("companyPartyId", companyPartyId), locale));
            }
            phoneNumber = phoneNumberValue.getString("areaCode") + phoneNumberValue.getString("contactNumber");
            // Fedex doesn't want the North American country code
            if (UtilValidate.isNotEmpty(phoneNumberValue.getString("countryCode")) && !(countryCode.equals("CA") || countryCode.equals("US"))) {
                phoneNumber = phoneNumberValue.getString("countryCode") + phoneNumber;
            }
            phoneNumber = phoneNumber.replaceAll("[^+\\d]", "");

            // Get the first valid fax number
            List<EntityCondition> faxNumberConditions = FastList.newInstance();
            faxNumberConditions.add(EntityCondition.makeCondition("contactMechTypeId", EntityOperator.EQUALS, "TELECOM_NUMBER"));
            faxNumberConditions.add(EntityCondition.makeCondition("contactMechPurposeTypeId", EntityOperator.EQUALS, "FAX_NUMBER"));
            faxNumberConditions.add(EntityCondition.makeCondition("areaCode", EntityOperator.NOT_EQUAL, null));
            faxNumberConditions.add(EntityCondition.makeCondition("areaCode", EntityOperator.NOT_EQUAL, ""));
            faxNumberConditions.add(EntityCondition.makeCondition("contactNumber", EntityOperator.NOT_EQUAL, null));
            faxNumberConditions.add(EntityCondition.makeCondition("contactNumber", EntityOperator.NOT_EQUAL, ""));
            List<GenericValue> faxNumbers = EntityUtil.filterByCondition(partyContactDetails, EntityCondition.makeCondition(faxNumberConditions, EntityOperator.AND));
            GenericValue faxNumberValue = EntityUtil.getFirst(faxNumbers);
            if (! UtilValidate.isEmpty(faxNumberValue)) {
                faxNumber = faxNumberValue.getString("areaCode") + faxNumberValue.getString("contactNumber");
                // Fedex doesn't want the North American country code
                if (UtilValidate.isNotEmpty(faxNumberValue.getString("countryCode")) && !(countryCode.equals("CA") || countryCode.equals("US"))) {
                    faxNumber = faxNumberValue.getString("countryCode") + faxNumber;
                }
                faxNumber = faxNumber.replaceAll("[^+\\d]", "");
            }

            // Get the first valid email address
            List<EntityCondition> emailConditions = FastList.newInstance();
            emailConditions.add(EntityCondition.makeCondition("contactMechTypeId", EntityOperator.EQUALS, "EMAIL_ADDRESS"));
            emailConditions.add(EntityCondition.makeCondition("infoString", EntityOperator.NOT_EQUAL, null));
            emailConditions.add(EntityCondition.makeCondition("infoString", EntityOperator.NOT_EQUAL, ""));
            List<GenericValue> emailAddresses = EntityUtil.filterByCondition(partyContactDetails, EntityCondition.makeCondition(emailConditions, EntityOperator.AND));
            GenericValue emailAddressValue = EntityUtil.getFirst(emailAddresses);
            if (! UtilValidate.isEmpty(emailAddressValue)) {
                emailAddress = emailAddressValue.getString("infoString");
            }

            // Get the location of the Freemarker (XML) template for the FDXSubscriptionRequest
            String templateLocation = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "templateSubscription", resource, "shipment.fedex.template.subscription.location");
            if (UtilValidate.isEmpty(templateLocation)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexSubscriptionTemplateLocationNotFound",
                        UtilMisc.toMap("templateLocation", templateLocation), locale));
            }

            // Populate the Freemarker context
            Map<String, Object> subscriptionRequestContext = FastMap.newInstance();
            subscriptionRequestContext.put("AccountNumber", accountNumber);
            subscriptionRequestContext.put("PersonName", contactPartyName);
            subscriptionRequestContext.put("CompanyName", companyName);
            subscriptionRequestContext.put("PhoneNumber", phoneNumber);
            if (UtilValidate.isNotEmpty(faxNumber)) {
                subscriptionRequestContext.put("FaxNumber", faxNumber);
            }
            if (UtilValidate.isNotEmpty(emailAddress)) {
                subscriptionRequestContext.put("EMailAddress", emailAddress);
            }
            subscriptionRequestContext.put("Line1", postalAddress.getString("address1"));
            if (UtilValidate.isNotEmpty(postalAddress.getString("address2"))) {
                subscriptionRequestContext.put("Line2", postalAddress.getString("address2"));
            }
            subscriptionRequestContext.put("City", postalAddress.getString("city"));
            if (UtilValidate.isNotEmpty(stateOrProvinceCode)) {
                subscriptionRequestContext.put("StateOrProvinceCode", stateOrProvinceCode);
            }
            subscriptionRequestContext.put("PostalCode", postalAddress.getString("postalCode"));
            subscriptionRequestContext.put("CountryCode", countryCode);

            StringWriter outWriter = new StringWriter();
            try {
                FreeMarkerWorker.renderTemplateAtLocation(templateLocation, subscriptionRequestContext, outWriter);
            } catch (Exception e) {
                String errorMessage = "Cannot send Fedex subscription request: Failed to render Fedex XML Subscription Request Template [" + templateLocation + "].";
                Debug.logError(e, errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexSubscriptionTemplateError",
                        UtilMisc.toMap("templateLocation", templateLocation, "errorString", e.getMessage()), locale));
            }
            String fDXSubscriptionRequestString = outWriter.toString();

            // Send the request
            String fDXSubscriptionReplyString = null;
            try {
                fDXSubscriptionReplyString = sendFedexRequest(fDXSubscriptionRequestString, delegator, shipmentGatewayConfigId, resource, locale);
                Debug.logInfo("Fedex response for FDXSubscriptionRequest:" + fDXSubscriptionReplyString, module);
            } catch (FedexConnectException e) {
                String errorMessage = "Error sending Fedex request for FDXSubscriptionRequest: " + e.toString();
                Debug.logError(e, errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexSubscriptionTemplateSendingError",
                        UtilMisc.toMap("errorString", e.toString()), locale));
            }

            Document fDXSubscriptionReplyDocument = null;
            try {
                fDXSubscriptionReplyDocument = UtilXml.readXmlDocument(fDXSubscriptionReplyString, false);
                Debug.logInfo("Fedex response for FDXSubscriptionRequest:" + fDXSubscriptionReplyString, module);
            } catch (Exception e) {
                String errorMessage = "Error parsing the FDXSubscriptionRequest response: " + e.toString();
                Debug.logError(e, errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexSubscriptionTemplateParsingError",
                        UtilMisc.toMap("errorString", e.toString()), locale));
            }

            Element fedexSubscriptionReplyElement = fDXSubscriptionReplyDocument.getDocumentElement();
            handleErrors(fedexSubscriptionReplyElement, errorList, locale);

            if (UtilValidate.isNotEmpty(errorList)) {
                return ServiceUtil.returnError(errorList);
            }

            String meterNumber = UtilXml.childElementValue(fedexSubscriptionReplyElement, "MeterNumber");

            result.put("meterNumber", meterNumber);

        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }

        return result;
    }

    /**
     *
     * Send a FDXShipRequest via the Ship Manager Direct API
     */
    public static Map<String, Object> fedexShipRequest(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        LocalDispatcher dispatcher = dctx.getDispatcher();
        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, 
                    "FacilityShipmentFedexGatewayNotAvailable", locale));
        }
        
        // Get the location of the Freemarker (XML) template for the FDXShipRequest
        String templateLocation = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "templateShipment", resource, "shipment.fedex.template.ship.location");
        if (UtilValidate.isEmpty(templateLocation)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexShipmentTemplateLocationNotFound",
                    UtilMisc.toMap("templateLocation", templateLocation), locale));
        }

        // Get the Fedex account number
        String accountNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessAccountNbr", resource, "shipment.fedex.access.accountNbr");
        if (UtilValidate.isEmpty(accountNumber)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexAccountNumberNotFound", locale));
        }

        // Get the Fedex meter number
        String meterNumber = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "accessMeterNumber", resource, "shipment.fedex.access.meterNumber");
        if (UtilValidate.isEmpty(meterNumber)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexMeterNumberNotFound",
                    UtilMisc.toMap("meterNumber", meterNumber), locale));
        }

        // Get the weight units to be used in the request
        String weightUomId = EntityUtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.weight.uom", delegator);
        if (UtilValidate.isEmpty(weightUomId)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentDefaultWeightUomIdNotFound", locale));
        } else if (! ("WT_lb".equals(weightUomId) || "WT_kg".equals(weightUomId))) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentDefaultWeightUomIdNotValid", locale));
        }

        // Get the dimension units to be used in the request
        String dimensionsUomId = EntityUtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.dimension.uom", delegator);
        if (UtilValidate.isEmpty(dimensionsUomId)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentDefaultDimensionUomIdNotFound", locale));
        } else if (! ("LEN_in".equals(dimensionsUomId) || "LEN_cm".equals(dimensionsUomId))) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentDefaultDimensionUomIdNotValid", locale));
        }

        // Get the label image type to be returned
        String labelImageType = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "labelImageType", resource, "shipment.fedex.labelImageType");
        if (UtilValidate.isEmpty(labelImageType)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexLabelImageTypeNotFound", locale));
        } else if (! ("PDF".equals(labelImageType) || "PNG".equals(labelImageType))) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexLabelImageTypeNotValid", locale));
        }

        // Get the default dropoff type
        String dropoffType = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "defaultDropoffType", resource, "shipment.fedex.default.dropoffType");
        if (UtilValidate.isEmpty(dropoffType)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexDropoffTypeNotFound", locale));
        }

        try {
            Map<String, Object> shipRequestContext = FastMap.newInstance();

            // Get the shipment and the shipmentRouteSegment
            GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne();
            if (UtilValidate.isEmpty(shipment)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "ProductShipmentNotFoundId", locale) + shipmentId);
            }
            GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne();
            if (UtilValidate.isEmpty(shipmentRouteSegment)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "ProductShipmentRouteSegmentNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            // Determine the Fedex carrier
            String carrierPartyId = shipmentRouteSegment.getString("carrierPartyId");
            if (! "FEDEX".equals(carrierPartyId)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexNotRouteSegmentCarrier",
                        UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale));
            }

            // Check the shipmentRouteSegment's carrier status
            if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("carrierServiceStatusId")) && !"SHRSCS_NOT_STARTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexRouteSegmentStatusNotStarted",
                        UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId, "shipmentRouteSegmentStatus", shipmentRouteSegment.getString("carrierServiceStatusId")), locale));
            }

            // Translate shipmentMethodTypeId to Fedex service code and carrier code
            String shipmentMethodTypeId = shipmentRouteSegment.getString("shipmentMethodTypeId");
            GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod").where("shipmentMethodTypeId", shipmentMethodTypeId, "partyId", "FEDEX", "roleTypeId", "CARRIER").queryOne();
            if (UtilValidate.isEmpty(carrierShipmentMethod)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexRouteSegmentCarrierShipmentMethodNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "carrierPartyId", carrierPartyId, "shipmentMethodTypeId", shipmentMethodTypeId), locale));
            }
            if (UtilValidate.isEmpty(carrierShipmentMethod.getString("carrierServiceCode"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexNoCarrieServiceCode",
                        UtilMisc.toMap("shipmentMethodTypeId", shipmentMethodTypeId), locale));
            }
            String service = carrierShipmentMethod.getString("carrierServiceCode");

            // CarrierCode is FDXG only for FEDEXGROUND and GROUNDHOMEDELIVERY services.
            boolean isGroundService = service.equals("FEDEXGROUND") || service.equals("GROUNDHOMEDELIVERY");
            String carrierCode = isGroundService ? "FDXG" : "FDXE";

            // 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(shipmentRouteSegment.getString("currencyUomId"))) {
                currencyCode = shipment.getString("currencyUomId");
            } else {
                currencyCode = EntityUtilProperties.getPropertyValue("general.properties", "currency.uom.id.default", "USD", delegator);
            }

            // Get and validate origin postal address
            GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false);
            if (UtilValidate.isEmpty(originPostalAddress)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginPostalAddressNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            } else if (UtilValidate.isEmpty(originPostalAddress.getString("address1"))      ||
                       UtilValidate.isEmpty(originPostalAddress.getString("city"))          ||
                       UtilValidate.isEmpty(originPostalAddress.getString("postalCode"))    ||
                       UtilValidate.isEmpty(originPostalAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginPostalAddressNotComplete",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo", false);
            if (UtilValidate.isEmpty(originCountryGeo)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginCountryGeoNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            
            String originAddressCountryCode = originCountryGeo.getString("geoCode");
            String originAddressStateOrProvinceCode = null;

            // Only add the StateOrProvinceCode element if the address is in USA or Canada
            if (originAddressCountryCode.equals("CA") || originAddressCountryCode.equals("US")) {
                if (UtilValidate.isEmpty(originPostalAddress.getString("stateProvinceGeoId"))) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentRouteSegmentOriginStateProvinceGeoIdRequired",
                            UtilMisc.toMap("contactMechId", originPostalAddress.getString("contactMechId"), 
                                    "shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
                }
                GenericValue stateProvinceGeo = EntityQuery.use(delegator).from("Geo").where("geoId", originPostalAddress.getString("stateProvinceGeoId")).cache().queryOne();
                originAddressStateOrProvinceCode = stateProvinceGeo.getString("geoCode");
            }

            // Get and validate origin telecom number
            GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber", false);
            if (UtilValidate.isEmpty(originTelecomNumber)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginTelecomNumberNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            String originContactPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber");

            // Fedex doesn't want the North American country code
            if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !(originAddressCountryCode.equals("CA") || originAddressCountryCode.equals("US"))) {
                originContactPhoneNumber = originTelecomNumber.getString("countryCode") + originContactPhoneNumber;
            }
            originContactPhoneNumber = originContactPhoneNumber.replaceAll("[^+\\d]", "");

            // Get the origin contact name from the owner of the origin facility
            GenericValue partyFrom = null;
            GenericValue originFacility = shipment.getRelatedOne("OriginFacility", false);
            if (UtilValidate.isEmpty(originFacility)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexOriginFacilityRequired",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            } else {
                partyFrom = originFacility.getRelatedOne("OwnerParty", false);
                if (UtilValidate.isEmpty(partyFrom)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexOwnerPartyRequired",
                            UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId,
                                    "facilityId", originFacility.getString("facilityId")), locale));
                }
            }

            String originContactKey = "PERSON".equals(partyFrom.getString("partyTypeId")) ? "OriginContactPersonName" : "OriginContactCompanyName";
            String originContactName = PartyHelper.getPartyName(partyFrom, false);
            if (UtilValidate.isEmpty(originContactName)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexPartyFromHasNoName",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            // Get and validate destination postal address
            GenericValue destinationPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false);
            if (UtilValidate.isEmpty(destinationPostalAddress)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestPostalAddressNotFound",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            } else if (UtilValidate.isEmpty(destinationPostalAddress.getString("address1"))      ||
                       UtilValidate.isEmpty(destinationPostalAddress.getString("city"))          ||
                       UtilValidate.isEmpty(destinationPostalAddress.getString("postalCode"))    ||
                       UtilValidate.isEmpty(destinationPostalAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestPostalAddressIncomplete",
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            GenericValue destinationCountryGeo = destinationPostalAddress.getRelatedOne("CountryGeo", false);
            if (UtilValidate.isEmpty(destinationCountryGeo)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestCountryGeoNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            String destinationAddressCountryCode = destinationCountryGeo.getString("geoCode");
            String destinationAddressStateOrProvinceCode = null;

            // Only add the StateOrProvinceCode element if the address is in USA or Canada
            if (destinationAddressCountryCode.equals("CA") || destinationAddressCountryCode.equals("US")) {
                if (UtilValidate.isEmpty(destinationPostalAddress.getString("stateProvinceGeoId"))) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentRouteSegmentDestStateProvinceGeoIdNotFound", 
                            UtilMisc.toMap("contactMechId", destinationPostalAddress.getString("contactMechId"), 
                                    "shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
                }
                GenericValue stateProvinceGeo = EntityQuery.use(delegator).from("Geo").where("geoId", destinationPostalAddress.getString("stateProvinceGeoId")).cache().queryOne();
                destinationAddressStateOrProvinceCode = stateProvinceGeo.getString("geoCode");
            }

            // Get and validate destination telecom number
            GenericValue destinationTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false);
            if (UtilValidate.isEmpty(destinationTelecomNumber)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestTelecomNumberNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            String destinationContactPhoneNumber = destinationTelecomNumber.getString("areaCode") + destinationTelecomNumber.getString("contactNumber");

            // Fedex doesn't want the North American country code
            if (UtilValidate.isNotEmpty(destinationTelecomNumber.getString("countryCode")) && !(destinationAddressCountryCode.equals("CA") || destinationAddressCountryCode.equals("US"))) {
                destinationContactPhoneNumber = destinationTelecomNumber.getString("countryCode") + destinationContactPhoneNumber;
            }
            destinationContactPhoneNumber = destinationContactPhoneNumber.replaceAll("[^+\\d]", "");

            // Get the destination contact name
            String destinationPartyId = shipment.getString("partyIdTo");
            if (UtilValidate.isEmpty(destinationPartyId)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexPartyToRequired", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            GenericValue partyTo = EntityQuery.use(delegator).from("Party").where("partyId", destinationPartyId).queryOne();
            String destinationContactKey = "PERSON".equals(partyTo.getString("partyTypeId")) ? "DestinationContactPersonName" : "DestinationContactCompanyName";
            String destinationContactName = PartyHelper.getPartyName(partyTo, false);
            if (UtilValidate.isEmpty(destinationContactName)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexPartyToHasNoName", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            String homeDeliveryType = null;
            Timestamp homeDeliveryDate = null;
            if ("GROUNDHOMEDELIVERY".equals(service)) {

                // Determine the home-delivery instructions
                homeDeliveryType = shipmentRouteSegment.getString("homeDeliveryType");
                if (UtilValidate.isNotEmpty(homeDeliveryType)) {
                    if (! (homeDeliveryType.equals("DATECERTAIN") || homeDeliveryType.equals("EVENING") || homeDeliveryType.equals("APPOINTMENT"))) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentFedexHomeDeliveryTypeInvalid", 
                                UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
                    }
                }
                homeDeliveryDate = shipmentRouteSegment.getTimestamp("homeDeliveryDate");
                if (UtilValidate.isEmpty(homeDeliveryDate)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexHomeDeliveryDateRequired", 
                            UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
                } else if (homeDeliveryDate.before(UtilDateTime.nowTimestamp())) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexHomeDeliveryDateBeforeCurrentDate", 
                            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, 
                        "FacilityShipmentFedexMultiplePackagesNotSupported", locale));
            }

            // TODO: Multi-piece shipments, including logic to cancel packages 1-n if FDXShipRequest n+1 fails

            // Populate the Freemarker context with the non-package-related information
            shipRequestContext.put("AccountNumber", accountNumber);
            shipRequestContext.put("MeterNumber", meterNumber);
            shipRequestContext.put("CarrierCode", carrierCode);
            shipRequestContext.put("ShipDate", UtilDateTime.nowTimestamp());
            shipRequestContext.put("ShipTime", UtilDateTime.nowTimestamp());
            shipRequestContext.put("DropoffType", dropoffType);
            shipRequestContext.put("Service", service);
            shipRequestContext.put("WeightUnits", weightUomId.equals("WT_kg") ? "KGS" : "LBS");
            shipRequestContext.put("CurrencyCode", currencyCode);
            shipRequestContext.put("PayorType", "SENDER");
            shipRequestContext.put(originContactKey, originContactName);
            shipRequestContext.put("OriginContactPhoneNumber", originContactPhoneNumber);
            shipRequestContext.put("OriginAddressLine1", originPostalAddress.getString("address1"));
            if (UtilValidate.isNotEmpty(originPostalAddress.getString("address2"))) {
                shipRequestContext.put("OriginAddressLine2", originPostalAddress.getString("address2"));
            }
            shipRequestContext.put("OriginAddressCity", originPostalAddress.getString("city"));
            if (UtilValidate.isNotEmpty(originAddressStateOrProvinceCode)) {
                shipRequestContext.put("OriginAddressStateOrProvinceCode", originAddressStateOrProvinceCode);
            }
            shipRequestContext.put("OriginAddressPostalCode", originPostalAddress.getString("postalCode"));
            shipRequestContext.put("OriginAddressCountryCode", originAddressCountryCode);
            shipRequestContext.put(destinationContactKey, destinationContactName);
            shipRequestContext.put("DestinationContactPhoneNumber", destinationContactPhoneNumber);
            shipRequestContext.put("DestinationAddressLine1", destinationPostalAddress.getString("address1"));
            if (UtilValidate.isNotEmpty(destinationPostalAddress.getString("address2"))) {
                shipRequestContext.put("DestinationAddressLine2", destinationPostalAddress.getString("address2"));
            }
            shipRequestContext.put("DestinationAddressCity", destinationPostalAddress.getString("city"));
            if (UtilValidate.isNotEmpty(destinationAddressStateOrProvinceCode)) {
                shipRequestContext.put("DestinationAddressStateOrProvinceCode", destinationAddressStateOrProvinceCode);
            }
            shipRequestContext.put("DestinationAddressPostalCode", destinationPostalAddress.getString("postalCode"));
            shipRequestContext.put("DestinationAddressCountryCode", destinationAddressCountryCode);
            shipRequestContext.put("LabelType", "2DCOMMON"); // Required type for FDXShipRequest. Not directly in the FTL because it shouldn't be changed.
            shipRequestContext.put("LabelImageType", labelImageType);
            if (UtilValidate.isNotEmpty(homeDeliveryType)) {
                shipRequestContext.put("HomeDeliveryType", homeDeliveryType);
            }
            if (homeDeliveryDate != null) {
                shipRequestContext.put("HomeDeliveryDate", homeDeliveryDate);
            }

            // Get the weight from the ShipmentRouteSegment first, which overrides all later weight computations
            boolean hasBillingWeight = false;
            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 + ", assuming default shipment.fedex.weightUomId of " + weightUomId + " from " + shipmentPropertiesFile,  module);
                    billingWeightUomId = weightUomId;
                }

                // Convert the weight if necessary
                if (! billingWeightUomId.equals(weightUomId)) {
                    Map<String, Object> results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", billingWeightUomId, "uomIdTo", weightUomId, "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)
            for (GenericValue shipmentPackageRouteSeg: shipmentPackageRouteSegs) {
                GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false);
                GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType", false);

                // FedEx requires the packaging type
                String packaging = null;
                if (UtilValidate.isEmpty(shipmentBoxType)) {
                    packaging = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "defaultPackagingType", resource, "shipment.fedex.default.packagingType");
                    if (UtilValidate.isEmpty(packaging)) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentFedexPackingTypeNotConfigured", 
                                UtilMisc.toMap("shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"), 
                                        "shipmentId", shipmentId), locale));
                    }
                    Debug.logWarning("Package " + shipmentPackage.getString("shipmentPackageSeqId") + " of shipment " + shipmentId + " has no packaging type set - defaulting to " + packaging, module);
                } else {
                    packaging = shipmentBoxType.getString("shipmentBoxTypeId");
                }

                // Make sure that the packaging type is valid for FedEx
                GenericValue carrierShipmentBoxType = EntityQuery.use(delegator).from("CarrierShipmentBoxType").where("partyId", "FEDEX", "shipmentBoxTypeId", packaging).queryOne();
                if (UtilValidate.isEmpty(carrierShipmentBoxType)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexPackingTypeInvalid", 
                            UtilMisc.toMap("shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                    "shipmentId", shipmentId), locale));
                } else if (UtilValidate.isEmpty(carrierShipmentBoxType.getString("packagingTypeCode"))) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexPackingTypeMissing", 
                            UtilMisc.toMap("shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                    "shipmentId", shipmentId), locale));
                }
                packaging = carrierShipmentBoxType.getString("packagingTypeCode");

                // Determine the dimensions of the package
                BigDecimal dimensionsLength = null;
                BigDecimal dimensionsWidth = null;
                BigDecimal dimensionsHeight = null;
                if (shipmentBoxType != null) {
                    dimensionsLength = shipmentBoxType.getBigDecimal("boxLength");
                    dimensionsWidth = shipmentBoxType.getBigDecimal("boxWidth");
                    dimensionsHeight = shipmentBoxType.getBigDecimal("boxHeight");

                    String boxDimensionsUomId = null;
                    GenericValue boxDimensionsUom = shipmentBoxType.getRelatedOne("DimensionUom", false);
                    if (! UtilValidate.isEmpty(boxDimensionsUom)) {
                        boxDimensionsUomId = boxDimensionsUom.getString("uomId");
                    } else {
                        Debug.logWarning("Packaging type for package " + shipmentPackage.getString("shipmentPackageSeqId") + " of shipmentRouteSegment " + shipmentRouteSegmentId + " of shipment " + shipmentId + " is missing dimensionUomId, assuming default shipment.default.dimension.uom of " + dimensionsUomId + " from " + shipmentPropertiesFile,  module);
                        boxDimensionsUomId = dimensionsUomId;
                    }
                    if (dimensionsLength != null && dimensionsLength.compareTo(BigDecimal.ZERO) > 0) {
                        if (! boxDimensionsUomId.equals(dimensionsUomId)) {
                            Map<String, Object> results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", boxDimensionsUomId, "uomIdTo", dimensionsUomId, "originalValue", dimensionsLength));
                            if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) {
                                Debug.logWarning("Unable to convert length for package " + shipmentPackage.getString("shipmentPackageSeqId") + " of shipmentRouteSegment " + shipmentRouteSegmentId + " of shipment " + shipmentId , module);
                                dimensionsLength = null;
                            } else {
                                dimensionsLength = (BigDecimal) results.get("convertedValue");
                            }
                        }

                    }
                    if (dimensionsWidth != null && dimensionsWidth.compareTo(BigDecimal.ZERO) > 0) {
                        if (! boxDimensionsUomId.equals(dimensionsUomId)) {
                            Map<String, Object> results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", boxDimensionsUomId, "uomIdTo", dimensionsUomId, "originalValue", dimensionsWidth));
                            if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) {
                                Debug.logWarning("Unable to convert width for package " + shipmentPackage.getString("shipmentPackageSeqId") + " of shipmentRouteSegment " + shipmentRouteSegmentId + " of shipment " + shipmentId , module);
                                dimensionsWidth = null;
                            } else {
                                dimensionsWidth = (BigDecimal) results.get("convertedValue");
                            }
                        }

                    }
                    if (dimensionsHeight != null && dimensionsHeight.compareTo(BigDecimal.ZERO) > 0) {
                        if (! boxDimensionsUomId.equals(dimensionsUomId)) {
                            Map<String, Object> results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", boxDimensionsUomId, "uomIdTo", dimensionsUomId, "originalValue", dimensionsHeight));
                            if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) {
                                Debug.logWarning("Unable to convert height for package " + shipmentPackage.getString("shipmentPackageSeqId") + " of shipmentRouteSegment " + shipmentRouteSegmentId + " of shipment " + shipmentId , module);
                                dimensionsHeight = null;
                            } else {
                                dimensionsHeight = (BigDecimal) results.get("convertedValue");
                            }
                        }

                    }
                }

                // Determine the package weight (possibly overriden by route segment billing weight)
                BigDecimal packageWeight = null;
                if (! hasBillingWeight) {
                    if (UtilValidate.isNotEmpty(shipmentPackage.getString("weight"))) {
                        packageWeight = shipmentPackage.getBigDecimal("weight");
                    } else {

                        // Use default weight if available
                        try {
                            packageWeight = new BigDecimal(EntityUtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.weight.value", delegator));
                        } catch (NumberFormatException ne) {
                            Debug.logWarning("Default shippable weight not configured (shipment.default.weight.value), assuming 1.0" + weightUomId , module);
                            packageWeight = BigDecimal.ONE;
                        }
                    }

                    // Convert weight if necessary
                    String packageWeightUomId = shipmentPackage.getString("weightUomId");
                    if (UtilValidate.isEmpty(packageWeightUomId)) {
                        Debug.logWarning("Shipment Route Segment missing weightUomId in shipmentId " + shipmentId + ", assuming shipment.default.weight.uom of " + weightUomId + " from " + shipmentPropertiesFile,  module);
                        packageWeightUomId = weightUomId;
                    }
                    if (! packageWeightUomId.equals(weightUomId)) {
                        Map<String, Object> results = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", packageWeightUomId, "uomIdTo", weightUomId, "originalValue", packageWeight));
                        if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) {
                            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                    "FacilityShipmentFedexWeightOfPackageCannotBeConverted", 
                                    UtilMisc.toMap("shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                            "shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale));
                        } else {
                            packageWeight = (BigDecimal) results.get("convertedValue");
                        }
                    }
                }
                BigDecimal weight = hasBillingWeight ? billingWeight : packageWeight;
                if (weight == null || weight.compareTo(BigDecimal.ZERO) < 0) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentFedexWeightOfPackageNotAvailable", 
                            UtilMisc.toMap("shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                    "shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale));
                }

                // Populate the Freemarker context with package-related information
                shipRequestContext.put("CustomerReference", shipmentId + ":" + shipmentRouteSegmentId + ":" + shipmentPackage.getString("shipmentPackageSeqId"));
                shipRequestContext.put("DropoffType", dropoffType);
                shipRequestContext.put("Packaging", packaging);
                if (UtilValidate.isNotEmpty(dimensionsUomId) &&
                    dimensionsLength != null && dimensionsLength.setScale(0, BigDecimal.ROUND_HALF_UP).compareTo(BigDecimal.ZERO) > 0 &&
                    dimensionsWidth != null && dimensionsWidth.setScale(0, BigDecimal.ROUND_HALF_UP).compareTo(BigDecimal.ZERO) > 0   &&
                    dimensionsHeight != null && dimensionsHeight.setScale(0, BigDecimal.ROUND_HALF_UP).compareTo(BigDecimal.ZERO) > 0) {
                        shipRequestContext.put("DimensionsUnits", dimensionsUomId.equals("LEN_in") ? "IN" : "CM");
                        shipRequestContext.put("DimensionsLength", dimensionsLength.setScale(0, BigDecimal.ROUND_HALF_UP).toString());
                        shipRequestContext.put("DimensionsWidth", dimensionsWidth.setScale(0, BigDecimal.ROUND_HALF_UP).toString());
                        shipRequestContext.put("DimensionsHeight", dimensionsHeight.setScale(0, BigDecimal.ROUND_HALF_UP).toString());
                }
                shipRequestContext.put("Weight", weight.setScale(1, BigDecimal.ROUND_UP).toString());
            }

            StringWriter outWriter = new StringWriter();
            try {
                FreeMarkerWorker.renderTemplateAtLocation(templateLocation, shipRequestContext, outWriter);
            } catch (Exception e) {
                String errorMessage = "Cannot confirm Fedex shipment: Failed to render Fedex XML Ship Request Template [" + templateLocation + "].";
                Debug.logError(e, errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexShipmentTemplateError", 
                        UtilMisc.toMap("templateLocation", templateLocation, "errorString", e.getMessage()), locale));
            }

            // Pass the request string to the sending method
            String fDXShipRequestString = outWriter.toString();
            String fDXShipReplyString = null;
            try {
                fDXShipReplyString = sendFedexRequest(fDXShipRequestString, delegator, shipmentGatewayConfigId, resource, locale);
                if (Debug.verboseOn()) {
                    Debug.logVerbose(fDXShipReplyString, module);
                }
            } catch (FedexConnectException e) {
                String errorMessage = "Error sending Fedex request for FDXShipRequest: ";
                Debug.logError(e, errorMessage, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentFedexShipmentTemplateSendingError", 
                        UtilMisc.toMap("errorString", e.toString()), locale));
            }

            // Pass the reply to the handler method
            return handleFedexShipReply(fDXShipReplyString, shipmentRouteSegment, shipmentPackageRouteSegs, locale);

        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexShipmentTemplateServiceError", 
                    UtilMisc.toMap("errorString", e.toString()), locale));
        } catch (GenericServiceException se) {
            Debug.logError(se, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexShipmentTemplateServiceError", 
                    UtilMisc.toMap("errorString", se.toString()), locale));
        }
    }

    /**
     * Extract the tracking number and shipping label from the FDXShipReply XML string
     * @param fDXShipReplyString
     * @param shipmentRouteSegment
     * @param shipmentPackageRouteSegs
     * @throws GenericEntityException
     */
    public static Map<String, Object> handleFedexShipReply(String fDXShipReplyString, GenericValue shipmentRouteSegment, 
            List<GenericValue> shipmentPackageRouteSegs, Locale locale) throws GenericEntityException {
        List<Object> errorList = FastList.newInstance();
        GenericValue shipmentPackageRouteSeg = shipmentPackageRouteSegs.get(0);

        Document fdxShipReplyDocument = null;
        try {
            fdxShipReplyDocument = UtilXml.readXmlDocument(fDXShipReplyString, false);
        } catch (Exception e) {
            String errorMessage = "Error parsing the FDXShipReply: " + e.toString();
            Debug.logError(e, errorMessage, module);
            // TODO Cancel the package
        }

        if (UtilValidate.isEmpty(fdxShipReplyDocument)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexShipmentTemplateParsingError", locale));
        }

        // Tracking number: Tracking/TrackingNumber
        Element rootElement = fdxShipReplyDocument.getDocumentElement();

        handleErrors(rootElement, errorList, locale);

        if (UtilValidate.isNotEmpty(errorList)) {
            return ServiceUtil.returnError(errorList);
        }

        Element trackingElement = UtilXml.firstChildElement(rootElement, "Tracking");
        String trackingNumber = UtilXml.childElementValue(trackingElement, "TrackingNumber");

        // Label: Labels/OutboundLabel
        Element labelElement = UtilXml.firstChildElement(rootElement, "Labels");
        String encodedImageString = UtilXml.childElementValue(labelElement, "OutboundLabel");
        if (UtilValidate.isEmpty(encodedImageString)) {
            Debug.logError("Cannot find FDXShipReply label. FDXShipReply document is: " + fDXShipReplyString, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentFedexShipmentTemplateLabelNotFound", 
                    UtilMisc.toMap("shipmentPackageRouteSeg", shipmentPackageRouteSeg,
                            "fDXShipReplyString", fDXShipReplyString), locale));
        }

        byte[] labelBytes = Base64.base64Decode(encodedImageString.getBytes());

        if (labelBytes != null) {

            // Store in db blob
            shipmentPackageRouteSeg.setBytes("labelImage", labelBytes);
        } else {
            Debug.logInfo("Failed to either decode returned FedEx label or no data found in Labels/OutboundLabel.", module);
            // TODO: Cancel the package
        }

        shipmentPackageRouteSeg.set("trackingCode", trackingNumber);
        shipmentPackageRouteSeg.set("labelHtml", encodedImageString);
        shipmentPackageRouteSeg.store();

        shipmentRouteSegment.set("trackingIdNumber", trackingNumber);
        shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_CONFIRMED");
        shipmentRouteSegment.store();
        
        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resourceError, 
                "FacilityShipmentFedexShipmentConfirmed", locale));
    }

    public static void handleErrors(Element rootElement, List<Object> errorList, Locale locale) {
        Element errorElement = null;
        if ("Error".equalsIgnoreCase(rootElement.getNodeName())) {
            errorElement = rootElement;
        } else {
            errorElement = UtilXml.firstChildElement(rootElement, "Error");
        }
        if (UtilValidate.isNotEmpty(errorElement)) {
            Element errorCodeElement = UtilXml.firstChildElement(errorElement, "Code");
            Element errorMessageElement = UtilXml.firstChildElement(errorElement, "Message");
            if (errorCodeElement != null || errorMessageElement != null) {
                String errorCode = UtilXml.childElementValue(errorElement, "Code");
                String errorMessage = UtilXml.childElementValue(errorElement, "Message");
                if (UtilValidate.isNotEmpty(errorCode) || UtilValidate.isNotEmpty(errorMessage)) {
                    errorList.add(UtilProperties.getMessage(resourceError, "FacilityShipmentFedexErrorMessage", 
                            UtilMisc.toMap("errorCode", errorCode, "errorMessage", errorMessage), locale));
                }
            }
        }
    }
    
    private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, 
            String resource, String parameterName) {
        String returnValue = "";
        if (UtilValidate.isNotEmpty(shipmentGatewayConfigId)) {
            try {
                GenericValue fedex = EntityQuery.use(delegator).from("ShipmentGatewayFedex").where("shipmentGatewayConfigId", shipmentGatewayConfigId).queryOne();
                if (UtilValidate.isNotEmpty(fedex)) {
                    Object fedexField = fedex.get(shipmentGatewayConfigParameterName);
                    if (fedexField != null) {
                        returnValue = fedexField.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 FedexConnectException extends GeneralException {
    FedexConnectException() {
        super();
    }

    FedexConnectException(String msg) {
        super(msg);
    }

    FedexConnectException(Throwable t) {
        super(t);
    }

    FedexConnectException(String msg, Throwable t) {
        super(msg, t);
    }
}
