0001: /*******************************************************************************
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: *******************************************************************************/package org.ofbiz.shipment.packing;
0019:
0020: import java.util.*;
0021:
0022: import javolution.util.FastMap;
0023: import javolution.util.FastList;
0024: import javolution.util.FastSet;
0025:
0026: import org.ofbiz.base.util.Debug;
0027: import org.ofbiz.base.util.GeneralException;
0028: import org.ofbiz.base.util.UtilFormatOut;
0029: import org.ofbiz.base.util.UtilMisc;
0030: import org.ofbiz.base.util.UtilValidate;
0031: import org.ofbiz.entity.GenericDelegator;
0032: import org.ofbiz.entity.GenericValue;
0033: import org.ofbiz.entity.GenericEntityException;
0034: import org.ofbiz.entity.util.EntityUtil;
0035: import org.ofbiz.service.GenericDispatcher;
0036: import org.ofbiz.service.GenericServiceException;
0037: import org.ofbiz.service.LocalDispatcher;
0038: import org.ofbiz.service.ServiceUtil;
0039: import org.ofbiz.product.product.ProductWorker;
0040:
0041: public class PackingSession implements java.io.Serializable {
0042:
0043: public static final String module = PackingSession.class.getName();
0044:
0045: protected GenericValue userLogin = null;
0046: protected String pickerPartyId = null;
0047: protected String primaryOrderId = null;
0048: protected String primaryShipGrp = null;
0049: protected String dispatcherName = null;
0050: protected String delegatorName = null;
0051: protected String picklistBinId = null;
0052: protected String facilityId = null;
0053: protected String shipmentId = null;
0054: protected String instructions = null;
0055: protected String weightUomId = null;
0056: protected Double additionalShippingCharge = null;
0057: protected Map packageWeights = null;
0058: protected List packEvents = null;
0059: protected List packLines = null;
0060: protected int packageSeq = -1;
0061: protected int status = 1;
0062:
0063: private transient GenericDelegator _delegator = null;
0064: private transient LocalDispatcher _dispatcher = null;
0065:
0066: public PackingSession(LocalDispatcher dispatcher,
0067: GenericValue userLogin, String facilityId, String binId,
0068: String orderId, String shipGrp) {
0069: this ._dispatcher = dispatcher;
0070: this .dispatcherName = dispatcher.getName();
0071:
0072: this ._delegator = _dispatcher.getDelegator();
0073: this .delegatorName = _delegator.getDelegatorName();
0074:
0075: this .primaryOrderId = orderId;
0076: this .primaryShipGrp = shipGrp;
0077: this .picklistBinId = binId;
0078: this .userLogin = userLogin;
0079: this .facilityId = facilityId;
0080: this .packLines = new ArrayList();
0081: this .packEvents = new ArrayList();
0082: this .packageSeq = 1;
0083: this .packageWeights = new HashMap();
0084: }
0085:
0086: public PackingSession(LocalDispatcher dispatcher,
0087: GenericValue userLogin, String facilityId) {
0088: this (dispatcher, userLogin, facilityId, null, null, null);
0089: }
0090:
0091: public PackingSession(LocalDispatcher dispatcher,
0092: GenericValue userLogin) {
0093: this (dispatcher, userLogin, null, null, null, null);
0094: }
0095:
0096: public void addOrIncreaseLine(String orderId,
0097: String orderItemSeqId, String shipGroupSeqId,
0098: String productId, double quantity, int packageSeqId,
0099: double weight, boolean update) throws GeneralException {
0100: // reset the session if we just completed
0101: if (status == 0) {
0102: throw new GeneralException(
0103: "Packing session has been completed; be sure to CLEAR before packing a new order! [000]");
0104: }
0105:
0106: // do nothing if we are trying to add a quantity of 0
0107: if (!update && quantity == 0) {
0108: return;
0109: }
0110:
0111: // find the actual product ID
0112: productId = ProductWorker.findProductId(this .getDelegator(),
0113: productId);
0114:
0115: // set the default null values - primary is the assumed first item
0116: if (orderId == null) {
0117: orderId = primaryOrderId;
0118: }
0119: if (shipGroupSeqId == null) {
0120: shipGroupSeqId = primaryShipGrp;
0121: }
0122: if (orderItemSeqId == null && productId != null) {
0123: orderItemSeqId = this .findOrderItemSeqId(productId,
0124: orderId, shipGroupSeqId, quantity);
0125: }
0126:
0127: // get the reservations for the item
0128: Map invLookup = FastMap.newInstance();
0129: invLookup.put("orderId", orderId);
0130: invLookup.put("orderItemSeqId", orderItemSeqId);
0131: invLookup.put("shipGroupSeqId", shipGroupSeqId);
0132: List reservations = this .getDelegator().findByAnd(
0133: "OrderItemShipGrpInvRes", invLookup,
0134: UtilMisc.toList("quantity DESC"));
0135:
0136: // no reservations we cannot add this item
0137: if (UtilValidate.isEmpty(reservations)) {
0138: throw new GeneralException(
0139: "No inventory reservations available; cannot pack this item! [101]");
0140: }
0141:
0142: // find the inventoryItemId to use
0143: if (reservations.size() == 1) {
0144: GenericValue res = EntityUtil.getFirst(reservations);
0145: int checkCode = this .checkLineForAdd(res, orderId,
0146: orderItemSeqId, shipGroupSeqId, quantity,
0147: packageSeqId, update);
0148: this .createPackLineItem(checkCode, res, orderId,
0149: orderItemSeqId, shipGroupSeqId, productId,
0150: quantity, weight, packageSeqId);
0151: } else {
0152: // more than one reservation found
0153: Map toCreateMap = FastMap.newInstance();
0154: Iterator i = reservations.iterator();
0155: double qtyRemain = quantity;
0156:
0157: while (i.hasNext() && qtyRemain > 0) {
0158: GenericValue res = (GenericValue) i.next();
0159: double resQty = res.getDouble("quantity").doubleValue();
0160: double resPackedQty = this .getPackedQuantity(orderId,
0161: orderItemSeqId, shipGroupSeqId, res
0162: .getString("inventoryItemId"), -1);
0163: if (resPackedQty >= resQty) {
0164: continue;
0165: } else if (!update) {
0166: resQty -= resPackedQty;
0167: }
0168:
0169: double this Qty = resQty > qtyRemain ? qtyRemain
0170: : resQty;
0171:
0172: int this Check = this .checkLineForAdd(res, orderId,
0173: orderItemSeqId, shipGroupSeqId, this Qty,
0174: packageSeqId, update);
0175: switch (this Check) {
0176: case 2:
0177: Debug
0178: .log(
0179: "Packing check returned '2' - new pack line will be created!",
0180: module);
0181: toCreateMap.put(res, new Double(this Qty));
0182: qtyRemain -= this Qty;
0183: break;
0184: case 1:
0185: Debug
0186: .log(
0187: "Packing check returned '1' - existing pack line has been updated!",
0188: module);
0189: qtyRemain -= this Qty;
0190: break;
0191: case 0:
0192: Debug
0193: .log(
0194: "Packing check returned '0' - doing nothing.",
0195: module);
0196: break;
0197: }
0198: }
0199:
0200: if (qtyRemain == 0) {
0201: Iterator x = toCreateMap.keySet().iterator();
0202: while (x.hasNext()) {
0203: GenericValue res = (GenericValue) x.next();
0204: Double qty = (Double) toCreateMap.get(res);
0205: this .createPackLineItem(2, res, orderId,
0206: orderItemSeqId, shipGroupSeqId, productId,
0207: qty.doubleValue(), weight, packageSeqId);
0208: }
0209: } else {
0210: throw new GeneralException(
0211: "Not enough inventory reservation available; cannot pack the item! [103]");
0212: }
0213: }
0214:
0215: // run the add events
0216: this .runEvents(PackingEvent.EVENT_CODE_ADD);
0217: }
0218:
0219: public void addOrIncreaseLine(String orderId,
0220: String orderItemSeqId, String shipGroupSeqId,
0221: double quantity, int packageSeqId) throws GeneralException {
0222: this .addOrIncreaseLine(orderId, orderItemSeqId, shipGroupSeqId,
0223: null, quantity, packageSeqId, 0, false);
0224: }
0225:
0226: public void addOrIncreaseLine(String productId, double quantity,
0227: int packageSeqId) throws GeneralException {
0228: this .addOrIncreaseLine(null, null, null, productId, quantity,
0229: packageSeqId, 0, false);
0230: }
0231:
0232: public PackingSessionLine findLine(String orderId,
0233: String orderItemSeqId, String shipGroupSeqId,
0234: String inventoryItemId, int packageSeq) {
0235: List lines = this .getLines();
0236: Iterator i = lines.iterator();
0237: while (i.hasNext()) {
0238: PackingSessionLine line = (PackingSessionLine) i.next();
0239: if (orderId.equals(line.getOrderId())
0240: && orderItemSeqId.equals(line.getOrderItemSeqId())
0241: && shipGroupSeqId.equals(line.getShipGroupSeqId())
0242: && inventoryItemId
0243: .equals(line.getInventoryItemId())
0244: && packageSeq == line.getPackageSeq()) {
0245: return line;
0246: }
0247: }
0248: return null;
0249: }
0250:
0251: protected void createPackLineItem(int checkCode, GenericValue res,
0252: String orderId, String orderItemSeqId,
0253: String shipGroupSeqId, String productId, double quantity,
0254: double weight, int packageSeqId) throws GeneralException {
0255: // process the result; add new item if necessary
0256: switch (checkCode) {
0257: case 0:
0258: // not enough reserved
0259: throw new GeneralException(
0260: "Not enough inventory reservation available; cannot pack the item! [201]");
0261: case 1:
0262: // we're all good to go; quantity already updated
0263: break;
0264: case 2:
0265: // need to create a new item
0266: String invItemId = res.getString("inventoryItemId");
0267: packLines.add(new PackingSessionLine(orderId,
0268: orderItemSeqId, shipGroupSeqId, productId,
0269: invItemId, quantity, weight, packageSeqId));
0270: break;
0271: }
0272:
0273: // Add the line weight to the package weight
0274: if (weight > 0)
0275: this .addToPackageWeight(packageSeqId, new Double(weight));
0276:
0277: // update the package sequence
0278: if (packageSeqId > packageSeq) {
0279: this .packageSeq = packageSeqId;
0280: }
0281: }
0282:
0283: protected String findOrderItemSeqId(String productId,
0284: String orderId, String shipGroupSeqId, double quantity)
0285: throws GeneralException {
0286: Map lookupMap = FastMap.newInstance();
0287: lookupMap.put("orderId", orderId);
0288: lookupMap.put("productId", productId);
0289: lookupMap.put("statusId", "ITEM_APPROVED");
0290: lookupMap.put("shipGroupSeqId", shipGroupSeqId);
0291:
0292: List sort = UtilMisc.toList("-quantity");
0293: List orderItems = this .getDelegator().findByAnd(
0294: "OrderItemAndShipGroupAssoc", lookupMap, sort);
0295:
0296: String orderItemSeqId = null;
0297: if (orderItems != null) {
0298: Iterator i = orderItems.iterator();
0299: while (i.hasNext()) {
0300: GenericValue item = (GenericValue) i.next();
0301:
0302: // get the reservations for the item
0303: Map invLookup = FastMap.newInstance();
0304: invLookup.put("orderId", orderId);
0305: invLookup.put("orderItemSeqId", item
0306: .getString("orderItemSeqId"));
0307: invLookup.put("shipGroupSeqId", shipGroupSeqId);
0308: List reservations = this .getDelegator().findByAnd(
0309: "OrderItemShipGrpInvRes", invLookup);
0310: Iterator resIter = reservations.iterator();
0311: while (resIter.hasNext()) {
0312: GenericValue res = (GenericValue) resIter.next();
0313: Double qty = res.getDouble("quantity");
0314: if (quantity <= qty.doubleValue()) {
0315: orderItemSeqId = item
0316: .getString("orderItemSeqId");
0317: break;
0318: }
0319: }
0320: }
0321: }
0322:
0323: if (orderItemSeqId != null) {
0324: return orderItemSeqId;
0325: } else {
0326: throw new GeneralException(
0327: "No valid order item found for product ["
0328: + productId + "] with quantity: "
0329: + quantity);
0330: }
0331: }
0332:
0333: protected int checkLineForAdd(GenericValue res, String orderId,
0334: String orderItemSeqId, String shipGroupSeqId,
0335: double quantity, int packageSeqId, boolean update) {
0336: // check to see if the reservation can hold the requested quantity amount
0337: String invItemId = res.getString("inventoryItemId");
0338: double resQty = res.getDouble("quantity").doubleValue();
0339:
0340: PackingSessionLine line = this
0341: .findLine(orderId, orderItemSeqId, shipGroupSeqId,
0342: invItemId, packageSeqId);
0343: double packedQty = this .getPackedQuantity(orderId,
0344: orderItemSeqId, shipGroupSeqId);
0345:
0346: Debug.log("Packed quantity [" + packedQty + "] + [" + quantity
0347: + "]", module);
0348:
0349: if (line == null) {
0350: Debug.log("No current line found testing [" + invItemId
0351: + "] R: " + resQty + " / Q: " + quantity, module);
0352: if (resQty < quantity) {
0353: return 0;
0354: } else {
0355: return 2;
0356: }
0357: } else {
0358: double newQty = update ? quantity
0359: : (line.getQuantity() + quantity);
0360: Debug.log("Existing line found testing [" + invItemId
0361: + "] R: " + resQty + " / Q: " + newQty, module);
0362: if (resQty < newQty) {
0363: return 0;
0364: } else {
0365: line.setQuantity(newQty);
0366: return 1;
0367: }
0368: }
0369: }
0370:
0371: public String getShipmentId() {
0372: return this .shipmentId;
0373: }
0374:
0375: public List getLines() {
0376: return this .packLines;
0377: }
0378:
0379: public int nextPackageSeq() {
0380: return ++packageSeq;
0381: }
0382:
0383: public int getCurrentPackageSeq() {
0384: return packageSeq;
0385: }
0386:
0387: public double getPackedQuantity(String orderId,
0388: String orderItemSeqId, String shipGroupSeqId) {
0389: return getPackedQuantity(orderId, orderItemSeqId,
0390: shipGroupSeqId, null, -1);
0391: }
0392:
0393: public double getPackedQuantity(String orderId,
0394: String orderItemSeqId, String shipGroupSeqId, int packageSeq) {
0395: return getPackedQuantity(orderId, orderItemSeqId,
0396: shipGroupSeqId, null, packageSeq);
0397: }
0398:
0399: public double getPackedQuantity(String orderId,
0400: String orderItemSeqId, String shipGroupSeqId,
0401: String inventoryItemId, int packageSeq) {
0402: double total = 0.0;
0403: List lines = this .getLines();
0404: Iterator i = lines.iterator();
0405: while (i.hasNext()) {
0406: PackingSessionLine line = (PackingSessionLine) i.next();
0407: if (orderId.equals(line.getOrderId())
0408: && orderItemSeqId.equals(line.getOrderItemSeqId())
0409: && shipGroupSeqId.equals(line.getShipGroupSeqId())) {
0410: if (inventoryItemId == null
0411: || inventoryItemId.equals(line
0412: .getInventoryItemId())) {
0413: if (packageSeq == -1
0414: || packageSeq == line.getPackageSeq()) {
0415: total += line.getQuantity();
0416: }
0417: }
0418: }
0419: }
0420: return total;
0421: }
0422:
0423: public double getPackedQuantity(String productId, int packageSeq) {
0424: if (productId != null) {
0425: try {
0426: productId = ProductWorker.findProductId(this
0427: .getDelegator(), productId);
0428: } catch (GenericEntityException e) {
0429: Debug.logError(e, module);
0430: }
0431: }
0432:
0433: double total = 0.0;
0434: if (productId != null) {
0435: List lines = this .getLines();
0436: Iterator i = lines.iterator();
0437: while (i.hasNext()) {
0438: PackingSessionLine line = (PackingSessionLine) i.next();
0439: if (productId.equals(line.getProductId())) {
0440: if (packageSeq == -1
0441: || packageSeq == line.getPackageSeq()) {
0442: total += line.getQuantity();
0443: }
0444: }
0445: }
0446: }
0447: return total;
0448: }
0449:
0450: public double getPackedQuantity(int packageSeq) {
0451: double total = 0.0;
0452: List lines = this .getLines();
0453: Iterator i = lines.iterator();
0454: while (i.hasNext()) {
0455: PackingSessionLine line = (PackingSessionLine) i.next();
0456: if (packageSeq == -1 || packageSeq == line.getPackageSeq()) {
0457: total += line.getQuantity();
0458: }
0459: }
0460: return total;
0461: }
0462:
0463: public double getPackedQuantity(String productId) {
0464: return getPackedQuantity(productId, -1);
0465: }
0466:
0467: public double getCurrentReservedQuantity(String orderId,
0468: String orderItemSeqId, String shipGroupSeqId) {
0469: double reserved = -1;
0470: List res = null;
0471: try {
0472: res = this .getDelegator().findByAnd(
0473: "OrderItemShipGrpInvRes",
0474: UtilMisc.toMap("orderId", orderId,
0475: "orderItemSeqId", orderItemSeqId,
0476: "shipGroupSeqId", shipGroupSeqId));
0477: } catch (GenericEntityException e) {
0478: Debug.logError(e, module);
0479: }
0480:
0481: if (res != null) {
0482: reserved = 0.0;
0483: Iterator i = res.iterator();
0484: while (i.hasNext()) {
0485: GenericValue v = (GenericValue) i.next();
0486: Double not = v.getDouble("quantityNotAvailable");
0487: Double qty = v.getDouble("quantity");
0488: if (not == null)
0489: not = new Double(0);
0490: if (qty == null)
0491: qty = new Double(0);
0492: reserved += (qty.doubleValue() - not.doubleValue());
0493: }
0494: }
0495:
0496: return reserved;
0497: }
0498:
0499: public double getCurrentShippedQuantity(String orderId,
0500: String orderItemSeqId, String shipGroupSeqId) {
0501: double shipped = 0.0;
0502: List issues = this .getItemIssuances(orderId, orderItemSeqId,
0503: shipGroupSeqId);
0504: if (issues != null) {
0505: Iterator i = issues.iterator();
0506: while (i.hasNext()) {
0507: GenericValue v = (GenericValue) i.next();
0508: Double qty = v.getDouble("quantity");
0509: if (qty == null)
0510: qty = new Double(0);
0511: shipped += qty.doubleValue();
0512: }
0513: }
0514:
0515: return shipped;
0516: }
0517:
0518: public List getCurrentShipmentIds(String orderId,
0519: String orderItemSeqId, String shipGroupSeqId) {
0520: Set shipmentIds = FastSet.newInstance();
0521: List issues = this .getItemIssuances(orderId, orderItemSeqId,
0522: shipGroupSeqId);
0523:
0524: if (issues != null) {
0525: Iterator i = issues.iterator();
0526: while (i.hasNext()) {
0527: GenericValue v = (GenericValue) i.next();
0528: shipmentIds.add(v.getString("shipmentId"));
0529: }
0530: }
0531:
0532: List retList = FastList.newInstance();
0533: retList.addAll(shipmentIds);
0534: return retList;
0535: }
0536:
0537: public List getCurrentShipmentIds(String orderId,
0538: String shipGroupSeqId) {
0539: return this
0540: .getCurrentShipmentIds(orderId, null, shipGroupSeqId);
0541: }
0542:
0543: public void registerEvent(PackingEvent event) {
0544: this .packEvents.add(event);
0545: this .runEvents(PackingEvent.EVENT_CODE_EREG);
0546: }
0547:
0548: public LocalDispatcher getDispatcher() {
0549: if (_dispatcher == null) {
0550: _dispatcher = GenericDispatcher.getLocalDispatcher(
0551: dispatcherName, this .getDelegator());
0552: }
0553: return _dispatcher;
0554: }
0555:
0556: public GenericDelegator getDelegator() {
0557: if (_delegator == null) {
0558: _delegator = GenericDelegator
0559: .getGenericDelegator(delegatorName);
0560: }
0561: return _delegator;
0562: }
0563:
0564: public GenericValue getUserLogin() {
0565: return this .userLogin;
0566: }
0567:
0568: public int getStatus() {
0569: return this .status;
0570: }
0571:
0572: public String getFacilityId() {
0573: return this .facilityId;
0574: }
0575:
0576: public void setFacilityId(String facilityId) {
0577: this .facilityId = facilityId;
0578: }
0579:
0580: public String getPrimaryOrderId() {
0581: return this .primaryOrderId;
0582: }
0583:
0584: public void setPrimaryOrderId(String orderId) {
0585: this .primaryOrderId = orderId;
0586: }
0587:
0588: public String getPrimaryShipGroupSeqId() {
0589: return this .primaryShipGrp;
0590: }
0591:
0592: public void setPrimaryShipGroupSeqId(String shipGroupSeqId) {
0593: this .primaryShipGrp = shipGroupSeqId;
0594: }
0595:
0596: public void setPicklistBinId(String binId) {
0597: this .picklistBinId = binId;
0598: }
0599:
0600: public String getPicklistBinId() {
0601: return this .picklistBinId;
0602: }
0603:
0604: public String getHandlingInstructions() {
0605: return this .instructions;
0606: }
0607:
0608: public void setHandlingInstructions(String instructions) {
0609: this .instructions = instructions;
0610: }
0611:
0612: public void setPickerPartyId(String partyId) {
0613: this .pickerPartyId = partyId;
0614: }
0615:
0616: public String getPickerPartyId() {
0617: return this .pickerPartyId;
0618: }
0619:
0620: public int clearLastPackage() {
0621: if (packageSeq == 1) {
0622: this .clear();
0623: return packageSeq;
0624: }
0625:
0626: List currentLines = new ArrayList(this .packLines);
0627: Iterator i = currentLines.iterator();
0628: while (i.hasNext()) {
0629: PackingSessionLine line = (PackingSessionLine) i.next();
0630: if (line.getPackageSeq() == packageSeq) {
0631: this .clearLine(line);
0632: }
0633: }
0634: return --packageSeq;
0635: }
0636:
0637: public void clearLine(PackingSessionLine line) {
0638: this .packLines.remove(line);
0639: }
0640:
0641: public void clearAllLines() {
0642: this .packLines.clear();
0643: }
0644:
0645: public void clear() {
0646: this .packLines.clear();
0647: this .instructions = null;
0648: this .pickerPartyId = null;
0649: this .picklistBinId = null;
0650: this .primaryOrderId = null;
0651: this .primaryShipGrp = null;
0652: this .additionalShippingCharge = null;
0653: if (this .packageWeights != null)
0654: this .packageWeights.clear();
0655: this .weightUomId = null;
0656: this .packageSeq = 1;
0657: this .status = 1;
0658: this .runEvents(PackingEvent.EVENT_CODE_CLEAR);
0659: }
0660:
0661: public String complete(boolean force) throws GeneralException {
0662: // clear out empty lines
0663: // this.checkEmptyLines(); // removing, this seems to be causeing issues - mja
0664:
0665: // check to see if there is anything to process
0666: if (this .getLines().size() == 0) {
0667: return "EMPTY";
0668: }
0669:
0670: // check for errors
0671: this .checkReservations(force);
0672: // set the status to 0
0673: this .status = 0;
0674: // create the shipment
0675: this .createShipment();
0676: // create the packages
0677: this .createPackages();
0678: // issue the items
0679: this .issueItemsToShipment();
0680: // assign items to packages
0681: this .applyItemsToPackages();
0682: // update ShipmentRouteSegments with total weight and weightUomId
0683: this .updateShipmentRouteSegments();
0684: // set the shipment to packed
0685: this .setShipmentToPacked();
0686: // set role on picklist
0687: this .setPickerOnPicklist();
0688: // run the complete events
0689: this .runEvents(PackingEvent.EVENT_CODE_COMPLETE);
0690:
0691: return this .shipmentId;
0692: }
0693:
0694: protected void checkReservations(boolean ignore)
0695: throws GeneralException {
0696: List errors = FastList.newInstance();
0697: Iterator i = this .getLines().iterator();
0698: while (i.hasNext()) {
0699: PackingSessionLine line = (PackingSessionLine) i.next();
0700: double reservedQty = this .getCurrentReservedQuantity(line
0701: .getOrderId(), line.getOrderItemSeqId(), line
0702: .getShipGroupSeqId());
0703: double packedQty = this .getPackedQuantity(
0704: line.getOrderId(), line.getOrderItemSeqId(), line
0705: .getShipGroupSeqId());
0706:
0707: if (packedQty != reservedQty) {
0708: errors
0709: .add("Packed amount does not match reserved amount for item ("
0710: + line.getProductId()
0711: + ") ["
0712: + packedQty + " / " + reservedQty + "]");
0713: }
0714: }
0715:
0716: if (errors.size() > 0) {
0717: if (!ignore) {
0718: throw new GeneralException(
0719: "Attempt to pack order failed.", errors);
0720: } else {
0721: Debug.logWarning("Packing warnings: " + errors, module);
0722: }
0723: }
0724: }
0725:
0726: protected void checkEmptyLines() throws GeneralException {
0727: List lines = FastList.newInstance();
0728: lines.addAll(this .getLines());
0729: Iterator i = lines.iterator();
0730: while (i.hasNext()) {
0731: PackingSessionLine l = (PackingSessionLine) i.next();
0732: if (l.getQuantity() == 0) {
0733: this .packLines.remove(l);
0734: }
0735: }
0736: }
0737:
0738: protected void runEvents(int eventCode) {
0739: if (this .packEvents.size() > 0) {
0740: Iterator i = this .packEvents.iterator();
0741: while (i.hasNext()) {
0742: PackingEvent event = (PackingEvent) i.next();
0743: event.runEvent(this , eventCode);
0744: }
0745: }
0746: }
0747:
0748: protected List getItemIssuances(String orderId,
0749: String orderItemSeqId, String shipGroupSeqId) {
0750: List issues = null;
0751: if (orderId == null) {
0752: throw new IllegalArgumentException(
0753: "Value for orderId is null");
0754: }
0755:
0756: Map lookupMap = FastMap.newInstance();
0757: lookupMap.put("orderId", orderId);
0758: if (UtilValidate.isNotEmpty(orderItemSeqId)) {
0759: lookupMap.put("orderItemSeqId", orderItemSeqId);
0760: }
0761: if (UtilValidate.isNotEmpty(shipGroupSeqId)) {
0762: lookupMap.put("shipGroupSeqId", shipGroupSeqId);
0763: }
0764: try {
0765: issues = this .getDelegator().findByAnd("ItemIssuance",
0766: lookupMap);
0767: } catch (GenericEntityException e) {
0768: Debug.logError(e, module);
0769: }
0770:
0771: return issues;
0772: }
0773:
0774: protected void createShipment() throws GeneralException {
0775: // first create the shipment
0776: Map newShipment = FastMap.newInstance();
0777: newShipment.put("originFacilityId", this .facilityId);
0778: newShipment.put("primaryShipGroupSeqId", primaryShipGrp);
0779: newShipment.put("primaryOrderId", primaryOrderId);
0780: newShipment.put("shipmentTypeId", "OUTGOING_SHIPMENT");
0781: newShipment.put("statusId", "SHIPMENT_INPUT");
0782: newShipment.put("handlingInstructions", instructions);
0783: newShipment.put("picklistBinId", picklistBinId);
0784: newShipment.put("additionalShippingCharge",
0785: additionalShippingCharge);
0786: newShipment.put("userLogin", userLogin);
0787: Debug.log("Creating new shipment with context: " + newShipment,
0788: module);
0789: Map newShipResp = this .getDispatcher().runSync(
0790: "createShipment", newShipment);
0791:
0792: if (ServiceUtil.isError(newShipResp)) {
0793: throw new GeneralException(ServiceUtil
0794: .getErrorMessage(newShipResp));
0795: }
0796: this .shipmentId = (String) newShipResp.get("shipmentId");
0797: }
0798:
0799: protected void issueItemsToShipment() throws GeneralException {
0800: List processedLines = FastList.newInstance();
0801: List lines = this .getLines();
0802: Iterator i = lines.iterator();
0803: while (i.hasNext()) {
0804: PackingSessionLine line = (PackingSessionLine) i.next();
0805: if (this .checkLine(processedLines, line)) {
0806: double totalPacked = this .getPackedQuantity(line
0807: .getOrderId(), line.getOrderItemSeqId(), line
0808: .getShipGroupSeqId(),
0809: line.getInventoryItemId(), -1);
0810:
0811: line.issueItemToShipment(shipmentId, picklistBinId,
0812: userLogin, new Double(totalPacked),
0813: getDispatcher());
0814: processedLines.add(line);
0815: }
0816: }
0817: }
0818:
0819: protected boolean checkLine(List processedLines,
0820: PackingSessionLine line) {
0821: Iterator i = processedLines.iterator();
0822: while (i.hasNext()) {
0823: PackingSessionLine l = (PackingSessionLine) i.next();
0824: if (line.isSameItem(l)) {
0825: line.setShipmentItemSeqId(l.getShipmentItemSeqId());
0826: return false;
0827: }
0828: }
0829:
0830: return true;
0831: }
0832:
0833: protected void createPackages() throws GeneralException {
0834: for (int i = 0; i < packageSeq; i++) {
0835: String shipmentPackageSeqId = UtilFormatOut
0836: .formatPaddedNumber(i + 1, 5);
0837:
0838: Map pkgCtx = FastMap.newInstance();
0839: pkgCtx.put("shipmentId", shipmentId);
0840: pkgCtx.put("shipmentPackageSeqId", shipmentPackageSeqId);
0841: //pkgCtx.put("shipmentBoxTypeId", "");
0842: pkgCtx.put("weight", getPackageWeight(i + 1));
0843: pkgCtx.put("weightUomId", getWeightUomId());
0844: pkgCtx.put("userLogin", userLogin);
0845: Map newPkgResp = this .getDispatcher().runSync(
0846: "createShipmentPackage", pkgCtx);
0847:
0848: if (ServiceUtil.isError(newPkgResp)) {
0849: throw new GeneralException(ServiceUtil
0850: .getErrorMessage(newPkgResp));
0851: }
0852: }
0853: }
0854:
0855: protected void applyItemsToPackages() throws GeneralException {
0856: List lines = this .getLines();
0857: Iterator i = lines.iterator();
0858: while (i.hasNext()) {
0859: PackingSessionLine line = (PackingSessionLine) i.next();
0860: line.applyLineToPackage(shipmentId, userLogin,
0861: getDispatcher());
0862: }
0863: }
0864:
0865: protected void updateShipmentRouteSegments()
0866: throws GeneralException {
0867: Double shipmentWeight = new Double(getTotalWeight());
0868: if (shipmentWeight.doubleValue() <= 0)
0869: return;
0870: List shipmentRouteSegments = getDelegator().findByAnd(
0871: "ShipmentRouteSegment",
0872: UtilMisc.toMap("shipmentId", this .getShipmentId()));
0873: if (!UtilValidate.isEmpty(shipmentRouteSegments)) {
0874: Iterator srit = shipmentRouteSegments.iterator();
0875: while (srit.hasNext()) {
0876: GenericValue shipmentRouteSegment = (GenericValue) srit
0877: .next();
0878: shipmentRouteSegment.set("billingWeight",
0879: shipmentWeight);
0880: shipmentRouteSegment.set("billingWeightUomId",
0881: getWeightUomId());
0882: }
0883: getDelegator().storeAll(shipmentRouteSegments);
0884: }
0885: }
0886:
0887: protected void setShipmentToPacked() throws GeneralException {
0888: Map packedCtx = UtilMisc.toMap("shipmentId", shipmentId,
0889: "statusId", "SHIPMENT_PACKED", "userLogin", userLogin);
0890: Map packedResp = this .getDispatcher().runSync("updateShipment",
0891: packedCtx);
0892: if (packedResp != null && ServiceUtil.isError(packedResp)) {
0893: throw new GeneralException(ServiceUtil
0894: .getErrorMessage(packedResp));
0895: }
0896: }
0897:
0898: protected void setPickerOnPicklist() throws GeneralException {
0899: if (picklistBinId != null) {
0900: // first find the picklist id
0901: GenericValue bin = this .getDelegator().findByPrimaryKey(
0902: "PicklistBin",
0903: UtilMisc.toMap("picklistBinId", picklistBinId));
0904: if (bin != null) {
0905: Map ctx = FastMap.newInstance();
0906: ctx.put("picklistId", bin.getString("picklistId"));
0907: ctx.put("partyId", pickerPartyId);
0908: ctx.put("roleTypeId", "PICKER");
0909:
0910: // check if the role already exists and is valid
0911: List currentRoles = this .getDelegator().findByAnd(
0912: "PicklistRole", ctx);
0913: currentRoles = EntityUtil.filterByDate(currentRoles);
0914:
0915: // if not; create the role
0916: if (currentRoles != null && currentRoles.size() > 0) {
0917: ctx.put("userLogin", userLogin);
0918: Map addRole = this .getDispatcher().runSync(
0919: "createPicklistRole", ctx);
0920: if (ServiceUtil.isError(addRole)) {
0921: throw new GeneralException(ServiceUtil
0922: .getErrorMessage(addRole));
0923: }
0924: }
0925: }
0926: }
0927: }
0928:
0929: public Double getAdditionalShippingCharge() {
0930: return additionalShippingCharge;
0931: }
0932:
0933: public void setAdditionalShippingCharge(
0934: Double additionalShippingCharge) {
0935: this .additionalShippingCharge = additionalShippingCharge;
0936: }
0937:
0938: public double getTotalWeight() {
0939: double total = 0.0;
0940: for (int i = 0; i < packageSeq; i++) {
0941: Double packageWeight = getPackageWeight(i);
0942: if (!UtilValidate.isEmpty(packageWeight)) {
0943: total += packageWeight.doubleValue();
0944: }
0945: }
0946: return total;
0947: }
0948:
0949: public Double getShipmentCostEstimate(
0950: GenericValue orderItemShipGroup, String productStoreId,
0951: List shippableItemInfo, Double shippableTotal,
0952: Double shippableWeight, Double shippableQuantity) {
0953: return getShipmentCostEstimate(orderItemShipGroup
0954: .getString("contactMechId"), orderItemShipGroup
0955: .getString("shipmentMethodTypeId"), orderItemShipGroup
0956: .getString("carrierPartyId"), orderItemShipGroup
0957: .getString("carrierRoleTypeId"), productStoreId,
0958: shippableItemInfo, shippableTotal, shippableWeight,
0959: shippableQuantity);
0960: }
0961:
0962: public Double getShipmentCostEstimate(
0963: GenericValue orderItemShipGroup, String productStoreId) {
0964: return getShipmentCostEstimate(orderItemShipGroup
0965: .getString("contactMechId"), orderItemShipGroup
0966: .getString("shipmentMethodTypeId"), orderItemShipGroup
0967: .getString("carrierPartyId"), orderItemShipGroup
0968: .getString("carrierRoleTypeId"), productStoreId, null,
0969: null, null, null);
0970: }
0971:
0972: public Double getShipmentCostEstimate(String shippingContactMechId,
0973: String shipmentMethodTypeId, String carrierPartyId,
0974: String carrierRoleTypeId, String productStoreId,
0975: List shippableItemInfo, Double shippableTotal,
0976: Double shippableWeight, Double shippableQuantity) {
0977:
0978: Double shipmentCostEstimate = null;
0979: Map serviceResult = null;
0980: try {
0981: Map serviceContext = FastMap.newInstance();
0982: serviceContext.put("shippingContactMechId",
0983: shippingContactMechId);
0984: serviceContext.put("shipmentMethodTypeId",
0985: shipmentMethodTypeId);
0986: serviceContext.put("carrierPartyId", carrierPartyId);
0987: serviceContext.put("carrierRoleTypeId", carrierRoleTypeId);
0988: serviceContext.put("productStoreId", productStoreId);
0989:
0990: if (UtilValidate.isEmpty(shippableItemInfo)) {
0991: shippableItemInfo = FastList.newInstance();
0992: Iterator lit = getLines().iterator();
0993: while (lit.hasNext()) {
0994: PackingSessionLine line = (PackingSessionLine) lit
0995: .next();
0996: List oiasgas = getDelegator().findByAnd(
0997: "OrderItemAndShipGroupAssoc",
0998: UtilMisc.toMap("orderId",
0999: line.getOrderId(),
1000: "orderItemSeqId", line
1001: .getOrderItemSeqId(),
1002: "shipGroupSeqId", line
1003: .getShipGroupSeqId()));
1004: shippableItemInfo.addAll(oiasgas);
1005: }
1006: }
1007: serviceContext.put("shippableItemInfo", shippableItemInfo);
1008:
1009: if (UtilValidate.isEmpty(shippableWeight)) {
1010: shippableWeight = new Double(getTotalWeight());
1011: }
1012: serviceContext.put("shippableWeight", shippableWeight);
1013:
1014: if (UtilValidate.isEmpty(shippableQuantity)) {
1015: shippableQuantity = new Double(getPackedQuantity(-1));
1016: }
1017: serviceContext.put("shippableQuantity", shippableQuantity);
1018:
1019: if (UtilValidate.isEmpty(shippableTotal)) {
1020: shippableTotal = new Double(0);
1021: }
1022: serviceContext.put("shippableTotal", shippableTotal);
1023:
1024: serviceResult = getDispatcher().runSync(
1025: "calcShipmentCostEstimate", serviceContext);
1026: } catch (GenericEntityException e) {
1027: Debug.logError(e, module);
1028: } catch (GenericServiceException e) {
1029: Debug.logError(e, module);
1030: }
1031:
1032: if (!UtilValidate.isEmpty(serviceResult
1033: .get("shippingEstimateAmount"))) {
1034: shipmentCostEstimate = (Double) serviceResult
1035: .get("shippingEstimateAmount");
1036: }
1037:
1038: return shipmentCostEstimate;
1039:
1040: }
1041:
1042: public String getWeightUomId() {
1043: return weightUomId;
1044: }
1045:
1046: public void setWeightUomId(String weightUomId) {
1047: this .weightUomId = weightUomId;
1048: }
1049:
1050: public List getPackageSeqIds() {
1051: Set packageSeqIds = new TreeSet();
1052: if (!UtilValidate.isEmpty(this .getLines())) {
1053: Iterator lit = this .getLines().iterator();
1054: while (lit.hasNext()) {
1055: PackingSessionLine line = (PackingSessionLine) lit
1056: .next();
1057: packageSeqIds.add(new Integer(line.getPackageSeq()));
1058: }
1059: }
1060: return new ArrayList(packageSeqIds);
1061: }
1062:
1063: public void setPackageWeight(int packageSeqId, Double packageWeight) {
1064: if (UtilValidate.isEmpty(packageWeight)) {
1065: packageWeights.remove(new Integer(packageSeqId));
1066: } else {
1067: packageWeights
1068: .put(new Integer(packageSeqId), packageWeight);
1069: }
1070: }
1071:
1072: public Double getPackageWeight(int packageSeqId) {
1073: if (this .packageWeights == null)
1074: return null;
1075: Double packageWeight = null;
1076: Object p = packageWeights.get(new Integer(packageSeqId));
1077: if (p != null) {
1078: packageWeight = (Double) p;
1079: }
1080: return packageWeight;
1081: }
1082:
1083: public void addToPackageWeight(int packageSeqId, Double weight) {
1084: if (UtilValidate.isEmpty(weight))
1085: return;
1086: Double packageWeight = getPackageWeight(packageSeqId);
1087: Double newPackageWeight = UtilValidate.isEmpty(packageWeight) ? weight
1088: : new Double(weight.doubleValue()
1089: + packageWeight.doubleValue());
1090: setPackageWeight(packageSeqId, newPackageWeight);
1091: }
1092:
1093: }
|