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

// This script can be used for testing right now but it should not be used for production because
// it does not work for marketing packages and more importantly, if there is a new product without any
// inventory items, it will not show up on the inventory report even if it had a ProductFacility record.
// These problems need to be addressed before this can be used in production.

// This script counts the inventory in the facility using a complex and
// pretty efficient dynamic view entity.
// However, since the quantities are not computed using the inventory
// services (getInventoryAvailableByFacility and getMktgPackagesAvailable)
// there are some limitations: the virtual inventory of marketing packages
// is not computed; you can use the ViewFacilityInventoryByProduct.groovy if you
// need it (but it is slower than this one).

import org.apache.ofbiz.base.util.Debug
import org.apache.ofbiz.entity.*
import org.apache.ofbiz.entity.condition.*
import org.apache.ofbiz.entity.transaction.*
import org.apache.ofbiz.entity.util.*
import org.apache.ofbiz.entity.model.DynamicViewEntity
import org.apache.ofbiz.entity.model.ModelKeyMap
import org.apache.ofbiz.entity.model.ModelViewEntity.ComplexAlias
import org.apache.ofbiz.entity.model.ModelViewEntity.ComplexAliasField
import org.apache.ofbiz.product.inventory.*

action = request.getParameter("action")

searchParameterString = "action=Y&facilityId=" + facilityId

offsetQOH = -1
offsetATP = -1
hasOffsetQOH = false
hasOffsetATP = false

EntityListIterator prodsEli = null
rows = [] as ArrayList

