/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/

package org.apache.ofbiz.manufacturing.bom;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.manufacturing.mrp.ProposedOrder;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;

/** An ItemCoinfigurationNode represents a component in a bill of materials.
 */

public class BOMNode {
    public static final String module = BOMNode.class.getName();

    protected LocalDispatcher dispatcher = null;
    protected Delegator delegator = null;
    protected GenericValue userLogin = null;

    private BOMTree tree; // the tree to which this node belongs
    private BOMNode parentNode; // the parent node (null if it's not present)
    private BOMNode substitutedNode; // The virtual node (if any) that this instance substitutes
    private GenericValue ruleApplied; // The rule (if any) that that has been applied to configure the current node
    private String productForRules;
    private GenericValue product; // the current product (from Product entity)
    private GenericValue productAssoc; // the product assoc record (from ProductAssoc entity) in which the current product is in productIdTo
    private List<GenericValue> children; // current node's children (ProductAssocs)
    private List<BOMNode> childrenNodes; // current node's children nodes (BOMNode)
    private BigDecimal quantityMultiplier; // the necessary quantity as declared in the bom (from ProductAssocs or ProductManufacturingRule)
    private BigDecimal scrapFactor; // the scrap factor as declared in the bom (from ProductAssocs)
    // Runtime fields
    private int depth; // the depth of this node in the current tree
    private BigDecimal quantity; // the quantity of this node in the current tree
    private String bomTypeId; // the type of the current tree

    public BOMNode(GenericValue product, LocalDispatcher dispatcher, GenericValue userLogin) {
        this.product = product;
        this.delegator = product.getDelegator();
        this.dispatcher = dispatcher;
        this.userLogin = userLogin;
        children = new LinkedList<GenericValue>();
        childrenNodes = new LinkedList<BOMNode>();
        parentNode = null;
        productForRules = null;
        bomTypeId = null;
        quantityMultiplier = BigDecimal.ONE;
        scrapFactor = BigDecimal.ONE;
        // Now we initialize the fields used in breakdowns
        depth = 0;
        quantity = BigDecimal.ZERO;
    }

    public BOMNode(String productId, Delegator delegator, LocalDispatcher dispatcher, GenericValue userLogin) throws GenericEntityException {
        this(EntityQuery.use(delegator).from("Product").where("productId", productId).queryOne(), dispatcher, userLogin);
    }

    protected void loadChildren(String partBomTypeId, Date inDate, List<GenericValue> productFeatures, int type) throws GenericEntityException {
        if (product == null) {
            throw new GenericEntityException("product is null");
        }
        // If the date is null, set it to today.
        if (inDate == null) inDate = new Date();
        bomTypeId = partBomTypeId;
        List<GenericValue> rows = EntityQuery.use(delegator).from("ProductAssoc")
                .where("productId", product.get("productId"),
                        "productAssocTypeId", partBomTypeId)
                .orderBy("sequenceNum", "productIdTo")
                .filterByDate(inDate).queryList();
        if ((UtilValidate.isEmpty(rows)) && substitutedNode != null) {
            // If no child is found and this is a substituted node
            // we try to search for substituted node's children.
            rows = EntityQuery.use(delegator).from("ProductAssoc")
                    .where("productId", substitutedNode.getProduct().get("productId"),
                            "productAssocTypeId", partBomTypeId)
                    .orderBy("sequenceNum")
                    .filterByDate(inDate).queryList();
        }
        children = new LinkedList<GenericValue>();
        children.addAll(rows);
        childrenNodes = new LinkedList<BOMNode>();
        BOMNode oneChildNode = null;
        for (GenericValue oneChild : children) {
            // Configurator
            oneChildNode = configurator(oneChild, productFeatures, getRootNode().getProductForRules(), inDate);
            // If the node is null this means that the node has been discarded by the rules.
            if (oneChildNode != null) {
                oneChildNode.setParentNode(this);
                switch (type) {
                    case BOMTree.EXPLOSION:
                        oneChildNode.loadChildren(partBomTypeId, inDate, productFeatures, BOMTree.EXPLOSION);
                    break;
                    case BOMTree.EXPLOSION_MANUFACTURING:
                        // for manufacturing trees, do not look through and create production runs for children unless there is no warehouse stocking of this node item
                        if (!oneChildNode.isWarehouseManaged(null)) { // FIXME: we will need to pass a facilityId here
                            oneChildNode.loadChildren(partBomTypeId, inDate, productFeatures, type);
                        }
                    break;
                }
            }
            childrenNodes.add(oneChildNode);
        }
    }

