KickJava   Java API By Example, From Geeks To Geeks.

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


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.sql.Timestamp JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Locale JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.ofbiz.base.util.Debug;
30 import org.ofbiz.base.util.UtilMisc;
31 import org.ofbiz.base.util.UtilProperties;
32 import org.ofbiz.base.util.UtilValidate;
33 import org.ofbiz.entity.GenericDelegator;
34 import org.ofbiz.entity.GenericEntityException;
35 import org.ofbiz.entity.GenericValue;
36 import org.ofbiz.entity.util.EntityUtil;
37 import org.ofbiz.order.order.OrderReadHelper;
38 import org.ofbiz.security.Security;
39 import org.ofbiz.service.DispatchContext;
40 import org.ofbiz.service.GenericServiceException;
41 import org.ofbiz.service.LocalDispatcher;
42 import org.ofbiz.service.ServiceUtil;
43
44 /** Bills of Materials' services implementation.
45  * These services are useful when dealing with product's
46  * bills of materials.
47  * @author <a HREF="mailto:tiz@sastau.it">Jacopo Cappellato</a>
48  */

49 public class BOMServices {
50
51     public static final String JavaDoc module = BOMServices.class.getName();
52     public static final String JavaDoc resource = "ManufacturingUiLabels";
53     
54     /** Returns the product's low level code (llc) i.e. the maximum depth
55      * in which the productId can be found in any of the
56      * bills of materials of bomType type.
57      * If the bomType input field is not passed then the depth is searched for all the bom types and the lowest depth is returned.
58      * @param dctx
59      * @param context
60      * @return
61      */

62     public static Map JavaDoc getMaxDepth(DispatchContext dctx, Map JavaDoc context) {
63
64         Map JavaDoc result = new HashMap JavaDoc();
65         Security security = dctx.getSecurity();
66         GenericDelegator delegator = dctx.getDelegator();
67         LocalDispatcher dispatcher = dctx.getDispatcher();
68         String JavaDoc productId = (String JavaDoc) context.get("productId");
69         String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
70         String JavaDoc bomType = (String JavaDoc) context.get("bomType");
71         
72         Date JavaDoc fromDate = null;
73         if (UtilValidate.isNotEmpty(fromDateStr)) {
74             try {
75                 fromDate = Timestamp.valueOf(fromDateStr);
76             } catch (Exception JavaDoc e) {
77             }
78         }
79         if (fromDate == null) {
80             fromDate = new Date JavaDoc();
81         }
82         List JavaDoc bomTypes = new ArrayList JavaDoc();
83         if (bomType == null) {
84             try {
85                 List JavaDoc bomTypesValues = delegator.findByAnd("ProductAssocType", UtilMisc.toMap("parentTypeId", "PRODUCT_COMPONENT"));
86                 Iterator JavaDoc bomTypesValuesIt = bomTypesValues.iterator();
87                 while (bomTypesValuesIt.hasNext()) {
88                     bomTypes.add(((GenericValue)bomTypesValuesIt.next()).getString("productAssocTypeId"));
89                 }
90             } catch(GenericEntityException gee) {
91                 return ServiceUtil.returnError("Error running max depth algorithm: " + gee.getMessage());
92             }
93         } else {
94             bomTypes.add(bomType);
95         }
96         
97         int depth = 0;
98         int maxDepth = 0;
99         Iterator JavaDoc bomTypesIt = bomTypes.iterator();
100         try {
101             while (bomTypesIt.hasNext()) {
102                 String JavaDoc oneBomType = (String JavaDoc)bomTypesIt.next();
103                 depth = BOMHelper.getMaxDepth(productId, oneBomType, fromDate, delegator);
104                 if (depth > maxDepth) {
105                     maxDepth = depth;
106                 }
107             }
108         } catch(GenericEntityException gee) {
109             return ServiceUtil.returnError("Error running max depth algorithm: " + gee.getMessage());
110         }
111         result.put("depth", new Integer JavaDoc(maxDepth));
112
113         return result;
114     }
115
116     /** Updates the product's low level code (llc)
117      * Given a product id, computes and updates the product's low level code (field billOfMaterialLevel in Product entity).
118      * It also updates the llc of all the product's descendants.
119      * For the llc only the manufacturing bom ("MANUF_COMPONENT") is considered.
120      * @param dctx
121      * @param context
122      * @return
123      */

124     public static Map JavaDoc updateLowLevelCode(DispatchContext dctx, Map JavaDoc context) {
125         Map JavaDoc result = new HashMap JavaDoc();
126         Security security = dctx.getSecurity();
127         GenericDelegator delegator = dctx.getDelegator();
128         LocalDispatcher dispatcher = dctx.getDispatcher();
129         String JavaDoc productId = (String JavaDoc) context.get("productIdTo");
130         Boolean JavaDoc alsoComponents = (Boolean JavaDoc) context.get("alsoComponents");
131         if (alsoComponents == null) {
132             alsoComponents = new Boolean JavaDoc(true);
133         }
134         Boolean JavaDoc alsoVariants = (Boolean JavaDoc) context.get("alsoVariants");
135         if (alsoVariants == null) {
136             alsoVariants = new Boolean JavaDoc(true);
137         }
138
139         Integer JavaDoc llc = null;
140         try {
141             GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
142             Map JavaDoc depthResult = dispatcher.runSync("getMaxDepth", UtilMisc.toMap("productId", productId, "bomType", "MANUF_COMPONENT"));
143             llc = (Integer JavaDoc)depthResult.get("depth");
144             // If the product is a variant of a virtual, then the billOfMaterialLevel cannot be
145
// lower than the billOfMaterialLevel of the virtual product.
146
List JavaDoc virtualProducts = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productIdTo", productId, "productAssocTypeId", "PRODUCT_VARIANT"));
147             if (virtualProducts != null) {
148                 int virtualMaxDepth = 0;
149                 Iterator JavaDoc virtualProductsIt = virtualProducts.iterator();
150                 while (virtualProductsIt.hasNext()) {
151                     int virtualDepth = 0;
152                     GenericValue oneVirtualProductAssoc = (GenericValue)virtualProductsIt.next();
153                     GenericValue virtualProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", oneVirtualProductAssoc.getString("productId")));
154                     if (virtualProduct.get("billOfMaterialLevel") != null) {
155                         virtualDepth = virtualProduct.getLong("billOfMaterialLevel").intValue();
156                     } else {
157                         virtualDepth = 0;
158                     }
159                     if (virtualDepth > virtualMaxDepth) {
160                         virtualMaxDepth = virtualDepth;
161                     }
162                 }
163                 if (virtualMaxDepth > llc.intValue()) {
164                     llc = new Integer JavaDoc(virtualMaxDepth);
165                 }
166             }
167             product.set("billOfMaterialLevel", llc);
168             product.store();
169             if (alsoComponents.booleanValue()) {
170                 Map JavaDoc treeResult = dispatcher.runSync("getBOMTree", UtilMisc.toMap("productId", productId, "bomType", "MANUF_COMPONENT"));
171                 BOMTree tree = (BOMTree)treeResult.get("tree");
172                 ArrayList JavaDoc products = new ArrayList JavaDoc();
173                 tree.print(products, llc.intValue());
174                 for (int i = 0; i < products.size(); i++) {
175                     BOMNode oneNode = (BOMNode)products.get(i);
176                     GenericValue oneProduct = oneNode.getProduct();
177                     int lev = 0;
178                     if (oneProduct.get("billOfMaterialLevel") != null) {
179                         lev = oneProduct.getLong("billOfMaterialLevel").intValue();
180                     }
181                     if (lev < oneNode.getDepth()) {
182                         oneProduct.set("billOfMaterialLevel", new Integer JavaDoc(oneNode.getDepth()));
183                         oneProduct.store();
184                     }
185                 }
186             }
187             if (alsoVariants.booleanValue()) {
188                 List JavaDoc variantProducts = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT"));
189                 if (variantProducts != null) {
190                     Iterator JavaDoc variantProductsIt = variantProducts.iterator();
191                     while (variantProductsIt.hasNext()) {
192                         GenericValue oneVariantProductAssoc = (GenericValue)variantProductsIt.next();
193                         GenericValue variantProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", oneVariantProductAssoc.getString("productId")));
194                         variantProduct.set("billOfMaterialLevel", llc);
195                         variantProduct.store();
196                     }
197                 }
198             }
199         } catch (Exception JavaDoc e) {
200             return ServiceUtil.returnError("Error running updateLowLevelCode: " + e.getMessage());
201         }
202         result.put("lowLevelCode", llc);
203         return result;
204     }
205
206     /** Updates the product's low level code (llc) for all the products in the Product entity.
207      * For the llc only the manufacturing bom ("MANUF_COMPONENT") is considered.
208      * @param dctx
209      * @param context
210      * @return
211      */

212     public static Map JavaDoc initLowLevelCode(DispatchContext dctx, Map JavaDoc context) {
213         Map JavaDoc result = new HashMap JavaDoc();
214         Security security = dctx.getSecurity();
215         GenericDelegator delegator = dctx.getDelegator();
216         LocalDispatcher dispatcher = dctx.getDispatcher();
217
218         try {
219             List JavaDoc products = delegator.findAll("Product", UtilMisc.toList("isVirtual DESC"));
220             Iterator JavaDoc productsIt = products.iterator();
221             Long JavaDoc zero = new Long JavaDoc(0);
222             List JavaDoc allProducts = new ArrayList JavaDoc();
223             while (productsIt.hasNext()) {
224                 GenericValue product = (GenericValue)productsIt.next();
225                 product.set("billOfMaterialLevel", zero);
226                 allProducts.add(product);
227             }
228             delegator.storeAll(allProducts);
229             Debug.logInfo("Low Level Code set to 0 for all the products", module);
230
231             productsIt = products.iterator();
232             while (productsIt.hasNext()) {
233                 GenericValue product = (GenericValue)productsIt.next();
234                 try {
235                     Map JavaDoc depthResult = dispatcher.runSync("updateLowLevelCode", UtilMisc.toMap("productIdTo", product.getString("productId"), "alsoComponents", Boolean.valueOf(false), "alsoVariants", Boolean.valueOf(false)));
236                     Debug.logInfo("Product [" + product.getString("productId") + "] Low Level Code [" + depthResult.get("lowLevelCode") + "]", module);
237                 } catch(Exception JavaDoc exc) {
238                     Debug.logWarning(exc.getMessage(), module);
239                 }
240             }
241             // FIXME: also all the variants llc should be updated?
242
} catch (Exception JavaDoc e) {
243             return ServiceUtil.returnError("Error running initLowLevelCode: " + e.getMessage());
244         }
245         return result;
246     }
247
248     /** Returns the ProductAssoc generic value for a duplicate productIdKey
249      * ancestor if present, null otherwise.
250      * Useful to avoid loops when adding new assocs (components)
251      * to a bill of materials.
252      * @param dctx
253      * @param context
254      * @return
255      */

256     public static Map JavaDoc searchDuplicatedAncestor(DispatchContext dctx, Map JavaDoc context) {
257         Map JavaDoc result = new HashMap JavaDoc();
258         Security security = dctx.getSecurity();
259         GenericDelegator delegator = dctx.getDelegator();
260         LocalDispatcher dispatcher = dctx.getDispatcher();
261         GenericValue userLogin = (GenericValue)context.get("userLogin");
262         
263         String JavaDoc productId = (String JavaDoc) context.get("productId");
264         String JavaDoc productIdKey = (String JavaDoc) context.get("productIdTo");
265         Timestamp JavaDoc fromDate = (Timestamp JavaDoc) context.get("fromDate");
266         String JavaDoc bomType = (String JavaDoc) context.get("productAssocTypeId");
267         if (fromDate == null) {
268             fromDate = Timestamp.valueOf((new Date JavaDoc()).toString());
269         }
270         GenericValue duplicatedProductAssoc = null;
271         try {
272             duplicatedProductAssoc = BOMHelper.searchDuplicatedAncestor(productId, productIdKey, bomType, fromDate, delegator, dispatcher, userLogin);
273         } catch(GenericEntityException gee) {
274             return ServiceUtil.returnError("Error running duplicated ancestor search: " + gee.getMessage());
275         }
276         result.put("duplicatedProductAssoc", duplicatedProductAssoc);
277         return result;
278     }
279
280     /** It reads the product's bill of materials,
281      * if necessary configures it, and it returns
282      * an object (see {@link BOMTree}
283      * and {@link BOMNode}) that represents a
284      * configured bill of material tree.
285      * Useful for tree traversal (breakdown, explosion, implosion).
286      * @param dctx
287      * @param context
288      * @return
289      */

290     public static Map JavaDoc getBOMTree(DispatchContext dctx, Map JavaDoc context) {
291
292         Map JavaDoc result = new HashMap JavaDoc();
293         Security security = dctx.getSecurity();
294         GenericDelegator delegator = dctx.getDelegator();
295         LocalDispatcher dispatcher = dctx.getDispatcher();
296         GenericValue userLogin = (GenericValue)context.get("userLogin");
297         String JavaDoc productId = (String JavaDoc) context.get("productId");
298         String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
299         String JavaDoc bomType = (String JavaDoc) context.get("bomType");
300         Integer JavaDoc type = (Integer JavaDoc) context.get("type");
301         Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
302         Double JavaDoc amount = (Double JavaDoc) context.get("amount");
303         if (type == null) {
304             type = new Integer JavaDoc(0);
305         }
306         
307         Date JavaDoc fromDate = null;
308         if (UtilValidate.isNotEmpty(fromDateStr)) {
309             try {
310                 fromDate = Timestamp.valueOf(fromDateStr);
311             } catch (Exception JavaDoc e) {
312             }
313         }
314         if (fromDate == null) {
315             fromDate = new Date JavaDoc();
316         }
317         
318         BOMTree tree = null;
319         try {
320             tree = new BOMTree(productId, bomType, fromDate, type.intValue(), delegator, dispatcher, userLogin);
321         } catch(GenericEntityException gee) {
322             return ServiceUtil.returnError("Error creating bill of materials tree: " + gee.getMessage());
323         }
324         if (tree != null && quantity != null) {
325             tree.setRootQuantity(quantity.doubleValue());
326         }
327         if (tree != null && amount != null) {
328             tree.setRootAmount(amount.doubleValue());
329         }
330         result.put("tree", tree);
331
332         return result;
333     }
334
335     /** It reads the product's bill of materials,
336      * if necessary configures it, and it returns its (possibly configured) components in
337      * a List of {@link BOMNode}).
338      * @param dctx
339      * @param context
340      * @return
341      */

342     public static Map JavaDoc getManufacturingComponents(DispatchContext dctx, Map JavaDoc context) {
343
344         Map JavaDoc result = new HashMap JavaDoc();
345         Security security = dctx.getSecurity();
346         GenericDelegator delegator = dctx.getDelegator();
347         LocalDispatcher dispatcher = dctx.getDispatcher();
348         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
349         GenericValue userLogin = (GenericValue)context.get("userLogin");
350
351         String JavaDoc productId = (String JavaDoc) context.get("productId");
352         Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
353         Double JavaDoc amount = (Double JavaDoc) context.get("amount");
354         String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
355         Boolean JavaDoc excludeWIPs = (Boolean JavaDoc) context.get("excludeWIPs");
356         
357         if (quantity == null) {
358             quantity = new Double JavaDoc(1);
359         }
360         if (amount == null) {
361             amount = new Double JavaDoc(0);
362         }
363
364         Date JavaDoc fromDate = null;
365         if (UtilValidate.isNotEmpty(fromDateStr)) {
366             try {
367                 fromDate = Timestamp.valueOf(fromDateStr);
368             } catch (Exception JavaDoc e) {
369             }
370         }
371         if (fromDate == null) {
372             fromDate = new Date JavaDoc();
373         }
374         if (excludeWIPs == null) {
375             excludeWIPs = new Boolean JavaDoc(true);
376         }
377         
378         //
379
// Components
380
//
381
BOMTree tree = null;
382         ArrayList JavaDoc components = new ArrayList JavaDoc();
383         try {
384             tree = new BOMTree(productId, "MANUF_COMPONENT", fromDate, BOMTree.EXPLOSION_SINGLE_LEVEL, delegator, dispatcher, userLogin);
385             tree.setRootQuantity(quantity.doubleValue());
386             tree.setRootAmount(amount.doubleValue());
387             tree.print(components, excludeWIPs.booleanValue());
388             if (components.size() > 0) components.remove(0);
389         } catch(GenericEntityException gee) {
390             return ServiceUtil.returnError("Error creating bill of materials tree: " + gee.getMessage());
391         }
392         //
393
// Product routing
394
//
395
String JavaDoc workEffortId = null;
396         try {
397             Map JavaDoc routingInMap = UtilMisc.toMap("productId", productId, "ignoreDefaultRouting", "Y", "userLogin", userLogin);
398             Map JavaDoc routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
399             GenericValue routing = (GenericValue)routingOutMap.get("routing");
400             if (routing == null) {
401                 // try to find a routing linked to the virtual product
402
routingInMap = UtilMisc.toMap("productId", tree.getRoot().getProduct().getString("productId"), "userLogin", userLogin);
403                 routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
404                 routing = (GenericValue)routingOutMap.get("routing");
405             }
406             if (routing != null) {
407                 workEffortId = routing.getString("workEffortId");
408             }
409         } catch(GenericServiceException gse) {
410             Debug.logWarning(gse.getMessage(), module);
411         }
412         if (workEffortId != null) {
413             result.put("workEffortId", workEffortId);
414         }
415         result.put("components", components);
416
417         // also return a componentMap (useful in scripts and simple language code)
418
List JavaDoc componentsMap = new ArrayList JavaDoc();
419         Iterator JavaDoc componentsIt = components.iterator();
420         while (componentsIt.hasNext()) {
421             Map JavaDoc componentMap = new HashMap JavaDoc();
422             BOMNode node = (BOMNode)componentsIt.next();
423             componentMap.put("product", node.getProduct());
424             componentMap.put("quantity", new Double JavaDoc(node.getQuantity()));
425             componentsMap.add(componentMap);
426         }
427         result.put("componentsMap", componentsMap);
428         return result;
429     }
430
431     public static Map JavaDoc getNotAssembledComponents(DispatchContext dctx, Map JavaDoc context) {
432         Map JavaDoc result = new HashMap JavaDoc();
433         Security security = dctx.getSecurity();
434         GenericDelegator delegator = dctx.getDelegator();
435         LocalDispatcher dispatcher = dctx.getDispatcher();
436         String JavaDoc productId = (String JavaDoc) context.get("productId");
437         Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
438         Double JavaDoc amount = (Double JavaDoc) context.get("amount");
439         String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
440         GenericValue userLogin = (GenericValue)context.get("userLogin");
441
442         if (quantity == null) {
443             quantity = new Double JavaDoc(1);
444         }
445         if (amount == null) {
446             amount = new Double JavaDoc(0);
447         }
448
449         Date JavaDoc fromDate = null;
450         if (UtilValidate.isNotEmpty(fromDateStr)) {
451             try {
452                 fromDate = Timestamp.valueOf(fromDateStr);
453             } catch (Exception JavaDoc e) {
454             }
455         }
456         if (fromDate == null) {
457             fromDate = new Date JavaDoc();
458         }
459         
460         BOMTree tree = null;
461         ArrayList JavaDoc components = new ArrayList JavaDoc();
462         ArrayList JavaDoc notAssembledComponents = new ArrayList JavaDoc();
463         try {
464             tree = new BOMTree(productId, "MANUF_COMPONENT", fromDate, BOMTree.EXPLOSION_MANUFACTURING, delegator, dispatcher, userLogin);
465             tree.setRootQuantity(quantity.doubleValue());
466             tree.setRootAmount(amount.doubleValue());
467             tree.print(components);
468         } catch(GenericEntityException gee) {
469             return ServiceUtil.returnError("Error creating bill of materials tree: " + gee.getMessage());
470         }
471         Iterator JavaDoc componentsIt = components.iterator();
472         while (componentsIt.hasNext()) {
473             BOMNode oneComponent = (BOMNode)componentsIt.next();
474             if (!oneComponent.isManufactured()) {
475                 notAssembledComponents.add(oneComponent);
476             }
477         }
478         result.put("notAssembledComponents" , notAssembledComponents);
479         return result;
480     }
481     
482     // ---------------------------------------------
483
// Service for the Product (Shipment) component
484
//
485
public static Map JavaDoc createShipmentPackages(DispatchContext dctx, Map JavaDoc context) {
486         Map JavaDoc result = new HashMap JavaDoc();
487         Security security = dctx.getSecurity();
488         GenericDelegator delegator = dctx.getDelegator();
489         LocalDispatcher dispatcher = dctx.getDispatcher();
490         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
491         GenericValue userLogin = (GenericValue)context.get("userLogin");
492         String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
493
494         try {
495             List JavaDoc packages = delegator.findByAnd("ShipmentPackage", UtilMisc.toMap("shipmentId", shipmentId));
496             if (!UtilValidate.isEmpty(packages)) {
497                 return ServiceUtil.returnError("Packages already found.");
498             }
499         } catch(GenericEntityException gee) {
500             return ServiceUtil.returnError("Error loading the ShipmentPackages");
501         }
502         // ShipmentItems are loaded
503
List JavaDoc shipmentItems = null;
504         try {
505             shipmentItems = delegator.findByAnd("ShipmentItem", UtilMisc.toMap("shipmentId", shipmentId));
506         } catch(GenericEntityException gee) {
507             return ServiceUtil.returnError("Error loading the ShipmentItems");
508         }
509         Iterator JavaDoc shipmentItemsIt = shipmentItems.iterator();
510         HashMap JavaDoc orderReadHelpers = new HashMap JavaDoc();
511         HashMap JavaDoc partyOrderShipments = new HashMap JavaDoc();
512         while (shipmentItemsIt.hasNext()) {
513             GenericValue shipmentItem = (GenericValue)shipmentItemsIt.next();
514             // Get the OrderShipments
515
List JavaDoc orderShipments = null;
516             try {
517                 orderShipments = delegator.findByAnd("OrderShipment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentItemSeqId", shipmentItem.getString("shipmentItemSeqId")));
518             } catch (GenericEntityException e) {
519                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
520             }
521             GenericValue orderShipment = org.ofbiz.entity.util.EntityUtil.getFirst(orderShipments);
522             if (orderShipment != null && !orderReadHelpers.containsKey(orderShipment.getString("orderId"))) {
523                 orderReadHelpers.put(orderShipment.getString("orderId"), new OrderReadHelper(delegator, orderShipment.getString("orderId")));
524             }
525             OrderReadHelper orderReadHelper = (OrderReadHelper)orderReadHelpers.get(orderShipment.getString("orderId"));
526             if (orderReadHelper != null) {
527                 Map JavaDoc orderShipmentReadMap = UtilMisc.toMap("orderShipment", orderShipment, "orderReadHelper", orderReadHelper);
528                 String JavaDoc partyId = (orderReadHelper.getPlacingParty() != null? orderReadHelper.getPlacingParty().getString("partyId"): null); // FIXME: is it the customer?
529
if (partyId != null) {
530                     if (!partyOrderShipments.containsKey(partyId)) {
531                         ArrayList JavaDoc orderShipmentReadMapList = new ArrayList JavaDoc();
532                         partyOrderShipments.put(partyId, orderShipmentReadMapList);
533                     }
534                     ArrayList JavaDoc orderShipmentReadMapList = (ArrayList JavaDoc)partyOrderShipments.get(partyId);
535                     orderShipmentReadMapList.add(orderShipmentReadMap);
536                 }
537             }
538         }
539         // For each party: try to expand the shipment item products
540
// (search for components that needs to be packaged).
541
Iterator JavaDoc partyOrderShipmentsIt = partyOrderShipments.entrySet().iterator();
542         while (partyOrderShipmentsIt.hasNext()) {
543             Map.Entry JavaDoc partyOrderShipment = (Map.Entry JavaDoc)partyOrderShipmentsIt.next();
544             String JavaDoc partyId = (String JavaDoc)partyOrderShipment.getKey();
545             List JavaDoc orderShipmentReadMapList = (List JavaDoc)partyOrderShipment.getValue();
546             for (int i = 0; i < orderShipmentReadMapList.size(); i++) {
547                 Map JavaDoc orderShipmentReadMap = (Map JavaDoc)orderShipmentReadMapList.get(i);
548                 GenericValue orderShipment = (GenericValue)orderShipmentReadMap.get("orderShipment");
549                 OrderReadHelper orderReadHelper = (OrderReadHelper)orderShipmentReadMap.get("orderReadHelper");
550                 GenericValue orderItem = orderReadHelper.getOrderItem(orderShipment.getString("orderItemSeqId"));
551                 // getProductsInPackages
552
Map JavaDoc serviceContext = new HashMap JavaDoc();
553                 serviceContext.put("productId", orderItem.getString("productId"));
554                 serviceContext.put("quantity", orderShipment.getDouble("quantity"));
555                 Map JavaDoc resultService = null;
556                 try {
557                     resultService = dispatcher.runSync("getProductsInPackages", serviceContext);
558                 } catch (GenericServiceException e) {
559                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
560                 }
561                 List JavaDoc productsInPackages = (List JavaDoc)resultService.get("productsInPackages");
562                 if (productsInPackages.size() == 1) {
563                     BOMNode root = (BOMNode)productsInPackages.get(0);
564                     String JavaDoc rootProductId = (root.getSubstitutedNode() != null? root.getSubstitutedNode().getProduct().getString("productId"): root.getProduct().getString("productId"));
565                     if (orderItem.getString("productId").equals(rootProductId)) {
566                         productsInPackages = null;
567                     }
568                 }
569                 if (productsInPackages != null && productsInPackages.size() == 0) {
570                     productsInPackages = null;
571                 }
572                 if (productsInPackages != null && productsInPackages.size() > 0) {
573                     orderShipmentReadMap.put("productsInPackages", productsInPackages);
574                 }
575             }
576         }
577         // Group together products and components
578
// of the same box type.
579
HashMap JavaDoc boxTypes = new HashMap JavaDoc();
580         partyOrderShipmentsIt = partyOrderShipments.entrySet().iterator();
581         while (partyOrderShipmentsIt.hasNext()) {
582             HashMap JavaDoc boxTypeContent = new HashMap JavaDoc();
583             Map.Entry JavaDoc partyOrderShipment = (Map.Entry JavaDoc)partyOrderShipmentsIt.next();
584             String JavaDoc partyId = (String JavaDoc)partyOrderShipment.getKey();
585             List JavaDoc orderShipmentReadMapList = (List JavaDoc)partyOrderShipment.getValue();
586             for (int i = 0; i < orderShipmentReadMapList.size(); i++) {
587                 Map JavaDoc orderShipmentReadMap = (Map JavaDoc)orderShipmentReadMapList.get(i);
588                 GenericValue orderShipment = (GenericValue)orderShipmentReadMap.get("orderShipment");
589                 OrderReadHelper orderReadHelper = (OrderReadHelper)orderShipmentReadMap.get("orderReadHelper");
590                 List JavaDoc productsInPackages = (List JavaDoc)orderShipmentReadMap.get("productsInPackages");
591                 if (productsInPackages != null) {
592                     // there are subcomponents:
593
// this is a multi package shipment item
594
for (int j = 0; j < productsInPackages.size(); j++) {
595                         BOMNode component = (BOMNode)productsInPackages.get(j);
596                         HashMap JavaDoc boxTypeContentMap = new HashMap JavaDoc();
597                         boxTypeContentMap.put("content", orderShipmentReadMap);
598                         boxTypeContentMap.put("componentIndex", new Integer JavaDoc(j));
599                         GenericValue product = component.getProduct();
600                         String JavaDoc boxTypeId = product.getString("shipmentBoxTypeId");
601                         if (boxTypeId != null) {
602                             if (!boxTypes.containsKey(boxTypeId)) {
603                                 GenericValue boxType = null;
604                                 try {
605                                     boxType = delegator.findByPrimaryKey("ShipmentBoxType", UtilMisc.toMap("shipmentBoxTypeId", boxTypeId));
606                                 } catch (GenericEntityException e) {
607                                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
608                                 }
609                                 boxTypes.put(boxTypeId, boxType);
610                                 boxTypeContent.put(boxTypeId, new ArrayList JavaDoc());
611                             }
612                             GenericValue boxType = (GenericValue)boxTypes.get(boxTypeId);
613                             List JavaDoc boxTypeContentList = (List JavaDoc)boxTypeContent.get(boxTypeId);
614                             boxTypeContentList.add(boxTypeContentMap);
615                         }
616                     }
617                 } else {
618                     // no subcomponents, the product has its own package:
619
// this is a single package shipment item
620
HashMap JavaDoc boxTypeContentMap = new HashMap JavaDoc();
621                     boxTypeContentMap.put("content", orderShipmentReadMap);
622                     GenericValue orderItem = orderReadHelper.getOrderItem(orderShipment.getString("orderItemSeqId"));
623                     GenericValue product = null;
624                     try {
625                         product = orderItem.getRelatedOne("Product");
626                     } catch (GenericEntityException e) {
627                         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
628                     }
629                     String JavaDoc boxTypeId = product.getString("shipmentBoxTypeId");
630                     if (boxTypeId != null) {
631                         if (!boxTypes.containsKey(boxTypeId)) {
632                             GenericValue boxType = null;
633                             try {
634                                 boxType = delegator.findByPrimaryKey("ShipmentBoxType", UtilMisc.toMap("shipmentBoxTypeId", boxTypeId));
635                             } catch (GenericEntityException e) {
636                                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
637                             }
638
639                             boxTypes.put(boxTypeId, boxType);
640                             boxTypeContent.put(boxTypeId, new ArrayList JavaDoc());
641                         }
642                         GenericValue boxType = (GenericValue)boxTypes.get(boxTypeId);
643                         List JavaDoc boxTypeContentList = (List JavaDoc)boxTypeContent.get(boxTypeId);
644                         boxTypeContentList.add(boxTypeContentMap);
645                     }
646                 }
647             }
648             // The packages and package contents are created.
649
Iterator JavaDoc boxTypeContentIt = boxTypeContent.entrySet().iterator();
650             while (boxTypeContentIt.hasNext()) {
651                 Map.Entry JavaDoc boxTypeContentEntry = (Map.Entry JavaDoc)boxTypeContentIt.next();
652                 String JavaDoc boxTypeId = (String JavaDoc)boxTypeContentEntry.getKey();
653                 List JavaDoc contentList = (List JavaDoc)boxTypeContentEntry.getValue();
654                 GenericValue boxType = (GenericValue)boxTypes.get(boxTypeId);
655                 Double JavaDoc boxWidth = boxType.getDouble("boxLength");
656                 double totalWidth = 0;
657                 double boxWidthDbl = 0;
658                 if (boxWidth != null) {
659                     boxWidthDbl = boxWidth.doubleValue();
660                 }
661                 String JavaDoc shipmentPackageSeqId = null;
662                 for (int i = 0; i < contentList.size(); i++) {
663                     Map JavaDoc contentMap = (Map JavaDoc)contentList.get(i);
664                     Map JavaDoc content = (Map JavaDoc)contentMap.get("content");
665                     OrderReadHelper orderReadHelper = (OrderReadHelper)content.get("orderReadHelper");
666                     List JavaDoc productsInPackages = (List JavaDoc)content.get("productsInPackages");
667                     GenericValue orderShipment = (GenericValue)content.get("orderShipment");
668
669                     GenericValue product = null;
670                     double quantity = 0;
671                     boolean subProduct = contentMap.containsKey("componentIndex");
672                     if (subProduct) {
673                         // multi package
674
Integer JavaDoc index = (Integer JavaDoc)contentMap.get("componentIndex");
675                         BOMNode component = (BOMNode)productsInPackages.get(index.intValue());
676                         product = component.getProduct();
677                         quantity = component.getQuantity();
678                     } else {
679                         // single package
680
GenericValue orderItem = orderReadHelper.getOrderItem(orderShipment.getString("orderItemSeqId"));
681                         try {
682                             product = orderItem.getRelatedOne("Product");
683                         } catch (GenericEntityException e) {
684                             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
685                         }
686                         quantity = orderShipment.getDouble("quantity").doubleValue();
687                     }
688
689                     Double JavaDoc productDepth = product.getDouble("shippingDepth");
690                     if (productDepth == null) {
691                         productDepth = product.getDouble("productDepth");
692                     }
693                     double productDepthDbl = 1;
694                     if (productDepth != null) {
695                         productDepthDbl = productDepth.doubleValue();
696                     }
697                     
698                     int firstMaxNumOfProducts = (int)((boxWidthDbl - totalWidth) / productDepthDbl);
699                     if (firstMaxNumOfProducts == 0) firstMaxNumOfProducts = 1;
700                     //
701
int maxNumOfProducts = (int)(boxWidthDbl / productDepthDbl);
702                     if (maxNumOfProducts == 0) maxNumOfProducts = 1;
703
704                     double remQuantity = quantity;
705                     boolean isFirst = true;
706                     while (remQuantity > 0) {
707                         int maxQuantity = 0;
708                         if (isFirst) {
709                             maxQuantity = firstMaxNumOfProducts;
710                             isFirst = false;
711                         } else {
712                             maxQuantity = maxNumOfProducts;
713                         }
714                         double qty = (remQuantity < maxQuantity? remQuantity: maxQuantity);
715                         // If needed, create the package
716
if (shipmentPackageSeqId == null) {
717                             try {
718                                 Map JavaDoc resultService = dispatcher.runSync("createShipmentPackage", UtilMisc.toMap("shipmentId", orderShipment.getString("shipmentId"), "shipmentBoxTypeId", boxTypeId, "userLogin", userLogin));
719                                 shipmentPackageSeqId = (String JavaDoc)resultService.get("shipmentPackageSeqId");
720                             } catch (GenericServiceException e) {
721                                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
722                             }
723                             totalWidth = 0;
724                         }
725                         try {
726                             Map JavaDoc inputMap = null;
727                             if (subProduct) {
728                                 inputMap = UtilMisc.toMap("shipmentId", orderShipment.getString("shipmentId"),
729                                 "shipmentPackageSeqId", shipmentPackageSeqId,
730                                 "shipmentItemSeqId", orderShipment.getString("shipmentItemSeqId"),
731                                 "subProductId", product.getString("productId"),
732                                 "userLogin", userLogin,
733                                 "subProductQuantity", new Double JavaDoc(qty));
734                             } else {
735                                 inputMap = UtilMisc.toMap("shipmentId", orderShipment.getString("shipmentId"),
736                                 "shipmentPackageSeqId", shipmentPackageSeqId,
737                                 "shipmentItemSeqId", orderShipment.getString("shipmentItemSeqId"),
738                                 "userLogin", userLogin,
739                                 "quantity", new Double JavaDoc(qty));
740                             }
741                             Map JavaDoc resultService = dispatcher.runSync("createShipmentPackageContent", inputMap);
742                         } catch (GenericServiceException e) {
743                             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingPackageConfiguratorError", locale));
744                         }
745                         totalWidth += qty * productDepthDbl;
746                         if (qty == maxQuantity) shipmentPackageSeqId = null;
747                         remQuantity = remQuantity - qty;
748                     }
749                 }
750             }
751         }
752         return result;
753     }
754
755     /** It reads the product's bill of materials,
756      * if necessary configures it, and it returns its (possibly configured) components in
757      * a List of {@link BOMNode}).
758      * @param dctx
759      * @param context
760      * @return
761      */

