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

import org.ofbiz.entity.condition.*
import org.ofbiz.entity.util.*
import org.ofbiz.service.ServiceUtil
import org.ofbiz.base.util.*

shipmentId = request.getParameter("shipmentId");
orderId = request.getParameter("purchaseOrderId");
shipGroupSeqId = request.getParameter("shipGroupSeqId");
context.shipmentId = shipmentId;
context.shipGroupSeqId = shipGroupSeqId;

// Retrieve the map resident in session which stores order item quantities to receive
itemQuantitiesToReceive = session.getAttribute("purchaseOrderItemQuantitiesToReceive");
if (itemQuantitiesToReceive) {
    sessionShipmentId = itemQuantitiesToReceive._shipmentId;
    sessionOrderId = itemQuantitiesToReceive._orderId;
    if ((sessionShipmentId && !sessionShipmentId.equals(shipmentId)) ||
        ((sessionOrderId && !sessionOrderId.equals(orderId)))        ||
         "Y".equals(request.getParameter("clearAll"))) {

             // Clear the map if the shipmentId or orderId are different than the current ones, or
             // if the clearAll parameter is present
             itemQuantitiesToReceive.clear();
    }
}

shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
context.shipment = shipment;
if (!shipment) {
    return;
}

isPurchaseShipment = "PURCHASE_SHIPMENT".equals(shipment.shipmentTypeId);
context.isPurchaseShipment = isPurchaseShipment;
if (!isPurchaseShipment) {
    return;
}

facility = shipment.getRelatedOne("DestinationFacility", false);
context.facility = facility;
context.facilityId = shipment.destinationFacilityId;
context.now = UtilDateTime.nowTimestamp();

if (!orderId) {
    orderId = shipment.primaryOrderId;
}
if (!shipGroupSeqId) {
    shipGroupSeqId = shipment.primaryShipGroupSeqId;
}
context.orderId = orderId;

if (!orderId) {
    return;
}

orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
context.orderHeader = orderHeader;
if (!orderHeader) {
    return;
}

isPurchaseOrder = "PURCHASE_ORDER".equals(orderHeader.orderTypeId);
context.isPurchaseOrder = isPurchaseOrder;
if (!isPurchaseOrder) {
    return;
}

// Get the base currency from the facility owner, for currency conversions
baseCurrencyUomId = null;
if (facility) {
    owner = facility.getRelatedOne("OwnerParty", false);
    if (owner) {
        result = dispatcher.runSync("getPartyAccountingPreferences", [organizationPartyId : owner.partyId, userLogin : request.getAttribute("userLogin")]);
        if (!ServiceUtil.isError(result) && result.partyAccountingPreference) {
            ownerAcctgPref = result.partyAccountingPreference;
        }
    }
    if (ownerAcctgPref) {
        baseCurrencyUomId = ownerAcctgPref.baseCurrencyUomId;
    }
}

inventoryItemTypes = delegator.findList("InventoryItemType", null, null, null, null, false);
context.inventoryItemTypes = inventoryItemTypes;

// Populate the tracking map with shipment and order IDs
if (!itemQuantitiesToReceive) {
    itemQuantitiesToReceive = [_shipmentId : shipmentId, _orderId : orderId];
}

oiasgaLimitMap = null;
if (shipGroupSeqId) {
    oiasgaLimitMap = [shipGroupSeqId : shipGroupSeqId];
}

orderItemDatas = [:] as TreeMap;
totalAvailableToReceive = 0;

// Populate the order item data for the FTL
orderItems = orderHeader.getRelated("OrderItemAndShipGroupAssoc", oiasgaLimitMap, ['shipGroupSeqId', 'orderItemSeqId'], false);
orderItems.each { orderItemAndShipGroupAssoc ->
    product = orderItemAndShipGroupAssoc.getRelatedOne("Product", false);

    // Get the order item, since the orderItemAndShipGroupAssoc's quantity field is manipulated in some cases
    orderItem = delegator.findOne("OrderItem", [orderId : orderId, orderItemSeqId : orderItemAndShipGroupAssoc.orderItemSeqId], false);
    orderItemData = [:];

    // Get the item's ordered quantity
    totalOrdered = 0;
    ordered = orderItem.getDouble("quantity");
    if (ordered) {
        totalOrdered += ordered.doubleValue();
    }
    cancelled = orderItem.getDouble("cancelQuantity");
    if (cancelled) {
        totalOrdered -= cancelled.doubleValue();
    }

    // Get the item quantity received from all shipments via the ShipmentReceipt entity
    totalReceived = 0.0;
    receipts = delegator.findList("ShipmentReceipt", EntityCondition.makeCondition([orderId : orderId, orderItemSeqId : orderItem.orderItemSeqId]), null, null, null, false);
    fulfilledReservations = [] as ArrayList;
    if (receipts) {
        receipts.each { rec ->
            accepted = rec.getDouble("quantityAccepted");
            rejected = rec.getDouble("quantityRejected");
            if (accepted) {
                totalReceived += accepted.doubleValue();
            }
            if (rejected) {
                totalReceived += rejected.doubleValue();
            }
            // Get the reservations related to this receipt
            oisgirs = delegator.findList("OrderItemShipGrpInvRes", EntityCondition.makeCondition([inventoryItemId : rec.inventoryItemId]), null, null, null, false);
            if (oisgirs) {
                fulfilledReservations.addAll(oisgirs);
            }
        }
    }
    orderItemData.fulfilledReservations = fulfilledReservations;

    // Update the unit cost with the converted value, if any
    if (baseCurrencyUomId && orderHeader.currencyUom) {
        if (product) {
            result = dispatcher.runSync("convertUom", [uomId : orderHeader.currencyUom, uomIdTo : baseCurrencyUomId, originalValue : orderItem.unitPrice]);
            if (!ServiceUtil.isError(result)) {
                orderItem.unitPrice = result.convertedValue;
            }
        }
    }

    // Retrieve the backordered quantity
    // TODO: limit to a facility? The shipment destination facility is not necessarily the same facility as the inventory
    conditions = [EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.productId),
                  EntityCondition.makeCondition("availableToPromiseTotal", EntityOperator.LESS_THAN, BigDecimal.ZERO)];
    negativeInventoryItems = delegator.findList("InventoryItem",  EntityCondition.makeCondition(conditions, EntityOperator.AND), null, null, null, false);
    backOrderedQuantity = 0;
    negativeInventoryItems.each { negativeInventoryItem ->
        backOrderedQuantity += negativeInventoryItem.getDouble("availableToPromiseTotal").doubleValue();
    }
    orderItemData.backOrderedQuantity = Math.abs(backOrderedQuantity);

    // Calculate how many units it should be possible to recieve for this purchase order
    availableToReceive = totalOrdered - totalReceived;
    totalAvailableToReceive += availableToReceive;
    orderItemData.availableToReceive = availableToReceive;
    orderItemData.totalQuantityReceived = totalReceived;
    orderItemData.shipGroupSeqId = orderItemAndShipGroupAssoc.shipGroupSeqId;
    orderItemData.orderItem = orderItem;
    orderItemData.product = product;
    orderItemDatas.put(orderItem.orderItemSeqId, orderItemData);
}
context.orderItemDatas = orderItemDatas.values();