    private BOMNode substituteNode(BOMNode oneChildNode, List<GenericValue> productFeatures,
            List<GenericValue> productPartRules) throws GenericEntityException {
        if (productPartRules != null) {
            GenericValue rule = null;
            for (int i = 0; i < productPartRules.size(); i++) {
                rule = productPartRules.get(i);
                String ruleCondition = (String)rule.get("productFeature");
                String ruleOperator = (String)rule.get("ruleOperator");
                String newPart = (String)rule.get("productIdInSubst");
                BigDecimal ruleQuantity = BigDecimal.ZERO;
                try {
                    ruleQuantity = rule.getBigDecimal("quantity");
                } catch (Exception exc) {
                    ruleQuantity = BigDecimal.ZERO;
                }

                GenericValue feature = null;
                boolean ruleSatisfied = false;
                if (ruleCondition == null || ruleCondition.equals("")) {
                    ruleSatisfied = true;
                } else {
                    if (productFeatures != null) {
                        for (int j = 0; j < productFeatures.size(); j++) {
                            feature = productFeatures.get(j);
                            if (ruleCondition.equals(feature.get("productFeatureId"))) {
                                ruleSatisfied = true;
                                break;
                            }
                        }
                    }
                }
                if (ruleSatisfied && ruleOperator.equals("OR")) {
                    BOMNode tmpNode = oneChildNode;
                    if (newPart == null || newPart.equals("")) {
                        oneChildNode = null;
                    } else {
                        BOMNode origNode = oneChildNode;
                        oneChildNode = new BOMNode(newPart, delegator, dispatcher, userLogin);
                        oneChildNode.setTree(tree);
                        oneChildNode.setSubstitutedNode(tmpNode);
                        oneChildNode.setRuleApplied(rule);
                        oneChildNode.setProductAssoc(origNode.getProductAssoc());
                        oneChildNode.setScrapFactor(origNode.getScrapFactor());
                        if (ruleQuantity.compareTo(BigDecimal.ZERO) > 0) {
                            oneChildNode.setQuantityMultiplier(ruleQuantity);
                        } else {
                            oneChildNode.setQuantityMultiplier(origNode.getQuantityMultiplier());
                        }
                    }
                    break;
                }
                // FIXME: AND operator still not implemented
            } // end of for

        }
        return oneChildNode;
    }

