KickJava   Java API By Example, From Geeks To Geeks.

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


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

27
28 package org.ofbiz.manufacturing.jobshopmgt;
29
30 import java.sql.Timestamp JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.LinkedList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import org.ofbiz.base.util.Debug;
37 import org.ofbiz.base.util.UtilMisc;
38 import org.ofbiz.base.util.UtilValidate;
39 import org.ofbiz.entity.GenericDelegator;
40 import org.ofbiz.entity.GenericEntityException;
41 import org.ofbiz.entity.GenericValue;
42 import org.ofbiz.entity.util.EntityUtil;
43 import org.ofbiz.service.GenericServiceException;
44 import org.ofbiz.service.LocalDispatcher;
45 import org.ofbiz.manufacturing.techdata.TechDataServices;
46
47
48 /**
49  * ProductionRun Object used by the Jobshop management OFBiz comonents,
50  * this object is used to find or updated an existing ProductionRun.
51  *
52  * @author <a HREF="mailto:olivier.heintz@nereide.biz">Olivier Heintz</a>
53  */

54 public class ProductionRun {
55     
56     public static final String JavaDoc module = ProductionRun.class.getName();
57     public static final String JavaDoc resource = "ManufacturingUiLabels";
58     
59     protected GenericValue productionRun; // WorkEffort (PROD_ORDER_HEADER)
60
protected GenericValue productionRunProduct; // WorkEffortGoodStandard (type: PRUN_PROD_DELIV)
61
protected GenericValue productProduced; // Product (from WorkEffortGoodStandard of type: PRUN_PROD_DELIV)
62
protected Double JavaDoc quantity; // the estimatedQuantity
63

64     protected Timestamp JavaDoc estimatedStartDate;
65     protected Timestamp JavaDoc estimatedCompletionDate;
66     protected String JavaDoc productionRunName;
67     protected String JavaDoc description;
68     protected GenericValue currentStatus;
69     protected List JavaDoc productionRunComponents;
70     protected List JavaDoc productionRunRoutingTasks;
71     protected LocalDispatcher dispatcher;
72     
73     /**
74      * indicate if quantity or estimatedStartDate has been modified and
75      * estimatedCompletionDate not yet recalculated with recalculateEstimatedCompletionDate() methode.
76      */

77     private boolean updateCompletionDate = false;
78     /**
79      * indicate if quantity has been modified, used for store() method to update appropriate entity.
80      */

81     private boolean quantityIsUpdated = false;
82     
83     public ProductionRun(String JavaDoc productionRunId, GenericDelegator delegator, LocalDispatcher dispatcher) {
84         try {
85             if (! UtilValidate.isEmpty(productionRunId)) {
86                 this.dispatcher = dispatcher;
87                 GenericValue workEffort = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", productionRunId));
88                 if (workEffort != null) {
89                     // If this is a task, get the parent production run
90
if (workEffort.getString("workEffortTypeId") != null && "PROD_ORDER_TASK".equals(workEffort.getString("workEffortTypeId"))) {
91                         workEffort = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffort.getString("workEffortParentId")));
92                     }
93                 }
94                 this.productionRun = workEffort;
95                 if (exist()) {
96                     this.estimatedStartDate = productionRun.getTimestamp("estimatedStartDate");
97                     this.estimatedCompletionDate = productionRun.getTimestamp("estimatedCompletionDate");
98                     this.productionRunName = productionRun.getString("workEffortName");
99                     this.description = productionRun.getString("description");
100                 }
101             }
102         } catch (GenericEntityException e) {
103             Debug.logWarning(e.getMessage(), module);
104         }
105     }
106     
107     /**
108      * test if the productionRun exist.
109      * @return true if it exist false otherwise.
110      **/

111     public boolean exist(){
112         return productionRun != null;
113     }
114     
115     /**
116      * get the ProductionRun GenericValue .
117      * @return the ProductionRun GenericValue
118      **/

119     public GenericValue getGenericValue(){
120         return productionRun;
121     }
122     /**
123      * store the modified ProductionRun object in the database.
124      * <li>store the the productionRun header
125      * <li> the productProduced related data
126      * <li> the listRoutingTask related data
127      * <li> the productComponent list related data
128      * @return true if success false otherwise
129      **/

