KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > manufacturing > jobshopmgt > ProductionRunServices


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

25 package org.ofbiz.manufacturing.jobshopmgt;
26
27 import java.sql.Timestamp JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Date JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.LinkedList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Locale JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.math.BigDecimal JavaDoc;
37
38 import org.ofbiz.base.util.Debug;
39 import org.ofbiz.base.util.UtilDateTime;
40 import org.ofbiz.base.util.UtilMisc;
41 import org.ofbiz.base.util.UtilProperties;
42 import org.ofbiz.base.util.UtilValidate;
43 import org.ofbiz.base.util.UtilNumber;
44 import org.ofbiz.entity.GenericDelegator;
45 import org.ofbiz.entity.GenericEntityException;
46 import org.ofbiz.entity.GenericValue;
47 import org.ofbiz.entity.util.EntityUtil;
48 import org.ofbiz.entity.condition.EntityExpr;
49 import org.ofbiz.entity.condition.EntityOperator;
50 import org.ofbiz.entity.condition.EntityConditionList;
51 import org.ofbiz.manufacturing.bom.BOMTree;
52 import org.ofbiz.manufacturing.techdata.TechDataServices;
53 import org.ofbiz.product.config.ProductConfigWrapper;
54 import org.ofbiz.product.config.ProductConfigWrapper.ConfigOption;
55 import org.ofbiz.security.Security;
56 import org.ofbiz.service.DispatchContext;
57 import org.ofbiz.service.GenericServiceException;
58 import org.ofbiz.service.LocalDispatcher;
59 import org.ofbiz.service.ModelService;
60 import org.ofbiz.service.ServiceUtil;
61
62 /**
63  * Services for Production Run maintenance
64  *
65  * @author <a HREF="mailto:olivier.heintz@nereide.biz">Olivier Heintz</a>
66  */

67 public class ProductionRunServices {
68     
69     public static final String JavaDoc module = ProductionRunServices.class.getName();
70     public static final String JavaDoc resource = "ManufacturingUiLabels";
71     
72     private static BigDecimal JavaDoc ZERO = new BigDecimal JavaDoc("0");
73     private static BigDecimal JavaDoc ONE = new BigDecimal JavaDoc("1");
74     private static int decimals = -1;
75     private static int rounding = -1;
76     static {
77         decimals = UtilNumber.getBigDecimalScale("order.decimals");
78         rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding");
79         // set zero to the proper scale
80
ZERO.setScale(decimals);
81         ONE.setScale(decimals);
82     }
83
84     /**
85      * Cancels a ProductionRun.
86      * @param ctx The DispatchContext that this service is operating in.
87      * @param context Map containing the input parameters.
88      * @return Map with the result of the service, the output parameters.
89      */

90     public static Map JavaDoc cancelProductionRun(DispatchContext ctx, Map JavaDoc context) {
91         Map JavaDoc result = new HashMap JavaDoc();
92         GenericDelegator delegator = ctx.getDelegator();
93         LocalDispatcher dispatcher = ctx.getDispatcher();
94         Security security = ctx.getSecurity();
95         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
96         GenericValue userLogin = (GenericValue) context.get("userLogin");
97         
98         String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
99         
100         ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
101         if (!productionRun.exist()){
102             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
103         }
104         String JavaDoc currentStatusId = productionRun.getGenericValue().getString("currentStatusId");
105
106         // PRUN_CREATED, PRUN_DOC_PRINTED --> PRUN_CANCELLED
107
if (currentStatusId.equals("PRUN_CREATED") || currentStatusId.equals("PRUN_DOC_PRINTED")) {
108             try {
109                 // First of all, make sure that there aren't production runs that depend on this one.
110
List JavaDoc mandatoryWorkEfforts = new ArrayList JavaDoc();
111                 ProductionRunHelper.getLinkedProductionRuns(delegator, dispatcher, productionRunId, mandatoryWorkEfforts);
112                 for (int i = 1; i < mandatoryWorkEfforts.size(); i++) {
113                     GenericValue mandatoryWorkEffort = ((ProductionRun)mandatoryWorkEfforts.get(i)).getGenericValue();
114                     if (!(mandatoryWorkEffort.getString("currentStatusId").equals("PRUN_CANCELLED"))) {
115                         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChangedMandatoryProductionRunFound", locale));
116                     }
117                 }
118                 Map JavaDoc serviceContext = new HashMap JavaDoc();
119                 // change the production run (header) status to PRUN_CANCELLED
120
serviceContext.put("workEffortId", productionRunId);
121                 serviceContext.put("currentStatusId", "PRUN_CANCELLED");
122                 serviceContext.put("userLogin", userLogin);
123                 Map JavaDoc resultService = null;
124                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
125                 // change the tasks status to PRUN_CANCELLED
126
List JavaDoc tasks = productionRun.getProductionRunRoutingTasks();
127                 GenericValue oneTask = null;
128                 String JavaDoc taskId = null;
129                 for (int i = 0; i < tasks.size(); i++) {
130                     oneTask = (GenericValue)tasks.get(i);
131                     taskId = oneTask.getString("workEffortId");
132                     serviceContext.clear();
133                     serviceContext.put("workEffortId", taskId);
134                     serviceContext.put("currentStatusId", "PRUN_CANCELLED");
135                     serviceContext.put("userLogin", userLogin);
136                     resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
137                 }
138             } catch (Exception JavaDoc e) {
139                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
140                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
141             }
142             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
143             return result;
144         }
145         return ServiceUtil.returnError("Cannot cancel productionRun, not in a valid status");
146     }
147     
148     /**
149      * Creates a Production Run.
150      * <li> check if routing - product link exist
151      * <li> check if product have a Bill Of Material
152      * <li> check if routing have routingTask
153      * <li> create the workEffort for ProductionRun
154      * <li> create the WorkEffortGoodStandard for link between ProductionRun and the product it will produce
155      * <li> for each valid routingTask of the routing create a workeffort-task
156      * <li> for the first routingTask, create for all the valid productIdTo with no associateRoutingTask a WorkEffortGoodStandard
157      * <li> for each valid routingTask of the routing and valid productIdTo associate with this RoutingTask create a WorkEffortGoodStandard
158      * @param ctx The DispatchContext that this service is operating in.
159      * @param context Map containing the input parameters, productId, routingId, pRQuantity, startDate, workEffortName, description
160      * @return Map with the result of the service, the output parameters.
161      */

162     public static Map JavaDoc createProductionRun(DispatchContext ctx, Map JavaDoc context) {
163         Map JavaDoc result = new HashMap JavaDoc();
164         GenericDelegator delegator = ctx.getDelegator();
165         LocalDispatcher dispatcher = ctx.getDispatcher();
166         Security security = ctx.getSecurity();
167         Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
168         List JavaDoc msgResult = new LinkedList JavaDoc();
169         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
170         GenericValue userLogin = (GenericValue) context.get("userLogin");
171         /* TODO: security management and finishing cleaning (ex copy from PartyServices.java)
172         if (!security.hasEntityPermission(secEntity, secOperation, userLogin)) {
173             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
174             result.put(ModelService.ERROR_MESSAGE, "You do not have permission to perform this operation for this party");
175             return partyId;
176         }
177          */

178         // Mandatory input fields
179
String JavaDoc productId = (String JavaDoc) context.get("productId");
180         Timestamp JavaDoc startDate = (Timestamp JavaDoc) context.get("startDate");
181         Double JavaDoc pRQuantity = (Double JavaDoc) context.get("pRQuantity");
182         String JavaDoc facilityId = (String JavaDoc) context.get("facilityId");
183         // Optional input fields
184
String JavaDoc workEffortId = (String JavaDoc) context.get("routingId");
185         String JavaDoc workEffortName = (String JavaDoc) context.get("workEffortName");
186         String JavaDoc description = (String JavaDoc) context.get("description");
187         
188         GenericValue routing = null;
189         GenericValue product = null;
190         List JavaDoc workEffortProducts = null;
191         List JavaDoc productBoms = null;
192         List JavaDoc routingTaskAssocs = null;
193         try {
194             // Find the product
195
product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
196             if (product == null) {
197                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductNotExists", locale));
198             }
199         } catch (GenericEntityException e) {
200             Debug.logWarning(e.getMessage(), module);
201             return ServiceUtil.returnError(e.getMessage());
202         }
203         
204         // -------------------
205
// Components
206
// -------------------
207
// The components are retrieved using the getManufacturingComponents service
208
// (that performs a bom breakdown and if needed runs the configurator).
209
List JavaDoc components = null;
210         Map JavaDoc serviceContext = new HashMap JavaDoc();
211         serviceContext.put("productId", productId); // the product that we want to manufacture
212
serviceContext.put("quantity", pRQuantity); // the quantity that we want to manufacture
213
serviceContext.put("userLogin", userLogin);
214         Map JavaDoc resultService = null;
215         try {
216             resultService = dispatcher.runSync("getManufacturingComponents", serviceContext);
217             components = (List JavaDoc)resultService.get("components"); // a list of objects representing the product's components
218
if (workEffortId == null) {
219                 workEffortId = (String JavaDoc)resultService.get("workEffortId"); // the product routing id
220
}
221         } catch (GenericServiceException e) {
222             Debug.logError(e, "Problem calling the getManufacturingComponents service", module);
223             return ServiceUtil.returnError(e.getMessage());
224         }
225         
226         // -------------------
227
// Routing and routing tasks
228
// -------------------
229
// Select the product's routing
230
try {
231             Map JavaDoc routingInMap = UtilMisc.toMap("productId", productId, "userLogin", userLogin);
232             Map JavaDoc routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
233             routing = (GenericValue)routingOutMap.get("routing");
234             routingTaskAssocs = (List JavaDoc)routingOutMap.get("tasks");
235         } catch(GenericServiceException gse) {
236             Debug.logWarning(gse.getMessage(), module);
237         }
238         // =================================
239
if (routing == null) {
240             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductRoutingNotExist", locale));
241         }
242         if (routingTaskAssocs == null || routingTaskAssocs.size()==0) {
243             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingHasNoRoutingTask", locale));
244         }
245         
246         // ProductionRun header creation,
247
if (workEffortName == null) {
248             String JavaDoc prdName = UtilValidate.isNotEmpty(product.getString("productName"))? product.getString("productName"): product.getString("productId");
249             String JavaDoc wefName = UtilValidate.isNotEmpty(routing.getString("workEffortName"))? routing.getString("workEffortName"): routing.getString("workEffortId");
250             workEffortName = prdName + "-" + wefName;
251         }
252         
253         serviceContext.clear();
254         serviceContext.put("workEffortTypeId", "PROD_ORDER_HEADER");
255         serviceContext.put("workEffortPurposeTypeId", "WEPT_PRODUCTION_RUN");
256         serviceContext.put("currentStatusId", "PRUN_CREATED");
257         serviceContext.put("workEffortName", workEffortName);
258         serviceContext.put("description",description);
259         serviceContext.put("facilityId", facilityId);
260         serviceContext.put("estimatedStartDate",startDate);
261         serviceContext.put("quantityToProduce", pRQuantity);
262         serviceContext.put("userLogin", userLogin);
263         try {
264             resultService = dispatcher.runSync("createWorkEffort", serviceContext);
265         } catch (GenericServiceException e) {
266             Debug.logError(e, "Problem calling the createWorkEffort service", module);
267             return ServiceUtil.returnError(e.getMessage());
268         }
269         String JavaDoc productionRunId = (String JavaDoc) resultService.get("workEffortId");
270         if (Debug.infoOn()) {
271             Debug.logInfo("ProductionRun created: " + productionRunId, module);
272         }
273         
274         // ProductionRun, product will be produce creation = WorkEffortGoodStandard for the productId
275
serviceContext.clear();
276         serviceContext.put("workEffortId", productionRunId);
277         serviceContext.put("productId", productId);
278         serviceContext.put("workEffortGoodStdTypeId", "PRUN_PROD_DELIV");
279         serviceContext.put("statusId", "WEGS_CREATED");
280         serviceContext.put("estimatedQuantity", pRQuantity);
281         serviceContext.put("fromDate", startDate);
282         serviceContext.put("userLogin", userLogin);
283         try {
284             resultService = dispatcher.runSync("createWorkEffortGoodStandard", serviceContext);
285         } catch (GenericServiceException e) {
286             Debug.logError(e, "Problem calling the createWorkEffortGoodStandard service", module);
287             return ServiceUtil.returnError(e.getMessage());
288         }
289         
290         // Multi creation (like clone) ProductionRunTask and GoodAssoc
291
Iterator JavaDoc rt = routingTaskAssocs.iterator();
292         boolean first = true;
293         while (rt.hasNext()) {
294             GenericValue routingTaskAssoc = (GenericValue) rt.next();
295             if (TechDataServices.routingTaskAssocIsValid(routingTaskAssoc, startDate)) {
296                 GenericValue routingTask = null;
297                 try {
298                     routingTask = routingTaskAssoc.getRelatedOne("ToWorkEffort");
299                 } catch (GenericEntityException e) {
300                     Debug.logError(e.getMessage(), module);
301                 }
302                 // Calculate the estimatedCompletionDate
303
long totalTime = ProductionRun.getEstimatedTaskTime(routingTask, pRQuantity, dispatcher);
304                 Timestamp JavaDoc endDate = TechDataServices.addForward(TechDataServices.getTechDataCalendar(routingTask),startDate, totalTime);
305                 
306                 serviceContext.clear();
307                 serviceContext.put("priority", routingTaskAssoc.get("sequenceNum"));
308                 serviceContext.put("workEffortPurposeTypeId", routingTask.get("workEffortPurposeTypeId"));
309                 serviceContext.put("workEffortName",routingTask.get("workEffortName"));
310                 serviceContext.put("description",routingTask.get("description"));
311                 serviceContext.put("fixedAssetId",routingTask.get("fixedAssetId"));
312                 serviceContext.put("workEffortTypeId", "PROD_ORDER_TASK");
313                 serviceContext.put("currentStatusId","PRUN_CREATED");
314                 serviceContext.put("workEffortParentId", productionRunId);
315                 serviceContext.put("facilityId", facilityId);
316                 serviceContext.put("estimatedStartDate",startDate);
317                 serviceContext.put("estimatedCompletionDate",endDate);
318                 serviceContext.put("estimatedSetupMillis", routingTask.get("estimatedSetupMillis"));
319                 serviceContext.put("estimatedMilliSeconds", routingTask.get("estimatedMilliSeconds"));
320                 serviceContext.put("quantityToProduce", pRQuantity);
321                 serviceContext.put("userLogin", userLogin);
322                 resultService = null;
323                 try {
324                     resultService = dispatcher.runSync("createWorkEffort", serviceContext);
325                 } catch (GenericServiceException e) {
326                     Debug.logError(e, "Problem calling the createWorkEffort service", module);
327                 }
328                 String JavaDoc productionRunTaskId = (String JavaDoc) resultService.get("workEffortId");
329                 if (Debug.infoOn()) Debug.logInfo("ProductionRunTaskId created: " + productionRunTaskId, module);
330                 // The newly created production run task is associated to the routing task
331
// to keep track of the template used to generate it.
332
serviceContext.clear();
333                 serviceContext.put("userLogin", userLogin);
334                 serviceContext.put("workEffortIdFrom", routingTask.getString("workEffortId"));
335                 serviceContext.put("workEffortIdTo", productionRunTaskId);
336                 serviceContext.put("workEffortAssocTypeId", "WORK_EFF_TEMPLATE");
337                 try {
338                     resultService = dispatcher.runSync("createWorkEffortAssoc", serviceContext);
339                 } catch (GenericServiceException e) {
340                     Debug.logError(e, "Problem calling the createWorkEffortAssoc service", module);
341                 }
342                 // copy date valid WorkEffortPartyAssignments from the routing task to the run task
343
List JavaDoc workEffortPartyAssignments = null;
344                 try {
345                     workEffortPartyAssignments = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortPartyAssignment",
346                             UtilMisc.toMap("workEffortId", routingTaskAssoc.getString("workEffortIdTo"))));
347                 } catch (GenericEntityException e) {
348                     Debug.logError(e.getMessage(), module);
349                 }
350                 if (workEffortPartyAssignments != null) {
351                     Iterator JavaDoc i = workEffortPartyAssignments.iterator();
352                     while(i.hasNext()) {
353                         GenericValue workEffortPartyAssignment = (GenericValue) i.next();
354                         Map JavaDoc partyToWorkEffort = UtilMisc.toMap(
355                                 "workEffortId", productionRunTaskId,
356                                 "partyId", workEffortPartyAssignment.getString("partyId"),
357                                 "roleTypeId", workEffortPartyAssignment.getString("roleTypeId"),
358                                 "fromDate", workEffortPartyAssignment.getTimestamp("fromDate"),
359                                 "statusId", workEffortPartyAssignment.getString("statusId"),
360                                 "userLogin", userLogin
361                         );
362                         try {
363                             resultService = dispatcher.runSync("assignPartyToWorkEffort", partyToWorkEffort);
364                         } catch (GenericServiceException e) {
365                             Debug.logError(e, "Problem calling the assignPartyToWorkEffort service", module);
366                         }
367                         if (Debug.infoOn()) Debug.logInfo("ProductionRunPartyassigment for party: " + workEffortPartyAssignment.get("partyId") + " created", module);
368                     }
369                 }
370
371                 // Now we iterate thru the components returned by the getManufacturingComponents service
372
// TODO: if in the BOM a routingWorkEffortId is specified, but the task is not in the routing
373
// the component is not added to the production run.
374
Iterator JavaDoc pb = components.iterator();
375                 while (pb.hasNext()) {
376                     // The components variable contains a list of BOMNodes:
377
// each node represents a product (component).
378
org.ofbiz.manufacturing.bom.BOMNode node = (org.ofbiz.manufacturing.bom.BOMNode) pb.next();
379                     GenericValue productBom = node.getProductAssoc();
380                     if ((productBom.getString("routingWorkEffortId") == null && first) || (productBom.getString("routingWorkEffortId") != null && productBom.getString("routingWorkEffortId").equals(routingTask.getString("workEffortId")))) {
381                         serviceContext.clear();
382                         serviceContext.put("workEffortId", productionRunTaskId);
383                         // Here we get the ProductAssoc record from the BOMNode
384
// object to be sure to use the
385
// right component (possibly configured).
386
serviceContext.put("productId", node.getProduct().get("productId"));
387                         serviceContext.put("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED");
388                         serviceContext.put("statusId", "WEGS_CREATED");
389                         serviceContext.put("fromDate", productBom.get("fromDate"));
390                         // Here we use the getQuantity method to get the quantity already
391
// computed by the getManufacturingComponents service
392
//double scrapFactor = (productBom.get("scrapFactor") != null)? productBom.getDouble("scrapFactor").doubleValue() : 0;
393
//serviceContext.put("estimatedQuantity", new Double(Math.floor((productBom.getDouble("quantity").doubleValue() * pRQuantity.doubleValue() / (1-(scrapFactor / 100))) + 0.5)));
394
serviceContext.put("estimatedQuantity", new Double JavaDoc(node.getQuantity()));
395                         serviceContext.put("userLogin", userLogin);
396                         resultService = null;
397                         try {
398                             resultService = dispatcher.runSync("createWorkEffortGoodStandard", serviceContext);
399                         } catch (GenericServiceException e) {
400                             Debug.logError(e, "Problem calling the createWorkEffortGoodStandard service", module);
401                         }
402                         if (Debug.infoOn()) Debug.logInfo("ProductLink created for productId: " + productBom.getString("productIdTo"), module);
403                     }
404                 }
405                 first = false;
406                 startDate = endDate;
407             }
408         }
409         
410         // update the estimatedCompletionDate field for the productionRun
411
serviceContext.clear();
412         serviceContext.put("workEffortId",productionRunId);
413         serviceContext.put("estimatedCompletionDate",startDate);
414         serviceContext.put("userLogin", userLogin);
415         resultService = null;
416         try {
417             resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
418         } catch (GenericServiceException e) {
419             Debug.logError(e, "Problem calling the updateWorkEffort service", module);
420         }
421         result.put("productionRunId", productionRunId);
422         result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunCreated",UtilMisc.toMap("productionRunId", productionRunId), locale));
423         return result;
424     }
425     /**
426      * Update a Production Run.
427      * <li> update field and after recalculate the entire ProductionRun data (routingTask and productComponent)
428      * <li> create the WorkEffortGoodStandard for link between ProductionRun and the product it will produce
429      * <li> for each valid routingTask of the routing create a workeffort-task
430      * <li> for the first routingTask, create for all the valid productIdTo with no associateRoutingTask a WorkEffortGoodStandard
431      * <li> for each valid routingTask of the routing and valid productIdTo associate with this RoutingTask create a WorkEffortGoodStandard
432      * @param ctx The DispatchContext that this service is operating in.
433      * @param context Map containing the input parameters, productId, routingId, quantity, estimatedStartDate, workEffortName, description
434      * @return Map with the result of the service, the output parameters.
435      */