    private BOMNode configurator(GenericValue node, List<GenericValue> productFeatures, 
            String productIdForRules, Date inDate) throws GenericEntityException {
        BOMNode oneChildNode = new BOMNode((String)node.get("productIdTo"), delegator, dispatcher, userLogin);
        oneChildNode.setTree(tree);
        oneChildNode.setProductAssoc(node);
        try {
            oneChildNode.setQuantityMultiplier(node.getBigDecimal("quantity"));
        } catch (Exception nfe) {
            oneChildNode.setQuantityMultiplier(BigDecimal.ONE);
        }
        try {
            BigDecimal percScrapFactor = node.getBigDecimal("scrapFactor");

            // A negative scrap factor is a salvage factor
            BigDecimal bdHundred = new BigDecimal("100");
            if (percScrapFactor.compareTo(bdHundred.negate()) > 0 && percScrapFactor.compareTo(bdHundred) < 0) {
                percScrapFactor = BigDecimal.ONE.add(percScrapFactor.movePointLeft(2));
            } else {
                Debug.logWarning("A scrap factor of [" + percScrapFactor + "] was ignored", module);
                percScrapFactor = BigDecimal.ONE;
            }
            oneChildNode.setScrapFactor(percScrapFactor);
        } catch (Exception nfe) {
            oneChildNode.setScrapFactor(BigDecimal.ONE);
        }
        BOMNode newNode = oneChildNode;
        // CONFIGURATOR
        if (oneChildNode.isVirtual()) {
            // If the part is VIRTUAL and
            // productFeatures and productPartRules are not null
            // we have to substitute the part with the right part's variant
            List<GenericValue> productPartRules = EntityQuery.use(delegator).from("ProductManufacturingRule")
                    .where("productId", productIdForRules,
                            "productIdFor", node.get("productId"),
                            "productIdIn", node.get("productIdTo"))
                    .filterByDate(inDate).queryList();
            if (substitutedNode != null) {
                productPartRules.addAll(EntityQuery.use(delegator).from("ProductManufacturingRule")
                        .where("productId", productIdForRules,
                                "productIdFor", substitutedNode.getProduct().get("productId"),
                                "productIdIn", node.get("productIdTo"))
                        .filterByDate(inDate).queryList());
            }
            newNode = substituteNode(oneChildNode, productFeatures, productPartRules);
            if (newNode.equals(oneChildNode)) {
                // If no substitution has been done (no valid rule applied),
                // we try to search for a generic link-rule
                List<GenericValue> genericLinkRules = EntityQuery.use(delegator).from("ProductManufacturingRule")
                        .where("productIdFor", node.get("productId"),
                                "productIdIn", node.get("productIdTo"))
                        .filterByDate(inDate).queryList();
                if (substitutedNode != null) {
                    genericLinkRules.addAll(EntityQuery.use(delegator).from("ProductManufacturingRule")
                            .where("productIdFor", substitutedNode.getProduct().get("productId"),
                                    "productIdIn", node.get("productIdTo"))
                            .filterByDate(inDate).queryList());
                }
                newNode = substituteNode(oneChildNode, productFeatures, genericLinkRules);
                if (newNode.equals(oneChildNode)) {
                    // If no substitution has been done (no valid rule applied),
                    // we try to search for a generic node-rule
                    List<GenericValue> genericNodeRules = EntityQuery.use(delegator).from("ProductManufacturingRule")
                            .where("productIdIn", node.get("productIdTo"))
                            .orderBy("ruleSeqId")
                            .filterByDate(inDate).queryList();
                    newNode = null;
                    newNode = substituteNode(oneChildNode, productFeatures, genericNodeRules);
                    if (newNode.equals(oneChildNode)) {
                        // If no substitution has been done (no valid rule applied),
                        // we try to set the default (first) node-substitution
                        if (UtilValidate.isNotEmpty(genericNodeRules)) {
                            // FIXME
                            //...
                        }
                        // -----------------------------------------------------------
                        // We try to apply directly the selected features
                        if (newNode.equals(oneChildNode)) {
                            Map<String, String> selectedFeatures = new HashMap<String, String>();
                            if (productFeatures != null) {
                                GenericValue feature = null;
                                for (int j = 0; j < productFeatures.size(); j++) {
                                    feature = productFeatures.get(j);
                                    selectedFeatures.put(feature.getString("productFeatureTypeId"), feature.getString("productFeatureId")); // FIXME
                                }
                            }

                            if (selectedFeatures.size() > 0) {
                                Map<String, Object> context = new HashMap<String, Object>();
                                context.put("productId", node.get("productIdTo"));
                                context.put("selectedFeatures", selectedFeatures);
                                Map<String, Object> storeResult = null;
                                GenericValue variantProduct = null;
                                try {
                                    storeResult = dispatcher.runSync("getProductVariant", context);
                                    List<GenericValue> variantProducts = UtilGenerics.checkList(storeResult.get("products"));
                                    if (variantProducts.size() == 1) {
                                        variantProduct = variantProducts.get(0);
                                    }
                                } catch (GenericServiceException e) {
                                    Debug.logError("Error calling getProductVariant service " + e.getMessage(), module);
                                }
                                if (variantProduct != null) {
                                    newNode = new BOMNode(variantProduct, dispatcher, userLogin);
                                    newNode.setTree(tree);
                                    newNode.setSubstitutedNode(oneChildNode);
                                    newNode.setQuantityMultiplier(oneChildNode.getQuantityMultiplier());
                                    newNode.setScrapFactor(oneChildNode.getScrapFactor());
                                    newNode.setProductAssoc(oneChildNode.getProductAssoc());
                                }
                            }

                        }
                        // -----------------------------------------------------------
                    }
                }
            }
        } // end of if (isVirtual())
        return newNode;
    }