// Handle any item product quantities to receive by adding to the map in session
productIdToReceive = request.getParameter("productId");
productQtyToReceive = request.getParameter("quantity");
context.newQuantity = productQtyToReceive;

if (productIdToReceive) {
    List candidateOrderItems = EntityUtil.filterByAnd(orderItems, [productId : productIdToReceive]);

    // If the productId as given isn't found in the order, try any goodIdentifications and use the first match
    if (!candidateOrderItems) {
        goodIdentifications = delegator.findList("GoodIdentification", EntityCondition.makeCondition([idValue : productIdToReceive]), null, null, null, false);
        if (goodIdentifications) {
            giit = goodIdentifications.iterator();
            while (giit.hasNext()) {
                goodIdentification = giit.next();
                candidateOrderItems = EntityUtil.filterByAnd(orderItems, [productId : goodIdentification.productId]);
                if (candidateOrderItems) {
                    productIdToReceive = goodIdentification.productId;
                    break;
                }
            }
        }
    }

    if (candidateOrderItems) {
        quantity = 0;
        if (productQtyToReceive) {
            try {
                quantity = Double.parseDouble(productQtyToReceive);
            } catch (Exception e) {
                // Ignore the quantity update if there's a problem parsing it
            }
        }

        totalQuantityUsed = 0;
        totalQuantityToReceiveBefore = 0;
        pqit = candidateOrderItems.iterator();
        while (pqit.hasNext() && totalQuantityUsed < quantity) {
            candidateOrderItem = pqit.next();
            orderItemSeqId = candidateOrderItem.orderItemSeqId;
            qtyBefore = itemQuantitiesToReceive.containsKey(orderItemSeqId) ? itemQuantitiesToReceive.get(orderItemSeqId) : 0;
            totalQuantityToReceiveBefore += qtyBefore;
            qtyMaxAvailable = orderItemDatas.get(orderItemSeqId).availableToReceive - qtyBefore;

            if (qtyMaxAvailable <= 0) {
                continue;
            }

            qtyUsedForItem  = quantity - totalQuantityUsed >= qtyMaxAvailable ? qtyMaxAvailable : quantity - totalQuantityUsed;
            itemQuantitiesToReceive.put(orderItemSeqId, qtyUsedForItem + qtyBefore);
            totalQuantityUsed += qtyUsedForItem;
        }

        // If there's any quantity to receive left after using as much as possible for every relevant order item, add an error message to the context
        if (quantity > totalQuantityUsed) {
            context.ProductReceiveInventoryAgainstPurchaseOrderQuantityExceedsAvailableToReceive = true;
        }

        // Notify if some or all of the quantity just entered for the product will go to a backorder
        backOrderedQuantity = orderItemDatas.get(EntityUtil.getFirst(candidateOrderItems).orderItemSeqId).backOrderedQuantity - totalQuantityToReceiveBefore;

        if (backOrderedQuantity > 0) {
            totalQtyUsedForBackorders = backOrderedQuantity >= totalQuantityUsed ? totalQuantityUsed : backOrderedQuantity;
            if (totalQtyUsedForBackorders > 0) {
                context.quantityToReceive = totalQuantityUsed;
                context.quantityToBackOrder = totalQtyUsedForBackorders;
                context.ProductReceiveInventoryAgainstPurchaseOrderQuantityGoesToBackOrder = true;
            }
        }
    } else {

        // Add an error message to the context if the productId doesn't exist in this purchase order
        context.ProductReceiveInventoryAgainstPurchaseOrderProductNotFound = true;
    }
}

// Put the tracking map back into the session, in case it has been reconstructed
session.setAttribute("purchaseOrderItemQuantitiesToReceive", itemQuantitiesToReceive);
context.itemQuantitiesToReceive = itemQuantitiesToReceive;
context.totalAvailableToReceive = totalAvailableToReceive;
