KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > manufacturing > mrp > MrpServices


1 /*
2  * $Id: MrpServices.java 7238 2006-04-08 07:30:54Z jacopo $
3  * Copyright (c) 2003, 2004 The Open For Business Project - www.ofbiz.org
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
20  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */

23
24 package org.ofbiz.manufacturing.mrp;
25
26 import java.sql.Timestamp JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.LinkedList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.ListIterator JavaDoc;
32 import java.util.Locale JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import org.ofbiz.base.util.Debug;
36 import org.ofbiz.base.util.UtilDateTime;
37 import org.ofbiz.base.util.UtilMisc;
38 import org.ofbiz.entity.GenericDelegator;
39 import org.ofbiz.entity.GenericEntityException;
40 import org.ofbiz.entity.GenericValue;
41 import org.ofbiz.entity.condition.EntityCondition;
42 import org.ofbiz.entity.condition.EntityExpr;
43 import org.ofbiz.entity.condition.EntityOperator;
44 import org.ofbiz.entity.util.EntityUtil;
45 import org.ofbiz.manufacturing.bom.BOMNode;
46 import org.ofbiz.security.Security;
47 import org.ofbiz.service.DispatchContext;
48 import org.ofbiz.service.GenericServiceException;
49 import org.ofbiz.service.LocalDispatcher;
50 import org.ofbiz.service.ModelService;
51 import org.ofbiz.service.ServiceUtil;
52
53 // TODO:
54
// Verificare il metodo: ProductHelper.isBuild(product)
55
// Verificare il metodo ProposedOrder.calculateQuantityToSupply()
56
// il metodo findProductMrpQoh() deve richiamare internamente un servizio
57
//
58
/**
59  * Services for running MRP
60  *
61  * @author <a HREF=mailto:thierry.grauss@etu.univ-tours.fr">Thierry GRAUSS</a>
62  */

