KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > manufacturing > bom > BOMTree


1 /*
2  *
3  * Copyright 2001-2006 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6  * use this file except in compliance with the License. You may obtain a copy of
7  * the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations
15  * under the License.
16  */

17
18 package org.ofbiz.manufacturing.bom;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.List JavaDoc;
24
25 import org.ofbiz.base.util.UtilMisc;
26 import org.ofbiz.entity.GenericDelegator;
27 import org.ofbiz.entity.GenericEntityException;
28 import org.ofbiz.entity.GenericValue;
29 import org.ofbiz.entity.util.EntityUtil;
30 import org.ofbiz.service.LocalDispatcher;
31
32 import org.ofbiz.product.store.ProductStoreWorker;
33
34     /** It represents an (in-memory) bill of materials (in which each
35      * component is an BOMNode)
36      * Useful for tree traversal (breakdown, explosion, implosion).
37      * @author <a HREF="mailto:tiz@sastau.it">Jacopo Cappellato</a>
38      */

39  
40 public class BOMTree {
41     public static final int EXPLOSION = 0;
42     public static final int EXPLOSION_SINGLE_LEVEL = 1;
43     public static final int EXPLOSION_MANUFACTURING = 2;
44     public static final int IMPLOSION = 3;
45
46     protected LocalDispatcher dispatcher = null;
47     protected GenericDelegator delegator = null;
48
49     BOMNode root;
50     double rootQuantity;
51     double rootAmount;
52     Date JavaDoc inDate;
53     String JavaDoc bomTypeId;
54     GenericValue inputProduct;
55
56     /** Creates a new instance of BOMTree by reading downward
57      * the productId's bill of materials (explosion).
58      * If virtual products are found, it tries to configure them by running
59      * the Product Configurator.
60      * @param productId The product for which we want to get the bom.
61      * @param bomTypeId The bill of materials type (e.g. manufacturing, engineering, ...)
62      * @param inDate Validity date (if null, today is used).
63      *
64      * @param delegator The delegator used.
65      * @throws GenericEntityException If a db problem occurs.
66      *
67      */

68     public BOMTree(String JavaDoc productId, String JavaDoc bomTypeId, Date JavaDoc inDate, GenericDelegator delegator, LocalDispatcher dispatcher, GenericValue userLogin) throws GenericEntityException {
69         this(productId, bomTypeId, inDate, EXPLOSION, delegator, dispatcher, userLogin);
70     }
71     
72     /** Creates a new instance of BOMTree by reading
73      * the productId's bill of materials (upward or downward).
74      * If virtual products are found, it tries to configure them by running
75      * the Product Configurator.
76      * @param productId The product for which we want to get the bom.
77      * @param bomTypeId The bill of materials type (e.g. manufacturing, engineering, ...)
78      * @param inDate Validity date (if null, today is used).
79      *
80      * @param type if equals to EXPLOSION, a downward visit is performed (explosion);
81      * if equals to EXPLOSION_SINGLE_LEVEL, a single level explosion is performed;
82      * if equals to EXPLOSION_MANUFACTURING, a downward visit is performed (explosion), including only the product that needs manufacturing;
83      * if equals to IMPLOSION an upward visit is done (implosion);
84      *
85      * @param delegator The delegator used.
86      * @throws GenericEntityException If a db problem occurs.
87      *
88      */

89     public BOMTree(String JavaDoc productId, String JavaDoc bomTypeId, Date JavaDoc inDate, int type, GenericDelegator delegator, LocalDispatcher dispatcher, GenericValue userLogin) throws GenericEntityException {
90         // If the parameters are not valid, return.
91
if (productId == null || bomTypeId == null || delegator == null || dispatcher == null) return;
92         // If the date is null, set it to today.
93
if (inDate == null) inDate = new Date JavaDoc();
94
95         this.delegator = delegator;
96         this.dispatcher = dispatcher;
97         
98         inputProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
99
100         String JavaDoc productIdForRules = productId;
101         // The selected product features are loaded
102
List JavaDoc productFeaturesAppl = delegator.findByAnd("ProductFeatureAppl",
103                                               UtilMisc.toMap("productId", productId,
104                                               "productFeatureApplTypeId", "STANDARD_FEATURE"));
105         List JavaDoc productFeatures = new ArrayList JavaDoc();
106         GenericValue oneProductFeatureAppl = null;
107         for (int i = 0; i < productFeaturesAppl.size(); i++) {
108             oneProductFeatureAppl = (GenericValue)productFeaturesAppl.get(i);
109             productFeatures.add(delegator.findByPrimaryKey("ProductFeature",
110                                        UtilMisc.toMap("productFeatureId", oneProductFeatureAppl.getString("productFeatureId"))));
111                                
112         }
113         // If the product is manufactured as a different product,
114
// load the new product
115
GenericValue manufacturedAsProduct = manufacturedAsProduct(productId, inDate);
116         // We load the information about the product that needs to be manufactured
117
// from Product entity
118
GenericValue product = delegator.findByPrimaryKey("Product",
119                                             UtilMisc.toMap("productId",
120                                             (manufacturedAsProduct != null? manufacturedAsProduct.getString("productIdTo"): productId)));
121         if (product == null) return;
122         BOMNode originalNode = new BOMNode(product, dispatcher, userLogin);
123         originalNode.setTree(this);
124         // If the product hasn't a bill of materials we try to retrieve
125
// the bill of materials of its virtual product (if the current
126
// product is variant).
127
if (!hasBom(product, inDate)) {
128             List JavaDoc virtualProducts = product.getRelatedByAnd("AssocProductAssoc", UtilMisc.toMap("productAssocTypeId", "PRODUCT_VARIANT"));
129             if (virtualProducts != null && virtualProducts.size() > 0) {
130                 virtualProducts = EntityUtil.filterByDate(virtualProducts, inDate);
131                 if (virtualProducts != null && virtualProducts.size() > 0) {
132                     GenericValue virtualProduct = (GenericValue)virtualProducts.get(0);
133                     // If the virtual product is manufactured as a different product,
134
// load the new product
135
productIdForRules = virtualProduct.getString("productId");
136                     manufacturedAsProduct = manufacturedAsProduct(virtualProduct.getString("productId"), inDate);
137                     product = delegator.findByPrimaryKey("Product",
138                                                 UtilMisc.toMap("productId",
139                                                 (manufacturedAsProduct != null? manufacturedAsProduct.getString("productIdTo"): virtualProduct.get("productId"))));
140                 }
141             }
142         }
143         if (product == null) return;
144         try {
145             root = new BOMNode(product, dispatcher, userLogin);
146             root.setTree(this);
147             root.setProductForRules(productIdForRules);
148             root.setSubstitutedNode(originalNode);
149             if (type == IMPLOSION) {
150                 root.loadParents(bomTypeId, inDate, productFeatures);
151             } else {
152                 root.loadChildren(bomTypeId, inDate, productFeatures, type);
153             }
154         } catch(GenericEntityException gee) {
155             root = null;
156         }
157         this.bomTypeId = bomTypeId;
158         this.inDate = inDate;
159         rootQuantity = 1;
160         rootAmount = 0;
161     }
162
163     public GenericValue getInputProduct() {
164         return inputProduct;
165     }
166     
167     private GenericValue manufacturedAsProduct(String JavaDoc productId, Date JavaDoc inDate) throws GenericEntityException {
168         List JavaDoc manufacturedAsProducts = delegator.findByAnd("ProductAssoc",
169                                          UtilMisc.toMap("productId", productId,
170                                          "productAssocTypeId", "PRODUCT_MANUFACTURED"));
171         manufacturedAsProducts = EntityUtil.filterByDate(manufacturedAsProducts, inDate);
172         GenericValue manufacturedAsProduct = null;
173         if (manufacturedAsProducts != null && manufacturedAsProducts.size() > 0) {
174             manufacturedAsProduct = (GenericValue)manufacturedAsProducts.get(0);
175         }
176         return manufacturedAsProduct;
177     }
178     
179     private boolean hasBom(GenericValue product, Date JavaDoc inDate) throws GenericEntityException {
180         List JavaDoc children = product.getRelatedByAnd("MainProductAssoc", UtilMisc.toMap("productAssocTypeId", bomTypeId));
181         children = EntityUtil.filterByDate(children, inDate);
182         return (children != null && children.size() > 0);
183     }
184
185     /** It tells if the current (in-memory) tree representing
186      * a product's bill of materials is completely configured
187      * or not.
188      * @return true if no virtual nodes (products) are present in the tree.
189      *
190      */

191     public boolean isConfigured() {
192         ArrayList JavaDoc notConfiguredParts = new ArrayList JavaDoc();
193         root.isConfigured(notConfiguredParts);
194         return (notConfiguredParts.size() == 0);
195     }
196     
197     /** Getter for property rootQuantity.
198      * @return Value of property rootQuantity.
199      *
200      */

201     public double getRootQuantity() {
202         return rootQuantity;
203     }
204     
205     /** Setter for property rootQuantity.
206      * @param rootQuantity New value of property rootQuantity.
207      *
208      */

209     public void setRootQuantity(double rootQuantity) {
210         this.rootQuantity = rootQuantity;
211     }
212
213     /** Getter for property rootAmount.
214      * @return Value of property rootAmount.
215      *
216      */

217     public double getRootAmount() {
218         return rootAmount;
219     }
220     
221     /** Setter for property rootAmount.
222      * @param rootAmount New value of property rootAmount.
223      *
224      */

225     public void setRootAmount(double rootAmount) {
226         this.rootAmount = rootAmount;
227     }
228     
229     /** Getter for property root.
230      * @return Value of property root.
231      *
232      */

233     public BOMNode getRoot() {
234         return root;
235     }
236     
237     /** Getter for property inDate.
238      * @return Value of property inDate.
239      *
240      */

241     public Date JavaDoc getInDate() {
242         return inDate;
243     }
244     
245     /** Getter for property bomTypeId.
246      * @return Value of property bomTypeId.
247      *
248      */

249     public String JavaDoc getBomTypeId() {
250         return bomTypeId;
251     }
252     
253     /** It visits the in-memory tree that represents a bill of materials
254      * and it collects info of its nodes in the StringBuffer.
255      * Method used for debug purposes.
256      * @param sb The StringBuffer used to collect tree info.
257      */

258     public void print(StringBuffer JavaDoc sb) {
259         if (root != null) {
260             root.print(sb, getRootQuantity(), 0);
261         }
262     }
263
264     /** It visits the in-memory tree that represents a bill of materials
265      * and it collects info of its nodes in the ArrayList.
266      * Method used for bom breakdown (explosion/implosion).
267      * @param arr The ArrayList used to collect tree info.
268      * @param initialDepth The depth of the root node.
269      */

270     public void print(ArrayList JavaDoc arr, int initialDepth) {
271         print(arr, initialDepth, true);
272     }
273     
274     public void print(ArrayList JavaDoc arr, int initialDepth, boolean excludeWIPs) {
275         if (root != null) {
276             root.print(arr, getRootQuantity(), initialDepth, excludeWIPs);
277         }
278     }
279     
280     /** It visits the in-memory tree that represents a bill of materials
281      * and it collects info of its nodes in the ArrayList.
282      * Method used for bom breakdown (explosion/implosion).
283      * @param arr The ArrayList used to collect tree info.
284      */

285     public void print(ArrayList JavaDoc arr) {
286         print(arr, 0, false);
287     }
288
289     public void print(ArrayList JavaDoc arr, boolean excludeWIPs) {
290         print(arr, 0, excludeWIPs);
291     }
292
293     /** It visits the in-memory tree that represents a bill of materials
294      * and it collects info of its nodes in the HashMap.
295      * Method used for bom summarized explosion.
296      * @param quantityPerNode The HashMap that will contain the summarized quantities per productId.
297      */

298     public void sumQuantities(HashMap JavaDoc quantityPerNode) {
299         if (root != null) {
300             root.sumQuantity(quantityPerNode);
301         }
302     }
303     
304     /** It visits the in-memory tree that represents a bill of materials
305      * and it collects all the productId it contains.
306      * @return ArrayLsit conatining all the tree's productId.
307      */

308     public ArrayList JavaDoc getAllProductsId() {
309         ArrayList JavaDoc nodeArr = new ArrayList JavaDoc();
310         ArrayList JavaDoc productsId = new ArrayList JavaDoc();
311         print(nodeArr);
312         for (int i = 0; i < nodeArr.size(); i++) {
313             productsId.add(((BOMNode)nodeArr.get(i)).getProduct().getString("productId"));
314         }
315         return productsId;
316     }
317     
318     /** It visits the in-memory tree that represents a bill of materials
319      * and it creates a manufacturing order for each of the nodes that needs
320      * to be manufactured.
321      * @param orderId The (sales) order id for which the manufacturing orders are created. If specified (together with orderItemSeqId) a link between the two order lines is created in the OrderItemAssociation entity. If null, no link is created.
322      * @param orderItemSeqId
323      * @param delegator The delegator used.
324      * @throws GenericEntityException If a db problem occurs.
325      */

326     public void createManufacturingOrders(String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipmentId, Date JavaDoc date, GenericValue userLogin) throws GenericEntityException {
327         if (root != null) {
328             String JavaDoc facilityId = null;
329             if (orderId != null) {
330                 GenericValue order = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
331                 String JavaDoc productStoreId = order.getString("productStoreId");
332                 if (productStoreId != null) {
333                     GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
334                     if (productStore != null) {
335                         facilityId = productStore.getString("inventoryFacilityId");
336                     }
337                 }
338
339             }
340             if (facilityId == null && shipmentId != null) {
341                 GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
342                 facilityId = shipment.getString("originFacilityId");
343             }
344             root.createManufacturingOrder(orderId, orderItemSeqId, shipmentId, facilityId, date, true);
345         }
346     }
347
348     public void getProductsInPackages(ArrayList JavaDoc arr) {
349         if (root != null) {
350             root.getProductsInPackages(arr, getRootQuantity(), 0, false);
351         }
352     }
353
354 }
355
Popular Tags