436     public static Map JavaDoc updateProductionRun(DispatchContext ctx, Map JavaDoc context) {
437         Map JavaDoc result = new HashMap JavaDoc();
438         GenericDelegator delegator = ctx.getDelegator();
439         LocalDispatcher dispatcher = ctx.getDispatcher();
440         Security security = ctx.getSecurity();
441         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
442         GenericValue userLogin = (GenericValue) context.get("userLogin");
443         /* TODO: security management and finishing cleaning (ex copy from PartyServices.java)
444         if (!security.hasEntityPermission(secEntity, secOperation, userLogin)) {
445             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
446             result.put(ModelService.ERROR_MESSAGE, "You do not have permission to perform this operation for this party");
447             return partyId;
448         }
449          */

450         String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
451         if (!UtilValidate.isEmpty(productionRunId)) {
452             ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
453             if (productionRun.exist()){
454                 
455                 if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
456                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunPrinted", locale));
457                 }
458
459                 Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
460                 if (quantity != null && ! quantity.equals(productionRun.getQuantity()))
461                     productionRun.setQuantity(quantity);
462                 
463                 Timestamp JavaDoc estimatedStartDate = (Timestamp JavaDoc) context.get("estimatedStartDate");
464                 if (estimatedStartDate != null && ! estimatedStartDate.equals(productionRun.getEstimatedStartDate()))
465                     productionRun.setEstimatedStartDate(estimatedStartDate);
466                 
467                 String JavaDoc workEffortName = (String JavaDoc) context.get("workEffortName");
468                 if (workEffortName != null) productionRun.setProductionRunName(workEffortName);
469                 
470                 String JavaDoc description = (String JavaDoc) context.get("description");
471                 if (description != null) productionRun.setDescription(description);
472                 
473                 String JavaDoc facilityId = (String JavaDoc) context.get("facilityId");
474                 if (facilityId != null) productionRun.getGenericValue().set("facilityId", facilityId);
475
476                 if (productionRun.store()) return ServiceUtil.returnSuccess();
477                 else {
478                     Debug.logError("productionRun.store() fail for productionRunId ="+productionRunId,module);
479                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
480                 }
481             }
482             Debug.logError("no productionRun for productionRunId ="+productionRunId,module);
483             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
484         }
485         Debug.logError("service updateProductionRun call with productionRunId empty",module);
486         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
487     }
488     
489     public static Map JavaDoc changeProductionRunStatus(DispatchContext ctx, Map JavaDoc context) {
490         Map JavaDoc result = new HashMap JavaDoc();
491         GenericDelegator delegator = ctx.getDelegator();
492         LocalDispatcher dispatcher = ctx.getDispatcher();
493         Security security = ctx.getSecurity();
494         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
495         GenericValue userLogin = (GenericValue) context.get("userLogin");
496         
497         String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
498         String JavaDoc statusId = (String JavaDoc) context.get("statusId");
499         
500         ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
501         if (!productionRun.exist()){
502             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
503         }
504         String JavaDoc currentStatusId = productionRun.getGenericValue().getString("currentStatusId");
505         
506         if (statusId != null && currentStatusId.equals(statusId)) {
507             result.put("newStatusId", currentStatusId);
508             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", currentStatusId), locale));
509             return result;
510         }
511         
512         // PRUN_CREATED --> PRUN_DOC_PRINTED
513
if (currentStatusId.equals("PRUN_CREATED") && (statusId == null || statusId.equals("PRUN_DOC_PRINTED"))) {
514             // change only the production run (header) status to PRUN_DOC_PRINTED
515
Map JavaDoc serviceContext = new HashMap JavaDoc();
516             serviceContext.clear();
517             serviceContext.put("workEffortId", productionRunId);
518             serviceContext.put("currentStatusId", "PRUN_DOC_PRINTED");
519             serviceContext.put("userLogin", userLogin);
520             Map JavaDoc resultService = null;
521             try {
522                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
523             } catch (GenericServiceException e) {
524                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
525                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
526             }
527             result.put("newStatusId", "PRUN_DOC_PRINTED");
528             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
529             return result;
530         }
531         
532         // PRUN_DOC_PRINTED --> PRUN_RUNNING
533
// this should be called only when the first task is started
534
if (currentStatusId.equals("PRUN_DOC_PRINTED") && (statusId == null || statusId.equals("PRUN_RUNNING"))) {
535             // change only the production run (header) status to PRUN_RUNNING
536
// First check if there are production runs with precedence not still completed
537
try {
538                 List JavaDoc mandatoryWorkEfforts = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc", UtilMisc.toMap("workEffortIdTo", productionRunId, "workEffortAssocTypeId", "WORK_EFF_PRECEDENCY")));
539                 for (int i = 0; i < mandatoryWorkEfforts.size(); i++) {
540                     GenericValue mandatoryWorkEffortAssoc = (GenericValue)mandatoryWorkEfforts.get(i);
541                     GenericValue mandatoryWorkEffort = mandatoryWorkEffortAssoc.getRelatedOne("FromWorkEffort");
542                     if (!(mandatoryWorkEffort.getString("currentStatusId").equals("PRUN_COMPLETED") ||
543                          mandatoryWorkEffort.getString("currentStatusId").equals("PRUN_CLOSED"))) {
544                         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChangedMandatoryProductionRunNotCompleted", locale));
545                     }
546                 }
547             } catch(GenericEntityException gee) {
548                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
549             }
550
551             Map JavaDoc serviceContext = new HashMap JavaDoc();
552             serviceContext.clear();
553             serviceContext.put("workEffortId", productionRunId);
554             serviceContext.put("currentStatusId", "PRUN_RUNNING");
555             serviceContext.put("actualStartDate", UtilDateTime.nowTimestamp());
556             serviceContext.put("userLogin", userLogin);
557             Map JavaDoc resultService = null;
558             try {
559                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
560             } catch (GenericServiceException e) {
561                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
562                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
563             }
564             result.put("newStatusId", "PRUN_RUNNING");
565             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
566             return result;
567         }
568         
569         // PRUN_RUNNING --> PRUN_COMPLETED
570
// this should be called only when the last task is completed
571
if (currentStatusId.equals("PRUN_RUNNING") && (statusId == null || statusId.equals("PRUN_COMPLETED"))) {
572             // change only the production run (header) status to PRUN_COMPLETED
573
Map JavaDoc serviceContext = new HashMap JavaDoc();
574             serviceContext.clear();
575             serviceContext.put("workEffortId", productionRunId);
576             serviceContext.put("currentStatusId", "PRUN_COMPLETED");
577             serviceContext.put("actualCompletionDate", UtilDateTime.nowTimestamp());
578             serviceContext.put("userLogin", userLogin);
579             Map JavaDoc resultService = null;
580             try {
581                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
582             } catch (GenericServiceException e) {
583                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
584                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
585             }
586             result.put("newStatusId", "PRUN_COMPLETED");
587             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
588             return result;
589         }
590         
591         // PRUN_COMPLETED --> PRUN_CLOSED
592
if (currentStatusId.equals("PRUN_COMPLETED") && (statusId == null || statusId.equals("PRUN_CLOSED"))) {
593             // change the production run status to PRUN_CLOSED
594
Map JavaDoc serviceContext = new HashMap JavaDoc();
595             serviceContext.clear();
596             serviceContext.put("workEffortId", productionRunId);
597             serviceContext.put("currentStatusId", "PRUN_CLOSED");
598             serviceContext.put("userLogin", userLogin);
599             Map JavaDoc resultService = null;
600             try {
601                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
602             } catch (GenericServiceException e) {
603                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
604                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
605             }
606             // change the production run tasks status to PRUN_CLOSED
607
Iterator JavaDoc tasks = productionRun.getProductionRunRoutingTasks().iterator();
608             while (tasks.hasNext()) {
609                 GenericValue task = (GenericValue)tasks.next();
610                 serviceContext.clear();
611                 serviceContext.put("workEffortId", task.getString("workEffortId"));
612                 serviceContext.put("currentStatusId", "PRUN_CLOSED");
613                 serviceContext.put("userLogin", userLogin);
614                 resultService = null;
615                 try {
616                     resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
617                 } catch (GenericServiceException e) {
618                     Debug.logError(e, "Problem calling the updateWorkEffort service", module);
619                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
620                 }
621             }
622             result.put("newStatusId", "PRUN_CLOSED");
623             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_CLOSED"), locale));
624             return result;
625         }
626         result.put("newStatusId", currentStatusId);
627         result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", currentStatusId), locale));
628         return result;
629     }
630
631     public static Map JavaDoc changeProductionRunTaskStatus(DispatchContext ctx, Map JavaDoc context) {
632         Map JavaDoc result = new HashMap JavaDoc();
633         GenericDelegator delegator = ctx.getDelegator();
634         LocalDispatcher dispatcher = ctx.getDispatcher();
635         Security security = ctx.getSecurity();
636         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
637         GenericValue userLogin = (GenericValue) context.get("userLogin");
638         
639         String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
640         String JavaDoc taskId = (String JavaDoc) context.get("workEffortId");
641         String JavaDoc statusId = (String JavaDoc) context.get("statusId");
642         Boolean JavaDoc issueAllComponents = (Boolean JavaDoc) context.get("issueAllComponents");
643         if (issueAllComponents == null) {
644             issueAllComponents = new Boolean JavaDoc(false);
645         }
646         
647         ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
648         if (!productionRun.exist()){
649             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
650         }
651         List JavaDoc tasks = productionRun.getProductionRunRoutingTasks();
652         GenericValue theTask = null;
653         GenericValue oneTask = null;
654         boolean allTaskCompleted = true;
655         boolean allPrecTaskCompleted = true;
656         for (int i = 0; i < tasks.size(); i++) {
657             oneTask = (GenericValue)tasks.get(i);
658             if (oneTask.getString("workEffortId").equals(taskId)) {
659                 theTask = oneTask;
660             } else {
661                 if (theTask == null && allPrecTaskCompleted && !oneTask.getString("currentStatusId").equals("PRUN_COMPLETED")) {
662                     allPrecTaskCompleted = false;
663                 }
664                 if (allTaskCompleted && !oneTask.getString("currentStatusId").equals("PRUN_COMPLETED")) {
665                     allTaskCompleted = false;
666                 }
667             }
668         }
669         if (theTask == null) {
670             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
671         }
672         
673         String JavaDoc currentStatusId = theTask.getString("currentStatusId");
674         
675         if (statusId != null && currentStatusId.equals(statusId)) {
676             result.put("newStatusId", currentStatusId);
677             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskStatusChanged",UtilMisc.toMap("newStatusId", currentStatusId), locale));
678             return result;
679         }
680         
681         // PRUN_CREATED --> PRUN_RUNNING
682
// this should be called only when the first task is started
683
if (currentStatusId.equals("PRUN_CREATED") && (statusId == null || statusId.equals("PRUN_RUNNING"))) {
684             // change the production run task status to PRUN_RUNNING
685
// if necessary change the production run (header) status to PRUN_RUNNING
686
if (!allPrecTaskCompleted) {
687                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskCannotStartPrevTasksNotCompleted", locale));
688             }
689             if (productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
690                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskCannotStartDocsNotPrinted", locale));
691             }
692             Map JavaDoc serviceContext = new HashMap JavaDoc();
693             serviceContext.clear();
694             serviceContext.put("workEffortId", taskId);
695             serviceContext.put("currentStatusId", "PRUN_RUNNING");
696             serviceContext.put("actualStartDate", UtilDateTime.nowTimestamp());
697             serviceContext.put("userLogin", userLogin);
698             Map JavaDoc resultService = null;
699             try {
700                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
701             } catch (GenericServiceException e) {
702                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
703                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
704             }
705             if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_RUNNING")) {
706                 serviceContext.clear();
707                 serviceContext.put("productionRunId", productionRunId);
708                 serviceContext.put("statusId", "PRUN_RUNNING");
709                 serviceContext.put("userLogin", userLogin);
710                 resultService = null;
711                 try {
712                     resultService = dispatcher.runSync("changeProductionRunStatus", serviceContext);
713                 } catch (GenericServiceException e) {
714                     Debug.logError(e, "Problem calling the changeProductionRunStatus service", module);
715                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
716                 }
717             }
718             result.put("newStatusId", "PRUN_RUNNING");
719             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
720             return result;
721         }
722         
723         // PRUN_RUNNING --> PRUN_COMPLETED
724
// this should be called only when the last task is completed
725
if (currentStatusId.equals("PRUN_RUNNING") && (statusId == null || statusId.equals("PRUN_COMPLETED"))) {
726             Map JavaDoc serviceContext = new HashMap JavaDoc();
727             Map JavaDoc resultService = null;
728             if (issueAllComponents.booleanValue()) {
729                 // Issue all the components, if this task needs components and they still need to be issued
730
try {
731                     List JavaDoc inventoryAssigned = delegator.findByAnd("WorkEffortInventoryAssign", UtilMisc.toMap("workEffortId", taskId));
732                     if (UtilValidate.isEmpty(inventoryAssigned)) {
733                         serviceContext.clear();
734                         serviceContext.put("workEffortId", taskId);
735                         serviceContext.put("userLogin", userLogin);
736                         resultService = dispatcher.runSync("issueProductionRunTask", serviceContext);
737                     }
738                 } catch (Exception JavaDoc e) {
739                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
740                 }
741             }
742             // change only the production run (header) status to PRUN_COMPLETED
743
serviceContext.clear();
744             serviceContext.put("workEffortId", taskId);
745             serviceContext.put("currentStatusId", "PRUN_COMPLETED");
746             serviceContext.put("actualCompletionDate", UtilDateTime.nowTimestamp());
747             Double JavaDoc quantityToProduce = theTask.getDouble("quantityToProduce");
748             if (quantityToProduce == null) {
749                 quantityToProduce = new Double JavaDoc(0);
750             }
751             Double JavaDoc quantityProduced = theTask.getDouble("quantityProduced");
752             if (quantityProduced == null) {
753                 quantityProduced = new Double JavaDoc(0);
754             }
755             Double JavaDoc quantityRejected = theTask.getDouble("quantityRejected");
756             if (quantityRejected == null) {
757                 quantityRejected = new Double JavaDoc(0);
758             }
759             double totalQuantity = quantityProduced.doubleValue() + quantityRejected.doubleValue();
760             double diffQuantity = quantityToProduce.doubleValue() - totalQuantity;
761             if (diffQuantity > 0) {
762                 quantityProduced = new Double JavaDoc(quantityProduced.doubleValue() + diffQuantity);
763             }
764             serviceContext.put("quantityProduced", quantityProduced);
765             if (theTask.get("actualSetupMillis") == null) {
766                 serviceContext.put("actualSetupMillis", theTask.get("estimatedSetupMillis"));
767             }
768             if (theTask.get("actualMilliSeconds") == null) {
769                 Double JavaDoc autoMillis = null;
770                 if (theTask.get("estimatedMilliSeconds") != null) {
771                     autoMillis = new Double JavaDoc(quantityProduced.doubleValue() * theTask.getDouble("estimatedMilliSeconds").doubleValue());
772                 }
773                 serviceContext.put("actualMilliSeconds", autoMillis);
774             }
775             serviceContext.put("userLogin", userLogin);
776             try {
777                 resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
778             } catch (GenericServiceException e) {
779                 Debug.logError(e, "Problem calling the updateWorkEffort service", module);
780                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
781             }
782             // If this is the last task, then the production run is marked as 'completed'
783
if (allTaskCompleted) {
784                 serviceContext.clear();
785                 serviceContext.put("productionRunId", productionRunId);
786                 serviceContext.put("statusId", "PRUN_COMPLETED");
787                 serviceContext.put("userLogin", userLogin);
788                 resultService = null;
789                 try {
790                     resultService = dispatcher.runSync("changeProductionRunStatus", serviceContext);
791                 } catch (GenericServiceException e) {
792                     Debug.logError(e, "Problem calling the updateWorkEffort service", module);
793                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
794                 }
795             }
796             result.put("newStatusId", "PRUN_COMPLETED");
797             result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
798             return result;
799         }
800         result.put("newStatusId", currentStatusId);
801         result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskStatusChanged",UtilMisc.toMap("newStatusId", currentStatusId), locale));
802         return result;
803     }
804
805     public static Map JavaDoc getWorkEffortCosts(DispatchContext ctx, Map JavaDoc context) {
806         Map JavaDoc result = new HashMap JavaDoc();
807         GenericDelegator delegator = ctx.getDelegator();
808         LocalDispatcher dispatcher = ctx.getDispatcher();
809         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
810         GenericValue userLogin = (GenericValue) context.get("userLogin");
811         String JavaDoc workEffortId = (String JavaDoc)context.get("workEffortId");
812         try {
813             GenericValue workEffort = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId));
814             if (workEffort == null) {
815                 return ServiceUtil.returnError("Cannot find work effort [" + workEffortId + "]");
816             }
817             // Get all the valid CostComponents entries
818
List JavaDoc costComponents = EntityUtil.filterByDate(delegator.findByAnd("CostComponent",
819                                                           UtilMisc.toMap("workEffortId", workEffortId)));
820             result.put("costComponents", costComponents);
821             Iterator JavaDoc costComponentsIt = costComponents.iterator();
822             // TODO: before doing these totals we should convert the cost components' costs to the
823
// base currency uom of the owner of the facility in which the task is running
824
BigDecimal JavaDoc totalCost = ZERO;
825             BigDecimal JavaDoc totalCostNoMaterials = ZERO;
826             while (costComponentsIt.hasNext()) {
827                 GenericValue costComponent = (GenericValue)costComponentsIt.next();
828                 BigDecimal JavaDoc cost = costComponent.getBigDecimal("cost");
829                 totalCost = totalCost.add(cost);
830                 if (!"ACTUAL_MAT_COST".equals(costComponent.getString("costComponentTypeId"))) {
831                     totalCostNoMaterials = totalCostNoMaterials.add(cost);
832                 }
833             }
834             result.put("totalCost", totalCost);
835             result.put("totalCostNoMaterials", totalCostNoMaterials);
836         } catch(GenericEntityException gee) {
837             return ServiceUtil.returnError("Cannot retrieve costs for work effort [" + workEffortId + "]: " + gee.getMessage());
838         }
839         return result;
840     }
841
842     public static Map JavaDoc getProductionRunCost(DispatchContext ctx, Map JavaDoc context) {
843         Map JavaDoc result = new HashMap JavaDoc();
844         GenericDelegator delegator = ctx.getDelegator();
845         LocalDispatcher dispatcher = ctx.getDispatcher();
846         GenericValue userLogin = (GenericValue) context.get("userLogin");
847         String JavaDoc workEffortId = (String JavaDoc)context.get("workEffortId");
848         try {
849             List JavaDoc tasks = delegator.findByAnd("WorkEffort", UtilMisc.toMap("workEffortParentId", workEffortId), UtilMisc.toList("workEffortId"));
850             Iterator JavaDoc tasksIt = tasks.iterator();
851             BigDecimal JavaDoc totalCost = ZERO;
852             while (tasksIt.hasNext()) {
853                 GenericValue task = (GenericValue)tasksIt.next();
854                 Map JavaDoc outputMap = dispatcher.runSync("getWorkEffortCosts", UtilMisc.toMap("userLogin", userLogin, "workEffortId", task.getString("workEffortId")));
855                 BigDecimal JavaDoc taskCost = (BigDecimal JavaDoc)outputMap.get("totalCost");
856                 totalCost = totalCost.add(taskCost);
857             }
858             result.put("totalCost", totalCost);
859         } catch(Exception JavaDoc exc) {
860             return ServiceUtil.returnError("Cannot retrieve costs for production run [" + workEffortId + "]: " + exc.getMessage());
861         }
862         return result;
863     }
864
865     /**
866      * check if field for routingTask update are correct and if need recalculated data in Production Run.
867      * Check<ul>
868      * <li> if estimatedStartDate is not before Production Run estimatedStartDate.</ul>
869      * <li> if there is not a another routingTask with the same priority
870      * If priority or estimatedStartDate has changed recalculated data for routingTask after that one.
871      * <br/> update the productionRun
872      * @param ctx The DispatchContext that this service is operating in.
873      * @param context Map containing the input parameters, productId, routingId, priority, estimatedStartDate, estimatedSetupMillis, estimatedMilliSeconds
874      * @return Map with the result of the service, the output parameters, estimatedCompletionDate.
875      */

