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

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javolution.util.FastList;
import javolution.util.FastMap;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilFormatOut;
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.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.transaction.GenericTransactionException;
import org.ofbiz.entity.transaction.TransactionUtil;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.product.product.ProductWorker;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class OagisInventoryServices {

    public static final String module = OagisInventoryServices.class.getName();
    public static final String resource = "OagisUiLabels";
    public static final Double doubleZero = new Double(0.0);
    public static final Double doubleOne = new Double(1.0);
    public static final String syncInventoryFacilityId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.SyncInventoryFacilityId");

    public static Map<String, Object> oagisReceiveSyncInventory(DispatchContext ctx, Map<String, Object> context) {
        Document doc = (Document) context.get("document");
        boolean isErrorRetry = Boolean.TRUE.equals(context.get("isErrorRetry"));
        Delegator delegator = ctx.getDelegator();
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        List<Map<String, String>> errorMapList = FastList.newInstance();
        List<Map<String, Object>> inventoryMapList = FastList.newInstance();

        GenericValue userLogin = null;
        try {
            userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system"));
        } catch (GenericEntityException e) {
            String errMsg = "Error Getting UserLogin: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        Element syncInventoryRootElement = doc.getDocumentElement();
        syncInventoryRootElement.normalize();
        Element docCtrlAreaElement = UtilXml.firstChildElement(syncInventoryRootElement, "os:CNTROLAREA");
        Element docBsrElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:BSR");
        Element docSenderElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:SENDER");

        String bsrVerb = UtilXml.childElementValue(docBsrElement, "of:VERB");
        String bsrNoun = UtilXml.childElementValue(docBsrElement, "of:NOUN");
        String bsrRevision = UtilXml.childElementValue(docBsrElement, "of:REVISION");


        String logicalId = UtilXml.childElementValue(docSenderElement, "of:LOGICALID");
        String component = UtilXml.childElementValue(docSenderElement, "of:COMPONENT");
        String task = UtilXml.childElementValue(docSenderElement, "of:TASK");
        String referenceId = UtilXml.childElementValue(docSenderElement, "of:REFERENCEID");
        String confirmation = UtilXml.childElementValue(docSenderElement, "of:CONFIRMATION");
        String authId = UtilXml.childElementValue(docSenderElement, "of:AUTHID");

        // create oagis message info
        Map<String, Object> comiCtx = FastMap.newInstance();
        comiCtx.put("logicalId", logicalId);
        comiCtx.put("component", component);
        comiCtx.put("task", task);
        comiCtx.put("referenceId", referenceId);
        comiCtx.put("confirmation", confirmation);
        comiCtx.put("authId", authId);
        comiCtx.put("bsrVerb", bsrVerb);
        comiCtx.put("bsrNoun", bsrNoun);
        comiCtx.put("bsrRevision", bsrRevision);
        comiCtx.put("receivedDate", UtilDateTime.nowTimestamp());
        comiCtx.put("outgoingMessage", "N");
        comiCtx.put("processingStatusId", "OAGMP_RECEIVED");
        comiCtx.put("userLogin", userLogin);
        if (OagisServices.debugSaveXmlIn) {
            try {
                comiCtx.put("fullMessageXml", UtilXml.writeXmlDocument(doc));
            } catch (IOException e) {
                // this is just for debug info, so just log and otherwise ignore error
                String errMsg = "Warning: error creating text from XML Document for saving to database: " + e.toString();
                Debug.logWarning(errMsg, module);
            }
        }
        try {
            if (isErrorRetry) {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } else {
                dispatcher.runSync("createOagisMessageInfo", comiCtx, 60, true);
            }
        } catch (GenericServiceException e) {
            String errMsg = "Error creating OagisMessageInfo for the Incoming Message: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        // data area elements
        List<? extends Element> dataAreaList = UtilXml.childElementList(syncInventoryRootElement, "ns:DATAAREA");
        if (UtilValidate.isNotEmpty(dataAreaList)) {
            try {
                for (Element dataAreaElement : dataAreaList) {
                    Element syncInventoryElement = UtilXml.firstChildElement(dataAreaElement, "ns:SYNC_INVENTORY");
                    Element inventoryElement = UtilXml.firstChildElement(syncInventoryElement, "ns:INVENTORY");

                    Element quantityElement = UtilXml.firstChildElement(inventoryElement, "os:QUANTITY");

                    String itemQtyStr = UtilXml.childElementValue(quantityElement, "of:VALUE");
                    double itemQty = Double.parseDouble(itemQtyStr);
                    /* TODO sign denoted whether quantity is accepted(+) or rejected(-), which plays role in receiving inventory
                     * In this message will it serve any purpose, since it is not handled.
                     */
                    
                    // TODOLATER: Not used now, Later we may need it
                    //String sign = UtilXml.childElementValue(quantityElement, "of:SIGN");
                    //String uom = UtilXml.childElementValue(quantityElement, "of:UOM");
                    String productId = UtilXml.childElementValue(inventoryElement, "of:ITEM");
                    String itemStatus = UtilXml.childElementValue(inventoryElement, "of:ITEMSTATUS");

                    // make sure productId is valid
                    GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
                    if (product == null) {
                        String errMsg = "Product with ID [" + productId + "] not found (invalid Product ID).";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdNotValid", "description", errMsg));
                        Debug.logError(errMsg, module);
                        continue;
                    }

                    // if anything but "NOTAVAILABLE" set to available
                    boolean isAvailable = !"NOTAVAILABLE".equals(itemStatus);
                    String statusId = "INV_AVAILABLE";
                    if (!isAvailable) {
                        statusId = "INV_ON_HOLD";
                    }

                    String snapshotDateStr = UtilXml.childElementValue(inventoryElement, "os:DATETIMEISO");
                    //Parse this into a valid Timestamp Object
                    Timestamp snapshotDate = OagisServices.parseIsoDateString(snapshotDateStr, errorMapList);

                    // get quantity on hand diff
                    double quantityOnHandTotal = 0.0;

                    // only if looking for available inventory find the non-serialized QOH total
                    if (isAvailable) {
                        EntityCondition condition = EntityCondition.makeCondition(UtilMisc.toList(
                                EntityCondition.makeCondition("effectiveDate", EntityOperator.LESS_THAN_EQUAL_TO, snapshotDate),
                                EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
                                EntityCondition.makeCondition("inventoryItemTypeId", EntityOperator.EQUALS, "NON_SERIAL_INV_ITEM"),
                                EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, syncInventoryFacilityId)), EntityOperator.AND);
                        List<GenericValue> invItemAndDetails = delegator.findList("InventoryItemDetailForSum", condition, UtilMisc.toSet("quantityOnHandSum"), null, null, false);
                        for (GenericValue inventoryItemDetailForSum : invItemAndDetails) {
                            quantityOnHandTotal += inventoryItemDetailForSum.getDouble("quantityOnHandSum").doubleValue();
                        }
                    }

                    // now regardless of AVAILABLE or NOTAVAILABLE check serialized inventory, just use the corresponding statusId as set above
                    EntityCondition serInvCondition = EntityCondition.makeCondition(UtilMisc.toList(
                            EntityCondition.makeCondition("statusDatetime", EntityOperator.LESS_THAN_EQUAL_TO, snapshotDate),
                            EntityCondition.makeCondition(EntityCondition.makeCondition("statusEndDatetime", EntityOperator.GREATER_THAN, snapshotDate), EntityOperator.OR, EntityCondition.makeCondition("statusEndDatetime", EntityOperator.EQUALS, null)),
                            EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
                            EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, statusId),
                            EntityCondition.makeCondition("inventoryItemTypeId", EntityOperator.EQUALS, "SERIALIZED_INV_ITEM"),
                            EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, syncInventoryFacilityId)), EntityOperator.AND);
                    long invItemQuantCount = delegator.findCountByCondition("InventoryItemStatusForCount", serInvCondition, null, null);
                    quantityOnHandTotal += invItemQuantCount;

                    // check for mismatch in quantity
                    if (itemQty != quantityOnHandTotal) {
                        double quantityDiff = Math.abs((itemQty - quantityOnHandTotal));
                        inventoryMapList.add(UtilMisc.toMap("productId", (Object) productId, "statusId", statusId,
                                "quantityOnHandTotal", String.valueOf(quantityOnHandTotal), "quantityFromMessage", itemQtyStr,
                                "quantityDiff", String.valueOf(quantityDiff), "timestamp", snapshotDate));
                    }
                }
            } catch (Throwable t) {
                String errMsg = "Error processing Sync Inventory message: " + t.toString();
                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "Exception"));
                Debug.logInfo(t, errMsg, module);
            }
        }
        // send mail if mismatch(s) found
        if (errorMapList.size() == 0 && inventoryMapList.size() > 0) {
            try {
                // prepare information to send mail
                Map<String, Object> sendMap = FastMap.newInstance();

                String sendToEmail = UtilProperties.getPropertyValue("oagis.properties", "oagis.notification.email.sendTo");

                /* DEJ20070802 changed to get email address from properties file, should be way easier to manage
                // get facility email address
                List facilityContactMechs = null;
                GenericValue contactMech = null;
                try {
                    facilityContactMechs = delegator.findByAnd("FacilityContactMech", UtilMisc.toMap("facilityId", facilityId));
                } catch (GenericEntityException e) {
                    String errMsg = "Error Getting FacilityContactMech: " + e.toString();
                    errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "GenericEntityException", "description", errMsg));
                    Debug.logError(e, errMsg, module);
                }

                Iterator fcmIter  = facilityContactMechs.iterator();
                while (fcmIter.hasNext()) {
                    GenericValue facilityContactMech = (GenericValue) fcmIter.next();
                    String contactMechId = facilityContactMech.getString("contactMechId");
                    try {
                        contactMech = delegator.findByPrimaryKey("ContactMech", UtilMisc.toMap("contactMechId", contactMechId));
                    } catch (GenericEntityException e) {
                        String errMsg = "Error Getting ContactMech: " + e.toString();
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "GenericEntityException", "description", errMsg));
                        Debug.logError(e, errMsg, module);
                    }
                    String contactMechTypeId = contactMech.getString("contactMechTypeId");
                    if (contactMechTypeId.equals("EMAIL_ADDRESS")) {
                        String emailString = contactMech.getString("infoString");
                        sendMap.put("sendTo", emailString);
                    }
                }
                */

                if (UtilValidate.isNotEmpty(sendToEmail)) {
                    String productStoreId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.SyncInventoryProductStoreId");
                    GenericValue productStoreEmail = delegator.findByPrimaryKey("OldProdStoreEmailSetting", UtilMisc.toMap("productStoreId", productStoreId, "emailType", "PRDS_OAGIS_CONFIRM"));
                    if (productStoreEmail != null) {
                        String bodyScreenLocation = productStoreEmail.getString("bodyScreenLocation");
                        sendMap.put("bodyScreenUri", bodyScreenLocation);
                    } else {
                        sendMap.put("bodyScreenUri", "component://oagis/widget/EmailOagisMessageScreens.xml#InventoryMismatchNotice");
                    }
                    if (locale == null) {
                        locale = Locale.getDefault();
                    }

                    sendMap.put("sendTo", sendToEmail);
                    sendMap.put("subject", productStoreEmail.getString("subject"));
                    sendMap.put("sendFrom", productStoreEmail.getString("fromAddress"));
                    sendMap.put("sendCc", productStoreEmail.getString("ccAddress"));
                    sendMap.put("sendBcc", productStoreEmail.getString("bccAddress"));
                    sendMap.put("contentType", productStoreEmail.getString("contentType"));

                    Map<String, Object> bodyParameters = UtilMisc.toMap("inventoryMapList", inventoryMapList, "locale", locale);
                    sendMap.put("bodyParameters", bodyParameters);
                    sendMap.put("userLogin", userLogin);

                    // send the notification
                    // run async so it will happen in the background AND so errors in sending won't mess this up
                    dispatcher.runAsync("sendMailFromScreen", sendMap, true);
                } else {
                    // no send to email address, just log to file
                    Debug.logImportant("No sendTo email address found in process oagisReceiveSyncInventory service: inventoryMapList: " + inventoryMapList, module);
                }
            } catch (Throwable t) {
                Debug.logInfo(t, "System Error processing Sync Inventory message: " + t.toString(), module);
                // in this case we don't want to return a Confirm BOD, so return an error now
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OagisErrorProcessingSyncInventory", UtilMisc.toMap("errorString", t.toString()), locale));
            }
        }

        Map<String, Object> result = FastMap.newInstance();
        result.put("logicalId", logicalId);
        result.put("component", component);
        result.put("task", task);
        result.put("referenceId", referenceId);
        result.put("userLogin", userLogin);

        if (errorMapList.size() > 0) {
            try {
                comiCtx.put("processingStatusId", "OAGMP_PROC_ERROR");
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            // call services createOagisMsgErrInfosFromErrMapList and for incoming messages oagisSendConfirmBod
            Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
            saveErrorMapListCtx.put("logicalId", logicalId);
            saveErrorMapListCtx.put("component", component);
            saveErrorMapListCtx.put("task", task);
            saveErrorMapListCtx.put("referenceId", referenceId);
            saveErrorMapListCtx.put("errorMapList", errorMapList);
            saveErrorMapListCtx.put("userLogin", userLogin);
            try {
                dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            try {
                Map<String, Object> sendConfirmBodCtx = FastMap.newInstance();
                sendConfirmBodCtx.putAll(saveErrorMapListCtx);
                // NOTE: this is different for each service, should be shipmentId or returnId or PO orderId or etc
                // for sync inventory no such ID: sendConfirmBodCtx.put("origRefId", shipmentId);

                // run async because this will send a message back to the other server and may take some time, and/or fail
                dispatcher.runAsync("oagisSendConfirmBod", sendConfirmBodCtx, null, true, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error sending Confirm BOD: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            // return success here so that the message won't be retried and the Confirm BOD, etc won't be sent multiple times
            result.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OagisErrorProcessingMessage", locale)));
            return result;
        } else {
            try {
                comiCtx.put("processingStatusId", "OAGMP_PROC_SUCCESS");
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                // don't pass this back, nothing they can do about it: errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "GenericServiceException"));
                Debug.logError(e, errMsg, module);
            }
        }

        result.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OagisServiceCompletedSuccessfully", locale)));
        return result;
    }

    public static Map<String, Object> oagisReceiveAcknowledgeDeliveryPo(DispatchContext ctx, Map<String, Object> context) {
        Document doc = (Document) context.get("document");
        boolean isErrorRetry = Boolean.TRUE.equals(context.get("isErrorRetry"));
        Locale locale = (Locale) context.get("locale");
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Delegator delegator = ctx.getDelegator();
        List<Map<String, String>> errorMapList = FastList.newInstance();
        Map<String, Object> comiCtx = FastMap.newInstance();

        GenericValue userLogin = null;
        try {
            userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system"));
        } catch (GenericEntityException e) {
            String errMsg = "Error Getting UserLogin: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        // parse the message
        Element receivePoElement = doc.getDocumentElement();
        receivePoElement.normalize();
        Element docCtrlAreaElement = UtilXml.firstChildElement(receivePoElement, "os:CNTROLAREA");

        Element docSenderElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:SENDER");
        Element docBsrElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:BSR");

        String bsrVerb = UtilXml.childElementValue(docBsrElement, "of:VERB");
        String bsrNoun = UtilXml.childElementValue(docBsrElement, "of:NOUN");
        String bsrRevision = UtilXml.childElementValue(docBsrElement, "of:REVISION");

        String logicalId = UtilXml.childElementValue(docSenderElement, "of:LOGICALID");
        String component = UtilXml.childElementValue(docSenderElement, "of:COMPONENT");
        String task = UtilXml.childElementValue(docSenderElement, "of:TASK"); // This field should be Not more then 10 char long
        String referenceId = UtilXml.childElementValue(docSenderElement, "of:REFERENCEID");
        String confirmation = UtilXml.childElementValue(docSenderElement, "of:CONFIRMATION");
        String authId = UtilXml.childElementValue(docSenderElement, "of:AUTHID");

        String sentDate = UtilXml.childElementValue(docCtrlAreaElement, "os:DATETIMEISO");
        Timestamp sentTimestamp = OagisServices.parseIsoDateString(sentDate, errorMapList);
        Timestamp timestamp = UtilDateTime.nowTimestamp();

        Map<String, Object> omiPkMap = UtilMisc.toMap("logicalId", (Object) logicalId, "component", component, "task", task, "referenceId", referenceId);

        // always log this to make messages easier to find
        Debug.logInfo("Processing oagisReceiveAcknowledgeDeliveryPo for message ID [" + omiPkMap + "]", module);

        // before getting into this check to see if we've tried once and had an error, if so set isErrorRetry even if it wasn't passed in
        GenericValue previousOagisMessageInfo = null;
        try {
            previousOagisMessageInfo = delegator.findByPrimaryKey("OagisMessageInfo", omiPkMap);
        } catch (GenericEntityException e) {
            String errMsg = "Error getting OagisMessageInfo from database for message ID [" + omiPkMap + "]: " + e.toString();
            Debug.logInfo(e, errMsg, module);
            // anything else to do about this? we don't really want to send the error back or anything...
        }

        if (previousOagisMessageInfo != null && !isErrorRetry) {
            if ("OAGMP_SYS_ERROR".equals(previousOagisMessageInfo.getString("processingStatusId"))) {
                isErrorRetry = true;
            } else {
                // message already in the db, but is not in a system error state...
                Debug.logError("Message received for message ID [" + omiPkMap + "] was already partially processed but is not in a system error state, needs manual review; message ID: " + omiPkMap, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OagisErrorMessageAlreadyProcessed", UtilMisc.toMap("shipmentId", "", "omiPkMap", omiPkMap), locale));
            }
        }

        comiCtx.putAll(omiPkMap);
        comiCtx.put("authId", authId);
        comiCtx.put("receivedDate", timestamp);
        comiCtx.put("sentDate", sentTimestamp);
        comiCtx.put("outgoingMessage", "N");
        comiCtx.put("confirmation", confirmation);
        comiCtx.put("bsrVerb", bsrVerb);
        comiCtx.put("bsrNoun", bsrNoun);
        comiCtx.put("bsrRevision", bsrRevision);
        comiCtx.put("processingStatusId", "OAGMP_RECEIVED");
        comiCtx.put("userLogin", userLogin);
        if (OagisServices.debugSaveXmlIn) {
            try {
                comiCtx.put("fullMessageXml", UtilXml.writeXmlDocument(doc));
            } catch (IOException e) {
                // this is just for debug info, so just log and otherwise ignore error
                String errMsg = "Warning: error creating text from XML Document for saving to database: " + e.toString();
                Debug.logWarning(errMsg, module);
            }
        }
        try {
            if (isErrorRetry) {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } else {
                dispatcher.runSync("createOagisMessageInfo", comiCtx, 60, true);
            }
        } catch (GenericServiceException e) {
            String errMsg = "Error creating OagisMessageInfo for the Incoming Message: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        Element dataAreaElement = UtilXml.firstChildElement(receivePoElement, "ns:DATAAREA");
        Element acknowledgeDeliveryElement = UtilXml.firstChildElement(dataAreaElement, "ns:ACKNOWLEDGE_DELIVERY");

        String facilityId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.PoReceiptFacilityId");
        String orderId = null;
        // get RECEIPTLN elements from message
        List<? extends Element> acknowledgeElementList = UtilXml.childElementList(acknowledgeDeliveryElement, "ns:RECEIPTLN");
        if (UtilValidate.isNotEmpty(acknowledgeElementList)) {
            try {
                for (Element receiptLnElement : acknowledgeElementList) {
                    Map<String, Object> ripCtx = FastMap.newInstance();
                    Element qtyElement = UtilXml.firstChildElement(receiptLnElement, "os:QUANTITY");

                    String itemQtyStr = UtilXml.childElementValue(qtyElement, "of:VALUE");
                    double itemQty = Double.parseDouble(itemQtyStr);
                    String sign = UtilXml.childElementValue(qtyElement, "of:SIGN");

                    String productId = UtilXml.childElementValue(receiptLnElement, "of:ITEM");

                    // make sure productId is valid
                    GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
                    if (product == null) {
                        String errMsg = "Product with ID [" + productId + "] not found (invalid Product ID).";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdNotValid", "description", errMsg));
                        Debug.logError(errMsg, module);
                        continue;
                    }

                    Element documentRefElement = UtilXml.firstChildElement(receiptLnElement, "os:DOCUMNTREF");
                    orderId = UtilXml.childElementValue(documentRefElement, "of:DOCUMENTID");
                    String orderTypeId = UtilXml.childElementValue(documentRefElement, "of:DOCTYPE");
                    if (orderTypeId.equals("PO")) {
                        orderTypeId = "PURCHASE_ORDER";
                    }

                    String datetimeReceived = UtilXml.childElementValue(receiptLnElement, "os:DATETIMEISO");
                    Timestamp timestampItemReceived = OagisServices.parseIsoDateString(datetimeReceived, errorMapList);
                    ripCtx.put("datetimeReceived", timestampItemReceived);
                    // Check reference to PO number, if exists
                    GenericValue orderHeader = null;
                    if (orderId != null) {
                        List<GenericValue> toStore = FastList.newInstance();
                        orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
                        if (orderHeader != null) {
                            // Case : update the record
                            ripCtx.put("orderId", orderId);
                            comiCtx.put("orderId", orderId);
                            GenericValue orderItem = delegator.makeValue("OrderItem", UtilMisc.toMap("orderId", orderId, "productId",productId,"quantity",new Double(itemQtyStr)));
                            delegator.setNextSubSeqId(orderItem, "orderItemSeqId", 5, 1);
                            delegator.create(orderItem);
                            ripCtx.put("orderItemSeqId", orderItem.get("orderItemSeqId"));
                        } else {
                            // Case : New record entry when PO not exists in the Database
                            orderHeader =  delegator.makeValue("OrderHeader", UtilMisc.toMap("orderId", orderId, "orderTypeId",orderTypeId ,
                                    "orderDate", timestampItemReceived, "statusId", "ORDER_CREATED", "entryDate", UtilDateTime.nowTimestamp(),
                                    "productStoreId", UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.SyncInventoryProductStoreId","9001")));
                            toStore.add(orderHeader);
                            GenericValue orderItem = delegator.makeValue("OrderItem", UtilMisc.toMap("orderId", orderId,
                                    "orderItemSeqId", UtilFormatOut.formatPaddedNumber(1L, 5),
                                    "productId", productId, "quantity", new Double(itemQtyStr)));
                            toStore.add(orderItem);
                            delegator.storeAll(toStore);
                        }
                    }

                    /* NOTE DEJ20070813 this is only meant to be used in the Ack Delivery RMA message, so ignoring here and always settings status to AVAILABLE
                    // get inventory item status
                    String invItemStatus = UtilXml.childElementValue(receiptLnElement, "of:DISPOSITN");
                    if (invItemStatus.equals("ReceivedTOAvailable") || invItemStatus.equals("NotAvailableTOAvailable")) {
                        ripCtx.put("statusId","INV_AVAILABLE");
                    } else if (invItemStatus.equals("ReceivedTONotAvailable") || invItemStatus.equals("AvailableTONotAvailable")) {
                        ripCtx.put("statusId","INV_ON_HOLD");
                    }
                    */

                    ripCtx.put("statusId","INV_AVAILABLE");
                    ripCtx.put("inventoryItemTypeId", "NON_SERIAL_INV_ITEM");
                    ripCtx.put("productId", productId);
                    ripCtx.put("facilityId",facilityId);
                    ripCtx.put("userLogin", userLogin);

                    // sign handling for items
                    double quantityAccepted = 0.0;
                    double quantityRejected = 0.0;
                    if (sign.equals("+")) {
                        quantityAccepted = itemQty;
                        quantityRejected= 0.0;
                    } else {
                        quantityRejected = itemQty;
                        quantityAccepted = 0.0;
                    }
                    ripCtx.put("quantityAccepted", new Double(quantityAccepted));
                    ripCtx.put("quantityRejected", new Double(quantityRejected));
                    Map<String, Object> ripResult = dispatcher.runSync("receiveInventoryProduct", ripCtx);
                    if (ServiceUtil.isError(ripResult)) {
                        String errMsg = ServiceUtil.getErrorMessage(ripResult);
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReceiveInventoryServiceError", "description", errMsg));
                    }
                }
            } catch (Throwable t) {
                String errMsg = UtilProperties.getMessage(resource, "OagisErrorDeliveryMessagePO", UtilMisc.toMap("omiPkMap", omiPkMap), locale) + t.toString();
                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SystemError"));

                try {
                    comiCtx.put("processingStatusId", "OAGMP_SYS_ERROR");
                    dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);

                    Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
                    saveErrorMapListCtx.putAll(omiPkMap);
                    saveErrorMapListCtx.put("errorMapList", errorMapList);
                    saveErrorMapListCtx.put("userLogin", userLogin);
                    dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
                } catch (GenericServiceException e) {
                    String errMsg2 = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                    Debug.logError(e, errMsg2, module);
                }

                Debug.logInfo(t, errMsg, module);
                // in this case we don't want to return a Confirm BOD, so return an error now
                return ServiceUtil.returnError(errMsg);
            }
        }

        Map<String, Object> result = FastMap.newInstance();
        result.put("logicalId", logicalId);
        result.put("component", component);
        result.put("task", task);
        result.put("referenceId", referenceId);
        result.put("userLogin", userLogin);

        if (errorMapList.size() > 0) {
            try {
                comiCtx.put("processingStatusId", "OAGMP_PROC_ERROR");
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            // call services createOagisMsgErrInfosFromErrMapList and for incoming messages oagisSendConfirmBod
            Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
            saveErrorMapListCtx.put("logicalId", logicalId);
            saveErrorMapListCtx.put("component", component);
            saveErrorMapListCtx.put("task", task);
            saveErrorMapListCtx.put("referenceId", referenceId);
            saveErrorMapListCtx.put("errorMapList", errorMapList);
            saveErrorMapListCtx.put("userLogin", userLogin);
            try {
                dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            try {
                Map<String, Object> sendConfirmBodCtx = FastMap.newInstance();
                sendConfirmBodCtx.putAll(saveErrorMapListCtx);
                // NOTE: this is different for each service, should be shipmentId or returnId or PO orderId or etc
                sendConfirmBodCtx.put("origRefId", orderId);

                // run async because this will send a message back to the other server and may take some time, and/or fail
                dispatcher.runAsync("oagisSendConfirmBod", sendConfirmBodCtx, null, true, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error sending Confirm BOD: " + e.toString();
                Debug.logError(e, errMsg, module);
            }
            
            // return success here so that the message won't be retried and the Confirm BOD, etc won't be sent multiple times
            String errMsg = UtilProperties.getMessage(resource, "OagisErrorBusinessLevel", UtilMisc.toMap("errorString", ""), locale) + errorMapList.get(0);
            result.putAll(ServiceUtil.returnSuccess(errMsg));

            // however, we still don't want to save the partial results, so set rollbackOnly
            try {
                TransactionUtil.setRollbackOnly(errMsg, null);
            } catch (GenericTransactionException e) {
                Debug.logError(e, "Error setting rollback only ", module);
            }

            return result;
        } else {
            comiCtx.put("processingStatusId", "OAGMP_PROC_SUCCESS");
            try {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                // don't pass this back, nothing they can do about it: errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "GenericServiceException"));
                Debug.logError(e, errMsg, module);
            }
        }

        result.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OagisServiceCompletedSuccessfully", locale)));
        return result;
    }

    public static Map<String, Object> oagisReceiveAcknowledgeDeliveryRma(DispatchContext ctx, Map<String, Object> context) {
        Document doc = (Document) context.get("document");
        boolean isErrorRetry = Boolean.TRUE.equals(context.get("isErrorRetry"));
        Locale locale = (Locale) context.get("locale");
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Delegator delegator = ctx.getDelegator();
        List<Map<String, String>> errorMapList = FastList.newInstance();

        GenericValue userLogin = null;
        try {
            userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system"));
        } catch (GenericEntityException e) {
            Debug.logError(e, "Error Getting UserLogin: " + e.toString(), module);
        }

        // parse the message
        Element receiveRmaElement = doc.getDocumentElement();
        receiveRmaElement.normalize();
        Element docCtrlAreaElement = UtilXml.firstChildElement(receiveRmaElement, "os:CNTROLAREA");
        Element docSenderElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:SENDER");
        Element docBsrElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:BSR");

        String bsrVerb = UtilXml.childElementValue(docBsrElement, "of:VERB");
        String bsrNoun = UtilXml.childElementValue(docBsrElement, "of:NOUN");
        String bsrRevision = UtilXml.childElementValue(docBsrElement, "of:REVISION");

        String logicalId = UtilXml.childElementValue(docSenderElement, "of:LOGICALID");
        String component = UtilXml.childElementValue(docSenderElement, "of:COMPONENT");
        String task = UtilXml.childElementValue(docSenderElement, "of:TASK");
        String referenceId = UtilXml.childElementValue(docSenderElement, "of:REFERENCEID");
        String confirmation = UtilXml.childElementValue(docSenderElement, "of:CONFIRMATION");
        String authId = UtilXml.childElementValue(docSenderElement, "of:AUTHID");

        String sentDate = UtilXml.childElementValue(docCtrlAreaElement, "os:DATETIMEISO");
        Timestamp sentTimestamp = OagisServices.parseIsoDateString(sentDate, errorMapList);

        Element dataAreaElement = UtilXml.firstChildElement(receiveRmaElement, "ns:DATAAREA");
        Element acknowledgeDeliveryElement = UtilXml.firstChildElement(dataAreaElement, "ns:ACKNOWLEDGE_DELIVERY");

        // get the first returnId from the list so we at least have something in the info record
        Element firstReceiptlnElement = UtilXml.firstChildElement(acknowledgeDeliveryElement, "ns:RECEIPTLN");
        Element firstDocRefElement = UtilXml.firstChildElement(firstReceiptlnElement, "os:DOCUMNTREF");
        String firstReturnId = UtilXml.childElementValue(firstDocRefElement, "of:DOCUMENTID");

        String facilityId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.PoReceiptFacilityId");
        String locationSeqId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.ReturnReceiptLocationSeqId");

        Timestamp timestamp = UtilDateTime.nowTimestamp();
        Map<String, Object> comiCtx = FastMap.newInstance();

        Map<String, Object> omiPkMap = UtilMisc.toMap("logicalId", (Object) logicalId, "component", component, "task", task, "referenceId", referenceId);

        // always log this to make messages easier to find
        Debug.logInfo("Processing oagisReceiveAcknowledgeDeliveryRma for message ID [" + omiPkMap + "]", module);

        // before getting into this check to see if we've tried once and had an error, if so set isErrorRetry even if it wasn't passed in
        GenericValue previousOagisMessageInfo = null;
        try {
            previousOagisMessageInfo = delegator.findByPrimaryKey("OagisMessageInfo", omiPkMap);
        } catch (GenericEntityException e) {
            String errMsg = "Error getting OagisMessageInfo from database for message ID [" + omiPkMap + "]: " + e.toString();
            Debug.logInfo(e, errMsg, module);
            // anything else to do about this? we don't really want to send the error back or anything...
        }

        if (previousOagisMessageInfo != null && !isErrorRetry) {
            if ("OAGMP_SYS_ERROR".equals(previousOagisMessageInfo.getString("processingStatusId"))) {
                isErrorRetry = true;
            } else {
                // message already in the db, but is not in a system error state...
                Debug.logError("Message received for message ID [" + omiPkMap + "] was already partially processed but is not in a system error state, needs manual review; message ID: " + omiPkMap, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OagisErrorMessageAlreadyProcessed", UtilMisc.toMap("shipmentId", "", "omiPkMap", omiPkMap), locale));
            }
        }

        comiCtx.putAll(omiPkMap);
        comiCtx.put("authId", authId);
        comiCtx.put("receivedDate", timestamp);
        comiCtx.put("sentDate", sentTimestamp);
        comiCtx.put("outgoingMessage", "N");
        comiCtx.put("confirmation", confirmation);
        comiCtx.put("bsrVerb", bsrVerb);
        comiCtx.put("bsrNoun", bsrNoun);
        comiCtx.put("bsrRevision", bsrRevision);
        comiCtx.put("processingStatusId", "OAGMP_RECEIVED");
        comiCtx.put("returnId", firstReturnId);
        comiCtx.put("userLogin", userLogin);
        if (OagisServices.debugSaveXmlIn) {
            try {
                comiCtx.put("fullMessageXml", UtilXml.writeXmlDocument(doc));
            } catch (IOException e) {
                // this is just for debug info, so just log and otherwise ignore error
                String errMsg = "Warning: error creating text from XML Document for saving to database: " + e.toString();
                Debug.logWarning(errMsg, module);
            }
        }
        try {
            if (isErrorRetry) {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } else {
                dispatcher.runSync("createOagisMessageInfo", comiCtx, 60, true);
            }
        } catch (GenericServiceException e) {
            String errMsg = "Error creating OagisMessageInfo for the Incoming Message: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        String lastReturnId = null;
        //String inventoryItemId = null;
        List<String> invItemIds = FastList.newInstance();
        // get RECEIPTLN elements from message
        List<? extends Element> receiptLineElementList = UtilXml.childElementList(acknowledgeDeliveryElement, "ns:RECEIPTLN");
        if (UtilValidate.isNotEmpty(receiptLineElementList)) {
            try {
                Map<String, String> processedStatusIdByReturnIdMap = FastMap.newInstance();

                for (Element receiptLnElement : receiptLineElementList) {
                    Map<String, Object> ripCtx = FastMap.newInstance();
                    Element qtyElement = UtilXml.firstChildElement(receiptLnElement, "os:QUANTITY");

                    String itemQtyStr = UtilXml.childElementValue(qtyElement, "of:VALUE");
                    double itemQty = Double.parseDouble(itemQtyStr);
                    String sign = UtilXml.childElementValue(qtyElement, "of:SIGN");

                    String productId = UtilXml.childElementValue(receiptLnElement, "of:ITEM");
                    if (UtilValidate.isEmpty(productId)) {
                        String errMsg = "Product ID Missing";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdMissing", "description", errMsg));
                        Debug.logError(errMsg, module);
                    }
                    // make sure productId is valid
                    GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
                    if (product == null) {
                        String errMsg = "Product with ID [" + productId + "] not found (invalid Product ID).";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdNotValid", "description", errMsg));
                        Debug.logError(errMsg, module);
                        continue;
                    }

                    Element documentRefElement = UtilXml.firstChildElement(receiptLnElement, "os:DOCUMNTREF");
                    String returnId = UtilXml.childElementValue(documentRefElement, "of:DOCUMENTID");
                    lastReturnId = returnId;
                    ripCtx.put("returnId", returnId);

                    String returnHeaderTypeId = UtilXml.childElementValue(documentRefElement, "of:DOCTYPE");
                    if (returnHeaderTypeId.equals("RMA")) {
                        returnHeaderTypeId = "CUSTOMER_RETURN";
                    }

                    String returnItemSeqId = UtilXml.childElementValue(documentRefElement, "of:LINENUM");
                    if (UtilValidate.isNotEmpty(returnItemSeqId)) {
                        // if there is a LINENUM/returnItemSeqId make sure it is valid
                        GenericValue returnItem = delegator.findByPrimaryKeyCache("ReturnItem", UtilMisc.toMap("returnId", returnId, "returnItemSeqId", returnItemSeqId));
                        if (returnItem == null) {
                            String errMsg = "Return Item with ID [" + returnId + ":" + returnItemSeqId + "] not found (invalid Return/Item ID Combination).";
                            errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReturnAndItemIdNotValid", "description", errMsg));
                            Debug.logError(errMsg, module);
                            continue;
                        }
                    } else {
                        String errMsg = "No Return Item ID (LINENUM) found in DOCUMNTREF for Return [" + returnId + "]; this is a required field.";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReturnItemIdLinenumMissing", "description", errMsg));
                        Debug.logError(errMsg, module);
                        continue;
                    }

                    // getting inventory item status
                    String invItemStatusId = null;
                    String disposition = UtilXml.childElementValue(receiptLnElement, "of:DISPOSITN");
                    if ("ReceivedTOAvailable".equals(disposition)) {
                        invItemStatusId = "INV_AVAILABLE";
                    } else if ("ReceivedTONotAvailable".equals(disposition)) {
                        invItemStatusId = "INV_ON_HOLD";
                    } else if ("NotAvailableTOAvailable".equals(disposition) || "AvailableTONotAvailable".equals(disposition)) {
                        // for RMA we should only get the ReceivedTO* DISPOSITN values; if we get something else we should return an error
                        String errMsg = "Got DISPOSITN value [" + disposition + "] that is not valid for RMA, only for status change.";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "DispositnNotValidForRMA", "description", errMsg));
                        continue;
                    }
                    ripCtx.put("statusId", invItemStatusId);

                    // TODOLATER: get the returnItem associated with the product received and update the receivedQuantity

                    String datetimeReceived = UtilXml.childElementValue(receiptLnElement, "os:DATETIMEISO");
                    Timestamp timestampItemReceived = OagisServices.parseIsoDateString(datetimeReceived, errorMapList);
                    ripCtx.put("datetimeReceived", timestampItemReceived);

                    GenericValue returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId));

                    if (returnHeader != null) {
                        //getting ReturnHeader status
                        String statusId = returnHeader.get("statusId").toString();

                        // save this here so the status will be updated after all processed
                        processedStatusIdByReturnIdMap.put(returnId, statusId);

                        // getting the serial number(s)
                        List<String> serialNumsList = FastList.newInstance();
                        List<? extends Element> invDetailList = UtilXml.childElementList(receiptLnElement, "ns:INVDETAIL");
                        if (UtilValidate.isNotEmpty(invDetailList)) {
                            for (Element invDetailElement : invDetailList) {
                                String serialNumber = UtilXml.childElementValue(invDetailElement, "of:SERIALNUM");
                                if (UtilValidate.isNotEmpty(serialNumber)) {
                                    serialNumsList.add(serialNumber);
                                }
                            }

                            /* DEJ20070711 Commenting this out because it shouldn't happen, ie more likely the ITEM element will be filled
                             * than INVDETAIL->SERIALNUM, and this isn't a reliable way to look it up (may be more than 1 record for a given
                             * serialNumber for different products
                             // this is a Serialized Inventory Item. If the productId from the message is not valid then lets read it from InventoryItem in Ofbiz database.
                             if (productId == null || "".equals(productId)) {
                             try {
                                 GenericValue inventoryItem = EntityUtil.getFirst(delegator.findByAnd("InventoryItem", UtilMisc.toMap("serialNumber", serialNumber)));
                                 if (inventoryItem !=null) {
                                     productId = inventoryItem.getString("productId");
                                 }
                             } catch (GenericEntityException e) {
                                 String errMsg = "Error Getting Entity InventoryItem";
                                 Debug.logError(e, errMsg, module);
                            } */
                        }

                        //do some validations
                        Integer messageQuantity = Integer.valueOf(itemQtyStr);
                        if (UtilValidate.isNotEmpty(serialNumsList)) {
                            if (messageQuantity.intValue() != serialNumsList.size()) {
                                String errMsg = "Not enough serial numbers [" + serialNumsList.size() + "] for the quantity [" + messageQuantity.intValue() + "].";
                                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumbersMissing"));
                                Debug.logInfo(errMsg, module);
                                continue;
                            }
                        }

                        ripCtx.put("facilityId",facilityId);
                        ripCtx.put("locationSeqId", locationSeqId);
                        ripCtx.put("userLogin", userLogin);

                        // sign handling for items
                        double quantityAccepted = 0.0;
                        if (sign.equals("+")) {
                            quantityAccepted = itemQty;
                        } else {
                            quantityAccepted = 0.0;
                        }
                        if (quantityAccepted > 0) {
                            if (serialNumsList.size() > 0) {
                                String inventoryItemTypeId = "SERIALIZED_INV_ITEM";
                                ripCtx.put("inventoryItemTypeId", inventoryItemTypeId);

                                for (String serialNum : serialNumsList) {
                                    // also look at the productId, and associated refurb productId(s) (or other way around, we might get a refurb sku
                                    //and need to look up by the non-refurb sku); serialNumbers may not be unique globally, but should be per product
                                    Set<String> productIdSet = ProductWorker.getRefurbishedProductIdSet(productId, delegator);
                                    productIdSet.add(productId);

                                    EntityCondition bySerialNumberCondition = EntityCondition.makeCondition(EntityCondition.makeCondition("serialNumber", EntityOperator.EQUALS, serialNum),
                                            EntityOperator.AND, EntityCondition.makeCondition("productId", EntityOperator.IN, productIdSet));
                                    List<GenericValue> inventoryItemsBySerialNumber = delegator.findList("InventoryItem", bySerialNumberCondition, null, null, null, false);

                                    if (OagisServices.requireSerialNumberExist != null) {
                                        // according to requireSerialNumberExist make sure serialNumber does or does not exist in database, add an error message as needed
                                        if (OagisServices.requireSerialNumberExist.booleanValue()) {
                                            if (inventoryItemsBySerialNumber.size() == 0) {
                                                String errMsg = "Referenced serial numbers must already exist, but serial number [" + serialNum + "] was not found.";
                                                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumberRequiredButNotFound"));
                                                continue;
                                            }
                                        } else {
                                            if (inventoryItemsBySerialNumber.size() > 0) {
                                                String errMsg = "Referenced serial numbers must NOT already exist, but serial number [" + serialNum + "] already exists.";
                                                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumberRequiredNotExistButFound"));
                                                continue;
                                            }
                                        }
                                    }

                                    // TODOLATER: another fun thing to check: see if the serial number matches a serial number attached to the original return (if possible!)

                                    //clone the context as it may be changed in the call
                                    Map<String, Object> localRipCtx = FastMap.newInstance();
                                    localRipCtx.putAll(ripCtx);
                                    localRipCtx.put("quantityAccepted", new Double(1.0));
                                    // always set this to 0, if needed we'll handle the rejected quantity separately
                                    localRipCtx.put("quantityRejected", new Double(0.0));
                                    localRipCtx.put("serialNumber", serialNum);
                                    localRipCtx.put("productId", productId);
                                    localRipCtx.put("returnItemSeqId", returnItemSeqId);

                                    GenericValue inventoryItem = EntityUtil.getFirst(inventoryItemsBySerialNumber);
                                    if (inventoryItem != null) {
                                        localRipCtx.put("currentInventoryItemId", inventoryItem.getString("inventoryItemId"));
                                    }

                                    Map<String, Object> ripResult = dispatcher.runSync("receiveInventoryProduct", localRipCtx);
                                    if (ServiceUtil.isError(ripResult)) {
                                        String errMsg = ServiceUtil.getErrorMessage(ripResult);
                                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReceiveInventoryServiceError", "description", errMsg));
                                    } else {
                                        invItemIds.add((String) ripResult.get("inventoryItemId"));
                                    }
                                }
                            } else {
                                String inventoryItemTypeId = "NON_SERIAL_INV_ITEM";
                                ripCtx.put("inventoryItemTypeId", inventoryItemTypeId);

                                // no serial numbers, just receive the quantity
                                // clone the context as it may be changted in the call
                                Map<String, Object> localRipCtx = FastMap.newInstance();
                                localRipCtx.putAll(ripCtx);
                                localRipCtx.put("quantityAccepted", new Double(quantityAccepted));
                                // always set this to 0, if needed we'll handle the rejected quantity separately
                                localRipCtx.put("quantityRejected", new Double(0.0));
                                localRipCtx.put("productId", productId);
                                localRipCtx.put("returnItemSeqId", returnItemSeqId);
                                String inventoryItemId = null;

                                Map<String, Object> ripResult = dispatcher.runSync("receiveInventoryProduct", localRipCtx);
                                if (ServiceUtil.isError(ripResult)) {
                                    String errMsg = ServiceUtil.getErrorMessage(ripResult);
                                    errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReceiveInventoryServiceError", "description", errMsg));
                                }
                                inventoryItemId = (String) ripResult.get("inventoryItemId");

                                invItemIds.add(inventoryItemId);

                                if (("INV_ON_HOLD").equals(invItemStatusId)) {
                                    Map<String, Object> createPhysicalInvAndVarCtx = FastMap.newInstance();
                                    createPhysicalInvAndVarCtx.put("inventoryItemId", inventoryItemId);
                                    createPhysicalInvAndVarCtx.put("physicalInventoryDate", UtilDateTime.nowTimestamp());
                                    // NOTE DEJ20070815: calling damaged for now as the only option so that all will feed into a check/repair process and go into the ON_HOLD status; we should at some point change OFBiz so these can go into the ON_HOLD status without having to call them damaged
                                    createPhysicalInvAndVarCtx.put("generalComments", "Damaged, in repair");
                                    createPhysicalInvAndVarCtx.put("varianceReasonId", "VAR_DAMAGED");
                                    createPhysicalInvAndVarCtx.put("availableToPromiseVar", new Double(-quantityAccepted));
                                    createPhysicalInvAndVarCtx.put("quantityOnHandVar", new Double(0.0));
                                    createPhysicalInvAndVarCtx.put("userLogin", userLogin);
                                    Map<String, Object> cpivResult = dispatcher.runSync("createPhysicalInventoryAndVariance", createPhysicalInvAndVarCtx);
                                    if (ServiceUtil.isError(cpivResult)) {
                                        String errMsg = ServiceUtil.getErrorMessage(cpivResult);
                                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "CreatePhysicalInventoryAndVarianceServiceError", "description", errMsg));
                                    }
                                }
                            }
                        } else {
                            // TODOLATER: need to run service receiveInventoryProduct and updateInventoryItem when quantityRejected > 0
                            // NOTE DEJ20070711 this shouldn't happen for current needs, so save for later
                        }
                    } else {
                        String errMsg = "Return ID [" + returnId + "] Not Found";
                        Debug.logError(errMsg, module);
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ReturnIdNotFound", "description", errMsg));
                    }
                }

                for (Map.Entry<String, String> processedStatusIdByReturnIdEntry : processedStatusIdByReturnIdMap.entrySet()) {
                    String returnId = processedStatusIdByReturnIdEntry.getKey();
                    String statusId = processedStatusIdByReturnIdEntry.getValue();

                    if (UtilValidate.isNotEmpty(statusId) && statusId.equals("RETURN_ACCEPTED")) {
                        // check to see if all return items have been received, if so then set to received then completed

                        // NOTE: an alternative method would be to see if the total has been received for each
                        //ReturnItem (receivedQuantity vs returnQuantity), but we may have a hard time matching
                        //those up so that information is probably not as reliable; another note: as of 20070821
                        //the receipt processing code properly updates ReturnItem with receivedQuantity and status
                        //so we _could_ possibly move to that method if needed

                        // loop through ReturnItem records, get totals for each productId
                        Map<String, Double> returnQuantityByProductIdMap = FastMap.newInstance();
                        List<GenericValue> returnItemList = delegator.findByAnd("ReturnItem", UtilMisc.toMap("returnId", returnId));
                        for (GenericValue returnItem : returnItemList) {
                            String productId = returnItem.getString("productId");
                            Double returnQuantityDbl = returnItem.getDouble("returnQuantity");
                            if (UtilValidate.isNotEmpty(productId) && returnQuantityDbl != null) {
                                double newTotal = returnQuantityDbl.doubleValue();
                                Double existingTotal = returnQuantityByProductIdMap.get(productId);
                                if (existingTotal != null) newTotal += existingTotal.doubleValue();
                                returnQuantityByProductIdMap.put(productId, new Double(newTotal));
                            }
                        }

                        // set to true, if we find any that aren't fully received, will set to false
                        boolean fullReturnReceived = true;

                        // for each productId see if total received is equal to the total for that ID
                        for (Map.Entry<String, Double> returnQuantityByProductIdEntry : returnQuantityByProductIdMap.entrySet()) {
                            String productId = returnQuantityByProductIdEntry.getKey();
                            double returnQuantity = returnQuantityByProductIdEntry.getValue();

                            double receivedQuantity = 0;
                            // note no facilityId because we don't really care where the return items were received
                            List<GenericValue> shipmentReceiptList = delegator.findByAnd("ShipmentReceipt", UtilMisc.toMap("productId", productId, "returnId", returnId));
                            // NOTE only consider those with a quantityOnHandDiff > 0 so we just look at how many have been received, not what was actually done with them
                            for (GenericValue shipmentReceipt : shipmentReceiptList) {
                                Double quantityAccepted = shipmentReceipt.getDouble("quantityAccepted");
                                if (quantityAccepted != null && quantityAccepted.doubleValue() > 0) {
                                    receivedQuantity += quantityAccepted.doubleValue();
                                }
                            }

                            if (receivedQuantity < returnQuantity) {
                                fullReturnReceived = false;
                                break;
                            } else if (receivedQuantity > returnQuantity) {
                                // TODOLATER: we received MORE than expected... what to do about that?!?
                                String warnMsg = "Received more [" + receivedQuantity + "] than were expected on return [" + returnQuantity + "] for Return ID [" + returnId + "] and Product ID [" + productId + "]";
                                warnMsg = warnMsg + "; still completing return, but something should be done with these extras!";
                                Debug.logWarning(warnMsg, module);
                                // even with that, allow it to go through and complete the return
                            }
                        }

                        if (fullReturnReceived) {
                            dispatcher.runSync("updateReturnHeader", UtilMisc.<String, Object>toMap("statusId", "RETURN_RECEIVED", "returnId", returnId, "userLogin", userLogin));
                            dispatcher.runSync("updateReturnHeader", UtilMisc.<String, Object>toMap("statusId", "RETURN_COMPLETED", "returnId", returnId, "userLogin", userLogin));
                        }
                    }
                }
            } catch (Throwable t) {
                String errMsg = "System Error processing Acknowledge Delivery RMA message for message [" + omiPkMap + "]: " + t.toString();
                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SystemError"));

                try {
                    comiCtx.put("processingStatusId", "OAGMP_SYS_ERROR");
                    dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);

                    Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
                    saveErrorMapListCtx.putAll(omiPkMap);
                    saveErrorMapListCtx.put("errorMapList", errorMapList);
                    saveErrorMapListCtx.put("userLogin", userLogin);
                    dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
                } catch (GenericServiceException e) {
                    String errMsg2 = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                    Debug.logError(e, errMsg2, module);
                }

                Debug.logInfo(t, errMsg, module);
                // in this case we don't want to return a Confirm BOD, so return an error now
                return ServiceUtil.returnError(errMsg);
            }
        }

        Map<String, Object> result = FastMap.newInstance();
        result.put("logicalId", logicalId);
        result.put("component", component);
        result.put("task", task);
        result.put("referenceId", referenceId);
        result.put("userLogin", userLogin);

        if (errorMapList.size() > 0) {
            try {
                comiCtx.put("processingStatusId", "OAGMP_PROC_ERROR");
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            // call services createOagisMsgErrInfosFromErrMapList and for incoming messages oagisSendConfirmBod
            Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
            saveErrorMapListCtx.put("logicalId", logicalId);
            saveErrorMapListCtx.put("component", component);
            saveErrorMapListCtx.put("task", task);
            saveErrorMapListCtx.put("referenceId", referenceId);
            saveErrorMapListCtx.put("errorMapList", errorMapList);
            saveErrorMapListCtx.put("userLogin", userLogin);
            try {
                dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            try {
                Map<String, Object> sendConfirmBodCtx = FastMap.newInstance();
                sendConfirmBodCtx.putAll(saveErrorMapListCtx);
                // NOTE: this is different for each service, should be shipmentId or returnId or PO orderId or etc
                // TODO: unfortunately there could be multiple returnIds for the message, so what to do...?
                sendConfirmBodCtx.put("origRefId", lastReturnId);

                // run async because this will send a message back to the other server and may take some time, and/or fail
                dispatcher.runAsync("oagisSendConfirmBod", sendConfirmBodCtx, null, true, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error sending Confirm BOD: " + e.toString();
                Debug.logError(e, errMsg, module);
            }
            String errMsg = "Found business level errors in message processing, not saving results; first error is: " + errorMapList.get(0);

            // return success here so that the message won't be retried and the Confirm BOD, etc won't be sent multiple times
            result.putAll(ServiceUtil.returnSuccess(errMsg));

            // however, we still don't want to save the partial results, so set rollbackOnly
            try {
                TransactionUtil.setRollbackOnly(errMsg, null);
            } catch (GenericTransactionException e) {
                Debug.logError(e, "Error setting rollback only ", module);
            }

            return result;
        } else {
            comiCtx.put("processingStatusId", "OAGMP_PROC_SUCCESS");
            try {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                // don't pass this back, nothing they can do about it: errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "GenericServiceException"));
                Debug.logError(e, errMsg, module);
            }
        }

        result.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OagisServiceCompletedSuccessfully", locale)));
        result.put("inventoryItemIdList", invItemIds);
        return result;
    }

    public static Map<String, Object> oagisReceiveAcknowledgeDeliveryStatus(DispatchContext ctx, Map<String, Object> context) {
        Document doc = (Document) context.get("document");
        boolean isErrorRetry = Boolean.TRUE.equals(context.get("isErrorRetry"));
        Locale locale = (Locale) context.get("locale");
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Delegator delegator = ctx.getDelegator();
        List<Map<String, String>> errorMapList = FastList.newInstance();

        GenericValue userLogin = null;
        try {
            userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system"));
        } catch (GenericEntityException e) {
            String errMsg = "Error Getting UserLogin: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        // parse the message
        Element receiveStatusElement = doc.getDocumentElement();
        receiveStatusElement.normalize();
        Element docCtrlAreaElement = UtilXml.firstChildElement(receiveStatusElement, "os:CNTROLAREA");
        Element docSenderElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:SENDER");
        Element docBsrElement = UtilXml.firstChildElement(docCtrlAreaElement, "os:BSR");

        String bsrVerb = UtilXml.childElementValue(docBsrElement, "of:VERB");
        String bsrNoun = UtilXml.childElementValue(docBsrElement, "of:NOUN");
        String bsrRevision = UtilXml.childElementValue(docBsrElement, "of:REVISION");

        String logicalId = UtilXml.childElementValue(docSenderElement, "of:LOGICALID");
        String component = UtilXml.childElementValue(docSenderElement, "of:COMPONENT");
        String task = UtilXml.childElementValue(docSenderElement, "of:TASK");
        String referenceId = UtilXml.childElementValue(docSenderElement, "of:REFERENCEID");
        String confirmation = UtilXml.childElementValue(docSenderElement, "of:CONFIRMATION");
        String authId = UtilXml.childElementValue(docSenderElement, "of:AUTHID");

        String sentDate = UtilXml.childElementValue(docCtrlAreaElement, "os:DATETIMEISO");
        Timestamp sentTimestamp = OagisServices.parseIsoDateString(sentDate, errorMapList);

        Element dataAreaElement = UtilXml.firstChildElement(receiveStatusElement, "ns:DATAAREA");
        Element acknowledgeDeliveryElement = UtilXml.firstChildElement(dataAreaElement, "ns:ACKNOWLEDGE_DELIVERY");

        String facilityId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.PoReceiptFacilityId");
        String locationSeqId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.ReturnReceiptLocationSeqId");

        Timestamp timestamp = UtilDateTime.nowTimestamp();
        Map<String, Object> comiCtx = FastMap.newInstance();

        Map<String, Object> omiPkMap = UtilMisc.toMap("logicalId", (Object) logicalId, "component", component, "task", task, "referenceId", referenceId);

        // always log this to make messages easier to find
        Debug.logInfo("Processing oagisReceiveAcknowledgeDeliveryStatus for message ID [" + omiPkMap + "]", module);

        // before getting into this check to see if we've tried once and had an error, if so set isErrorRetry even if it wasn't passed in
        GenericValue previousOagisMessageInfo = null;
        try {
            previousOagisMessageInfo = delegator.findByPrimaryKey("OagisMessageInfo", omiPkMap);
        } catch (GenericEntityException e) {
            String errMsg = "Error getting OagisMessageInfo from database for message ID [" + omiPkMap + "]: " + e.toString();
            Debug.logInfo(e, errMsg, module);
            // anything else to do about this? we don't really want to send the error back or anything...
        }

        if (previousOagisMessageInfo != null && !isErrorRetry) {
            if ("OAGMP_SYS_ERROR".equals(previousOagisMessageInfo.getString("processingStatusId"))) {
                isErrorRetry = true;
            } else {
                // message already in the db, but is not in a system error state...
                Debug.logError("Message received for message ID [" + omiPkMap + "] was already partially processed but is not in a system error state, needs manual review; message ID: " + omiPkMap, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OagisErrorMessageAlreadyProcessed", UtilMisc.toMap("shipmentId", "", "omiPkMap", omiPkMap), locale));
            }
        }

        comiCtx.putAll(omiPkMap);
        comiCtx.put("authId", authId);
        comiCtx.put("receivedDate", timestamp);
        comiCtx.put("sentDate", sentTimestamp);
        comiCtx.put("outgoingMessage", "N");
        comiCtx.put("confirmation", confirmation);
        comiCtx.put("bsrVerb", bsrVerb);
        comiCtx.put("bsrNoun", bsrNoun);
        comiCtx.put("bsrRevision", bsrRevision);
        comiCtx.put("processingStatusId", "OAGMP_RECEIVED");
        comiCtx.put("userLogin", userLogin);
        if (OagisServices.debugSaveXmlIn) {
            try {
                comiCtx.put("fullMessageXml", UtilXml.writeXmlDocument(doc));
            } catch (IOException e) {
                // this is just for debug info, so just log and otherwise ignore error
                String errMsg = "Warning: error creating text from XML Document for saving to database: " + e.toString();
                Debug.logWarning(errMsg, module);
            }
        }
        try {
            if (isErrorRetry) {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } else {
                dispatcher.runSync("createOagisMessageInfo", comiCtx, 60, true);
            }
        } catch (GenericServiceException e) {
            String errMsg = "Error creating OagisMessageInfo for the Incoming Message: " + e.toString();
            Debug.logError(e, errMsg, module);
        }

        //String inventoryItemId = null;
        List<String> invItemIds = FastList.newInstance();
        // get RECEIPTLN elements from message
        List<? extends Element> receiptLineElementList = UtilXml.childElementList(acknowledgeDeliveryElement, "ns:RECEIPTLN");
        if (UtilValidate.isNotEmpty(receiptLineElementList)) {
            try {
                for (Element receiptLnElement : receiptLineElementList) {
                    Map<String, Object> uiiCtx = FastMap.newInstance();
                    Element qtyElement = UtilXml.firstChildElement(receiptLnElement, "os:QUANTITY");

                    String itemQtyStr = UtilXml.childElementValue(qtyElement, "of:VALUE");
                    String sign = UtilXml.childElementValue(qtyElement, "of:SIGN");

                    String productId = UtilXml.childElementValue(receiptLnElement, "of:ITEM");
                    if (UtilValidate.isEmpty(productId)) {
                        String errMsg = "Product ID Missing";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdMissing", "description", errMsg));
                        Debug.logError(errMsg, module);
                    }
                    // make sure productId is valid
                    GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
                    if (product == null) {
                        String errMsg = "Product with ID [" + productId + "] not found (invalid Product ID).";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "ProductIdNotValid", "description", errMsg));
                        Debug.logError(errMsg, module);
                        continue;
                    }

                    /* no place to put this in the InventoryItem update
                    String datetimeReceived = UtilXml.childElementValue(receiptLnElement, "os:DATETIMEISO");
                    Timestamp timestampItemReceived = OagisServices.parseIsoDateString(datetimeReceived, errorMapList);
                    uiiCtx.put("datetimeReceived", timestampItemReceived);
                    */

                    String invItemStatusId = null;
                    String reqFromItemStatusId = null;
                    String disposition = UtilXml.childElementValue(receiptLnElement, "of:DISPOSITN");
                    if ("NotAvailableTOAvailable".equals(disposition)) {
                        invItemStatusId = "INV_AVAILABLE";
                        reqFromItemStatusId = "INV_ON_HOLD";
                    } else if ("AvailableTONotAvailable".equals(disposition)) {
                        invItemStatusId = "INV_ON_HOLD";
                        reqFromItemStatusId = "INV_AVAILABLE";
                    } else if ("ReceivedTOAvailable".equals(disposition) || "ReceivedTONotAvailable".equals(disposition)) {
                        String errMsg = "Got DISPOSITN value [" + disposition + "] that is not valid for Status Change, only for RMA/return.";
                        errorMapList.add(UtilMisc.<String, String>toMap("reasonCode", "DispositnNotValidForStatusChange", "description", errMsg));
                        continue;
                    }

                    uiiCtx.put("statusId", invItemStatusId);

                    // geting the serial number(s)
                    List<String> serialNumsList = FastList.newInstance();
                    List<? extends Element> invDetailList = UtilXml.childElementList(receiptLnElement, "ns:INVDETAIL");
                    if (UtilValidate.isNotEmpty(invDetailList)) {
                        for (Element invDetailElement : invDetailList) {
                            String serialNumber = UtilXml.childElementValue(invDetailElement, "of:SERIALNUM");
                            if (UtilValidate.isNotEmpty(serialNumber)) {
                                serialNumsList.add(serialNumber);
                            }
                        }
                    }

                    //do some validations
                    Integer messageQuantity = Integer.valueOf(itemQtyStr);
                    if (UtilValidate.isNotEmpty(serialNumsList)) {
                        if (messageQuantity.intValue() != serialNumsList.size()) {
                            String errMsg = "Not enough serial numbers [" + serialNumsList.size() + "] for the quantity [" + messageQuantity.intValue() + "].";
                            errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumbersMissing"));
                            Debug.logInfo(errMsg, module);
                            continue;
                        }
                    }

                    uiiCtx.put("facilityId",facilityId);
                    uiiCtx.put("locationSeqId", locationSeqId);
                    uiiCtx.put("userLogin", userLogin);

                    // sign handling for items
                    if (!"+".equals(sign)) {
                        String errMsg = "Got a sign [" + sign + "] that was not plus (+), this is not valid for a Status Change operation.";
                        errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SignNotPlusForStatusChange"));
                        continue;
                    }

                    if (serialNumsList.size() > 0) {
                        String inventoryItemTypeId = "SERIALIZED_INV_ITEM";
                        uiiCtx.put("inventoryItemTypeId", inventoryItemTypeId);

                        for (String serialNum : serialNumsList) {
                            // also look at the productId, and associated refurb productId(s) (or other way around, we might get a refurb sku
                            //and need to look up by the non-refurb sku); serialNumbers may not be unique globally, but should be per product
                            Set<String> productIdSet = ProductWorker.getRefurbishedProductIdSet(productId, delegator);
                            productIdSet.add(productId);

                            EntityCondition bySerialNumberCondition = EntityCondition.makeCondition(EntityCondition.makeCondition("serialNumber", EntityOperator.EQUALS, serialNum),
                                    EntityOperator.AND, EntityCondition.makeCondition("productId", EntityOperator.IN, productIdSet));
                            List<GenericValue> inventoryItemsBySerialNumber = delegator.findList("InventoryItem", bySerialNumberCondition, null, null, null, false);

                            // this is a status update, so referenced serial number MUST already exist
                            if (inventoryItemsBySerialNumber.size() == 0) {
                                String errMsg = "Referenced serial numbers must already exist, but serial number [" + serialNum + "] was not found.";
                                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumberRequiredButNotFound"));
                                continue;
                            }

                            GenericValue inventoryItem = EntityUtil.getFirst(inventoryItemsBySerialNumber);
                            if (UtilValidate.isNotEmpty(reqFromItemStatusId) && !reqFromItemStatusId.equals(inventoryItem.getString("statusId"))) {
                                String errMsg = "Referenced serial number [" + serialNum + "] has status [" + inventoryItem.getString("statusId") + "] but we were expecting [" + reqFromItemStatusId + "]; this may mean the Acknowledge Delivery RMA message has not yet come in for this item.";
                                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SerialNumberRequiredButNotFound"));
                                continue;
                            }

                            Map<String, Object> updateInvItmMap = FastMap.newInstance();
                            updateInvItmMap.put("inventoryItemId", inventoryItem.getString("inventoryItemId"));
                            updateInvItmMap.put("userLogin", userLogin);
                            updateInvItmMap.put("statusId", invItemStatusId);
                            String inventoryItemProductId = inventoryItem.getString("productId");
                            if (!inventoryItemProductId.equals(productId)) {
                                // got a new productId for the serial number; this may happen for refurbishment, etc
                                updateInvItmMap.put("productId",productId);
                            }
                            dispatcher.runSync("updateInventoryItem", updateInvItmMap);
                            invItemIds.add(inventoryItem.getString("inventoryItemId"));
                        }
                    } else {
                        String inventoryItemTypeId = "NON_SERIAL_INV_ITEM";
                        uiiCtx.put("inventoryItemTypeId", inventoryItemTypeId);

                        // TODO: later somehow do status changes for non-serialized inventory

                        // for now just return an error message
                        String errMsg = "No serial numbers were included in the message and right now this is not supported";
                        errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "NoSerialNumbersInMessage"));
                    }
                }
            } catch (Throwable t) {
                String errMsg = "System Error processing Acknowledge Delivery Status message for message [" + omiPkMap + "]: " + t.toString();
                errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "SystemError"));

                try {
                    comiCtx.put("processingStatusId", "OAGMP_SYS_ERROR");
                    dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);

                    Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
                    saveErrorMapListCtx.putAll(omiPkMap);
                    saveErrorMapListCtx.put("errorMapList", errorMapList);
                    saveErrorMapListCtx.put("userLogin", userLogin);
                    dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
                } catch (GenericServiceException e) {
                    String errMsg2 = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                    Debug.logError(e, errMsg2, module);
                }

                Debug.logInfo(t, errMsg, module);
                // in this case we don't want to return a Confirm BOD, so return an error now
                return ServiceUtil.returnError(errMsg);
            }
        }

        Map<String, Object> result = FastMap.newInstance();
        result.putAll(omiPkMap);
        result.put("userLogin", userLogin);

        if (errorMapList.size() > 0) {
            try {
                comiCtx.put("processingStatusId", "OAGMP_PROC_ERROR");
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            // call services createOagisMsgErrInfosFromErrMapList and for incoming messages oagisSendConfirmBod
            Map<String, Object> saveErrorMapListCtx = FastMap.newInstance();
            saveErrorMapListCtx.putAll(omiPkMap);
            saveErrorMapListCtx.put("errorMapList", errorMapList);
            saveErrorMapListCtx.put("userLogin", userLogin);
            try {
                dispatcher.runSync("createOagisMsgErrInfosFromErrMapList", saveErrorMapListCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            try {
                Map<String, Object> sendConfirmBodCtx = FastMap.newInstance();
                sendConfirmBodCtx.putAll(saveErrorMapListCtx);

                // run async because this will send a message back to the other server and may take some time, and/or fail
                dispatcher.runAsync("oagisSendConfirmBod", sendConfirmBodCtx, null, true, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error sending Confirm BOD: " + e.toString();
                Debug.logError(e, errMsg, module);
            }

            String errMsg = "Found business level errors in message processing, not saving results; first error is: " + errorMapList.get(0);

            // return success here so that the message won't be retried and the Confirm BOD, etc won't be sent multiple times
            result.putAll(ServiceUtil.returnSuccess(errMsg));

            // however, we still don't want to save the partial results, so set rollbackOnly
            try {
                TransactionUtil.setRollbackOnly(errMsg, null);
            } catch (GenericTransactionException e) {
                Debug.logError(e, "Error setting rollback only ", module);
            }

            return result;
        } else {
            comiCtx.put("processingStatusId", "OAGMP_PROC_SUCCESS");
            try {
                dispatcher.runSync("updateOagisMessageInfo", comiCtx, 60, true);
            } catch (GenericServiceException e) {
                String errMsg = "Error updating OagisMessageInfo for the Incoming Message: " + e.toString();
                // don't pass this back, nothing they can do about it: errorMapList.add(UtilMisc.<String, String>toMap("description", errMsg, "reasonCode", "GenericServiceException"));
                Debug.logError(e, errMsg, module);
            }
        }

        result.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OagisServiceCompletedSuccessfully", locale)));
        result.put("inventoryItemIdList", invItemIds);
        return result;
    }
}