    protected void loadParents(String partBomTypeId, Date inDate, List<GenericValue> productFeatures) throws GenericEntityException {
        if (product == null) {
            throw new GenericEntityException("product is null");
        }
        // If the date is null, set it to today.
        if (inDate == null) inDate = new Date();

        bomTypeId = partBomTypeId;
        List<GenericValue> rows = EntityQuery.use(delegator).from("ProductAssoc")
                .where("productIdTo", product.get("productId"),
                        "productAssocTypeId", partBomTypeId)
                .orderBy("sequenceNum")
                .filterByDate(inDate).queryList();
        if ((UtilValidate.isEmpty(rows)) && substitutedNode != null) {
            // If no parent is found and this is a substituted node
            // we try to search for substituted node's parents.
            rows = EntityQuery.use(delegator).from("ProductAssoc")
                    .where("productIdTo", substitutedNode.getProduct().get("productId"),
                            "productAssocTypeId", partBomTypeId)
                    .orderBy("sequenceNum")
                    .filterByDate(inDate).queryList();
        }
        children = new LinkedList<GenericValue>();
        children.addAll(rows);
        childrenNodes = new LinkedList<BOMNode>();

        BOMNode oneChildNode = null;
        for (GenericValue oneChild : children) {
            oneChildNode = new BOMNode(oneChild.getString("productId"), delegator, dispatcher, userLogin);
            // Configurator
            // If the node is null this means that the node has been discarded by the rules.
            if (oneChildNode != null) {
                oneChildNode.setParentNode(this);
                oneChildNode.setTree(tree);
                oneChildNode.loadParents(partBomTypeId, inDate, productFeatures);
            }
            childrenNodes.add(oneChildNode);
        }
    }


    /** Getter for property parentNode.
     * @return Value of property parentNode.
     *
     */
    public BOMNode getParentNode() {
        return parentNode;
    }

    public BOMNode getRootNode() {
        return (parentNode != null? getParentNode(): this);
    }
    /** Setter for property parentNode.
     * @param parentNode New value of property parentNode.
     *
     */
    public void setParentNode(BOMNode parentNode) {
        this.parentNode = parentNode;
    }
    // ------------------------------------
    // Method used for TEST and DEBUG purposes
    public void print(StringBuffer sb, BigDecimal quantity, int depth) {
        for (int i = 0; i < depth; i++) {
            sb.append("<b>&nbsp;*&nbsp;</b>");
        }
        sb.append(product.get("productId"));
        sb.append(" - ");
        sb.append(quantity);
        GenericValue oneChild = null;
        BOMNode oneChildNode = null;
        depth++;
        for (int i = 0; i < children.size(); i++) {
            oneChild = children.get(i);
            BigDecimal bomQuantity = BigDecimal.ZERO;
            try {
                bomQuantity = oneChild.getBigDecimal("quantity");
            } catch (Exception exc) {
                bomQuantity = BigDecimal.ONE;
            }
            oneChildNode = childrenNodes.get(i);
            sb.append("<br/>");
            if (oneChildNode != null) {
                oneChildNode.print(sb, quantity.multiply(bomQuantity), depth);
            }
        }
    }