876     public static Map JavaDoc checkUpdatePrunRoutingTask(DispatchContext ctx, Map JavaDoc context) {
877         Map JavaDoc result = new HashMap JavaDoc();
878         GenericDelegator delegator = ctx.getDelegator();
879         LocalDispatcher dispatcher = ctx.getDispatcher();
880         Security security = ctx.getSecurity();
881         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
882         GenericValue userLogin = (GenericValue) context.get("userLogin");
883         /* TODO: security management and finishing cleaning (ex copy from PartyServices.java)
884         if (!security.hasEntityPermission(secEntity, secOperation, userLogin)) {
885             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
886             result.put(ModelService.ERROR_MESSAGE, "You do not have permission to perform this operation for this party");
887             return partyId;
888         }
889          */

890         String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
891         String JavaDoc routingTaskId = (String JavaDoc) context.get("routingTaskId");
892         if (! UtilValidate.isEmpty(productionRunId) && ! UtilValidate.isEmpty(routingTaskId)) {
893             ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
894             if (productionRun.exist()){
895                 
896                 if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
897                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunPrinted", locale));
898                 }
899
900                 Timestamp JavaDoc estimatedStartDate = (Timestamp JavaDoc) context.get("estimatedStartDate");
901                 Timestamp JavaDoc pRestimatedStartDate = productionRun.getEstimatedStartDate();
902                 if (pRestimatedStartDate.after(estimatedStartDate)) {
903                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingTaskStartDateBeforePRun", locale));
904                 }
905                 
906                 Long JavaDoc priority = (Long JavaDoc) context.get("priority");
907                 List JavaDoc pRRoutingTasks = productionRun.getProductionRunRoutingTasks();
908                 boolean first = true;
909                 for (Iterator JavaDoc iter=pRRoutingTasks.iterator();iter.hasNext();){
910                     GenericValue routingTask = (GenericValue) iter.next();
911                     if (priority.equals(routingTask.get("priority")) && ! routingTaskId.equals(routingTask.get("workEffortId")))
912                         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingTaskSeqIdAlreadyExist", locale));
913                     if (routingTaskId.equals(routingTask.get("workEffortId"))){
914                         routingTask.set("estimatedSetupMillis", context.get("estimatedSetupMillis"));
915                         routingTask.set("estimatedMilliSeconds", context.get("estimatedMilliSeconds"));
916                         if (first){ // for the first routingTask the estimatedStartDate update imply estimatedStartDate productonRun update
917
if (! estimatedStartDate.equals(pRestimatedStartDate)){
918                                 productionRun.setEstimatedStartDate(estimatedStartDate);
919                             }
920                         }
921                         // the priority has been changed
922
if (! priority.equals(routingTask.get("priority"))){
923                             routingTask.set("priority", priority);
924                             // update the routingTask List and re-read it to be able to have it sorted with the new value
925
if ( ! productionRun.store()) {
926                                 Debug.logError("productionRun.store(), in routingTask.priority update, fail for productionRunId ="+productionRunId,module);
927                                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
928                             }
929                             productionRun.clearRoutingTasksList();
930                         }
931                     }
932                     if (first) first = false;
933                 }
934                 productionRun.setEstimatedCompletionDate(productionRun.recalculateEstimatedCompletionDate(priority, estimatedStartDate));
935                 
936                 if (productionRun.store()) {
937                     return ServiceUtil.returnSuccess();
938                 } else {
939                     Debug.logError("productionRun.store() fail for productionRunId ="+productionRunId,module);
940                     return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
941                 }
942             }
943             Debug.logError("no productionRun for productionRunId ="+productionRunId,module);
944             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
945         }
946         Debug.logError("service updateProductionRun call with productionRunId empty",module);
947         return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotUpdated", locale));
948     }
949     
950     public static Map JavaDoc addProductionRunComponent(DispatchContext ctx, Map JavaDoc context) {
951         Map JavaDoc result = new HashMap JavaDoc();
952         GenericDelegator delegator = ctx.getDelegator();
953         LocalDispatcher dispatcher = ctx.getDispatcher();
954         Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
955         List JavaDoc msgResult = new LinkedList JavaDoc();
956         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
957         GenericValue userLogin = (GenericValue) context.get("userLogin");
958         // Mandatory input fields
959
String JavaDoc productionRunId = (String JavaDoc)context.get("productionRunId");
960         String JavaDoc productId = (String JavaDoc)context.get("productId");
961         Double JavaDoc quantity = (Double JavaDoc) context.get("estimatedQuantity");
962         // Optional input fields
963
String JavaDoc workEffortId = (String JavaDoc)context.get("workEffortId");
964         
965         ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
966         List JavaDoc tasks = productionRun.getProductionRunRoutingTasks();
967         if (tasks == null || tasks.size() == 0){
968             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
969         }
970         
971         if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
972             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunPrinted", locale));
973         }
974
975         if (workEffortId != null) {
976             boolean found = false;
977             for (int i = 0; i < tasks.size(); i++) {
978                 GenericValue oneTask = (GenericValue)tasks.get(i);
979                 if (oneTask.getString("workEffortId").equals(workEffortId)) {
980                     found = true;
981                     break;
982                 }
983             }
984             if (!found) {
985                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
986             }
987         } else {
988             workEffortId = EntityUtil.getFirst(tasks).getString("workEffortId");
989         }
990         
991         try {
992             // Find the product
993
GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
994             if (product == null) {
995                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductNotExists", locale));
996             }
997         } catch (GenericEntityException e) {
998             Debug.logWarning(e.getMessage(), module);
999             return ServiceUtil.returnError(e.getMessage());
1000        }
1001        Map JavaDoc serviceContext = new HashMap JavaDoc();
1002        serviceContext.clear();
1003        serviceContext.put("workEffortId", workEffortId);
1004        serviceContext.put("productId", productId);
1005        serviceContext.put("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED");
1006        serviceContext.put("statusId", "WEGS_CREATED");
1007        serviceContext.put("fromDate", now);
1008        serviceContext.put("estimatedQuantity", quantity);
1009        serviceContext.put("userLogin", userLogin);
1010        Map JavaDoc resultService = null;
1011        try {
1012            resultService = dispatcher.runSync("createWorkEffortGoodStandard", serviceContext);
1013        } catch (GenericServiceException e) {
1014            Debug.logError(e, "Problem calling the createWorkEffortGoodStandard service", module);
1015            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunComponentNotAdded", locale));
1016        }
1017        result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunComponentAdded",UtilMisc.toMap("productionRunId", productionRunId), locale));
1018        return result;
1019    }
1020    
1021    public static Map JavaDoc updateProductionRunComponent(DispatchContext ctx, Map JavaDoc context) {
1022        Map JavaDoc result = new HashMap JavaDoc();
1023        GenericDelegator delegator = ctx.getDelegator();
1024        LocalDispatcher dispatcher = ctx.getDispatcher();
1025        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1026        List JavaDoc msgResult = new LinkedList JavaDoc();
1027        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1028        GenericValue userLogin = (GenericValue) context.get("userLogin");
1029        // Mandatory input fields
1030
String JavaDoc productionRunId = (String JavaDoc)context.get("productionRunId");
1031        String JavaDoc productId = (String JavaDoc)context.get("productId");
1032        // Optional input fields
1033
String JavaDoc workEffortId = (String JavaDoc)context.get("workEffortId"); // the production run task
1034
Double JavaDoc quantity = (Double JavaDoc) context.get("estimatedQuantity");
1035        
1036        ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
1037        List JavaDoc components = productionRun.getProductionRunComponents();
1038        if (components == null || components.size() == 0){
1039            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunComponentNotExists", locale));
1040        }
1041        
1042        if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
1043            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunPrinted", locale));
1044        }
1045
1046        boolean found = false;
1047        GenericValue theComponent = null;
1048        for (int i = 0; i < components.size(); i++) {
1049            theComponent = (GenericValue)components.get(i);
1050            if (theComponent.getString("productId").equals(productId)) {
1051                if (workEffortId != null) {
1052                    if (theComponent.getString("workEffortId").equals(workEffortId)) {
1053                        found = true;
1054                        break;
1055                    }
1056                } else {
1057                    found = true;
1058                    break;
1059                }
1060            }
1061        }
1062        if (!found) {
1063            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
1064        }
1065        
1066        try {
1067            // Find the product
1068
GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
1069            if (product == null) {
1070                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductNotExists", locale));
1071            }
1072        } catch (GenericEntityException e) {
1073            Debug.logWarning(e.getMessage(), module);
1074            return ServiceUtil.returnError(e.getMessage());
1075        }
1076        Map JavaDoc serviceContext = new HashMap JavaDoc();
1077        serviceContext.clear();
1078        serviceContext.put("workEffortId", theComponent.getString("workEffortId"));
1079        serviceContext.put("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED");
1080        serviceContext.put("productId", productId);
1081        serviceContext.put("fromDate", theComponent.getTimestamp("fromDate"));
1082        if (quantity != null) {
1083            serviceContext.put("estimatedQuantity", quantity);
1084        }
1085        serviceContext.put("userLogin", userLogin);
1086        Map JavaDoc resultService = null;
1087        try {
1088            resultService = dispatcher.runSync("updateWorkEffortGoodStandard", serviceContext);
1089        } catch (GenericServiceException e) {
1090            Debug.logError(e, "Problem calling the updateWorkEffortGoodStandard service", module);
1091            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunComponentNotAdded", locale));
1092        }
1093        result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunComponentUpdated",UtilMisc.toMap("productionRunId", productionRunId), locale));
1094        return result;
1095    }
1096    
1097    public static Map JavaDoc addProductionRunRoutingTask(DispatchContext ctx, Map JavaDoc context) {
1098        Map JavaDoc result = new HashMap JavaDoc();
1099        GenericDelegator delegator = ctx.getDelegator();
1100        LocalDispatcher dispatcher = ctx.getDispatcher();
1101        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1102        List JavaDoc msgResult = new LinkedList JavaDoc();
1103        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1104        GenericValue userLogin = (GenericValue) context.get("userLogin");
1105        // Mandatory input fields
1106
String JavaDoc productionRunId = (String JavaDoc)context.get("productionRunId");
1107        String JavaDoc routingTaskId = (String JavaDoc)context.get("routingTaskId");
1108        Long JavaDoc priority = (Long JavaDoc)context.get("priority");
1109        
1110        // Optional input fields
1111
String JavaDoc workEffortName = (String JavaDoc)context.get("workEffortName");
1112        String JavaDoc description = (String JavaDoc)context.get("description");
1113        Timestamp JavaDoc estimatedStartDate = (Timestamp JavaDoc)context.get("estimatedStartDate");
1114        Timestamp JavaDoc estimatedCompletionDate = (Timestamp JavaDoc)context.get("estimatedCompletionDate");
1115        Double JavaDoc estimatedSetupMillis = (Double JavaDoc)context.get("estimatedSetupMillis");
1116        Double JavaDoc estimatedMilliSeconds = (Double JavaDoc)context.get("estimatedMilliSeconds");
1117        
1118        // The production run is loaded
1119
ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
1120        Double JavaDoc pRQuantity = productionRun.getQuantity();
1121        if (pRQuantity == null) {
1122            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
1123        }
1124        
1125        if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
1126            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunPrinted", locale));
1127        }
1128
1129        if (estimatedStartDate != null) {
1130            Timestamp JavaDoc pRestimatedStartDate = productionRun.getEstimatedStartDate();
1131            if (pRestimatedStartDate.after(estimatedStartDate)) {
1132                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingTaskStartDateBeforePRun", locale));
1133            }
1134        }
1135        
1136        // The routing task is loaded
1137
GenericValue routingTask = null;
1138        try {
1139            routingTask = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", routingTaskId));
1140        } catch (GenericEntityException e) {
1141            Debug.logError(e.getMessage(), module);
1142            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingTaskNotExists", locale));
1143        }
1144        if (routingTask == null) {
1145            Debug.logError("Routing task: " + routingTaskId + " is null.", module);
1146            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRoutingTaskNotExists", locale));
1147        }
1148        
1149        if (workEffortName == null) {
1150            workEffortName = (String JavaDoc)routingTask.get("workEffortName");
1151        }
1152        if (description == null) {
1153            description = (String JavaDoc)routingTask.get("description");
1154        }
1155        if (estimatedSetupMillis == null) {
1156            estimatedSetupMillis = (Double JavaDoc)routingTask.get("estimatedSetupMillis");
1157        }
1158        if (estimatedMilliSeconds == null) {
1159            estimatedMilliSeconds = (Double JavaDoc)routingTask.get("estimatedMilliSeconds");
1160        }
1161        if (estimatedStartDate == null) {
1162            estimatedStartDate = productionRun.getEstimatedStartDate();
1163        }
1164        if (estimatedCompletionDate == null) {
1165            // Calculate the estimatedCompletionDate
1166
long totalTime = ProductionRun.getEstimatedTaskTime(routingTask, pRQuantity, dispatcher);
1167            estimatedCompletionDate = TechDataServices.addForward(TechDataServices.getTechDataCalendar(routingTask), estimatedStartDate, totalTime);
1168        }
1169        Map JavaDoc serviceContext = new HashMap JavaDoc();
1170        serviceContext.clear();
1171        serviceContext.put("priority", priority);
1172        serviceContext.put("workEffortPurposeTypeId", routingTask.get("workEffortPurposeTypeId"));
1173        serviceContext.put("workEffortName", workEffortName);
1174        serviceContext.put("description", description);
1175        serviceContext.put("fixedAssetId", routingTask.get("fixedAssetId"));
1176        serviceContext.put("workEffortTypeId", "PROD_ORDER_TASK");
1177        serviceContext.put("currentStatusId","PRUN_CREATED");
1178        serviceContext.put("workEffortParentId", productionRunId);
1179        serviceContext.put("facilityId", productionRun.getGenericValue().getString("facilityId"));
1180        serviceContext.put("estimatedStartDate", estimatedStartDate);
1181        serviceContext.put("estimatedCompletionDate", estimatedCompletionDate);
1182        serviceContext.put("estimatedSetupMillis", estimatedSetupMillis);
1183        serviceContext.put("estimatedMilliSeconds", estimatedMilliSeconds);
1184        serviceContext.put("quantityToProduce", pRQuantity);
1185        serviceContext.put("userLogin", userLogin);
1186        Map JavaDoc resultService = null;
1187        try {
1188            resultService = dispatcher.runSync("createWorkEffort", serviceContext);
1189        } catch (GenericServiceException e) {
1190            Debug.logError(e, "Problem calling the createWorkEffort service", module);
1191            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingAddProductionRunRoutingTaskNotCreated", locale));
1192        }
1193        String JavaDoc productionRunTaskId = (String JavaDoc) resultService.get("workEffortId");
1194        if (Debug.infoOn()) Debug.logInfo("ProductionRunTaskId created: " + productionRunTaskId, module);
1195        
1196        
1197        productionRun.setEstimatedCompletionDate(productionRun.recalculateEstimatedCompletionDate());
1198        if (!productionRun.store()) {
1199            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingAddProductionRunRoutingTaskNotCreated", locale));
1200        }
1201        
1202        // copy date valid WorkEffortPartyAssignments from the routing task to the run task
1203
List JavaDoc workEffortPartyAssignments = null;
1204        try {
1205            workEffortPartyAssignments = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortPartyAssignment", UtilMisc.toMap("workEffortId", routingTaskId)));
1206        } catch (GenericEntityException e) {
1207            Debug.logError(e.getMessage(), module);
1208        }
1209        if (workEffortPartyAssignments != null) {
1210            Iterator JavaDoc i = workEffortPartyAssignments.iterator();
1211            while(i.hasNext()) {
1212                GenericValue workEffortPartyAssignment = (GenericValue) i.next();
1213                Map JavaDoc partyToWorkEffort = UtilMisc.toMap(
1214                        "workEffortId", productionRunTaskId,
1215                        "partyId", workEffortPartyAssignment.getString("partyId"),
1216                        "roleTypeId", workEffortPartyAssignment.getString("roleTypeId"),
1217                        "fromDate", workEffortPartyAssignment.getTimestamp("fromDate"),
1218                        "statusId", workEffortPartyAssignment.getString("statusId"),
1219                        "userLogin", userLogin
1220                );
1221                try {
1222                    resultService = dispatcher.runSync("assignPartyToWorkEffort", partyToWorkEffort);
1223                } catch (GenericServiceException e) {
1224                    Debug.logError(e, "Problem calling the assignPartyToWorkEffort service", module);
1225                }
1226                if (Debug.infoOn()) Debug.logInfo("ProductionRunPartyassigment for party: " + workEffortPartyAssignment.get("partyId") + " created", module);
1227            }
1228        }
1229        
1230        result.put("routingTaskId", productionRunTaskId);
1231        result.put("estimatedStartDate", estimatedStartDate);
1232        result.put("estimatedCompletionDate", estimatedCompletionDate);
1233        return result;
1234    }
1235
1236    public static Map JavaDoc productionRunProduce(DispatchContext ctx, Map JavaDoc context) {
1237        Map JavaDoc result = new HashMap JavaDoc();
1238        GenericDelegator delegator = ctx.getDelegator();
1239        LocalDispatcher dispatcher = ctx.getDispatcher();
1240        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1241        List JavaDoc msgResult = new LinkedList JavaDoc();
1242        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1243        GenericValue userLogin = (GenericValue) context.get("userLogin");
1244        // Mandatory input fields
1245
String JavaDoc productionRunId = (String JavaDoc)context.get("workEffortId");
1246        
1247        // Optional input fields
1248
Double JavaDoc quantity = (Double JavaDoc)context.get("quantity");
1249        Boolean JavaDoc createSerializedInventory = (Boolean JavaDoc)context.get("createSerializedInventory");
1250        String JavaDoc lotId = (String JavaDoc)context.get("lotId");
1251        Boolean JavaDoc createLotIfNeeded = (Boolean JavaDoc)context.get("createLotIfNeeded");
1252        Boolean JavaDoc autoCreateLot = (Boolean JavaDoc)context.get("autoCreateLot");
1253        
1254        // The default is non-serialized inventory item
1255
if (createSerializedInventory == null) {
1256            createSerializedInventory = new Boolean JavaDoc(false);
1257        }
1258        // The default is to create a lot if the lotId is given, but the lot doesn't exist
1259
if (createLotIfNeeded == null) {
1260            createLotIfNeeded = new Boolean JavaDoc(true);
1261        }
1262        if (autoCreateLot == null) {
1263            autoCreateLot = new Boolean JavaDoc(false);
1264        }
1265       
1266        List JavaDoc inventoryItemIds = new ArrayList JavaDoc();
1267        // The production run is loaded
1268
ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
1269        // The last task is loaded
1270
GenericValue lastTask = productionRun.getLastProductionRunRoutingTask();
1271        if (lastTask == null) {
1272            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
1273        }
1274        String JavaDoc productType = productionRun.getProductProduced().getString("productTypeId");
1275        if ("WIP".equals("productTypeId")) {
1276            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductIsWIP", locale));
1277        }
1278        Double JavaDoc quantityProduced = productionRun.getGenericValue().getDouble("quantityProduced");
1279        if (quantityProduced == null) {
1280            quantityProduced = new Double JavaDoc(0);
1281        }
1282        Double JavaDoc quantityDeclared = lastTask.getDouble("quantityProduced");
1283        if (quantityDeclared == null) {
1284            quantityDeclared = new Double JavaDoc(0);
1285        }
1286        // If the quantity already produced is not lower than the quantity declared, no inventory is created.
1287
double maxQuantity = quantityDeclared.doubleValue() - quantityProduced.doubleValue();
1288        if (maxQuantity <= 0) {
1289            return ServiceUtil.returnSuccess();
1290        }
1291
1292        // If quantity was not passed, the max quantity is used
1293
if (quantity == null) {
1294            quantity = new Double JavaDoc(maxQuantity);
1295        }
1296        //
1297
if (quantity.doubleValue() > maxQuantity) {
1298            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunProductProducedNotStillAvailable", locale));
1299        }
1300        
1301        if (lotId == null && autoCreateLot.booleanValue()) {
1302            lotId = delegator.getNextSeqId("Lot");
1303            createLotIfNeeded = new Boolean JavaDoc(true);
1304        }
1305        if (lotId != null) {
1306            try {
1307                // Find the lot
1308
GenericValue lot = delegator.findByPrimaryKey("Lot", UtilMisc.toMap("lotId", lotId));
1309                if (lot == null) {
1310                    if (createLotIfNeeded.booleanValue()) {
1311                        lot = delegator.makeValue("Lot", UtilMisc.toMap("lotId", lotId, "creationDate", UtilDateTime.nowDate()));
1312                        lot.create();
1313                    } else {
1314                        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingLotNotExists", locale));
1315                    }
1316                }
1317            } catch (GenericEntityException e) {
1318                Debug.logWarning(e.getMessage(), module);
1319                return ServiceUtil.returnError(e.getMessage());
1320            }
1321        }
1322        
1323        GenericValue orderItem = null;
1324        try {
1325            // Find the related order item (if exists)
1326
List JavaDoc orderItems = productionRun.getGenericValue().getRelated("WorkOrderItemFulfillment");
1327            orderItem = EntityUtil.getFirst(orderItems);
1328        } catch (GenericEntityException e) {
1329            Debug.logWarning(e.getMessage(), module);
1330            return ServiceUtil.returnError(e.getMessage());
1331        }
1332        // calculate the inventory item unit cost
1333
BigDecimal JavaDoc unitCost = ZERO;
1334        try {
1335            Map JavaDoc outputMap = dispatcher.runSync("getProductionRunCost", UtilMisc.toMap("userLogin", userLogin, "workEffortId", productionRunId));
1336            BigDecimal JavaDoc totalCost = (BigDecimal JavaDoc)outputMap.get("totalCost");
1337            // FIXME
1338
unitCost = totalCost.divide(new BigDecimal JavaDoc(quantity.intValue()), decimals, rounding);
1339        } catch (GenericServiceException e) {
1340            Debug.logWarning(e.getMessage(), module);
1341            return ServiceUtil.returnError(e.getMessage());
1342        }
1343        
1344        if (createSerializedInventory.booleanValue()) {
1345            try {
1346                int numOfItems = quantity.intValue();
1347                for (int i = 0; i < numOfItems; i++) {
1348                    Map JavaDoc serviceContext = UtilMisc.toMap("productId", productionRun.getProductProduced().getString("productId"),
1349                                                        "inventoryItemTypeId", "SERIALIZED_INV_ITEM",
1350                                                        "statusId", "INV_AVAILABLE");
1351                    serviceContext.put("facilityId", productionRun.getGenericValue().getString("facilityId"));
1352                    serviceContext.put("datetimeReceived", UtilDateTime.nowDate());
1353                    serviceContext.put("comments", "Created by production run " + productionRunId);
1354                    if (unitCost.compareTo(ZERO) != 0) {
1355                        serviceContext.put("unitCost", new Double JavaDoc(unitCost.doubleValue()));
1356                    }
1357                    //serviceContext.put("serialNumber", productionRunId);
1358
serviceContext.put("lotId", lotId);
1359                    serviceContext.put("userLogin", userLogin);
1360                    Map JavaDoc resultService = dispatcher.runSync("createInventoryItem", serviceContext);
1361                    String JavaDoc inventoryItemId = (String JavaDoc)resultService.get("inventoryItemId");
1362                    inventoryItemIds.add(inventoryItemId);
1363                    GenericValue inventoryProduced = delegator.makeValue("WorkEffortInventoryProduced", UtilMisc.toMap("workEffortId", productionRunId , "inventoryItemId", inventoryItemId));
1364                    inventoryProduced.create();
1365                    serviceContext.clear();
1366                    serviceContext.put("inventoryItemId", inventoryItemId);
1367                    serviceContext.put("workEffortId", productionRunId);
1368                    serviceContext.put("availableToPromiseDiff", new Double JavaDoc(1));
1369                    serviceContext.put("quantityOnHandDiff", new Double JavaDoc(1));
1370                    serviceContext.put("userLogin", userLogin);
1371                    resultService = dispatcher.runSync("createInventoryItemDetail", serviceContext);
1372                    // Recompute reservations
1373
serviceContext = new HashMap JavaDoc();
1374                    serviceContext.put("inventoryItemId", inventoryItemId);
1375                    serviceContext.put("userLogin", userLogin);
1376                    resultService = resultService = dispatcher.runSync("balanceInventoryItems", serviceContext);
1377                }
1378            } catch(Exception JavaDoc exc) {
1379                return ServiceUtil.returnError(exc.getMessage());
1380            }
1381        } else {
1382            try {
1383                Map JavaDoc serviceContext = UtilMisc.toMap("productId", productionRun.getProductProduced().getString("productId"),
1384                                                    "inventoryItemTypeId", "NON_SERIAL_INV_ITEM");
1385                serviceContext.put("facilityId", productionRun.getGenericValue().getString("facilityId"));
1386                serviceContext.put("datetimeReceived", UtilDateTime.nowTimestamp());
1387                serviceContext.put("comments", "Created by production run " + productionRunId);
1388                serviceContext.put("lotId", lotId);
1389                if (unitCost.compareTo(ZERO) != 0) {
1390                    serviceContext.put("unitCost", new Double JavaDoc(unitCost.doubleValue()));
1391                }
1392                serviceContext.put("userLogin", userLogin);
1393                Map JavaDoc resultService = dispatcher.runSync("createInventoryItem", serviceContext);
1394                String JavaDoc inventoryItemId = (String JavaDoc)resultService.get("inventoryItemId");
1395                inventoryItemIds.add(inventoryItemId);
1396                GenericValue inventoryProduced = delegator.makeValue("WorkEffortInventoryProduced", UtilMisc.toMap("workEffortId", productionRunId , "inventoryItemId", inventoryItemId));
1397                inventoryProduced.create();
1398                serviceContext.clear();
1399                serviceContext.put("inventoryItemId", inventoryItemId);
1400                serviceContext.put("workEffortId", productionRunId);
1401                serviceContext.put("availableToPromiseDiff", quantity);
1402                serviceContext.put("quantityOnHandDiff", quantity);
1403                serviceContext.put("userLogin", userLogin);
1404                resultService = dispatcher.runSync("createInventoryItemDetail", serviceContext);
1405                // Recompute reservations
1406
serviceContext = new HashMap JavaDoc();
1407                serviceContext.put("inventoryItemId", inventoryItemId);
1408                serviceContext.put("userLogin", userLogin);
1409                if (orderItem != null) {
1410                    // the reservations of this order item are privileged reservations
1411
serviceContext.put("priorityOrderId", orderItem.getString("orderId"));
1412                    serviceContext.put("priorityOrderItemSeqId", orderItem.getString("orderItemSeqId"));
1413                }
1414                resultService = resultService = dispatcher.runSync("balanceInventoryItems", serviceContext);
1415            } catch(Exception JavaDoc exc) {
1416                return ServiceUtil.returnError(exc.getMessage());
1417            }
1418            // Now the production run's quantityProduced is updated
1419
double totalQuantity = quantityProduced.doubleValue() + quantity.doubleValue();
1420            Map JavaDoc serviceContext = new HashMap JavaDoc();
1421            serviceContext.clear();
1422            serviceContext.put("workEffortId", productionRunId);
1423            serviceContext.put("quantityProduced", new Double JavaDoc(totalQuantity));
1424            serviceContext.put("actualCompletionDate", UtilDateTime.nowTimestamp());
1425            serviceContext.put("userLogin", userLogin);
1426            Map JavaDoc resultService = null;
1427            try {
1428                resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
1429            } catch (GenericServiceException e) {
1430                Debug.logError(e, "Problem calling the updateWorkEffort service", module);
1431                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
1432            }
1433        }
1434        result.put("quantity", quantity);
1435        result.put("inventoryItemIds", inventoryItemIds);
1436        return result;
1437    }
1438
1439    public static Map JavaDoc productionRunTaskProduce(DispatchContext ctx, Map JavaDoc context) {
1440        Map JavaDoc result = new HashMap JavaDoc();
1441        GenericDelegator delegator = ctx.getDelegator();
1442        LocalDispatcher dispatcher = ctx.getDispatcher();
1443        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1444        List JavaDoc msgResult = new LinkedList JavaDoc();
1445        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1446        GenericValue userLogin = (GenericValue) context.get("userLogin");
1447        // Mandatory input fields
1448
String JavaDoc productionRunTaskId = (String JavaDoc)context.get("workEffortId");
1449        String JavaDoc productId = (String JavaDoc)context.get("productId");
1450        Double JavaDoc quantity = (Double JavaDoc)context.get("quantity");
1451        
1452        // Optional input fields
1453
Boolean JavaDoc createSerializedInventory = (Boolean JavaDoc)context.get("createSerializedInventory");
1454        
1455        // The default is non-serialized inventory item
1456
if (createSerializedInventory == null) {
1457            createSerializedInventory = new Boolean JavaDoc(false);
1458        }
1459        // TODO: if the task is not running, then return an error message.
1460

1461        // The production run is loaded
1462
ProductionRun productionRun = new ProductionRun(productionRunTaskId, delegator, dispatcher);
1463
1464        if (createSerializedInventory.booleanValue()) {
1465            try {
1466                int numOfItems = quantity.intValue();
1467                for (int i = 0; i < numOfItems; i++) {
1468                    Map JavaDoc serviceContext = UtilMisc.toMap("productId", productId,
1469                                                        "inventoryItemTypeId", "SERIALIZED_INV_ITEM",
1470                                                        "statusId", "INV_AVAILABLE");
1471                    serviceContext.put("facilityId", productionRun.getGenericValue().getString("facilityId"));
1472                    serviceContext.put("datetimeReceived", UtilDateTime.nowDate());
1473                    serviceContext.put("comments", "Created by production run task " + productionRunTaskId);
1474                    //serviceContext.put("serialNumber", productionRunTaskId);
1475
serviceContext.put("userLogin", userLogin);
1476                    Map JavaDoc resultService = dispatcher.runSync("createInventoryItem", serviceContext);
1477                    String JavaDoc inventoryItemId = (String JavaDoc)resultService.get("inventoryItemId");
1478                    GenericValue inventoryProduced = delegator.makeValue("WorkEffortInventoryProduced", UtilMisc.toMap("workEffortId", productionRunTaskId , "inventoryItemId", inventoryItemId));
1479                    inventoryProduced.create();
1480                    serviceContext.clear();
1481                    serviceContext.put("inventoryItemId", inventoryItemId);
1482                    serviceContext.put("workEffortId", productionRunTaskId);
1483                    serviceContext.put("availableToPromiseDiff", new Double JavaDoc(1));
1484                    serviceContext.put("quantityOnHandDiff", new Double JavaDoc(1));
1485                    serviceContext.put("userLogin", userLogin);
1486                    resultService = dispatcher.runSync("createInventoryItemDetail", serviceContext);
1487                    // Recompute reservations
1488
serviceContext = new HashMap JavaDoc();
1489                    serviceContext.put("inventoryItemId", inventoryItemId);
1490                    serviceContext.put("userLogin", userLogin);
1491                    resultService = dispatcher.runSync("balanceInventoryItems", serviceContext);
1492                }
1493            } catch(Exception JavaDoc exc) {
1494                return ServiceUtil.returnError(exc.getMessage());
1495            }
1496        } else {
1497            try {
1498                Map JavaDoc serviceContext = UtilMisc.toMap("productId", productId,
1499                                                    "inventoryItemTypeId", "NON_SERIAL_INV_ITEM");
1500                serviceContext.put("facilityId", productionRun.getGenericValue().getString("facilityId"));
1501                serviceContext.put("datetimeReceived", UtilDateTime.nowTimestamp());
1502                serviceContext.put("comments", "Created by production run task " + productionRunTaskId);
1503                serviceContext.put("userLogin", userLogin);
1504                Map JavaDoc resultService = dispatcher.runSync("createInventoryItem", serviceContext);
1505                String JavaDoc inventoryItemId = (String JavaDoc)resultService.get("inventoryItemId");
1506                
1507                GenericValue inventoryProduced = delegator.makeValue("WorkEffortInventoryProduced", UtilMisc.toMap("workEffortId", productionRunTaskId , "inventoryItemId", inventoryItemId));
1508                inventoryProduced.create();
1509                
1510                serviceContext.clear();
1511                serviceContext.put("inventoryItemId", inventoryItemId);
1512                serviceContext.put("workEffortId", productionRunTaskId);
1513                serviceContext.put("availableToPromiseDiff", quantity);
1514                serviceContext.put("quantityOnHandDiff", quantity);
1515                serviceContext.put("userLogin", userLogin);
1516                resultService = dispatcher.runSync("createInventoryItemDetail", serviceContext);
1517                // Recompute reservations
1518
serviceContext = new HashMap JavaDoc();
1519                serviceContext.put("inventoryItemId", inventoryItemId);
1520                serviceContext.put("userLogin", userLogin);
1521                resultService = dispatcher.runSync("balanceInventoryItems", serviceContext);
1522            } catch(Exception JavaDoc exc) {
1523                return ServiceUtil.returnError(exc.getMessage());
1524            }
1525        }
1526        return result;
1527    }
1528
1529    public static Map JavaDoc productionRunTaskReturnMaterial(DispatchContext ctx, Map JavaDoc context) {
1530        GenericDelegator delegator = ctx.getDelegator();
1531        LocalDispatcher dispatcher = ctx.getDispatcher();
1532        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1533        List JavaDoc msgResult = new LinkedList JavaDoc();
1534        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1535        GenericValue userLogin = (GenericValue) context.get("userLogin");
1536        // Mandatory input fields
1537
String JavaDoc productionRunTaskId = (String JavaDoc)context.get("workEffortId");
1538        String JavaDoc productId = (String JavaDoc)context.get("productId");
1539        // Optional input fields
1540
Double JavaDoc quantity = (Double JavaDoc)context.get("quantity");
1541        if (quantity == null || quantity.doubleValue() == 0) {
1542            return ServiceUtil.returnSuccess();
1543        }
1544        // Verify how many items of the given productId
1545
// are currently assigned to this task.
1546
// If less than passed quantity then return an error message.
1547
try {
1548            Iterator JavaDoc issuances = (delegator.findByAnd("WorkEffortAndInventoryAssign", UtilMisc.toMap("workEffortId", productionRunTaskId, "productId", productId))).iterator();
1549            double totalIssued = 0.0;
1550            while (issuances.hasNext()) {
1551                GenericValue issuance = (GenericValue)issuances.next();
1552                Double JavaDoc issued = issuance.getDouble("quantity");
1553                if (issued != null) {
1554                    totalIssued += issued.doubleValue();
1555                }
1556            }
1557            Iterator JavaDoc returns = (delegator.findByAnd("WorkEffortAndInventoryProduced", UtilMisc.toMap("workEffortId", productionRunTaskId, "productId", productId))).iterator();
1558            double totalReturned = 0.0;
1559            while (returns.hasNext()) {
1560                GenericValue returned = (GenericValue)returns.next();
1561                GenericValue returnDetail = EntityUtil.getFirst(delegator.findByAnd("InventoryItemDetail", UtilMisc.toMap("inventoryItemId", returned.getString("inventoryItemId")), UtilMisc.toList("inventoryItemDetailSeqId")));
1562                if (returnDetail != null) {
1563                    Double JavaDoc qtyReturned = returnDetail.getDouble("quantityOnHandDiff");
1564                    if (qtyReturned != null) {
1565                        totalReturned += qtyReturned.doubleValue();
1566                    }
1567                }
1568            }
1569            if (quantity.doubleValue() > totalIssued - totalReturned) {
1570                return ServiceUtil.returnError("Production Run Task with id [" + productionRunTaskId + "] cannot return more items [" + quantity + "] than the ones currently allocated [" + (totalIssued - totalReturned) + "]");
1571            }
1572        } catch(GenericEntityException gee) {
1573            return ServiceUtil.returnError(gee.getMessage());
1574        }
1575        Boolean JavaDoc createSerializedInventory = (Boolean JavaDoc)context.get("createSerializedInventory");
1576        // The default is non-serialized inventory item
1577
if (createSerializedInventory == null) {
1578            createSerializedInventory = new Boolean JavaDoc(false);
1579        }
1580        // TODO: if the task is not running, then return an error message.
1581

1582        try {
1583            Map JavaDoc inventoryResult = dispatcher.runSync("productionRunTaskProduce", UtilMisc.toMap("workEffortId", productionRunTaskId,
1584                                                                                                "productId", productId,
1585                                                                                                "quantity", quantity,
1586                                                                                                "createSerializedInventory", createSerializedInventory,
1587                                                                                                "userLogin", userLogin));
1588            if (ServiceUtil.isError(inventoryResult)) {
1589                return ServiceUtil.returnError("Error calling productionRunTaskProduce: " + ServiceUtil.getErrorMessage(inventoryResult));
1590            }
1591        } catch(GenericServiceException exc) {
1592            return ServiceUtil.returnError(exc.getMessage());
1593        }
1594        return ServiceUtil.returnSuccess();
1595    }
1596    
1597    public static Map JavaDoc updateProductionRunTask(DispatchContext ctx, Map JavaDoc context) {
1598        Map JavaDoc result = new HashMap JavaDoc();
1599        GenericDelegator delegator = ctx.getDelegator();
1600        LocalDispatcher dispatcher = ctx.getDispatcher();
1601        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1602        List JavaDoc msgResult = new LinkedList JavaDoc();
1603        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1604        GenericValue userLogin = (GenericValue) context.get("userLogin");
1605        // Mandatory input fields
1606
String JavaDoc productionRunId = (String JavaDoc)context.get("productionRunId");
1607        String JavaDoc workEffortId = (String JavaDoc)context.get("productionRunTaskId");
1608        String JavaDoc partyId = (String JavaDoc)context.get("partyId");
1609        
1610        // Optional input fields
1611
Timestamp JavaDoc fromDate = (Timestamp JavaDoc)context.get("fromDate");
1612        Timestamp JavaDoc toDate = (Timestamp JavaDoc)context.get("toDate");
1613        Double JavaDoc addQuantityProduced = (Double JavaDoc)context.get("addQuantityProduced");
1614        Double JavaDoc addQuantityRejected = (Double JavaDoc)context.get("addQuantityRejected");
1615        Double JavaDoc addSetupTime = (Double JavaDoc)context.get("addSetupTime");
1616        Double JavaDoc addTaskTime = (Double JavaDoc)context.get("addTaskTime");
1617        String JavaDoc comments = (String JavaDoc)context.get("comments");
1618        
1619        if (fromDate == null) {
1620            fromDate = UtilDateTime.nowTimestamp();
1621        }
1622        if (toDate == null) {
1623            toDate = UtilDateTime.nowTimestamp();
1624        }
1625        if (addQuantityProduced == null) {
1626            addQuantityProduced = new Double JavaDoc(0);
1627        }
1628        if (addQuantityRejected == null) {
1629            addQuantityRejected = new Double JavaDoc(0);
1630        }
1631        if (addSetupTime == null) {
1632            addSetupTime = new Double JavaDoc(0);
1633        }
1634        if (addTaskTime == null) {
1635            addTaskTime = new Double JavaDoc(0);
1636        }
1637        if (comments == null) {
1638            comments = "";
1639        }
1640        
1641        ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
1642        if (!productionRun.exist()){
1643            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
1644        }
1645        List JavaDoc tasks = productionRun.getProductionRunRoutingTasks();
1646        GenericValue theTask = null;
1647        GenericValue oneTask = null;
1648        for (int i = 0; i < tasks.size(); i++) {
1649            oneTask = (GenericValue)tasks.get(i);
1650            if (oneTask.getString("workEffortId").equals(workEffortId)) {
1651                theTask = oneTask;
1652                break;
1653            }
1654        }
1655        if (theTask == null) {
1656            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
1657        }
1658        
1659        String JavaDoc currentStatusId = theTask.getString("currentStatusId");
1660        
1661        if (!currentStatusId.equals("PRUN_RUNNING")) {
1662            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotRunning", locale));
1663        }
1664
1665        Double JavaDoc actualMilliSeconds = theTask.getDouble("actualMilliSeconds");
1666        if (actualMilliSeconds == null) {
1667            actualMilliSeconds = new Double JavaDoc(0);
1668        }
1669        Double JavaDoc actualSetupMillis = theTask.getDouble("actualSetupMillis");
1670        if (actualSetupMillis == null) {
1671            actualSetupMillis = new Double JavaDoc(0);
1672        }
1673
1674        Double JavaDoc quantityProduced = theTask.getDouble("quantityProduced");
1675        if (quantityProduced == null) {
1676            quantityProduced = new Double JavaDoc(0);
1677        }
1678        Double JavaDoc quantityRejected = theTask.getDouble("quantityRejected");
1679        if (quantityRejected == null) {
1680            quantityRejected = new Double JavaDoc(0);
1681        }
1682        double totalMillis = actualMilliSeconds.doubleValue() + addTaskTime.doubleValue();
1683        double totalSetupMillis = actualSetupMillis.doubleValue() + addSetupTime.doubleValue();
1684        double totalQuantityProduced = quantityProduced.doubleValue() + addQuantityProduced.doubleValue();
1685        double totalQuantityRejected = quantityRejected.doubleValue() + addQuantityRejected.doubleValue();
1686        
1687        // Create a new TimeEntry
1688
try {
1689            String JavaDoc timeEntryId = delegator.getNextSeqId("TimeEntry");
1690            Map JavaDoc timeEntryFields = UtilMisc.toMap("timeEntryId", timeEntryId,
1691                                                 "workEffortId", workEffortId);
1692            Double JavaDoc totalTime = new Double JavaDoc(addSetupTime.doubleValue() + addTaskTime.doubleValue());
1693            timeEntryFields.put("partyId", partyId);
1694            timeEntryFields.put("fromDate", fromDate);
1695            timeEntryFields.put("thruDate", toDate);
1696            timeEntryFields.put("hours", totalTime); // FIXME
1697
//timeEntryFields.put("setupTime", addSetupTime); // FIXME
1698
//timeEntryFields.put("quantityProduced", addQuantityProduced); // FIXME
1699
//timeEntryFields.put("quantityRejected", addQuantityRejected); // FIXME
1700
timeEntryFields.put("comments", comments);
1701            GenericValue timeEntry = delegator.makeValue("TimeEntry", timeEntryFields);
1702            timeEntry.create();
1703            
1704            Map JavaDoc serviceContext = new HashMap JavaDoc();
1705            serviceContext.clear();
1706            serviceContext.put("workEffortId", workEffortId);
1707            serviceContext.put("actualMilliSeconds", new Double JavaDoc(totalMillis));
1708            serviceContext.put("actualSetupMillis", new Double JavaDoc(totalSetupMillis));
1709            serviceContext.put("quantityProduced", new Double JavaDoc(totalQuantityProduced));
1710            serviceContext.put("quantityRejected", new Double JavaDoc(totalQuantityRejected));
1711            serviceContext.put("userLogin", userLogin);
1712            Map JavaDoc resultService = resultService = dispatcher.runSync("updateWorkEffort", serviceContext);
1713        } catch(Exception JavaDoc exc) {
1714            return ServiceUtil.returnError(exc.getMessage());
1715        }
1716        
1717        return result;
1718    }
1719
1720    public static Map JavaDoc approveRequirement(DispatchContext ctx, Map JavaDoc context) {
1721        Map JavaDoc result = new HashMap JavaDoc();
1722        GenericDelegator delegator = ctx.getDelegator();
1723        LocalDispatcher dispatcher = ctx.getDispatcher();
1724        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1725        List JavaDoc msgResult = new LinkedList JavaDoc();
1726        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1727        GenericValue userLogin = (GenericValue) context.get("userLogin");
1728        // Mandatory input fields
1729
String JavaDoc requirementId = (String JavaDoc)context.get("requirementId");
1730        GenericValue requirement = null;
1731        try {
1732            requirement = delegator.findByPrimaryKey("Requirement", UtilMisc.toMap("requirementId", requirementId));
1733        } catch(GenericEntityException gee) {
1734        }
1735
1736        if (requirement == null) {
1737            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRequirementNotExists", locale));
1738        }
1739        try {
1740            result = dispatcher.runSync("updateRequirement", UtilMisc.toMap("requirementId", requirementId, "statusId", "REQ_APPROVED", "requirementTypeId", requirement.getString("requirementTypeId"), "userLogin", userLogin));
1741        } catch (GenericServiceException e) {
1742            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRequirementNotUpdated", locale));
1743        }
1744        return ServiceUtil.returnSuccess();
1745    }
1746    
1747    public static Map JavaDoc createProductionRunFromRequirement(DispatchContext ctx, Map JavaDoc context) {
1748        Map JavaDoc result = new HashMap JavaDoc();
1749        GenericDelegator delegator = ctx.getDelegator();
1750        LocalDispatcher dispatcher = ctx.getDispatcher();
1751        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1752        List JavaDoc msgResult = new LinkedList JavaDoc();
1753        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1754        GenericValue userLogin = (GenericValue) context.get("userLogin");
1755        // Mandatory input fields
1756
String JavaDoc requirementId = (String JavaDoc)context.get("requirementId");
1757        // Optional input fields
1758
Double JavaDoc quantity = (Double JavaDoc)context.get("quantity");
1759        
1760        GenericValue requirement = null;
1761        try {
1762            requirement = delegator.findByPrimaryKey("Requirement", UtilMisc.toMap("requirementId", requirementId));
1763        } catch(GenericEntityException gee) {
1764        }
1765        if (requirement == null) {
1766            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRequirementNotExists", locale));
1767        }
1768        // TODO: fix the allowed types
1769
if (!"MRP_PRO_PROD_ORDER".equals(requirement.getString("requirementTypeId")) &&
1770               !"WORK_REQUIREMENT".equals(requirement.getString("requirementTypeId"))) {
1771            return ServiceUtil.returnSuccess();
1772        }
1773        
1774        if (quantity == null) {
1775            quantity = requirement.getDouble("quantity");
1776        }
1777        Map JavaDoc serviceContext = new HashMap JavaDoc();
1778        serviceContext.clear();
1779        serviceContext.put("productId", requirement.getString("productId"));
1780        serviceContext.put("pRQuantity", quantity);
1781        serviceContext.put("startDate", requirement.getTimestamp("requirementStartDate"));
1782        serviceContext.put("facilityId", requirement.getString("facilityId"));
1783        String JavaDoc workEffortName = null;
1784        if (requirement.getString("description") != null) {
1785            workEffortName = requirement.getString("description");
1786            if (workEffortName.length() > 50) {
1787                workEffortName = workEffortName.substring(0, 50);
1788            }
1789        } else {
1790            workEffortName = "Created from requirement " + requirement.getString("requirementId");
1791        }
1792        serviceContext.put("workEffortName", workEffortName);
1793        serviceContext.put("userLogin", userLogin);
1794        Map JavaDoc resultService = null;
1795        try {
1796            resultService = dispatcher.runSync("createProductionRun", serviceContext);
1797        } catch (GenericServiceException e) {
1798            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotCreated", locale));
1799        }
1800        String JavaDoc productionRunId = (String JavaDoc)resultService.get("productionRunId");
1801        result.put("productionRunId", productionRunId);
1802        
1803// try {
1804
// requirement.remove();
1805
// } catch (GenericEntityException e) {
1806
// return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRequirementNotDeleted", locale));
1807
// }
1808

1809        result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunCreated",UtilMisc.toMap("productionRunId", productionRunId), locale));
1810        return result;
1811    }
1812    
1813    public static Map JavaDoc createProductionRunFromConfiguration(DispatchContext ctx, Map JavaDoc context) {
1814        Map JavaDoc result = new HashMap JavaDoc();
1815        GenericDelegator delegator = ctx.getDelegator();
1816        LocalDispatcher dispatcher = ctx.getDispatcher();
1817        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1818        List JavaDoc msgResult = new LinkedList JavaDoc();
1819        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
1820        GenericValue userLogin = (GenericValue) context.get("userLogin");
1821        // Mandatory input fields
1822
String JavaDoc facilityId = (String JavaDoc)context.get("facilityId");
1823        // Optional input fields
1824
String JavaDoc configId = (String JavaDoc)context.get("configId");
1825        ProductConfigWrapper config = (ProductConfigWrapper)context.get("config");
1826        Double JavaDoc quantity = (Double JavaDoc)context.get("quantity");
1827        String JavaDoc orderId = (String JavaDoc)context.get("orderId");
1828        String JavaDoc orderItemSeqId = (String JavaDoc)context.get("orderItemSeqId");
1829        
1830        if (config == null && configId == null) {
1831            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingConfigurationNotAvailable", locale));
1832        }
1833        if (config == null && configId != null) {
1834            // TODO: load the configuration
1835
return ServiceUtil.returnError("Operation not yet implemented");
1836        }
1837        if (!config.isCompleted()) {
1838            return ServiceUtil.returnError("ProductConfigurationNotValid");
1839        }
1840        if (quantity == null) {
1841            quantity = new Double JavaDoc(1);
1842        }
1843        Map JavaDoc serviceContext = new HashMap JavaDoc();
1844        serviceContext.clear();
1845        serviceContext.put("productId", config.getProduct().getString("productId"));
1846        serviceContext.put("pRQuantity", quantity);
1847        serviceContext.put("startDate", UtilDateTime.nowTimestamp());
1848        serviceContext.put("facilityId", facilityId);
1849        //serviceContext.put("workEffortName", "");
1850
serviceContext.put("userLogin", userLogin);
1851        Map JavaDoc resultService = null;
1852        try {
1853            resultService = dispatcher.runSync("createProductionRun", serviceContext);
1854        } catch (GenericServiceException e) {
1855            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotCreated", locale));
1856        }
1857        String JavaDoc productionRunId = (String JavaDoc)resultService.get("productionRunId");
1858        result.put("productionRunId", productionRunId);
1859
1860        Iterator JavaDoc options = config.getSelectedOptions().iterator();
1861        HashMap JavaDoc components = new HashMap JavaDoc();
1862        while (options.hasNext()) {
1863            ConfigOption co = (ConfigOption)options.next();
1864            //components.addAll(co.getComponents());
1865
Iterator JavaDoc selComponents = co.getComponents().iterator();
1866            while (selComponents.hasNext()) {
1867                Double JavaDoc componentQuantity = null;
1868                GenericValue selComponent = (GenericValue)selComponents.next();
1869                if (selComponent.get("quantity") != null) {
1870                    componentQuantity = selComponent.getDouble("quantity");
1871                }
1872                if (componentQuantity == null) {
1873                    componentQuantity = new Double JavaDoc(1);
1874                }
1875                componentQuantity = new Double JavaDoc(quantity.doubleValue() * componentQuantity.doubleValue());
1876                if (components.containsKey(selComponent.getString("productId"))) {
1877                    Double JavaDoc totalQuantity = (Double JavaDoc)components.get(selComponent.getString("productId"));
1878                    componentQuantity = new Double JavaDoc(totalQuantity.doubleValue() + componentQuantity.doubleValue());
1879                }
1880                components.put(selComponent.getString("productId"), componentQuantity);
1881            }
1882        }
1883        
1884        Iterator JavaDoc componentsIt = components.entrySet().iterator();
1885        while (componentsIt.hasNext()) {
1886            Map.Entry JavaDoc component = (Map.Entry JavaDoc)componentsIt.next();
1887            String JavaDoc productId = (String JavaDoc)component.getKey();
1888            Double JavaDoc componentQuantity = (Double JavaDoc)component.getValue();
1889            if (componentQuantity == null) {
1890                componentQuantity = new Double JavaDoc(1);
1891            }
1892            resultService = null;
1893            serviceContext = new HashMap JavaDoc();
1894            serviceContext.put("productionRunId", productionRunId);
1895            serviceContext.put("productId", productId);
1896            serviceContext.put("estimatedQuantity", componentQuantity);
1897            serviceContext.put("userLogin", userLogin);
1898            try {
1899                resultService = dispatcher.runSync("addProductionRunComponent", serviceContext);
1900            } catch (GenericServiceException e) {
1901                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotCreated", locale));
1902            }
1903        }
1904        try {
1905            if (productionRunId != null && orderId != null && orderItemSeqId != null) {
1906                delegator.create("WorkOrderItemFulfillment", UtilMisc.toMap("workEffortId", productionRunId, "orderId", orderId, "orderItemSeqId", orderItemSeqId));
1907            }
1908        } catch (GenericEntityException e) {
1909            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingRequirementNotDeleted", locale));
1910        }
1911        
1912        result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunCreated",UtilMisc.toMap("productionRunId", productionRunId), locale));
1913        return result;
1914    }
1915
1916    public static Map JavaDoc createProductionRunsForOrder(DispatchContext dctx, Map JavaDoc context) {
1917
1918        Map JavaDoc result = new HashMap JavaDoc();
1919        Security security = dctx.getSecurity();
1920        GenericDelegator delegator = dctx.getDelegator();
1921        LocalDispatcher dispatcher = dctx.getDispatcher();
1922        GenericValue userLogin = (GenericValue)context.get("userLogin");
1923
1924        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1925
1926        String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
1927        String JavaDoc orderItemSeqId = (String JavaDoc) context.get("orderItemSeqId");
1928        Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
1929        String JavaDoc fromDateStr = (String JavaDoc) context.get("fromDate");
1930        
1931        Double JavaDoc amount = null;
1932        Date JavaDoc fromDate = null;
1933        if (UtilValidate.isNotEmpty(fromDateStr)) {
1934            try {
1935                fromDate = Timestamp.valueOf(fromDateStr);
1936            } catch (Exception JavaDoc e) {
1937            }
1938        }
1939        if (fromDate == null) {
1940            fromDate = new Date JavaDoc();
1941        }
1942
1943        List JavaDoc orderItems = null;
1944        
1945        if (orderItemSeqId != null) {
1946            try {
1947                GenericValue orderItem = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId));
1948                if (orderItem == null) {
1949                    return ServiceUtil.returnError("OrderItem [" + orderItemSeqId + "] not found.");
1950                }
1951                if (quantity != null) {
1952                    orderItem.set("quantity", quantity);
1953                }
1954                orderItems = UtilMisc.toList(orderItem);
1955            } catch(GenericEntityException gee) {
1956                return ServiceUtil.returnError("Error reading the OrderItem: " + gee.getMessage());
1957            }
1958        } else {
1959            try {
1960                orderItems = delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId));
1961                if (orderItems == null) {
1962                    return ServiceUtil.returnError("OrderItems for order [" + orderId + "] not found.");
1963                }
1964            } catch(GenericEntityException gee) {
1965                return ServiceUtil.returnError("Error reading the OrderItems: " + gee.getMessage());
1966            }
1967        }
1968        for (int i = 0; i < orderItems.size(); i++) {
1969            GenericValue orderItem = (GenericValue)orderItems.get(i);
1970            if (orderItem.get("productId") == null) {
1971                continue;
1972            }
1973            if (orderItem.get("quantity") != null) {
1974                quantity = orderItem.getDouble("quantity");
1975            } else {
1976                continue;
1977            }
1978            try {
1979                List JavaDoc existingProductionRuns = delegator.findByAndCache("WorkOrderItemFulfillment", UtilMisc.toMap("orderId", orderItem.getString("orderId"), "orderItemSeqId", orderItem.getString("orderItemSeqId")));
1980                if (existingProductionRuns != null && existingProductionRuns.size() > 0) {
1981                    Debug.logWarning("Production Run for order item [" + orderItem.getString("orderId") + "/" + orderItem.getString("orderItemSeqId") + "] already exists.", module);
1982                    continue;
1983                }
1984            } catch(GenericEntityException gee) {
1985                return ServiceUtil.returnError("Error reading the WorkOrderItemFulfillment: " + gee.getMessage());
1986            }
1987            if (orderItem.get("selectedAmount") != null) {
1988                amount = orderItem.getDouble("selectedAmount");
1989            }
1990            if (amount == null) {
1991                amount = new Double JavaDoc(0);
1992            }
1993            try {
1994                ArrayList JavaDoc components = new ArrayList JavaDoc();
1995                BOMTree tree = new BOMTree(orderItem.getString("productId"), "MANUF_COMPONENT", fromDate, BOMTree.EXPLOSION_MANUFACTURING, delegator, dispatcher, userLogin);
1996                tree.setRootQuantity(quantity.doubleValue());
1997                tree.setRootAmount(amount.doubleValue());
1998                tree.print(components);
1999                tree.createManufacturingOrders(orderId, orderItem.getString("orderItemSeqId"), shipmentId, fromDate, userLogin);
2000            } catch(GenericEntityException gee) {
2001                return ServiceUtil.returnError("Error creating bill of materials tree: " + gee.getMessage());
2002            }
2003        }
2004        ArrayList JavaDoc productionRuns = new ArrayList JavaDoc();
2005        result.put("productionRuns" , productionRuns);
2006        return result;
2007    }
2008
2009    /**
2010     * Quick runs a ProductionRun task to the completed status, also issuing components
2011     * if necessary.
2012     * @param ctx The DispatchContext that this service is operating in.
2013     * @param context Map containing the input parameters.
2014     * @return Map with the result of the service, the output parameters.
2015     */