130     public boolean store(){
131         if (exist()){
132             if (updateCompletionDate){
133                 this.estimatedCompletionDate = recalculateEstimatedCompletionDate();
134             }
135             productionRun.set("estimatedStartDate",this.estimatedStartDate);
136             productionRun.set("estimatedCompletionDate",this.estimatedCompletionDate);
137             productionRun.set("workEffortName",this.productionRunName);
138             productionRun.set("description",this.description);
139             try {
140                 productionRun.store();
141                 if (quantityIsUpdated) {
142                     productionRunProduct.set("estimatedQuantity",this.quantity);
143                     productionRunProduct.store();
144                     quantityIsUpdated = false;
145                 }
146                 if (productionRunRoutingTasks != null) {
147                     for (Iterator JavaDoc iter = productionRunRoutingTasks.iterator(); iter.hasNext();){
148                         GenericValue routingTask = (GenericValue) iter.next();
149                         routingTask.store();
150                     }
151                 }
152                 if (productionRunComponents != null) {
153                     for (Iterator JavaDoc iter = productionRunComponents.iterator(); iter.hasNext();){
154                         GenericValue component = (GenericValue) iter.next();
155                         component.store();
156                     }
157                 }
158             } catch (GenericEntityException e) {
159                 Debug.logWarning(e.getMessage(), module);
160                 return false;
161             }
162             return true;
163         }
164         return false;
165     }
166     
167     /**
168      * get the Product GenericValue corresponding to the productProduced.
169      * In the same time this method read the quantity property from SGBD
170      * @return the productProduced related object
171      **/

172     public GenericValue getProductProduced(){
173         if (exist()) {
174             if (productProduced == null) {
175                 try {
176                     List JavaDoc productionRunProducts = productionRun.getRelated("WorkEffortGoodStandard", UtilMisc.toMap("workEffortGoodStdTypeId", "PRUN_PROD_DELIV"),null);
177                     this.productionRunProduct = EntityUtil.getFirst(productionRunProducts);
178                     quantity = productionRunProduct.getDouble("estimatedQuantity");
179                     productProduced = productionRunProduct.getRelatedOneCache("Product");
180                 } catch (GenericEntityException e) {
181                     Debug.logWarning(e.getMessage(), module);
182                 }
183             }
184             return productProduced;
185         }
186         return null;
187     }
188     
189     /**
190      * get the quantity property.
191      * @return the quantity property
192      **/

193     public Double JavaDoc getQuantity(){
194         if (exist()) {
195             if (quantity == null) getProductProduced();
196             return quantity;
197         }
198         else return null;
199     }
200     /**
201      * set the quantity property and recalculated the productComponent quantity.
202      * @return
203      **/

204     public void setQuantity(Double JavaDoc newQuantity) {
205         if (quantity == null) getProductProduced();
206         double previousQuantity = quantity.doubleValue(), componentQuantity;
207         this.quantity = newQuantity;
208         this.quantityIsUpdated = true;
209         this.updateCompletionDate = true;
210         if (productionRunComponents == null) getProductionRunComponents();
211         for (Iterator JavaDoc iter = productionRunComponents.iterator(); iter.hasNext();){
212             GenericValue component = (GenericValue) iter.next();
213             componentQuantity = component.getDouble("estimatedQuantity").doubleValue();
214             component.set("estimatedQuantity", new Double JavaDoc(Math.floor((componentQuantity / previousQuantity * newQuantity.doubleValue() ) + 0.5)));
215         }
216         return;
217     }
218     /**
219      * get the estimatedStartDate property.
220      * @return the estimatedStartDate property
221      **/

222     public Timestamp JavaDoc getEstimatedStartDate(){
223         return (exist()? this.estimatedStartDate: null);
224     }
225     /**
226      * set the estimatedStartDate property.
227      * @return
228      **/

229     public void setEstimatedStartDate(Timestamp JavaDoc estimatedStartDate){
230         this.estimatedStartDate = estimatedStartDate;
231         this.updateCompletionDate = true;
232     }
233     /**
234      * get the estimatedCompletionDate property.
235      * @return the estimatedCompletionDate property
236      **/

237     public Timestamp JavaDoc getEstimatedCompletionDate(){
238         if (exist()) {
239             if (updateCompletionDate) {
240                 this.estimatedCompletionDate = recalculateEstimatedCompletionDate();
241             }
242             return this.estimatedCompletionDate;
243         }
244         else return null;
245     }
246     /**
247      * set the estimatedCompletionDate property without any control or calculation.
248      * usage productionRun.setEstimatedCompletionDate(productionRun.recalculateEstimatedCompletionDate(priority);
249      * @return
250      **/

