KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > shipment > packing > PackingSession


1 /*
2  * $Id$
3  *
4  * Copyright (c) 2001-2005 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.shipment.packing;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31
32 import javolution.util.FastMap;
33 import javolution.util.FastList;
34
35 import org.ofbiz.base.util.Debug;
36 import org.ofbiz.base.util.GeneralException;
37 import org.ofbiz.base.util.UtilFormatOut;
38 import org.ofbiz.base.util.UtilMisc;
39 import org.ofbiz.base.util.UtilValidate;
40 import org.ofbiz.entity.GenericDelegator;
41 import org.ofbiz.entity.GenericValue;
42 import org.ofbiz.entity.util.EntityUtil;
43 import org.ofbiz.service.GenericDispatcher;
44 import org.ofbiz.service.GenericServiceException;
45 import org.ofbiz.service.LocalDispatcher;
46 import org.ofbiz.service.ServiceUtil;
47 import org.ofbiz.product.product.ProductWorker;
48
49 /**
50  *
51  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
52  * @version $Rev: 6764 $
53  * @since Sep 1, 2005
54  */

55 public class PackingSession implements java.io.Serializable JavaDoc {
56
57     public static final String JavaDoc module = PackingSession.class.getName();
58
59     protected GenericValue userLogin = null;
60     protected String JavaDoc primaryOrderId = null;
61     protected String JavaDoc primaryShipGrp = null;
62     protected String JavaDoc dispatcherName = null;
63     protected String JavaDoc delegatorName = null;
64     protected String JavaDoc facilityId = null;
65     protected String JavaDoc shipmentId = null;
66     protected String JavaDoc instructions = null;
67     protected List JavaDoc packEvents = null;
68     protected List JavaDoc packLines = null;
69     protected int packageSeq = -1;
70     protected int status = 1;
71
72     private transient GenericDelegator _delegator = null;
73     private transient LocalDispatcher _dispatcher = null;
74
75     public PackingSession(LocalDispatcher dispatcher, GenericValue userLogin, String JavaDoc facilityId, String JavaDoc orderId, String JavaDoc shipGrp) {
76         this._dispatcher = dispatcher;
77         this.dispatcherName = dispatcher.getName();
78
79         this._delegator = _dispatcher.getDelegator();
80         this.delegatorName = _delegator.getDelegatorName();
81
82         this.primaryOrderId = orderId;
83         this.primaryShipGrp = shipGrp;
84         this.userLogin = userLogin;
85         this.facilityId = facilityId;
86         this.packLines = new ArrayList JavaDoc();
87         this.packEvents = new ArrayList JavaDoc();
88         this.packageSeq = 1;
89     }
90
91     public PackingSession(LocalDispatcher dispatcher, GenericValue userLogin, String JavaDoc facilityId) {
92         this(dispatcher, userLogin, facilityId, null, null);
93     }
94
95     public PackingSession(LocalDispatcher dispatcher, GenericValue userLogin) {
96         this(dispatcher, userLogin, null, null, null);
97     }
98
99     public void addOrIncreaseLine(String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId, String JavaDoc productId, double quantity, int packageSeqId) throws GeneralException {
100         // reset the session if we just completed
101
if (status == 0) {
102             throw new GeneralException("Packing session has been completed; be sure to CLEAR before packing a new order! [000]");
103         }
104
105         // find the actual product ID
106
productId = ProductWorker.findProductId(this.getDelegator(), productId);
107
108         // set the default null values - primary is the assumed first item
109
if (orderId == null) {
110             orderId = primaryOrderId;
111         }
112         if (shipGroupSeqId == null) {
113             shipGroupSeqId = primaryShipGrp;
114         }
115         if (orderItemSeqId == null && productId != null) {
116             orderItemSeqId = this.findOrderItemSeqId(productId, orderId, shipGroupSeqId, quantity);
117         }
118
119         // get the reservations for the item
120
Map JavaDoc invLookup = FastMap.newInstance();
121         invLookup.put("orderId", orderId);
122         invLookup.put("orderItemSeqId", orderItemSeqId);
123         invLookup.put("shipGroupSeqId", shipGroupSeqId);
124         List JavaDoc reservations = this.getDelegator().findByAnd("OrderItemShipGrpInvRes", invLookup);
125
126         // no reservations we cannot add this item
127
if (UtilValidate.isEmpty(reservations)) {
128             throw new GeneralException("No inventory reservations available; cannot pack this item! [101]");
129         }
130
131         // find the inventoryItemId to use
132
if (reservations.size() == 1) {
133             GenericValue res = EntityUtil.getFirst(reservations);
134             int checkCode = this.checkLineForAdd(res, orderId, orderItemSeqId, shipGroupSeqId, quantity, packageSeqId);
135             this.createPackLineItem(checkCode, res, orderId, orderItemSeqId, shipGroupSeqId, productId, quantity, packageSeqId);
136         } else {
137             // more than one reservation found
138
Map JavaDoc toCreateMap = FastMap.newInstance();
139             Iterator JavaDoc i = reservations.iterator();
140             double qtyRemain = quantity;
141
142             while (i.hasNext() && qtyRemain > 0) {
143                 GenericValue res = (GenericValue) i.next();
144                 double resQty = res.getDouble("quantity").doubleValue();
145                 double thisQty = resQty > qtyRemain ? qtyRemain : resQty;
146
147                 int thisCheck = this.checkLineForAdd(res, orderId, orderItemSeqId, shipGroupSeqId, thisQty, packageSeqId);
148                 switch (thisCheck) {
149                     case 2:
150                         Debug.log("Packing check returned '2' - new pack line will be created!", module);
151                         toCreateMap.put(res, new Double JavaDoc(resQty));
152                         qtyRemain -= resQty;
153                         break;
154                     case 1:
155                         Debug.log("Packing check returned '1' - existing pack line has been updated!", module);
156                         qtyRemain -= resQty;
157                         break;
158                     case 0:
159                         Debug.log("Packing check returned '0' - doing nothing.", module);
160                         break;
161                 }
162             }
163
164             if (qtyRemain == 0) {
165                 Iterator JavaDoc x = toCreateMap.keySet().iterator();
166                 while (x.hasNext()) {
167                     GenericValue res = (GenericValue) x.next();
168                     Double JavaDoc qty = (Double JavaDoc) toCreateMap.get(res);
169                     this.createPackLineItem(2, res, orderId, orderItemSeqId, shipGroupSeqId, productId, qty.doubleValue(), packageSeqId);
170                 }
171             } else {
172                 throw new GeneralException("Not enough inventory reservation available; cannot pack the item! [103]");
173             }
174         }
175
176         // run the add events
177
this.runEvents(PackingEvent.EVENT_CODE_ADD);
178     }
179
180     public void addOrIncreaseLine(String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId, double quantity, int packageSeqId) throws GeneralException {
181         this.addOrIncreaseLine(orderId, orderItemSeqId, shipGroupSeqId, null, quantity, packageSeqId);
182     }
183
184     public void addOrIncreaseLine(String JavaDoc productId, double quantity, int packageSeqId) throws GeneralException {
185         this.addOrIncreaseLine(null, null, null, productId, quantity, packageSeqId);
186     }
187
188     public PackingSessionLine findLine(String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId, String JavaDoc inventoryItemId, int packageSeq) {
189         List JavaDoc lines = this.getLines();
190         Iterator JavaDoc i = lines.iterator();
191         while (i.hasNext()) {
192             PackingSessionLine line = (PackingSessionLine) i.next();
193             if (orderId.equals(line.getOrderId()) &&
194                     orderItemSeqId.equals(line.getOrderItemSeqId()) &&
195                     shipGroupSeqId.equals(line.getShipGroupSeqId()) &&
196                     inventoryItemId.equals(line.getInventoryItemId()) &&
197                     packageSeq == line.getPackageSeq()) {
198                 return line;
199             }
200         }
201         return null;
202     }
203
204     protected void createPackLineItem(int checkCode, GenericValue res, String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId, String JavaDoc productId, double quantity, int packageSeqId) throws GeneralException {
205         // process the result; add new item if necessary
206
switch(checkCode) {
207             case 0:
208                 // not enough reserved
209
throw new GeneralException("Not enough inventory reservation available; cannot pack the item! [201]");
210             case 1:
211                 // we're all good to go; quantity already updated
212
break;
213             case 2:
214                 // need to create a new item
215
String JavaDoc invItemId = res.getString("inventoryItemId");
216                 packLines.add(new PackingSessionLine(orderId, orderItemSeqId, shipGroupSeqId, productId, invItemId, quantity, packageSeqId));
217                 break;
218         }
219
220         // update the package sequence
221
if (packageSeqId > packageSeq) {
222             this.packageSeq = packageSeqId;
223         }
224     }
225
226     protected String JavaDoc findOrderItemSeqId(String JavaDoc productId, String JavaDoc orderId, String JavaDoc shipGroupSeqId, double quantity) throws GeneralException {
227         Map JavaDoc lookupMap = FastMap.newInstance();
228         lookupMap.put("orderId", orderId);
229         lookupMap.put("productId", productId);
230         lookupMap.put("shipGroupSeqId", shipGroupSeqId);
231
232         List JavaDoc sort = UtilMisc.toList("-quantity");
233         List JavaDoc orderItems = this.getDelegator().findByAnd("OrderItemAndShipGroupAssoc", lookupMap, sort);
234
235         String JavaDoc orderItemSeqId = null;
236         if (orderItems != null) {
237             Iterator JavaDoc i = orderItems.iterator();
238             while (i.hasNext()) {
239                 GenericValue item = (GenericValue) i.next();
240                 Double JavaDoc qty = item.getDouble("quantity");
241                 if (quantity <= qty.doubleValue()) {
242                     orderItemSeqId = item.getString("orderItemSeqId");
243                     break;
244                 }
245             }
246         }
247
248         if (orderItemSeqId != null) {
249             return orderItemSeqId;
250         } else {
251             throw new GeneralException("No valid order item found for product [" + productId + "] with quantity: " + quantity);
252         }
253     }
254
255     protected int checkLineForAdd(GenericValue res, String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId, double quantity, int packageSeqId) {
256         // check to see if the reservation can hold the requested quantity amount
257
String JavaDoc invItemId = res.getString("inventoryItemId");
258         double resQty = res.getDouble("quantity").doubleValue();
259
260         PackingSessionLine line = this.findLine(orderId, orderItemSeqId, shipGroupSeqId, invItemId, packageSeqId);
261         if (line == null) {
262             Debug.log("No current line found testing [" + invItemId + "] R: " + resQty + " / Q: " + quantity, module);
263             if (resQty < quantity) {
264                 return 0;
265             } else {
266                 return 2;
267             }
268         } else {
269             double newQty = line.getQuantity() + quantity;
270             Debug.log("Existing line found testing [" + invItemId + "] R: " + resQty + " / Q: " + newQty, module);
271             if (resQty < newQty) {
272                 return 0;
273             } else {
274                 line.setQuantity(newQty);
275                 return 1;
276             }
277         }
278     }
279
280     public String JavaDoc getShipmentId() {
281         return this.shipmentId;
282     }
283
284     public List JavaDoc getLines() {
285         return this.packLines;
286     }
287
288     public int nextPackageSeq() {
289         return ++packageSeq;
290     }
291
292     public int getCurrentPackageSeq() {
293         return packageSeq;
294     }
295
296     public double getPackedQuantity(String JavaDoc orderId, String JavaDoc orderItemSeqId, String JavaDoc shipGroupSeqId) {
297         double total = 0.0;
298         List JavaDoc lines = this.getLines();
299         Iterator JavaDoc i = lines.iterator();
300         while (i.hasNext()) {
301             PackingSessionLine line = (PackingSessionLine) i.next();
302             if (orderId.equals(line.getOrderId()) && orderItemSeqId.equals(line.getOrderItemSeqId()) &&
303                     shipGroupSeqId.equals(line.getShipGroupSeqId())) {
304                 total += line.getQuantity();
305             }
306         }
307         return total;
308     }
309
310     public void registerEvent(PackingEvent event) {
311         this.packEvents.add(event);
312         this.runEvents(PackingEvent.EVENT_CODE_EREG);
313     }
314
315     public LocalDispatcher getDispatcher() {
316         if (_dispatcher == null) {
317             try {
318                 _dispatcher = GenericDispatcher.getLocalDispatcher(dispatcherName, this.getDelegator());
319             } catch (GenericServiceException e) {
320                 throw new RuntimeException JavaDoc(e);
321             }
322         }
323         return _dispatcher;
324     }
325
326     public GenericDelegator getDelegator() {
327         if (_delegator == null) {
328             _delegator = GenericDelegator.getGenericDelegator(delegatorName);
329         }
330         return _delegator;
331     }
332
333     public GenericValue getUserLogin() {
334         return this.userLogin;
335     }
336
337     public int getStatus() {
338         return this.status;
339     }
340
341     public String JavaDoc getFacilityId() {
342         return this.facilityId;
343     }
344
345     public void setFacilityId(String JavaDoc facilityId) {
346         this.facilityId = facilityId;
347     }
348
349     public String JavaDoc getPrimaryOrderId() {
350         return this.primaryOrderId;
351     }
352
353     public void setPrimaryOrderId(String JavaDoc orderId) {
354         this.primaryOrderId = orderId;
355     }
356
357     public String JavaDoc getPrimaryShipGroupSeqId() {
358         return this.primaryShipGrp;
359     }
360
361     public void setPrimaryShipGroupSeqId(String JavaDoc shipGroupSeqId) {
362         this.primaryShipGrp = shipGroupSeqId;
363     }
364
365     public String JavaDoc getHandlingInstructions() {
366         return this.instructions;
367     }
368
369     public void setHandlingInstructions(String JavaDoc instructions) {
370         this.instructions = instructions;
371     }
372
373     public void clearLine(PackingSessionLine line) {
374         this.packLines.remove(line);
375     }
376
377     public void clear() {
378         this.packLines.clear();
379         this.instructions = null;
380         this.primaryOrderId = null;
381         this.primaryShipGrp = null;
382         this.packageSeq = 1;
383         this.status = 1;
384         this.runEvents(PackingEvent.EVENT_CODE_CLEAR);
385     }
386
387     public String JavaDoc complete(boolean force) throws GeneralException {
388         if (this.getLines().size() == 0) {
389             return "EMPTY";
390         }
391
392         // check for errors
393
this.checkReservations(force);
394         // set the status to 0
395
this.status = 0;
396         // create the shipment
397
this.createShipment();
398         // create the packages
399
this.createPackages();
400         // issue the items
401
this.issueItemsToShipment();
402         // assign items to packages
403
this.applyItemsToPackages();
404         // set the shipment to packed
405
this.setShipmentToPacked();
406         // run the complete events
407
this.runEvents(PackingEvent.EVENT_CODE_COMPLETE);
408
409         return this.shipmentId;
410     }
411
412     protected void checkReservations(boolean ignore) throws GeneralException {
413         List JavaDoc errors = FastList.newInstance();
414         Iterator JavaDoc i = this.getLines().iterator();
415         while (i.hasNext()) {
416             PackingSessionLine line = (PackingSessionLine) i.next();
417             Map JavaDoc invLookup = FastMap.newInstance();
418             invLookup.put("orderId", line.getOrderId());
419             invLookup.put("orderItemSeqId", line.getOrderItemSeqId());
420             invLookup.put("shipGroupSeqId", line.getShipGroupSeqId());
421             invLookup.put("inventoryItemId", line.getInventoryItemId());
422             GenericValue res = this.getDelegator().findByPrimaryKey("OrderItemShipGrpInvRes", invLookup);
423             Double JavaDoc qty = res.getDouble("quantity");
424             if (qty == null) qty = new Double JavaDoc(0);
425
426             double resQty = qty.doubleValue();
427             double lineQty = line.getQuantity();
428
429             if (lineQty != resQty) {
430                 errors.add("Packed amount does not match reserved amount for item (" + line.getProductId() + ") [" + lineQty + " / " + resQty + "]");
431             }
432         }
433
434         if (errors.size() > 0) {
435             if (!ignore) {
436                 throw new GeneralException("Attempt to pack order failed. Click COMPLETE again to force.", errors);
437             } else {
438                 Debug.logWarning("Packing warnings: " + errors, module);
439             }
440         }
441     }
442
443     protected void runEvents(int eventCode) {
444         if (this.packEvents.size() > 0) {
445             Iterator JavaDoc i = this.packEvents.iterator();
446             while (i.hasNext()) {
447                 PackingEvent event = (PackingEvent) i.next();
448                 event.runEvent(this, eventCode);
449             }
450         }
451     }
452
453     protected void createShipment() throws GeneralException {
454         // first create the shipment
455
Map JavaDoc newShipment = FastMap.newInstance();
456         newShipment.put("originFacilityId", this.facilityId);
457         newShipment.put("primaryShipGroupSeqId", primaryShipGrp);
458         newShipment.put("primaryOrderId", primaryOrderId);
459         newShipment.put("shipmentTypeId", "OUTGOING_SHIPMENT");
460         newShipment.put("statusId", "SHIPMENT_INPUT");
461         newShipment.put("handlingInstructions", instructions);
462         newShipment.put("userLogin", userLogin);
463         Debug.log("Creating new shipment with context: " + newShipment, module);
464         Map JavaDoc newShipResp = this.getDispatcher().runSync("createShipment", newShipment);
465
466         if (ServiceUtil.isError(newShipResp)) {
467             throw new GeneralException(ServiceUtil.getErrorMessage(newShipResp));
468         }
469         this.shipmentId = (String JavaDoc) newShipResp.get("shipmentId");
470     }
471
472     protected void issueItemsToShipment() throws GeneralException {
473         List JavaDoc lines = this.getLines();
474         Iterator JavaDoc i = lines.iterator();
475         while (i.hasNext()) {
476             PackingSessionLine line = (PackingSessionLine) i.next();
477             line.issueItemToShipment(shipmentId, userLogin, getDispatcher());
478         }
479     }
480
481     protected void createPackages() throws GeneralException {
482         for (int i = 0; i < packageSeq; i++) {
483             String JavaDoc shipmentPackageSeqId = UtilFormatOut.formatPaddedNumber(i+1, 5);
484
485             Map JavaDoc pkgCtx = FastMap.newInstance();
486             pkgCtx.put("shipmentId", shipmentId);
487             pkgCtx.put("shipmentPackageSeqId", shipmentPackageSeqId);
488             //pkgCtx.put("shipmentBoxTypeId", "");
489
pkgCtx.put("userLogin", userLogin);
490             Map JavaDoc newPkgResp = this.getDispatcher().runSync("createShipmentPackage", pkgCtx);
491
492             if (ServiceUtil.isError(newPkgResp)) {
493                 throw new GeneralException(ServiceUtil.getErrorMessage(newPkgResp));
494             }
495         }
496     }
497
498     protected void applyItemsToPackages() throws GeneralException {
499         List JavaDoc lines = this.getLines();
500         Iterator JavaDoc i = lines.iterator();
501         while (i.hasNext()) {
502             PackingSessionLine line = (PackingSessionLine) i.next();
503             line.applyLineToPackage(shipmentId, userLogin, getDispatcher());
504         }
505     }
506
507     protected void setShipmentToPacked() throws GeneralException {
508         Map JavaDoc packedCtx = UtilMisc.toMap("shipmentId", shipmentId, "statusId", "SHIPMENT_PACKED", "userLogin", userLogin);
509         Map JavaDoc packedResp = this.getDispatcher().runSync("updateShipment", packedCtx);
510         if (packedResp != null && ServiceUtil.isError(packedResp)) {
511             throw new GeneralException(ServiceUtil.getErrorMessage(packedResp));
512         }
513     }
514 }
515
Popular Tags