2016    public static Map JavaDoc quickRunProductionRunTask(DispatchContext ctx, Map JavaDoc context) {
2017        Map JavaDoc result = ServiceUtil.returnSuccess();
2018        GenericDelegator delegator = ctx.getDelegator();
2019        LocalDispatcher dispatcher = ctx.getDispatcher();
2020        Security security = ctx.getSecurity();
2021        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
2022        GenericValue userLogin = (GenericValue) context.get("userLogin");
2023        
2024        String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
2025        String JavaDoc taskId = (String JavaDoc) context.get("taskId");
2026
2027        try {
2028            Map JavaDoc serviceContext = new HashMap JavaDoc();
2029            Map JavaDoc resultService = null;
2030            GenericValue task = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", taskId));
2031            String JavaDoc currentStatusId = task.getString("currentStatusId");
2032            String JavaDoc prevStatusId = "";
2033            while (!"PRUN_COMPLETED".equals(currentStatusId)) {
2034                serviceContext.put("productionRunId", productionRunId);
2035                serviceContext.put("workEffortId", taskId);
2036                serviceContext.put("issueAllComponents", new Boolean JavaDoc(true));
2037                serviceContext.put("userLogin", userLogin);
2038                resultService = dispatcher.runSync("changeProductionRunTaskStatus", serviceContext);
2039                currentStatusId = (String JavaDoc)resultService.get("newStatusId");
2040                if (currentStatusId.equals(prevStatusId)) {
2041                    return ServiceUtil.returnError("Unable to progress from status [" + prevStatusId + "] for task [" + taskId + "]");
2042                } else {
2043                    prevStatusId = currentStatusId;
2044                }
2045                serviceContext.clear();
2046            }
2047        } catch (Exception JavaDoc e) {
2048            Debug.logError(e, "Problem calling the changeProductionRunTaskStatus service", module);
2049            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
2050        }
2051        return result;
2052    }
2053    
2054    /**
2055     * Quick runs all the tasks of a ProductionRun to the completed status,
2056     * also issuing components if necessary.
2057     * @param ctx The DispatchContext that this service is operating in.
2058     * @param context Map containing the input parameters.
2059     * @return Map with the result of the service, the output parameters.
2060     */