63 public class MrpServices {
64     
65     public static final String JavaDoc module = MrpServices.class.getName();
66     public static final String JavaDoc resource = "ManufacturingUiLabels";
67     
68     
69     
70     /**
71      * Initialize the InventoryEventPlanned table.
72      * <li>PreConditions : none</li>
73      * <li>Result : The table InventoryEventPlannedForMRP is initialized</li>
74      * <li>INPUT : Parameter to get from the context :</li><ul>
75      * <li>Boolean reInitialize<br/>
76      * if true : we must reinitialize the table, else we synchronize the table (not for the moment)</li></ul>
77      *
78      * <li>OUTPUT : Result to put in the map :</li><ul>
79      * <li>none</li></ul>
80      *
81      * @param ctx The DispatchContext that this service is operating in.
82      * @param context Map containing the input parameters.
83      * @return Map with the result of the service, the output parameters.
84      */

85     
86     public static Map JavaDoc initInventoryEventPlanned(DispatchContext ctx, Map JavaDoc context) {
87         GenericDelegator delegator = ctx.getDelegator();
88         LocalDispatcher dispatcher = ctx.getDispatcher();
89         Security security = ctx.getSecurity();
90         Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
91         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
92         GenericValue userLogin = (GenericValue) context.get("userLogin");
93         
94         //Erases the old table for the moment and initializes it with the new orders,
95
//Does not modify the old one now.
96
Debug.logInfo("initInventoryEventPlanned called", module);
97         
98         List JavaDoc listResult = null;
99         try{
100             listResult = delegator.findAll("InventoryEventPlanned");
101         } catch(GenericEntityException e) {
102             Debug.logError(e,"Error : delegator.findAll(\"InventoryEventPlanned\")", module);
103             return ServiceUtil.returnError("Problem, we can not find all the items of InventoryEventPlanned, for more detail look at the log");
104         }
105         if(listResult != null){
106             try{
107                 delegator.removeAll(listResult);
108             } catch(GenericEntityException e) {
109                 Debug.logError(e,"Error : delegator.removeAll(listResult), listResult ="+listResult, module);
110                 return ServiceUtil.returnError("Problem, we can not remove the InventoryEventPlanned items, for more detail look at the log");
111             }
112         }
113
114         // MRP proposed requirements are deleted
115
// TODO: is it correct?
116

117         listResult = null;
118         try{
119             listResult = delegator.findByAnd("Requirement", UtilMisc.toMap("requirementTypeId", "MRP_PRO_PURCH_ORDER", "statusId", "REQ_CREATED"));
120         } catch(GenericEntityException e) {
121             return ServiceUtil.returnError("Problem, we can not find all the items of InventoryEventPlanned, for more detail look at the log");
122         }
123         if(listResult != null){
124             try{
125                 delegator.removeAll(listResult);
126             } catch(GenericEntityException e) {
127                 return ServiceUtil.returnError("Problem, we can not remove the InventoryEventPlanned items, for more detail look at the log");
128             }
129         }
130         listResult = null;
131         try{
132             listResult = delegator.findByAnd("Requirement", UtilMisc.toMap("requirementTypeId", "MRP_PRO_PROD_ORDER", "statusId", "REQ_CREATED"));
133         } catch(GenericEntityException e) {
134             return ServiceUtil.returnError("Problem, we can not find all the items of InventoryEventPlanned, for more detail look at the log");
135         }
136         if(listResult != null){
137             try{
138                 delegator.removeAll(listResult);
139             } catch(GenericEntityException e) {
140                 return ServiceUtil.returnError("Problem, we can not remove the InventoryEventPlanned items, for more detail look at the log");
141             }
142         }
143
144         GenericValue genericResult = null;
145         Map JavaDoc parameters = null;
146         List JavaDoc resultList = null;
147         Iterator JavaDoc iteratorResult = null;
148         // ----------------------------------------
149
// Loads all the approved sales order items and purchase order items
150
// ----------------------------------------
151
resultList = null;
152         iteratorResult = null;
153         parameters = UtilMisc.toMap("orderTypeId", "SALES_ORDER", "itemStatusId", "ITEM_APPROVED");
154         try {
155             resultList = delegator.findByAnd("OrderHeaderAndItems", parameters);
156         } catch(GenericEntityException e) {
157             Debug.logError(e, "Error : delegator.findByAnd(\"OrderItem\", parameters\")", module);
158             Debug.logError(e, "Error : parameters = "+parameters,module);
159             return ServiceUtil.returnError("Problem, we can not find the order items, for more detail look at the log");
160         }
161         iteratorResult = resultList.iterator();
162         while(iteratorResult.hasNext()){
163             genericResult = (GenericValue) iteratorResult.next();
164             String JavaDoc productId = genericResult.getString("productId");
165             Double JavaDoc eventQuantityTmp = new Double JavaDoc(-1.0 * genericResult.getDouble("quantity").doubleValue());
166             Timestamp JavaDoc estimatedShipDate = genericResult.getTimestamp("estimatedDeliveryDate");
167             if (estimatedShipDate == null) {
168                 estimatedShipDate = now;
169             }
170             parameters = UtilMisc.toMap("productId", productId, "eventDate", estimatedShipDate, "inventoryEventPlanTypeId", "SALE_ORDER_SHIP");
171             try {
172                 InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(parameters, eventQuantityTmp, delegator);
173             } catch (GenericEntityException e) {
174                 return ServiceUtil.returnError("Problem initializing the InventoryEventPlanned entity (SALE_ORDER_SHIP)");
175             }
176         }
177         
178         // ----------------------------------------
179
// Loads all the approved purchase order items
180
// ----------------------------------------
181
resultList = null;
182         iteratorResult = null;
183         parameters = UtilMisc.toMap("orderTypeId", "PURCHASE_ORDER", "itemStatusId", "ITEM_APPROVED");
184         try {
185             resultList = delegator.findByAnd("OrderHeaderAndItems", parameters);
186         } catch(GenericEntityException e) {
187             Debug.logError(e, "Error : delegator.findByAnd(\"OrderItem\", parameters\")", module);
188             Debug.logError(e, "Error : parameters = "+parameters,module);
189             return ServiceUtil.returnError("Problem, we can not find the order items, for more detail look at the log");
190         }
191         iteratorResult = resultList.iterator();
192         while(iteratorResult.hasNext()){
193             genericResult = (GenericValue) iteratorResult.next();
194             String JavaDoc productId = genericResult.getString("productId");
195             Double JavaDoc eventQuantityTmp = new Double JavaDoc(genericResult.getDouble("quantity").doubleValue());
196             Timestamp JavaDoc estimatedShipDate = genericResult.getTimestamp("estimatedShipDate");
197             if (estimatedShipDate == null) {
198                 estimatedShipDate = now;
199             }
200             
201             parameters = UtilMisc.toMap("productId", productId, "eventDate", estimatedShipDate, "inventoryEventPlanTypeId", "PUR_ORDER_RECP");
202             try {
203                 InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(parameters, eventQuantityTmp, delegator);
204             } catch (GenericEntityException e) {
205                 return ServiceUtil.returnError("Problem initializing the InventoryEventPlanned entity (PUR_ORDER_RECP)");
206             }
207         }
208         // ----------------------------------------
209
// PRODUCTION Run: components
210
// ----------------------------------------
211
resultList = null;
212         iteratorResult = null;
213         parameters = UtilMisc.toMap("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED", "statusId", "WEGS_CREATED");
214         try {
215             resultList = delegator.findByAnd("WorkEffortAndGoods", parameters);
216         } catch(GenericEntityException e) {
217             Debug.logError(e, "Error : delegator.findByAnd(\"OrderItem\", parameters\")", module);
218             Debug.logError(e, "Error : parameters = "+parameters,module);
219             return ServiceUtil.returnError("Problem, we can not find the order items, for more detail look at the log");
220         }
221         iteratorResult = resultList.iterator();
222         while(iteratorResult.hasNext()){
223             genericResult = (GenericValue) iteratorResult.next();
224             String JavaDoc productId = genericResult.getString("productId");
225             Double JavaDoc eventQuantityTmp = new Double JavaDoc(-1.0 * genericResult.getDouble("estimatedQuantity").doubleValue());
226             Timestamp JavaDoc estimatedShipDate = genericResult.getTimestamp("estimatedStartDate");
227             if (estimatedShipDate == null) {
228                 estimatedShipDate = now;
229             }
230             
231             parameters = UtilMisc.toMap("productId", productId, "eventDate", estimatedShipDate, "inventoryEventPlanTypeId", "MANUF_ORDER_REQ");
232             try {
233                 InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(parameters, eventQuantityTmp, delegator);
234             } catch (GenericEntityException e) {
235                 return ServiceUtil.returnError("Problem initializing the InventoryEventPlanned entity (MRP_REQUIREMENT)");
236             }
237         }
238         
239         // ----------------------------------------
240
// PRODUCTION Run: product produced
241
// ----------------------------------------
242
resultList = null;
243         iteratorResult = null;
244         parameters = UtilMisc.toMap("workEffortGoodStdTypeId", "PRUN_PROD_DELIV", "statusId", "WEGS_CREATED", "workEffortTypeId", "PROD_ORDER_HEADER");
245         try {
246             resultList = delegator.findByAnd("WorkEffortAndGoods", parameters);
247         } catch(GenericEntityException e) {
248             Debug.logError(e, "Error : delegator.findByAnd(\"OrderItem\", parameters\")", module);
249             Debug.logError(e, "Error : parameters = "+parameters,module);
250             return ServiceUtil.returnError("Problem, we can not find the order items, for more detail look at the log");
251         }
252         iteratorResult = resultList.iterator();
253         while(iteratorResult.hasNext()){
254             genericResult = (GenericValue) iteratorResult.next();
255             if ("PRUN_CLOSED".equals(genericResult.getString("currentStatusId"))) {
256                 continue;
257             }
258             Double JavaDoc qtyToProduce = genericResult.getDouble("quantityToProduce");
259             if (qtyToProduce == null) {
260                 qtyToProduce = new Double JavaDoc(0);
261             }
262             Double JavaDoc qtyProduced = genericResult.getDouble("quantityProduced");
263             if (qtyProduced == null) {
264                 qtyProduced = new Double JavaDoc(0);
265             }
266             if (qtyProduced.compareTo(qtyToProduce) >= 0) {
267                 continue;
268             }
269             double qtyDiff = qtyToProduce.doubleValue() - qtyProduced.doubleValue();
270             String JavaDoc productId = genericResult.getString("productId");
271             Double JavaDoc eventQuantityTmp = new Double JavaDoc(qtyDiff);
272             Timestamp JavaDoc estimatedShipDate = genericResult.getTimestamp("estimatedCompletionDate");
273             if (estimatedShipDate == null) {
274                 estimatedShipDate = now;
275             }
276             
277             parameters = UtilMisc.toMap("productId", productId, "eventDate", estimatedShipDate, "inventoryEventPlanTypeId", "MANUF_ORDER_RECP");
278             try {
279                 InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(parameters, eventQuantityTmp, delegator);
280             } catch (GenericEntityException e) {
281                 return ServiceUtil.returnError("Problem initializing the InventoryEventPlanned entity (MANUF_ORDER_RECP)");
282             }
283         }
284
285         
286         Map JavaDoc result = new HashMap JavaDoc();
287         result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
288         Debug.logInfo("return from initInventoryEventPlanned", module);
289         return result;
290     }
291     /**
292      * Create a List with all the event of InventotyEventPlanned for one billOfMaterialLevel, sorted by productId and eventDate.
293      *
294      * <li>INPUT : Parameter to get from the context : </li><ul>
295      * <li>Integer billOfMaterialLevel : 0 for root for more detail see BomHelper.getMaxDepth</li></ul>
296      *
297      * <li>OUTPUT : Result to put in the map :</li><ul>
298      * <li>List listInventoryEventForMRP : all the event of InventotyEventPlanned for one billOfMaterialLevel, sorted by productId and eventDate<br/>
299      * @param ctx The DispatchContext that this service is operating in.
300      * @param context Map containing the input parameters.
301      * @return Map with the result of the service, the output parameters.
302      */

303     public static Map JavaDoc listProductForMrp(DispatchContext ctx, Map JavaDoc context) {
304         Debug.logInfo("listProductForMrp called", module);
305         // read parameters from context
306
GenericDelegator delegator = ctx.getDelegator();
307         Security security = ctx.getSecurity();
308         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
309         GenericValue userLogin = (GenericValue) context.get("userLogin");
310         Long JavaDoc billOfMaterialLevel = (Long JavaDoc) context.get("billOfMaterialLevel");
311         
312         // Find all products in MrpInventoryEventPlanned, ordered by bom and eventDate
313
List JavaDoc listResult = null;
314         // If billOfMaterialLevel == 0 the search must be done with (billOfMaterialLevel == 0 || billOfMaterialLevel == null)
315
EntityCondition parameters = null;
316         if (billOfMaterialLevel.intValue() == 0) {
317             parameters = new EntityExpr(new EntityExpr("billOfMaterialLevel", EntityOperator.EQUALS, null),
318                                         EntityOperator.OR,
319                                         new EntityExpr("billOfMaterialLevel", EntityOperator.EQUALS, billOfMaterialLevel));
320         } else {
321             parameters = new EntityExpr("billOfMaterialLevel", EntityOperator.EQUALS, billOfMaterialLevel);
322         }
323
324         List JavaDoc orderBy = UtilMisc.toList("productId", "eventDate");
325         try{
326             //listResult = delegator.findByAnd("MrpInventoryEventPlanned", parameters, orderBy);
327
listResult = delegator.findByCondition("MrpInventoryEventPlanned", parameters, null, orderBy);
328         } catch(GenericEntityException e) {
329             Debug.logError(e, "Error : delegator.findByCondition(\"MrpInventoryEventPlanned\", parameters, null, orderBy)", module);
330             Debug.logError(e, "Error : parameters = "+parameters,module);
331             Debug.logError(e, "Error : orderBy = "+orderBy,module);
332             return ServiceUtil.returnError("Problem, we can not find the products, for more detail look at the log");
333         }
334         Map JavaDoc result = new HashMap JavaDoc();
335         result.put("listInventoryEventForMrp",listResult);
336         result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
337         Debug.logInfo("return from listProductForMrp "+billOfMaterialLevel, module);
338         return result;
339     }
340     
341     /**
342      * Find the quantity on hand of products for MRP.
343      * <li>PreConditions : none</li>
344      * <li>Result : We get the quantity of product available in the stocks.</li>
345      *
346      * @param product the product for which the Quantity Available is required
347      * @return the sum of all the totalAvailableToPromise of the inventoryItem related to the product, if the related facility is Mrp available (not yet implemented!!)
348      */

349     public static double findProductMrpQoh(GenericValue product, LocalDispatcher dispatcher) {
350         List JavaDoc orderBy = UtilMisc.toList("facilityId", "-receivedDate", "-inventoryItemId");
351         Map JavaDoc resultMap = null;
352         try{
353             resultMap = dispatcher.runSync("getProductInventoryAvailable", UtilMisc.toMap("productId", product.getString("productId")));
354             // TODO: aggiungere facilityId come argomento ed usare il seguente
355
//resultMap = dispatcher.runSync("getProductInventoryAvailableByFacility", UtilMisc.toMap("productId", product.getString("productId"), "facilityId", facilityId));
356
} catch (GenericServiceException e) {
357             Debug.logError(e, "Error calling getProductInventoryAvailableByFacility service", module);
358             return 0;
359         }
360         return ((Double JavaDoc)resultMap.get("quantityOnHandTotal")).doubleValue();
361     }
362     
363     /**
364      * Process the bill of material (bom) of the product to insert components in the InventoryEventPlanned table.
365      * Before inserting in the entity, test if there is the record already existing to add quantity rather to create a new one.
366      *
367      * @param product
368      * @param eventQuantity the product quantity needed
369      * @param startDate the startDate of the productionRun which will used to produce the product
370      * @param routingTaskStartDate Map with all the routingTask as keys and startDate of each of them
371      * @return None
372      */

373     
374     public static void processBomComponent(GenericValue product, double eventQuantity, Timestamp JavaDoc startDate, Map JavaDoc routingTaskStartDate, List JavaDoc listComponent) {
375         // TODO : change the return type to boolean to be able to test if all is ok or if it have had a exception
376
GenericDelegator delegator = product.getDelegator();
377
378         if (listComponent != null && listComponent.size() >0) {
379             Iterator JavaDoc listComponentIter = listComponent.iterator();
380             while (listComponentIter.hasNext()) {
381                 BOMNode node = (BOMNode) listComponentIter.next();
382                 GenericValue productComponent = node.getProductAssoc();
383                 // read the startDate for the component
384
String JavaDoc routingTask = node.getProductAssoc().getString("routingWorkEffortId");
385                 Timestamp JavaDoc eventDate = (routingTask == null || !routingTaskStartDate.containsKey(routingTask)) ? startDate : (Timestamp JavaDoc) routingTaskStartDate.get(routingTask);
386                 // if the components is valid at the event Date create the Mrp requirement in the InventoryEventPlanned entity
387
if (EntityUtil.isValueActive(productComponent, eventDate)) {
388                     //Map parameters = UtilMisc.toMap("productId", productComponent.getString("productIdTo"));
389
Map JavaDoc parameters = UtilMisc.toMap("productId", node.getProduct().getString("productId"));
390                     parameters.put("eventDate", eventDate);
391                     parameters.put("inventoryEventPlanTypeId", "MRP_REQUIREMENT");
392                     double componentEventQuantity = node.getQuantity();
393                     try {
394                         InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(parameters, new Double JavaDoc(-1.0 * componentEventQuantity), delegator);
395                     } catch (GenericEntityException e) {
396                         Debug.logError("Error : delegator.findByPrimaryKey(\"InventoryEventPlanned\", parameters) ="+parameters+"--"+e.getMessage(), module);
397                     }
398                 }
399             }
400         }
401         return;
402     }
403     
404     /**
405      * Launch the MRP.
406      * <li>PreConditions : none</li>
407      * <li>Result : The date when we must order or begin to build the products and subproducts we need are calclated</li>
408      *
409      * <li>INPUT : parameters to get from the context :</li><ul>
410      * <li>String mrpName</li></ul>
411      *
412      * <li>OUTPUT : Result to put in the map :</li><ul>
413      * <li>none</li></ul>
414      * @param ctx The DispatchContext that this service is operating in.
415      * @param context Map containing the input parameters, productId routingId, quantity, startDate.
416      * @return Map with the result of the service, the output parameters.
417      */

418     public static Map JavaDoc runningMrp(DispatchContext ctx, Map JavaDoc context) {
419         Debug.logInfo("runningMrp called", module);
420         //Context
421
GenericDelegator delegator = ctx.getDelegator();
422         LocalDispatcher dispatcher = ctx.getDispatcher();
423         Security security = ctx.getSecurity();
424         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
425         GenericValue userLogin = (GenericValue) context.get("userLogin");
426         
427         String JavaDoc mrpName = (String JavaDoc)context.get("mrpName");
428         String JavaDoc facilityId = (String JavaDoc)context.get("facilityId");
429         // Variable declaration
430
int bomLevelWithNoEvent = 0;
431         double stockTmp = 0;
432         String JavaDoc oldProductId = null;
433         String JavaDoc productId = null;
434         GenericValue product = null;
435         GenericValue productFacility = null;
436         double eventQuantity = 0;
437         Timestamp JavaDoc eventDate = null;
438         boolean isNegative = false;
439         double quantityNeeded = 0;
440         double reorderQuantity = 0;
441         double minimumStock = 0;
442         int daysToShip = 0;
443         List JavaDoc components = null;
444         boolean isbuild = false;
445         GenericValue routing = null;
446         
447         Map JavaDoc result = null;
448         Map JavaDoc parameters = null;
449         List JavaDoc listInventoryEventForMRP = null;
450         ListIterator JavaDoc iteratorListInventoryEventForMRP = null;
451         GenericValue inventoryEventForMRP = null;
452         
453         // Initialisation of the InventoryEventPlanned table, This table will contain the products we want to buy or build.
454
parameters = UtilMisc.toMap("reInitialize",new Boolean JavaDoc(true),"userLogin", userLogin);
455         try {
456             result = dispatcher.runSync("initInventoryEventPlanned", parameters);
457         } catch (GenericServiceException e) {
458             Debug.logError("Error : initInventoryEventPlanned", module);
459             Debug.logError("Error : parameters = "+parameters,module);
460             return ServiceUtil.returnError("Problem, can not initialise the table InventoryEventPlanned, for more detail look at the log");
461         }
462         // TODO : modifier le jeux d'essai de TGR pour mettre 0 au niveau pf
463
long bomLevel = 0;
464         // iteration for the bomLevel for which there are some events
465
do {
466             //get the products from the InventoryEventPlanned table for the current billOfMaterialLevel (ie. BOM)
467
parameters = UtilMisc.toMap("billOfMaterialLevel", new Long JavaDoc(bomLevel), "userLogin", userLogin);
468             try {
469                 result = dispatcher.runSync("listProductForMrp", parameters);
470             } catch (GenericServiceException e) {
471                 Debug.logError("Error : listProductForMrp, parameters ="+parameters, module);
472                 return ServiceUtil.returnError("Problem, can not list the products for the MRP, for more detail look at the log");
473             }
474             listInventoryEventForMRP = (List JavaDoc) result.get("listInventoryEventForMrp");
475             
476             if (listInventoryEventForMRP != null && listInventoryEventForMRP.size()>0) {
477                 bomLevelWithNoEvent = 0;
478                 iteratorListInventoryEventForMRP = listInventoryEventForMRP.listIterator();
479                 
480                 oldProductId = "";
481                 while (iteratorListInventoryEventForMRP.hasNext()) {
482                     inventoryEventForMRP = (GenericValue) iteratorListInventoryEventForMRP.next();
483                     productId = (String JavaDoc) inventoryEventForMRP.getString("productId");
484                     eventQuantity = inventoryEventForMRP.getDouble("eventQuantity").doubleValue();
485
486                     if (!productId.equals(oldProductId)) {
487                         double positiveEventQuantity = (eventQuantity > 0? eventQuantity: -1 * eventQuantity);
488                         // It's a new product, so it's necessary to read the MrpQoh
489
try {
490                             product = inventoryEventForMRP.getRelatedOneCache("Product");
491                             productFacility = (GenericValue)EntityUtil.getFirst(product.getRelatedByAndCache("ProductFacility", UtilMisc.toMap("facilityId", facilityId)));
492                         } catch (GenericEntityException e) {
493                             return ServiceUtil.returnError("Problem, can not find the product for a event, for more detail look at the log");
494                         }
495                         stockTmp = findProductMrpQoh(product, dispatcher);
496                         if (productFacility != null) {
497                             reorderQuantity = (productFacility.getDouble("reorderQuantity") != null? productFacility.getDouble("reorderQuantity").doubleValue(): -1);
498                             minimumStock = (productFacility.getDouble("minimumStock") != null? productFacility.getDouble("minimumStock").doubleValue(): 0);
499                             daysToShip = (productFacility.getLong("daysToShip") != null? productFacility.getLong("daysToShip").intValue(): 0);
500                         } else {
501                             minimumStock = 0;
502                             daysToShip = 0;
503                             reorderQuantity = -1;
504                         }
505                         // -----------------------------------------------------
506
// The components are also loaded thru the configurator
507
Map JavaDoc serviceResponse = null;
508                         try {
509                             serviceResponse = dispatcher.runSync("getManufacturingComponents", UtilMisc.toMap("productId", product.getString("productId"), "quantity", new Double JavaDoc(positiveEventQuantity), "userLogin", userLogin));
510                         } catch (Exception JavaDoc e) {
511                             return ServiceUtil.returnError("An error occurred exploding the product [" + product.getString("productId") + "]");
512                         }
513                         components = (List JavaDoc)serviceResponse.get("components");
514                         if (components != null && components.size() > 0) {
515                             BOMNode node = ((BOMNode)components.get(0)).getParentNode();
516                             isbuild = node.isManufactured();
517                         } else {
518                             isbuild = false;
519                         }
520                         // #####################################################
521

522                         oldProductId = productId;
523                     }
524                     
525                     stockTmp = stockTmp + eventQuantity;
526                     if(stockTmp < minimumStock){
527                         double qtyToStock = minimumStock - stockTmp;
528                         //need to buy or build the product as we have not enough stock
529
eventDate = inventoryEventForMRP.getTimestamp("eventDate");
530                         // to be just before the requirement
531
eventDate.setTime(eventDate.getTime()-1);
532                         ProposedOrder proposedOrder = new ProposedOrder(product, facilityId, isbuild, eventDate, qtyToStock);
533                         proposedOrder.setMrpName(mrpName);
534                         // calculate the ProposedOrder quantity and update the quantity object property.
535
proposedOrder.calculateQuantityToSupply(reorderQuantity, minimumStock, iteratorListInventoryEventForMRP);
536                         
537                         // -----------------------------------------------------
538
// The components are also loaded thru the configurator
539
Map JavaDoc serviceResponse = null;
540                         try {
541                             serviceResponse = dispatcher.runSync("getManufacturingComponents", UtilMisc.toMap("productId", product.getString("productId"), "quantity", new Double JavaDoc(proposedOrder.getQuantity()), "userLogin", userLogin));
542                         } catch (Exception JavaDoc e) {
543                             return ServiceUtil.returnError("An error occurred exploding the product [" + product.getString("productId") + "]");
544                         }
545                         components = (List JavaDoc)serviceResponse.get("components");
546                         String JavaDoc routingId = (String JavaDoc)serviceResponse.get("workEffortId");
547                         if (routingId != null) {
548                             try {
549                                 routing = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", routingId));
550                             } catch (GenericEntityException e) {
551                                 return ServiceUtil.returnError("Problem, can not find the product for a event, for more detail look at the log");
552                             }
553                         } else {
554                             routing = null;
555                         }
556                         if (components != null && components.size() > 0) {
557                             BOMNode node = ((BOMNode)components.get(0)).getParentNode();
558                             isbuild = node.isManufactured();
559                         } else {
560                             isbuild = false;
561                         }
562                         // #####################################################
563

564                         // calculate the ProposedOrder requirementStartDate and update the requirementStartDate object property.
565
Map JavaDoc routingTaskStartDate = proposedOrder.calculateStartDate(daysToShip, routing, delegator, dispatcher, userLogin);
566                         if (isbuild) {
567                             // process the product components
568
processBomComponent(product, proposedOrder.getQuantity(), proposedOrder.getRequirementStartDate(), routingTaskStartDate, components);
569                         }
570                         // create the ProposedOrder (only if the product is warehouse managed), and the InventoryEventPlanned associated
571
if (productFacility != null) {
572                             String JavaDoc proposedOrderId = proposedOrder.create(ctx, userLogin);
573                         }
574                         Map JavaDoc eventMap = UtilMisc.toMap("productId", product.getString("productId"),
575                                                       "eventDate", eventDate,
576                                                       "inventoryEventPlanTypeId", (isbuild? "PROP_MANUF_O_RECP" : "PROP_PUR_O_RECP"));
577                         try {
578                             InventoryEventPlannedServices.createOrUpdateInventoryEventPlanned(eventMap, new Double JavaDoc(proposedOrder.getQuantity()), delegator);
579                         } catch (GenericEntityException e) {
580                             return ServiceUtil.returnError("Problem running createOrUpdateInventoryEventPlanned");
581                         }
582                         //
583
stockTmp = stockTmp + proposedOrder.getQuantity();
584                     }
585                 }
586             } else {
587                 bomLevelWithNoEvent += 1;
588             }
589             
590             bomLevel += 1;
591             // if there are 3 levels with no inventoryEvenPanned we stop
592
} while (bomLevelWithNoEvent < 3);
593         
594         result = new HashMap JavaDoc();
595         List JavaDoc msgResult = new LinkedList JavaDoc();
596         result.put("msgResult",msgResult);
597         result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
598         Debug.logInfo("return from runningMrp", module);
599         return result;
600     }
601 }
602
Popular Tags