001: /*
002: * BOMHelper.java
003: *
004: * Created on 3 novembre 2003, 16.55
005: */
006:
007: package org.ofbiz.manufacturing.bom;
008:
009: import java.util.Date;
010: import java.util.List;
011: import java.util.Iterator;
012: import java.util.ArrayList;
013:
014: import org.ofbiz.entity.util.EntityUtil;
015: import org.ofbiz.entity.GenericDelegator;
016: import org.ofbiz.entity.GenericValue;
017: import org.ofbiz.entity.GenericEntityException;
018: import org.ofbiz.base.util.UtilMisc;
019:
020: /** Helper class containing static method useful when dealing
021: * with product's bills of materials.
022: * These methods are also available as services (see {@link BOMServices}).
023: * @author <a href="mailto:tiz@sastau.it">Jacopo Cappellato</a>
024: */
025: public class BOMHelper {
026:
027: /** Creates a new instance of BOMHelper */
028: public BOMHelper() {
029: }
030:
031: /** Returns the product's low level code (llc) i.e. the maximum depth
032: * in which the productId can be found in any of the
033: * bills of materials of bomType type.
034: * @return The low level code for the productId. (0 = root, 1 = first level, etc...)
035: * @param productId The product id
036: * @param bomType The bill of materials type (e.g. manufacturing, engineering,...)
037: * @param delegator Validity date (if null, today is used).
038: * @param inDate The delegator
039: * @throws GenericEntityException If a db problem occurs.
040: */
041: /*
042: * It's implemented as a recursive method that performs the following tasks:
043: * 1.given a product id, it selects all the product's parents
044: * 2.if no parents are found, the method returns zero (llc = 0, this is a root element)
045: * 3.for every parent the method is called recursively, the llc returned is incremented by one and the max of these number is saved as maxDepth
046: * 4.the maxDepth value is returned
047: */
048: public static int getMaxDepth(String productId, String bomType,
049: Date inDate, GenericDelegator delegator)
050: throws GenericEntityException {
051: // If the date is null, set it to today.
052: if (inDate == null)
053: inDate = new Date();
054: int maxDepth = 0;
055: List productNodesList = delegator.findByAndCache(
056: "ProductAssoc", UtilMisc.toMap("productIdTo",
057: productId, "productAssocTypeId", bomType));
058: productNodesList = EntityUtil.filterByDate(productNodesList,
059: inDate);
060: GenericValue oneNode = null;
061: Iterator nodesIterator = productNodesList.iterator();
062: int depth = 0;
063: while (nodesIterator.hasNext()) {
064: oneNode = (GenericValue) nodesIterator.next();
065: depth = 0;
066: depth = getMaxDepth(oneNode.getString("productId"),
067: bomType, inDate, delegator);
068: depth++;
069: if (depth > maxDepth) {
070: maxDepth = depth;
071: }
072: }
073:
074: return maxDepth;
075: }
076:
077: /** Returns the ProductAssoc generic value for a duplicate productIdKey
078: * ancestor if present, null otherwise.
079: * Useful to avoid loops when adding new assocs (components)
080: * to a bill of materials.
081: * @param productId The product to which we want to add a new child.
082: * @param productIdKey The new component we want to add to the existing bom.
083: * @param bomType The bill of materials type (e.g. manufacturing, engineering).
084: * @param inDate Validity date (if null, today is used).
085: *
086: * @param delegator The delegator used
087: * @throws GenericEntityException If a db problem occurs
088: * @return the ProductAssoc generic value for a duplicate productIdKey
089: * ancestor if present, null otherwise.
090: */
091: public static GenericValue searchDuplicatedAncestor(
092: String productId, String productIdKey, String bomType,
093: Date inDate, GenericDelegator delegator)
094: throws GenericEntityException {
095: return searchDuplicatedAncestor(productId, productIdKey, null,
096: bomType, inDate, delegator);
097: }
098:
099: private static GenericValue searchDuplicatedAncestor(
100: String productId, String productIdKey,
101: ArrayList productIdKeys, String bomType, Date inDate,
102: GenericDelegator delegator) throws GenericEntityException {
103: // If the date is null, set it to today.
104: if (inDate == null)
105: inDate = new Date();
106: if (productIdKeys == null) {
107: ItemConfigurationTree tree = new ItemConfigurationTree(
108: productIdKey, bomType, inDate, delegator);
109: productIdKeys = tree.getAllProductsId();
110: productIdKeys.add(productIdKey);
111: }
112: List productNodesList = delegator.findByAndCache(
113: "ProductAssoc", UtilMisc.toMap("productIdTo",
114: productId, "productAssocTypeId", bomType));
115: productNodesList = EntityUtil.filterByDate(productNodesList,
116: inDate);
117: GenericValue oneNode = null;
118: GenericValue duplicatedNode = null;
119: Iterator nodesIterator = productNodesList.iterator();
120: while (nodesIterator.hasNext()) {
121: oneNode = (GenericValue) nodesIterator.next();
122: for (int i = 0; i < productIdKeys.size(); i++) {
123: if (oneNode.getString("productId").equals(
124: (String) productIdKeys.get(i))) {
125: return oneNode;
126: }
127: }
128: duplicatedNode = searchDuplicatedAncestor(oneNode
129: .getString("productId"), productIdKey,
130: productIdKeys, bomType, inDate, delegator);
131: if (duplicatedNode != null) {
132: break;
133: }
134: }
135: return duplicatedNode;
136: }
137:
138: }
|