001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.order.shoppingcart.shipping;
019:
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.List;
023: import java.util.Map;
024: import javax.servlet.http.HttpServletRequest;
025: import javax.servlet.http.HttpServletResponse;
026:
027: import org.ofbiz.base.util.Debug;
028: import org.ofbiz.base.util.GeneralException;
029: import org.ofbiz.base.util.UtilValidate;
030: import org.ofbiz.entity.GenericDelegator;
031: import org.ofbiz.entity.GenericValue;
032: import org.ofbiz.order.order.OrderReadHelper;
033: import org.ofbiz.order.shoppingcart.ShoppingCart;
034: import org.ofbiz.product.store.ProductStoreWorker;
035: import org.ofbiz.service.GenericServiceException;
036: import org.ofbiz.service.LocalDispatcher;
037: import org.ofbiz.service.ModelService;
038: import org.ofbiz.service.ServiceUtil;
039: import org.ofbiz.base.util.UtilMisc;
040:
041: /**
042: * ShippingEvents - Events used for processing shipping fees
043: */
044: public class ShippingEvents {
045:
046: public static final String module = ShippingEvents.class.getName();
047:
048: public static String getShipEstimate(HttpServletRequest request,
049: HttpServletResponse response) {
050: ShoppingCart cart = (ShoppingCart) request.getSession()
051: .getAttribute("shoppingCart");
052: LocalDispatcher dispatcher = (LocalDispatcher) request
053: .getAttribute("dispatcher");
054: GenericDelegator delegator = (GenericDelegator) request
055: .getAttribute("delegator");
056:
057: int shipGroups = cart.getShipGroupSize();
058: for (int i = 0; i < shipGroups; i++) {
059: Map result = getShipGroupEstimate(dispatcher, delegator,
060: cart, i);
061: ServiceUtil.getMessages(request, result, null, "", "", "",
062: "", null, null);
063: if (result.get(ModelService.RESPONSE_MESSAGE).equals(
064: ModelService.RESPOND_ERROR)) {
065: return "error";
066: }
067:
068: Double shippingTotal = (Double) result.get("shippingTotal");
069: if (shippingTotal == null) {
070: shippingTotal = new Double(0.00);
071: }
072: cart.setItemShipGroupEstimate(shippingTotal.doubleValue(),
073: i);
074: }
075:
076: // all done
077: return "success";
078: }
079:
080: public static Map getShipGroupEstimate(LocalDispatcher dispatcher,
081: GenericDelegator delegator, ShoppingCart cart, int groupNo) {
082: // check for shippable items
083: if (!cart.shippingApplies()) {
084: Map responseResult = ServiceUtil.returnSuccess();
085: responseResult.put("shippingTotal", new Double(0.00));
086: return responseResult;
087: }
088:
089: String shipmentMethodTypeId = cart
090: .getShipmentMethodTypeId(groupNo);
091: String carrierPartyId = cart.getCarrierPartyId(groupNo);
092:
093: return getShipGroupEstimate(dispatcher, delegator, cart
094: .getOrderType(), shipmentMethodTypeId, carrierPartyId,
095: null, cart.getShippingContactMechId(groupNo), cart
096: .getProductStoreId(), cart
097: .getShippableItemInfo(groupNo), cart
098: .getShippableWeight(groupNo), cart
099: .getShippableQuantity(groupNo), cart
100: .getShippableTotal(groupNo));
101: }
102:
103: public static Map getShipEstimate(LocalDispatcher dispatcher,
104: GenericDelegator delegator, OrderReadHelper orh,
105: String shipGroupSeqId) {
106: // check for shippable items
107: if (!orh.shippingApplies()) {
108: Map responseResult = ServiceUtil.returnSuccess();
109: responseResult.put("shippingTotal", new Double(0.00));
110: return responseResult;
111: }
112:
113: GenericValue shipGroup = orh
114: .getOrderItemShipGroup(shipGroupSeqId);
115: String shipmentMethodTypeId = shipGroup
116: .getString("shipmentMethodTypeId");
117: String carrierRoleTypeId = shipGroup
118: .getString("carrierRoleTypeId");
119: String carrierPartyId = shipGroup.getString("carrierPartyId");
120:
121: GenericValue shipAddr = orh.getShippingAddress(shipGroupSeqId);
122: if (shipAddr == null) {
123: return UtilMisc.toMap("shippingTotal", new Double(0));
124: }
125:
126: String contactMechId = shipAddr.getString("contactMechId");
127: return getShipGroupEstimate(dispatcher, delegator, orh
128: .getOrderTypeId(), shipmentMethodTypeId,
129: carrierPartyId, carrierRoleTypeId, contactMechId, orh
130: .getProductStoreId(), orh
131: .getShippableItemInfo(shipGroupSeqId), orh
132: .getShippableWeightBd(shipGroupSeqId)
133: .doubleValue(), orh.getShippableQuantityBd(
134: shipGroupSeqId).doubleValue(), orh
135: .getShippableTotalBd(shipGroupSeqId)
136: .doubleValue());
137: }
138:
139: public static Map getShipGroupEstimate(LocalDispatcher dispatcher,
140: GenericDelegator delegator, String orderTypeId,
141: String shipmentMethodTypeId, String carrierPartyId,
142: String carrierRoleTypeId, String shippingContactMechId,
143: String productStoreId, List itemInfo,
144: double shippableWeight, double shippableQuantity,
145: double shippableTotal) {
146: String standardMessage = "A problem occurred calculating shipping. Fees will be calculated offline.";
147: List errorMessageList = new ArrayList();
148:
149: if (shipmentMethodTypeId == null || carrierPartyId == null) {
150: if ("SALES_ORDER".equals(orderTypeId)) {
151: errorMessageList
152: .add("Please Select Your Shipping Method.");
153: return ServiceUtil.returnError(errorMessageList);
154: } else {
155: return ServiceUtil.returnSuccess();
156: }
157: }
158:
159: if (carrierRoleTypeId == null) {
160: carrierRoleTypeId = "CARRIER";
161: }
162:
163: if (shippingContactMechId == null) {
164: errorMessageList
165: .add("Please Select Your Shipping Address.");
166: return ServiceUtil.returnError(errorMessageList);
167: }
168:
169: // no shippable items; we won't change any shipping at all
170: if (shippableQuantity == 0) {
171: Map result = ServiceUtil.returnSuccess();
172: result.put("shippingTotal", new Double(0));
173: return result;
174: }
175:
176: // check for an external service call
177: GenericValue storeShipMethod = ProductStoreWorker
178: .getProductStoreShipmentMethod(delegator,
179: productStoreId, shipmentMethodTypeId,
180: carrierPartyId, carrierRoleTypeId);
181:
182: if (storeShipMethod == null) {
183: errorMessageList
184: .add("No applicable shipment method found.");
185: return ServiceUtil.returnError(errorMessageList);
186: }
187:
188: // the initial amount before manual estimates
189: double shippingTotal = 0.00;
190:
191: // prepare the service invocation fields
192: Map serviceFields = new HashMap();
193: serviceFields.put("initialEstimateAmt", new Double(
194: shippingTotal));
195: serviceFields.put("shippableTotal", new Double(shippableTotal));
196: serviceFields.put("shippableQuantity", new Double(
197: shippableQuantity));
198: serviceFields.put("shippableWeight",
199: new Double(shippableWeight));
200: serviceFields.put("shippableItemInfo", itemInfo);
201: serviceFields.put("productStoreId", productStoreId);
202: serviceFields.put("carrierRoleTypeId", "CARRIER");
203: serviceFields.put("carrierPartyId", carrierPartyId);
204: serviceFields.put("shipmentMethodTypeId", shipmentMethodTypeId);
205: serviceFields.put("shippingContactMechId",
206: shippingContactMechId);
207:
208: // call the external shipping service
209: try {
210: Double externalAmt = getExternalShipEstimate(dispatcher,
211: storeShipMethod, serviceFields);
212: if (externalAmt != null) {
213: shippingTotal += externalAmt.doubleValue();
214: }
215: } catch (GeneralException e) {
216: return ServiceUtil.returnSuccess(standardMessage);
217: }
218:
219: // update the initial amount
220: serviceFields.put("initialEstimateAmt", new Double(
221: shippingTotal));
222:
223: // call the generic estimate service
224: try {
225: Double genericAmt = getGenericShipEstimate(dispatcher,
226: storeShipMethod, serviceFields);
227: if (genericAmt != null) {
228: shippingTotal += genericAmt.doubleValue();
229: }
230: } catch (GeneralException e) {
231: return ServiceUtil.returnSuccess(standardMessage);
232: }
233:
234: // return the totals
235: Map responseResult = ServiceUtil.returnSuccess();
236: responseResult.put("shippingTotal", new Double(shippingTotal));
237: return responseResult;
238: }
239:
240: public static Double getGenericShipEstimate(
241: LocalDispatcher dispatcher, GenericValue storeShipMeth,
242: Map context) throws GeneralException {
243: // invoke the generic estimate service next -- append to estimate amount
244: Map genericEstimate = null;
245: Double genericShipAmt = null;
246: try {
247: genericEstimate = dispatcher.runSync(
248: "calcShipmentCostEstimate", context);
249: } catch (GenericServiceException e) {
250: Debug.logError(e, "Shipment Service Error", module);
251: throw new GeneralException();
252: }
253: if (ServiceUtil.isError(genericEstimate)) {
254: Debug.logError(
255: ServiceUtil.getErrorMessage(genericEstimate),
256: module);
257: throw new GeneralException();
258: } else {
259: genericShipAmt = (Double) genericEstimate
260: .get("shippingEstimateAmount");
261: }
262: return genericShipAmt;
263: }
264:
265: public static Double getExternalShipEstimate(
266: LocalDispatcher dispatcher, GenericValue storeShipMeth,
267: Map context) throws GeneralException {
268: // invoke the external shipping estimate service
269: Double externalShipAmt = null;
270: if (storeShipMeth.get("serviceName") != null) {
271: String serviceName = storeShipMeth.getString("serviceName");
272: String configProps = storeShipMeth.getString("configProps");
273: if (UtilValidate.isNotEmpty(serviceName)) {
274: // prepare the external service context
275: context.put("serviceConfigProps", configProps);
276:
277: // invoke the service
278: Map serviceResp = null;
279: try {
280: Debug.log("Service : " + serviceName + " / "
281: + configProps + " -- " + context, module);
282: // because we don't want to blow up too big or rollback the transaction when this happens, always have it run in its own transaction...
283: serviceResp = dispatcher.runSync(serviceName,
284: context, 0, true);
285: } catch (GenericServiceException e) {
286: Debug.logError(e, "Shipment Service Error", module);
287: throw new GeneralException();
288: }
289: if (!ServiceUtil.isError(serviceResp)) {
290: externalShipAmt = (Double) serviceResp
291: .get("shippingEstimateAmount");
292: } else {
293: String errMsg = "Error getting external shipment cost estimate: "
294: + ServiceUtil.getErrorMessage(serviceResp);
295: Debug.logError(errMsg, module);
296: throw new GeneralException(errMsg);
297: }
298: }
299: }
300: return externalShipAmt;
301: }
302: }
|