2061    public static Map JavaDoc quickRunAllProductionRunTasks(DispatchContext ctx, Map JavaDoc context) {
2062        Map JavaDoc result = ServiceUtil.returnSuccess();
2063        GenericDelegator delegator = ctx.getDelegator();
2064        LocalDispatcher dispatcher = ctx.getDispatcher();
2065        Security security = ctx.getSecurity();
2066        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
2067        GenericValue userLogin = (GenericValue) context.get("userLogin");
2068        
2069        String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
2070
2071        ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
2072        if (!productionRun.exist()){
2073            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
2074        }
2075        List JavaDoc tasks = productionRun.getProductionRunRoutingTasks();
2076        GenericValue oneTask = null;
2077        String JavaDoc taskId = null;
2078        for (int i = 0; i < tasks.size(); i++) {
2079            oneTask = (GenericValue)tasks.get(i);
2080            taskId = oneTask.getString("workEffortId");
2081            try {
2082                Map JavaDoc serviceContext = null;
2083                Map JavaDoc resultService = null;
2084                serviceContext = new HashMap JavaDoc();
2085                serviceContext.put("productionRunId", productionRunId);
2086                serviceContext.put("taskId", taskId);
2087                serviceContext.put("userLogin", userLogin);
2088                resultService = dispatcher.runSync("quickRunProductionRunTask", serviceContext);
2089            } catch (GenericServiceException e) {
2090                Debug.logError(e, "Problem calling the quickRunProductionRunTask service", module);
2091                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
2092            }
2093        }
2094        return result;
2095    }
2096
2097    /**
2098     * Quick moves a ProductionRun to the passed in status, performing all
2099     * the needed tasks in the way.
2100     * @param ctx The DispatchContext that this service is operating in.
2101     * @param context Map containing the input parameters.
2102     * @return Map with the result of the service, the output parameters.
2103     */