    public void print(List<BOMNode> arr, BigDecimal quantity, int depth, boolean excludeWIPs) {
        // Now we set the depth and quantity of the current node
        // in this breakdown.
        this.depth = depth;
        String serviceName = null;
        if (this.productAssoc != null && this.productAssoc.getString("estimateCalcMethod") != null) {
            try {
                GenericValue genericService = productAssoc.getRelatedOne("CustomMethod", false);
                if (genericService != null && genericService.getString("customMethodName") != null) {
                    serviceName = genericService.getString("customMethodName");
                }
            } catch (Exception exc) {
            }
        }
        if (serviceName != null) {
            Map<String, Object> resultContext = null;
            Map<String, Object> arguments = UtilMisc.<String, Object>toMap("neededQuantity", quantity.multiply(quantityMultiplier), "amount", tree != null ? tree.getRootAmount() : BigDecimal.ZERO);
            BigDecimal width = null;
            if (getProduct().get("productWidth") != null) {
                width = getProduct().getBigDecimal("productWidth");
            }
            if (width == null) {
                width = BigDecimal.ZERO;
            }
            arguments.put("width", width);
            Map<String, Object> inputContext = UtilMisc.<String, Object>toMap("arguments", arguments, "userLogin", userLogin);
            try {
                resultContext = dispatcher.runSync(serviceName, inputContext);
                BigDecimal calcQuantity = (BigDecimal)resultContext.get("quantity");
                if (calcQuantity != null) {
                    this.quantity = calcQuantity;
                }
            } catch (GenericServiceException e) {
                Debug.logError(e, "Problem calling the " + serviceName + " service (called by the createManufacturingOrder service)", module);
            }
        } else {
            this.quantity = quantity.multiply(quantityMultiplier).multiply(scrapFactor);
        }
        // First of all we visit the current node.
        arr.add(this);
        // Now (recursively) we visit the children.
        BOMNode oneChildNode = null;
        depth++;
        for (int i = 0; i < children.size(); i++) {
            oneChildNode = childrenNodes.get(i);
            if (excludeWIPs && "WIP".equals(oneChildNode.getProduct().getString("productTypeId"))) {
                continue;
            }
            if (oneChildNode != null) {
                oneChildNode.print(arr, this.quantity, depth, excludeWIPs);
            }
        }
    }

    public void getProductsInPackages(List<BOMNode> arr, BigDecimal quantity, int depth, boolean excludeWIPs) {
        // Now we set the depth and quantity of the current node
        // in this breakdown.
        this.depth = depth;
        this.quantity = quantity.multiply(quantityMultiplier).multiply(scrapFactor);
        // First of all we visit the current node.
        if (this.getProduct().getString("defaultShipmentBoxTypeId") != null) {
            arr.add(this);
        } else {
            BOMNode oneChildNode = null;
            depth++;
            for (int i = 0; i < children.size(); i++) {
                oneChildNode = childrenNodes.get(i);
                if (excludeWIPs && "WIP".equals(oneChildNode.getProduct().getString("productTypeId"))) {
                    continue;
                }
                if (oneChildNode != null) {
                    oneChildNode.getProductsInPackages(arr, this.quantity, depth, excludeWIPs);
                }
            }
        }
    }

    public void sumQuantity(Map<String, BOMNode> nodes) {
        // First of all, we try to fetch a node with the same partId
        BOMNode sameNode = nodes.get(product.getString("productId"));
        // If the node is not found we create a new node for the current product
        if (sameNode == null) {
            sameNode = new BOMNode(product, dispatcher, userLogin);
            nodes.put(product.getString("productId"), sameNode);
        }
        // Now we add the current quantity to the node
        sameNode.setQuantity(sameNode.getQuantity().add(quantity));
        // Now (recursively) we visit the children.
        BOMNode oneChildNode = null;
        for (int i = 0; i < childrenNodes.size(); i++) {
            oneChildNode = childrenNodes.get(i);
            if (oneChildNode != null) {
                oneChildNode.sumQuantity(nodes);
            }
        }
    }