if (action) {
    // ------------------------------
    prodView = new DynamicViewEntity()
    atpDiffComplexAlias = new ComplexAlias("-")

    conditionMap = [facilityId : facilityId]

    if (offsetQOHQty) {
        try {
            offsetQOH = Integer.parseInt(offsetQOHQty)
            hasOffsetQOH = true
            searchParameterString = searchParameterString + "&offsetQOHQty=" + offsetQOH
        } catch (NumberFormatException nfe) {
        }
    }
    if (offsetATPQty) {
        try {
            offsetATP = Integer.parseInt(offsetATPQty)
            hasOffsetATP = true
            searchParameterString = searchParameterString + "&offsetATPQty=" + offsetATP
        } catch (NumberFormatException nfe) {
        }
    }

    prodView.addMemberEntity("PRFA", "ProductFacility")
    prodView.addAlias("PRFA", "productId", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PRFA", "minimumStock", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PRFA", "reorderQuantity", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PRFA", "daysToShip", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PRFA", "facilityId", null, null, null, Boolean.TRUE, null)

    prodView.addMemberEntity("PROD", "Product")
    prodView.addViewLink("PROD", "PRFA", Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId"))
    prodView.addAlias("PROD", "internalName", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PROD", "isVirtual", null, null, null, Boolean.TRUE, null)
    prodView.addAlias("PROD", "salesDiscontinuationDate", null, null, null, Boolean.TRUE, null)
    if (productTypeId) {
        prodView.addAlias("PROD", "productTypeId", null, null, null, Boolean.TRUE, null)
        conditionMap.productTypeId = productTypeId
        searchParameterString = searchParameterString + "&productTypeId=" + productTypeId
    }

    prodView.addMemberEntity("IITE", "InventoryItem")
    prodView.addViewLink("PRFA", "IITE", Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId", "productId", "facilityId", "facilityId"))
    prodView.addAlias("IITE", "totalQuantityOnHandTotal", "quantityOnHandTotal", null, null, null, "sum")
    prodView.addAlias("IITE", "totalAvailableToPromiseTotal", "availableToPromiseTotal", null, null, null, "sum")
    qohDiffComplexAlias = new ComplexAlias("-")
    qohDiffComplexAlias.addComplexAliasMember(new ComplexAliasField("IITE", "quantityOnHandTotal", null, "sum"))
    qohDiffComplexAlias.addComplexAliasMember(new ComplexAliasField("PRFA", "minimumStock", null, null))
    prodView.addAlias(null, "offsetQOHQtyAvailable", null, null, null, null, null, qohDiffComplexAlias)
    atpDiffComplexAlias = new ComplexAlias("-")
    atpDiffComplexAlias.addComplexAliasMember(new ComplexAliasField("IITE", "availableToPromiseTotal", null, "sum"))
    atpDiffComplexAlias.addComplexAliasMember(new ComplexAliasField("PRFA", "minimumStock", null, null))
    prodView.addAlias(null, "offsetATPQtyAvailable", null, null, null, null, null, atpDiffComplexAlias)

    if (searchInProductCategoryId) {
        prodView.addMemberEntity("PRCA", "ProductCategoryMember")
        prodView.addViewLink("PRFA", "PRCA", Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId"))
        prodView.addAlias("PRCA", "productCategoryId", null, null, null, Boolean.TRUE, null)
        conditionMap.productCategoryId = searchInProductCategoryId
        searchParameterString = searchParameterString + "&searchInProductCategoryId=" + searchInProductCategoryId
    }

    if (productSupplierId) {
        prodView.addMemberEntity("SPPR", "SupplierProduct")
        prodView.addViewLink("PRFA", "SPPR", Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId"))
        prodView.addAlias("SPPR", "partyId", null, null, null, Boolean.TRUE, null)
        conditionMap.partyId = productSupplierId
        searchParameterString = searchParameterString + "&productSupplierId=" + productSupplierId
    }

    // set distinct on so we only get one row per product
    searchCondition = EntityCondition.makeCondition(conditionMap, EntityOperator.AND)
    notVirtualCondition = EntityCondition.makeCondition(EntityCondition.makeCondition("isVirtual", EntityOperator.EQUALS, null),
                                                        EntityOperator.OR,
                                                        EntityCondition.makeCondition("isVirtual", EntityOperator.NOT_EQUAL, "Y"))

    whereConditionsList = [searchCondition, notVirtualCondition]
    // add the discontinuation date condition
    if (productsSoldThruTimestamp) {
        discontinuationDateCondition = EntityCondition.makeCondition(
               [
                EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.EQUALS, null),
                EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.GREATER_THAN,productsSoldThruTimestamp)
               ],
               EntityOperator.OR)
        whereConditionsList.add(discontinuationDateCondition)
        searchParameterString = searchParameterString + "&productsSoldThruTimestamp=" + productsSoldThruTimestamp
    }

    // add search on internal name
    if (internalName) {
        whereConditionsList.add(EntityCondition.makeCondition("internalName", EntityOperator.LIKE, "%" + internalName + "%"))
        searchParameterString = searchParameterString + "&internalName=" + internalName
    }

    // add search on productId
    if (productId) {
        whereConditionsList.add(EntityCondition.makeCondition("productId", EntityOperator.LIKE, productId + "%"))
        searchParameterString = searchParameterString + "&productId=" + productId
    }

    orderBy = []
    if (hasOffsetATP) {
        orderBy.add("offsetATPQtyAvailable")
    }
    if (hasOffsetQOH) {
        orderBy.add("offsetQOHQtyAvailable")
    }
    orderBy.add("productId")

    // If the user has specified a number of months over which to sum usage quantities, define the correct timestamp
    checkTime = null
    monthsInPastLimitStr = request.getParameter("monthsInPastLimit")
    if (monthsInPastLimitStr) {
        try {
            monthsInPastLimit = Integer.parseInt(monthsInPastLimitStr)
            cal = UtilDateTime.toCalendar(null)
            cal.add(Calendar.MONTH, 0 - monthsInPastLimit)
            checkTime = UtilDateTime.toTimestamp(cal.getTime())
            searchParameterString += "&monthsInPastLimit=" + monthsInPastLimitStr
        } catch (Exception e) {
            // Ignore
        }
    }

    if (checkTime) {

        // Construct a dynamic view entity to search against for sales usage quantities
        salesUsageViewEntity = new DynamicViewEntity()
        salesUsageViewEntity.addMemberEntity("OI", "OrderItem")
        salesUsageViewEntity.addMemberEntity("OH", "OrderHeader")
        salesUsageViewEntity.addMemberEntity("ItIss", "ItemIssuance")
        salesUsageViewEntity.addMemberEntity("InvIt", "InventoryItem")
        salesUsageViewEntity.addViewLink("OI", "OH", false, ModelKeyMap.makeKeyMapList("orderId"))
        salesUsageViewEntity.addViewLink("OI", "ItIss", false, ModelKeyMap.makeKeyMapList("orderId", "orderId", "orderItemSeqId", "orderItemSeqId"))
        salesUsageViewEntity.addViewLink("ItIss", "InvIt", false, ModelKeyMap.makeKeyMapList("inventoryItemId"))
        salesUsageViewEntity.addAlias("OI", "productId")
        salesUsageViewEntity.addAlias("OH", "statusId")
        salesUsageViewEntity.addAlias("OH", "orderTypeId")
        salesUsageViewEntity.addAlias("OH", "orderDate")
        salesUsageViewEntity.addAlias("ItIss", "inventoryItemId")
        salesUsageViewEntity.addAlias("ItIss", "quantity")
        salesUsageViewEntity.addAlias("InvIt", "facilityId")

        // Construct a dynamic view entity to search against for production usage quantities
        productionUsageViewEntity = new DynamicViewEntity()
        productionUsageViewEntity.addMemberEntity("WEIA", "WorkEffortInventoryAssign")
        productionUsageViewEntity.addMemberEntity("WE", "WorkEffort")
        productionUsageViewEntity.addMemberEntity("II", "InventoryItem")
        productionUsageViewEntity.addViewLink("WEIA", "WE", false, ModelKeyMap.makeKeyMapList("workEffortId"))
        productionUsageViewEntity.addViewLink("WEIA", "II", false, ModelKeyMap.makeKeyMapList("inventoryItemId"))
        productionUsageViewEntity.addAlias("WEIA", "quantity")
        productionUsageViewEntity.addAlias("WE", "actualCompletionDate")
        productionUsageViewEntity.addAlias("WE", "workEffortTypeId")
        productionUsageViewEntity.addAlias("II", "facilityId")
        productionUsageViewEntity.addAlias("II", "productId")
    }

    whereCondition = EntityCondition.makeCondition(whereConditionsList, EntityOperator.AND)

    beganTransaction = false
    List prods = null
    try {
        beganTransaction = TransactionUtil.begin()

        // get the indexes for the partial list
        lowIndex = ((viewIndex.intValue() * viewSize.intValue()) + 1)
        highIndex = (viewIndex.intValue() + 1) * viewSize.intValue()
        prodsEli = from(prodView).where(whereCondition).orderBy(orderBy).cursorScrollInsensitive().maxRows(highIndex).distinct().queryIterator()

        // get the partial list for this page
        prods = prodsEli.getPartialList(lowIndex, highIndex)
        prodsIt = prods.iterator()
        while (prodsIt) {
            oneProd = prodsIt.next()
            offsetQOHQtyAvailable = oneProd.getBigDecimal("offsetQOHQtyAvailable")
            offsetATPQtyAvailable = oneProd.getBigDecimal("offsetATPQtyAvailable")
            if (hasOffsetATP) {
                if (offsetATPQtyAvailable && offsetATPQtyAvailable.doubleValue() > offsetATP) {
                    break
                }
            }
            if (hasOffsetQOH) {
                if (offsetQOHQtyAvailable && offsetQOHQtyAvailable.doubleValue() > offsetQOH) {
                    break
                }
            }

            oneInventory = [:]
            oneInventory.productId = oneProd.productId
            oneInventory.minimumStock = oneProd.getBigDecimal("minimumStock")
            oneInventory.reorderQuantity = oneProd.getBigDecimal("reorderQuantity")
            oneInventory.daysToShip = oneProd.getString("daysToShip")
            oneInventory.totalQuantityOnHand = oneProd.totalQuantityOnHandTotal
            oneInventory.totalAvailableToPromise = oneProd.totalAvailableToPromiseTotal
            oneInventory.offsetQOHQtyAvailable = offsetQOHQtyAvailable
            oneInventory.offsetATPQtyAvailable = offsetATPQtyAvailable
            oneInventory.quantityOnOrder = InventoryWorker.getOutstandingPurchasedQuantity(oneProd.productId, delegator)


            if (checkTime) {

                // Make a query against the sales usage view entity
                salesUsageIt = from(salesUsageViewEntity)
                                    .where(EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
                                        EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
                                        EntityCondition.makeCondition("statusId", EntityOperator.IN, ['ORDER_COMPLETED', 'ORDER_APPROVED', 'ORDER_HELD']),
                                        EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
                                        EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime))
                                    .queryIterator()

                // Sum the sales usage quantities found
                salesUsageQuantity = 0
                salesUsageIt.each { salesUsageItem ->
                    if (salesUsageItem.quantity) {
                        try {
                            salesUsageQuantity += salesUsageItem.getDouble("quantity").doubleValue()
                        } catch (Exception e) {
                            // Ignore
                        }
                    }
                }
                salesUsageIt.close()

                // Make a query against the production usage view entity
                productionUsageIt = from(productionUsageViewEntity)
                                    .where(EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
                                         EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
                                         EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "PROD_ORDER_TASK"),
                                         EntityCondition.makeCondition("actualCompletionDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime))
                                    .queryIterator()

                // Sum the production usage quantities found
                productionUsageQuantity = 0
                productionUsageIt.each { productionUsageItem ->
                    if (productionUsageItem.quantity) {
                        try {
                            productionUsageQuantity += productionUsageItem.getDouble("quantity").doubleValue()
                        } catch (Exception e) {
                            // Ignore
                        }
                    }
                }
                productionUsageIt.close()
                oneInventory.usageQuantity = salesUsageQuantity + productionUsageQuantity
            }
            rows.add(oneInventory)
        }
        if (rows.size() < viewSize.intValue()) {
            productListSize = lowIndex + rows.size() - 1
        } else {
            // attempt to get the full size
            if (hasOffsetQOH || hasOffsetATP) {
                rowProcessed = 0
                while (nextValue = prodsEli.next()) {
                    offsetQOHQtyAvailable = nextValue.getDouble("offsetQOHQtyAvailable")
                    offsetATPQtyAvailable = nextValue.getDouble("offsetATPQtyAvailable")
                    if (hasOffsetATP) {
                        if (offsetATPQtyAvailable && offsetATPQtyAvailable.doubleValue() > offsetATP) {
                            break
                        }
                    }
                    if (hasOffsetQOH) {
                        if (offsetQOHQtyAvailable && offsetQOHQtyAvailable.doubleValue() > offsetQOH) {
                            break
                        }
                    }
                    rowProcessed++
                }
                productListSize = lowIndex + rows.size() + rowProcessed - 1
            } else {
                productListSize = prodsEli.getResultsSizeAfterPartialList()
            }
        }
        prodsEli.close()
        if (highIndex > productListSize) {
            highIndex = productListSize
        }
        context.overrideListSize = productListSize
        context.highIndex = highIndex
        context.lowIndex = lowIndex

    } catch (GenericEntityException e) {
        errMsg = "Failure in operation, rolling back transaction"
        Debug.logError(e, errMsg, "ViewFacilityInventoryByProduct")
        try {
            // only rollback the transaction if we started one...
            TransactionUtil.rollback(beganTransaction, errMsg, e)
        } catch (GenericEntityException e2) {
            Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), "ViewFacilityInventoryByProduct")
        }
        // after rolling back, rethrow the exception
        throw e
    } finally {
        if (prodsEli != null) {
            try {
                prodsEli.close()
            } catch (Exception exc) {}
        }
        // only commit the transaction if we started one... this will throw an exception if it fails
        TransactionUtil.commit(beganTransaction)
    }
}
context.inventoryByProduct = rows
context.searchParameterString = searchParameterString