2104    public static Map JavaDoc quickChangeProductionRunStatus(DispatchContext ctx, Map JavaDoc context) {
2105        Map JavaDoc result = ServiceUtil.returnSuccess();
2106        GenericDelegator delegator = ctx.getDelegator();
2107        LocalDispatcher dispatcher = ctx.getDispatcher();
2108        Security security = ctx.getSecurity();
2109        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
2110        GenericValue userLogin = (GenericValue) context.get("userLogin");
2111        
2112        String JavaDoc productionRunId = (String JavaDoc) context.get("productionRunId");
2113        String JavaDoc statusId = (String JavaDoc) context.get("statusId");
2114
2115        try {
2116            Map JavaDoc serviceContext = null;
2117            Map JavaDoc resultService = null;
2118            // Change the task status to running
2119
serviceContext = new HashMap JavaDoc();
2120            if (statusId.equals("PRUN_DOC_PRINTED") ||
2121                    statusId.equals("PRUN_RUNNING") ||
2122                    statusId.equals("PRUN_COMPLETED") ||
2123                    statusId.equals("PRUN_CLOSED")) {
2124                serviceContext.put("productionRunId", productionRunId);
2125                serviceContext.put("statusId", "PRUN_DOC_PRINTED");
2126                serviceContext.put("userLogin", userLogin);
2127                resultService = dispatcher.runSync("changeProductionRunStatus", serviceContext);
2128            }
2129            if (statusId.equals("PRUN_COMPLETED") ||
2130                    statusId.equals("PRUN_CLOSED")) {
2131                serviceContext.clear();
2132                serviceContext.put("productionRunId", productionRunId);
2133                serviceContext.put("userLogin", userLogin);
2134                resultService = dispatcher.runSync("quickRunAllProductionRunTasks", serviceContext);
2135            }
2136            if (statusId.equals("PRUN_CLOSED")) {
2137                // Put in warehouse the products manufactured
2138
serviceContext.clear();
2139                serviceContext.put("workEffortId", productionRunId);
2140                serviceContext.put("userLogin", userLogin);
2141                resultService = dispatcher.runSync("productionRunProduce", serviceContext);
2142                serviceContext.clear();
2143                serviceContext.put("productionRunId", productionRunId);
2144                serviceContext.put("statusId", "PRUN_CLOSED");
2145                serviceContext.put("userLogin", userLogin);
2146                resultService = dispatcher.runSync("changeProductionRunStatus", serviceContext);
2147            }
2148        } catch (GenericServiceException e) {
2149            Debug.logError(e, "Problem calling the changeProductionRunStatus service", module);
2150            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
2151        }
2152        return result;
2153    }
2154
2155    /**
2156     * Given a productId and an optional date, returns the total qty
2157     * of productId reserved by production runs.
2158     * @param ctx The DispatchContext that this service is operating in.
2159     * @param context Map containing the input parameters.
2160     * @return Map with the result of the service, the output parameters.
2161     */