251     public void setEstimatedCompletionDate(Timestamp JavaDoc estimatedCompletionDate){
252         this.estimatedCompletionDate = estimatedCompletionDate;
253     }
254     /**
255      * recalculated the estimatedCompletionDate property.
256      * Use the quantity and the estimatedStartDate properties as entries parameters.
257      * <br/>read the listRoutingTask and for each recalculated and update the estimatedStart and endDate in the object.
258      * <br/> no store in the database is done.
259      * @param priority give the routingTask start point to recalculated
260      * @return the estimatedCompletionDate calculated
261      **/

262     public Timestamp JavaDoc recalculateEstimatedCompletionDate(Long JavaDoc priority, Timestamp JavaDoc startDate){
263         if (exist()) {
264             getProductionRunRoutingTasks();
265             if (quantity == null) getQuantity();
266             Timestamp JavaDoc endDate=null;
267             for (Iterator JavaDoc iter=productionRunRoutingTasks.iterator(); iter.hasNext();){
268                 GenericValue routingTask = (GenericValue) iter.next();
269                 if (priority.compareTo(routingTask.getLong("priority")) <= 0){
270                     // Calculate the estimatedCompletionDate
271
long totalTime = ProductionRun.getEstimatedTaskTime(routingTask, quantity, dispatcher);
272                     endDate = TechDataServices.addForward(TechDataServices.getTechDataCalendar(routingTask),startDate, totalTime);
273                     // update the routingTask
274
routingTask.set("estimatedStartDate",startDate);
275                     routingTask.set("estimatedCompletionDate",endDate);
276                     startDate = endDate;
277                 }
278             }
279             return endDate;
280         } else {
281             return null;
282         }
283     }
284     /**
285      * call recalculateEstimatedCompletionDate(0,estimatedStartDate), so recalculated for all the routingtask.
286      */

287     public Timestamp JavaDoc recalculateEstimatedCompletionDate(){
288         this.updateCompletionDate = false;
289         return recalculateEstimatedCompletionDate(new Long JavaDoc(0), estimatedStartDate);
290     }
291     /**
292      * get the productionRunName property.
293      * @return the productionRunName property
294      **/

295     public String JavaDoc getProductionRunName(){
296         if (exist()) return this.productionRunName;
297         else return null;
298     }
299     public void setProductionRunName(String JavaDoc name){
300         this.productionRunName = name;
301     }
302     /**
303      * get the description property.
304      * @return the description property
305      **/

306     public String JavaDoc getDescription(){
307         if (exist()) return productionRun.getString("description");
308         else return null;
309     }
310     public void setDescription(String JavaDoc description){
311         this.description = description;
312     }
313     /**
314      * get the GenericValue currentStatus.
315      * @return the currentStatus related object
316      **/

317     public GenericValue getCurrentStatus(){
318         if (exist()) {
319             if (currentStatus == null) {
320                 try {
321                     currentStatus = productionRun.getRelatedOneCache("StatusItem");
322                 } catch (GenericEntityException e) {
323                     Debug.logWarning(e.getMessage(), module);
324                 }
325             }
326             return currentStatus;
327         }
328         return null;
329     }
330     /**
331      * get the list of all the productionRunComponents as a list of GenericValue.
332      * @return the productionRunComponents related object
333      **/

334     public List JavaDoc getProductionRunComponents(){
335         if (exist()) {
336             if (productionRunComponents == null) {
337                 if (productionRunRoutingTasks == null) this.getProductionRunRoutingTasks();
338                 if (productionRunRoutingTasks != null) {
339                     try {
340                         productionRunComponents = new LinkedList JavaDoc();
341                         GenericValue routingTask;
342                         for (Iterator JavaDoc iter=productionRunRoutingTasks.iterator(); iter.hasNext();) {
343                             routingTask = (GenericValue)iter.next();
344                             productionRunComponents.addAll(routingTask.getRelated("WorkEffortGoodStandard", UtilMisc.toMap("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED"),null));
345                         }
346                     } catch (GenericEntityException e) {
347                         Debug.logWarning(e.getMessage(), module);
348                     }
349                 }
350             }
351             return productionRunComponents;
352         }
353         return null;
354     }
355     /**
356      * get the list of all the productionRunRoutingTasks as a list of GenericValue.
357      * @return the productionRunRoutingTasks related object
358      **/