    public Map<String, Object> createManufacturingOrder(String facilityId, Date date, String workEffortName, String description, String routingId, String orderId, String orderItemSeqId, String shipGroupSeqId, String shipmentId, boolean useSubstitute, boolean ignoreSupplierProducts) throws GenericEntityException {
        String productionRunId = null;
        Timestamp endDate = null;
        if (isManufactured(ignoreSupplierProducts)) {
            BOMNode oneChildNode = null;
            List<String> childProductionRuns = new LinkedList<String>();
            Timestamp maxEndDate = null;
            for (int i = 0; i < childrenNodes.size(); i++) {
                oneChildNode = childrenNodes.get(i);
                if (oneChildNode != null) {
                    Map<String, Object> tmpResult = oneChildNode.createManufacturingOrder(facilityId, date, null, null, null, null, null, shipGroupSeqId, shipmentId, false, false);
                    String childProductionRunId = (String)tmpResult.get("productionRunId");
                    Timestamp childEndDate = (Timestamp)tmpResult.get("endDate");
                    if (maxEndDate == null) {
                        maxEndDate = childEndDate;
                    }
                    if (childEndDate != null && maxEndDate.compareTo(childEndDate) < 0) {
                        maxEndDate = childEndDate;
                    }

                    if (childProductionRunId != null) {
                        childProductionRuns.add(childProductionRunId);
                    }
                }
            }

            Timestamp startDate = UtilDateTime.toTimestamp(UtilDateTime.toDateTimeString(date));
            Map<String, Object> serviceContext = new HashMap<String, Object>();
            if (!useSubstitute) {
                serviceContext.put("productId", getProduct().getString("productId"));
                serviceContext.put("facilityId", getProduct().getString("facilityId"));
            } else {
                serviceContext.put("productId", getSubstitutedNode().getProduct().getString("productId"));
                serviceContext.put("facilityId", getSubstitutedNode().getProduct().getString("facilityId"));
            }
            if (UtilValidate.isNotEmpty(facilityId)) {
                serviceContext.put("facilityId", facilityId);
            }
            if (UtilValidate.isNotEmpty(workEffortName)) {
                serviceContext.put("workEffortName", workEffortName);
            }
            if (UtilValidate.isNotEmpty(description)) {
                serviceContext.put("description", description);
            }
            if (UtilValidate.isNotEmpty(routingId)) {
                serviceContext.put("routingId", routingId);
            }
            if (UtilValidate.isNotEmpty(shipmentId) && UtilValidate.isEmpty(workEffortName)) {
                serviceContext.put("workEffortName", "SP_" + shipmentId + "_" + serviceContext.get("productId"));
            }

            serviceContext.put("pRQuantity", getQuantity());
            if (UtilValidate.isNotEmpty(maxEndDate)) {
                serviceContext.put("startDate", maxEndDate);
            } else {
                serviceContext.put("startDate", startDate);
            }
            serviceContext.put("userLogin", userLogin);
            Map<String, Object> resultService = null;
            try {
                resultService = dispatcher.runSync("createProductionRun", serviceContext);
                productionRunId = (String)resultService.get("productionRunId");
                endDate = (Timestamp)resultService.get("estimatedCompletionDate");
            } catch (GenericServiceException e) {
                Debug.logError("Problem calling the createProductionRun service", module);
            }
            try {
                if (productionRunId != null) {
                    if (orderId != null && orderItemSeqId != null) {
                        delegator.create("WorkOrderItemFulfillment", UtilMisc.toMap("workEffortId", productionRunId, "orderId", orderId, "orderItemSeqId", orderItemSeqId, "shipGroupSeqId", shipGroupSeqId));
                    }
                    for (int i = 0; i < childProductionRuns.size(); i++) {
                        delegator.create("WorkEffortAssoc", UtilMisc.toMap("workEffortIdFrom", childProductionRuns.get(i), "workEffortIdTo", productionRunId, "workEffortAssocTypeId", "WORK_EFF_PRECEDENCY", "fromDate", startDate));
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Problem calling the getManufacturingComponents service", module);
            }
        }
        return UtilMisc.toMap("productionRunId", productionRunId, "endDate", endDate);
    }

    public Timestamp getStartDate(String facilityId, Timestamp requiredBydate, boolean allNodes) {
        Timestamp minStartDate = requiredBydate;
        if ("WIP".equals(getProduct().getString("productTypeId")) || allNodes) {
            ProposedOrder proposedOrder = new ProposedOrder(getProduct(), facilityId, facilityId, true, requiredBydate, getQuantity());
            proposedOrder.calculateStartDate(0, null, delegator, dispatcher, userLogin);
            Timestamp startDate = proposedOrder.getRequirementStartDate();
            minStartDate = startDate;
            for (int i = 0; i < childrenNodes.size(); i++) {
                BOMNode oneChildNode = childrenNodes.get(i);
                if (oneChildNode != null) {
                    Timestamp childStartDate = oneChildNode.getStartDate(facilityId, startDate, false);
                    if (childStartDate.compareTo(minStartDate) < 0) {
                        minStartDate = childStartDate;
                    }
                }
            }
        }
        return minStartDate;
    }

    /**
     * Returns false if the product of this BOM Node is of type "WIP" or if it has no ProductFacility records defined for it,
     * meaning that no active stock targets are set for this product.
     */
    public boolean isWarehouseManaged(String facilityId) {
        boolean isWarehouseManaged = false;
        try {
            if ("WIP".equals(getProduct().getString("productTypeId"))) {
                return false;
            }
            List<GenericValue> pfs = null;
            if (UtilValidate.isEmpty(facilityId)) {
                pfs = getProduct().getRelated("ProductFacility", null, null, true);
            } else {
                pfs = getProduct().getRelated("ProductFacility", UtilMisc.toMap("facilityId", facilityId), null, true);
            }
            if (UtilValidate.isEmpty(pfs)) {
                if (getSubstitutedNode() != null && getSubstitutedNode().getProduct() != null) {
                    if (UtilValidate.isEmpty(facilityId)) {
                        pfs = getSubstitutedNode().getProduct().getRelated("ProductFacility", null, null, true);
                    } else {
                        pfs = getSubstitutedNode().getProduct().getRelated("ProductFacility", UtilMisc.toMap("facilityId", facilityId), null, true);
                    }
                }
            }
            if (UtilValidate.isNotEmpty(pfs)) {
                for (int i = 0; i < pfs.size(); i++) {
                    GenericValue pf = pfs.get(i);
                    if (UtilValidate.isNotEmpty(pf.get("minimumStock")) && UtilValidate.isNotEmpty(pf.get("reorderQuantity"))) {
                        isWarehouseManaged = true;
                        break;
                    }
                }
            }
        } catch (GenericEntityException gee) {
            Debug.logError("Problem in BOMNode.isWarehouseManaged()", module);
        }
    return isWarehouseManaged;
    }

    /**
     * A part is considered manufactured if it has child nodes AND unless ignoreSupplierProducts is set, if it also has no unexpired SupplierProducts defined
     * @param ignoreSupplierProducts
     * @return return if a part is considered manufactured 
     */
    public boolean isManufactured(boolean ignoreSupplierProducts) {
        List<GenericValue> supplierProducts = null;
        try {
            supplierProducts = product.getRelated("SupplierProduct", UtilMisc.toMap("supplierPrefOrderId", "10_MAIN_SUPPL"), UtilMisc.toList("minimumOrderQuantity"), false);
        } catch (GenericEntityException gee) {
            Debug.logError("Problem in BOMNode.isManufactured()", module);
        }
        supplierProducts = EntityUtil.filterByDate(supplierProducts, UtilDateTime.nowTimestamp(), "availableFromDate", "availableThruDate", true);
        return childrenNodes.size() > 0 && (ignoreSupplierProducts || UtilValidate.isEmpty(supplierProducts));
    }

    /**
     * By default, a part is manufactured if it has child nodes and it has NO SupplierProducts defined
     * @return return if a part is manufactured
     */
    public boolean isManufactured() {
        return isManufactured(false);
    }

    public boolean isVirtual() {
        return (product.get("isVirtual") != null? product.get("isVirtual").equals("Y"): false);
    }

    public void isConfigured(List<BOMNode> arr) {
        // First of all we visit the current node.
        if (isVirtual()) {
            arr.add(this);
        }
        // Now (recursively) we visit the children.
        BOMNode oneChildNode = null;
        for (int i = 0; i < children.size(); i++) {
            oneChildNode = childrenNodes.get(i);
            if (oneChildNode != null) {
                oneChildNode.isConfigured(arr);
            }
        }
    }

    /** Getter for property quantity.
     * @return Value of property quantity.
     *
     */
    public BigDecimal getQuantity() {
        return quantity;
    }

    public void setQuantity(BigDecimal quantity) {
        this.quantity = quantity;
    }

    /** Getter for property depth.
     * @return Value of property depth.
     *
     */

    public int getDepth() {
        return depth;
    }

    public GenericValue getProduct() {
        return product;
    }

    /** Getter for property substitutedNode.
     * @return Value of property substitutedNode.
     *
     */
    public BOMNode getSubstitutedNode() {
        return substitutedNode;
    }

    /** Setter for property substitutedNode.
     * @param substitutedNode New value of property substitutedNode.
     *
     */
    public void setSubstitutedNode(BOMNode substitutedNode) {
        this.substitutedNode = substitutedNode;
    }

    public String getRootProductForRules() {
        return getParentNode().getProductForRules();
    }

    /** Getter for property productForRules.
     * @return Value of property productForRules.
     *
     */
    public String getProductForRules() {
        return productForRules;
    }

    /** Setter for property productForRules.
     * @param productForRules New value of property productForRules.
     *
     */
    public void setProductForRules(String productForRules) {
        this.productForRules = productForRules;
    }

    /** Getter for property bomTypeId.
     * @return Value of property bomTypeId.
     *
     */
    public java.lang.String getBomTypeId() {
        return bomTypeId;
    }

    /** Getter for property quantityMultiplier.
     * @return Value of property quantityMultiplier.
     *
     */
    public BigDecimal getQuantityMultiplier() {
        return quantityMultiplier;
    }

    /** Setter for property quantityMultiplier.
     * @param quantityMultiplier New value of property quantityMultiplier.
     *
     */
    public void setQuantityMultiplier(BigDecimal quantityMultiplier) {
        if (quantityMultiplier != null) {
            this.quantityMultiplier = quantityMultiplier;
        }
    }

    /** Getter for property ruleApplied.
     * @return Value of property ruleApplied.
     *
     */
    public org.apache.ofbiz.entity.GenericValue getRuleApplied() {
        return ruleApplied;
    }

    /** Setter for property ruleApplied.
     * @param ruleApplied New value of property ruleApplied.
     *
     */
    public void setRuleApplied(org.apache.ofbiz.entity.GenericValue ruleApplied) {
        this.ruleApplied = ruleApplied;
    }

    /** Getter for property scrapFactor.
     * @return Value of property scrapFactor.
     *
     */
    public BigDecimal getScrapFactor() {
        return scrapFactor;
    }

    /** Setter for property scrapFactor.
     * @param scrapFactor New value of property scrapFactor.
     *
     */
    public void setScrapFactor(BigDecimal scrapFactor) {
        if (scrapFactor != null) {
            this.scrapFactor = scrapFactor;
        }
    }

    /** Getter for property childrenNodes.
     * @return Value of property childrenNodes.
     *
     */
    public List<BOMNode> getChildrenNodes() {
        return childrenNodes;
    }

    /** Setter for property childrenNodes.
     * @param childrenNodes New value of property childrenNodes.
     *
     */
    public void setChildrenNodes(List<BOMNode> childrenNodes) {
        this.childrenNodes = childrenNodes;
    }

    /** Getter for property productAssoc.
     * @return Value of property productAssoc.
     *
     */
    public org.apache.ofbiz.entity.GenericValue getProductAssoc() {
        return productAssoc;
    }

    /** Setter for property productAssoc.
     * @param productAssoc New value of property productAssoc.
     *
     */
    public void setProductAssoc(org.apache.ofbiz.entity.GenericValue productAssoc) {
        this.productAssoc = productAssoc;
    }

    public void setTree(BOMTree tree) {
        this.tree = tree;
    }

    public BOMTree getTree() {
        return tree;
    }

}