762     public static Map JavaDoc getProductsInPackages(DispatchContext dctx, Map JavaDoc context) {
763
764         Map JavaDoc result = new HashMap JavaDoc();
765         Security security = dctx.getSecurity();
766         GenericDelegator delegator = dctx.getDelegator();
767         LocalDispatcher dispatcher = dctx.getDispatcher();
768         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
769         GenericValue userLogin = (GenericValue)context.get("userLogin");
770         
771         String JavaDoc productId = (String JavaDoc) context.get("productId");
772         Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
773         String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
774         
775         if (quantity == null) {
776             quantity = new Double JavaDoc(1);
777         }
778         Date JavaDoc fromDate = null;
779         if (UtilValidate.isNotEmpty(fromDateStr)) {
780             try {
781                 fromDate = Timestamp.valueOf(fromDateStr);
782             } catch (Exception JavaDoc e) {
783             }
784         }
785         if (fromDate == null) {
786             fromDate = new Date JavaDoc();
787         }
788        
789         //
790
// Components
791
//
792
BOMTree tree = null;
793         ArrayList JavaDoc components = new ArrayList JavaDoc();
794         try {
795             tree = new BOMTree(productId, "MANUF_COMPONENT", fromDate, BOMTree.EXPLOSION_MANUFACTURING, delegator, dispatcher, userLogin);
796             tree.setRootQuantity(quantity.doubleValue());
797             tree.getProductsInPackages(components);
798         } catch(GenericEntityException gee) {
799             return ServiceUtil.returnError("Error creating bill of materials tree: " + gee.getMessage());
800         }
801         
802         result.put("productsInPackages", components);
803
804         return result;
805     }
806
807 }
808
Popular Tags