359     public List JavaDoc getProductionRunRoutingTasks(){
360         if (exist()) {
361             if (productionRunRoutingTasks == null) {
362                 try {
363                     productionRunRoutingTasks = productionRun.getRelated("ChildWorkEffort",UtilMisc.toMap("workEffortTypeId","PROD_ORDER_TASK"),UtilMisc.toList("priority"));
364                 } catch (GenericEntityException e) {
365                     Debug.logWarning(e.getMessage(), module);
366                 }
367             }
368             return productionRunRoutingTasks;
369         }
370         return null;
371     }
372     
373     /**
374      * get the list of all the productionRunRoutingTasks as a list of GenericValue.
375      * @return the productionRunRoutingTasks related object
376      **/

377     public GenericValue getLastProductionRunRoutingTask(){
378         if (exist()) {
379             if (productionRunRoutingTasks == null) {
380                 try {
381                     productionRunRoutingTasks = productionRun.getRelated("ChildWorkEffort",UtilMisc.toMap("workEffortTypeId","PROD_ORDER_TASK"),UtilMisc.toList("priority"));
382                 } catch (GenericEntityException e) {
383                     Debug.logWarning(e.getMessage(), module);
384                 }
385             }
386             return (GenericValue)(productionRunRoutingTasks != null && productionRunRoutingTasks.size() > 0? productionRunRoutingTasks.get(productionRunRoutingTasks.size() - 1): null);
387         }
388         return null;
389     }
390
391     /**
392      * clear list of all the productionRunRoutingTasks to force re-reading at the next need.
393      * This methode is used when the routingTasks ordering is changed.
394      * @return
395      **/

396     public void clearRoutingTasksList(){
397         this.productionRunRoutingTasks = null;
398     }
399     
400     /*
401      * FIXME: the three getEstimatedTaskTime(...) methods will be removed and
402      * implemented in the "getEstimatedTaskTime" service.
403      */

404     public static long getEstimatedTaskTime(GenericValue task, double quantity, LocalDispatcher dispatcher) {
405         return getEstimatedTaskTime(task, new Double JavaDoc(quantity), dispatcher);
406     }
407     public static long getEstimatedTaskTime(GenericValue task, Double JavaDoc quantity, LocalDispatcher dispatcher) {
408         return getEstimatedTaskTime(task, quantity, null, null, dispatcher);
409     }
410     public static long getEstimatedTaskTime(GenericValue task, Double JavaDoc quantity, String JavaDoc productId, String JavaDoc routingId, LocalDispatcher dispatcher) {
411         if (quantity == null) {
412             quantity = new Double JavaDoc(1);
413         }
414         if (task == null) return 0;
415         double setupTime = 0;
416         double taskTime = 1;
417         double totalTaskTime = 0;
418         if (task.get("estimatedSetupMillis") != null) {
419             setupTime = task.getDouble("estimatedSetupMillis").doubleValue();
420         }
421         if (task.get("estimatedMilliSeconds") != null) {
422             taskTime = task.getDouble("estimatedMilliSeconds").doubleValue();
423         }
424         totalTaskTime = (setupTime + taskTime * quantity.doubleValue());
425         // TODO
426
if (task.get("estimateCalcMethod") != null) {
427             String JavaDoc serviceName = null;
428             try {
429                 GenericValue genericService = task.getRelatedOne("CustomMethod");
430                 if (genericService != null && genericService.getString("customMethodName") != null) {
431                     serviceName = genericService.getString("customMethodName");
432                     // call the service
433
// and put the value in totalTaskTime
434
Map JavaDoc estimateCalcServiceMap = UtilMisc.toMap("workEffort", task, "quantity", quantity, "productId", productId, "routingId", routingId);
435                     Map JavaDoc serviceContext = UtilMisc.toMap("arguments", estimateCalcServiceMap);
436                     // serviceContext.put("userLogin", userLogin);
437
Map JavaDoc resultService = dispatcher.runSync(serviceName, serviceContext);
438                     totalTaskTime = ((Double JavaDoc)resultService.get("totalTime")).doubleValue();
439                 }
440             } catch(Exception JavaDoc exc) {
441                 Debug.logError(exc, "Problem calling the customMethod service " + serviceName);
442             }
443         }
444         
445         return (long) totalTaskTime;
446     }
447
448 }
449
Popular Tags