2162    public static Map JavaDoc getProductionRunTotResQty(DispatchContext ctx, Map JavaDoc context) {
2163        Map JavaDoc result = ServiceUtil.returnSuccess();
2164        GenericDelegator delegator = ctx.getDelegator();
2165        Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
2166
2167        String JavaDoc productId = (String JavaDoc) context.get("productId");
2168        Timestamp JavaDoc startDate = (Timestamp JavaDoc) context.get("startDate");
2169        if (startDate == null) {
2170            startDate = UtilDateTime.nowTimestamp();
2171        }
2172        double totQty = 0.0;
2173        try {
2174            List JavaDoc findOutgoingProductionRunsConds = new LinkedList JavaDoc();
2175
2176            findOutgoingProductionRunsConds.add(new EntityExpr("productId", EntityOperator.EQUALS, productId));
2177            findOutgoingProductionRunsConds.add(new EntityExpr("statusId", EntityOperator.EQUALS, "WEGS_CREATED"));
2178            findOutgoingProductionRunsConds.add(new EntityExpr("estimatedStartDate", EntityOperator.LESS_THAN_EQUAL_TO, startDate));
2179
2180            List JavaDoc findOutgoingProductionRunsStatusConds = new LinkedList JavaDoc();
2181            findOutgoingProductionRunsStatusConds.add(new EntityExpr("currentStatusId", EntityOperator.EQUALS, "PRUN_CREATED"));
2182            findOutgoingProductionRunsStatusConds.add(new EntityExpr("currentStatusId", EntityOperator.EQUALS, "PRUN_DOC_PRINTED"));
2183            findOutgoingProductionRunsStatusConds.add(new EntityExpr("currentStatusId", EntityOperator.EQUALS, "PRUN_RUNNING"));
2184            findOutgoingProductionRunsConds.add(new EntityConditionList(findOutgoingProductionRunsStatusConds, EntityOperator.OR));
2185
2186            List JavaDoc outgoingProductionRuns = delegator.findByCondition("WorkEffortAndGoods", new EntityConditionList(findOutgoingProductionRunsConds, EntityOperator.AND), null, UtilMisc.toList("-estimatedStartDate"));
2187            if (outgoingProductionRuns != null) {
2188                for (int i = 0; i < outgoingProductionRuns.size(); i++) {
2189                    GenericValue outgoingProductionRun = (GenericValue)outgoingProductionRuns.get(i);
2190                    Double JavaDoc dblQty = outgoingProductionRun.getDouble("estimatedQuantity");
2191                    double qty = (dblQty != null? dblQty.doubleValue(): 0.0);
2192                    totQty += qty;
2193                }
2194            }
2195        } catch (GenericEntityException e) {
2196            Debug.logError(e, "Problem calling the getProductionRunTotResQty service", module);
2197            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionResQtyCalc", locale));
2198        }
2199        result.put("reservedQuantity", new Double JavaDoc(totQty));
2200        return result;
2201    }
2202
2203}
2204
Popular Tags