blob: 34ecb2d7b4b16899b1cb8f8f9d380a491f0668f9 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.ofbiz.shipment.shipment;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilNumber;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
import org.ofbiz.common.geo.GeoWorker;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityConditionList;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.party.party.PartyWorker;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;
/**
* ShipmentServices
*/
public class ShipmentServices {
public static final String module = ShipmentServices.class.getName();
public static final String resource = "ProductUiLabels";
public static final String resource_error = "OrderErrorUiLabels";
public static final int decimals = UtilNumber.getBigDecimalScale("order.decimals");
public static final int rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding");
public static final BigDecimal ZERO = BigDecimal.ZERO.setScale(decimals, rounding);
public static Map<String, Object> createShipmentEstimate(DispatchContext dctx, Map<String, ? extends Object> context) {
Map<String, Object> result = FastMap.newInstance();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
List<GenericValue> storeAll = FastList.newInstance();
String productStoreShipMethId = (String)context.get("productStoreShipMethId");
GenericValue productStoreShipMeth = null;
try {
productStoreShipMeth = delegator.findOne("ProductStoreShipmentMeth", UtilMisc.toMap("productStoreShipMethId", productStoreShipMethId), false);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductStoreShipmentMethodCannotRetrieve",
UtilMisc.toMap("productStoreShipMethId", productStoreShipMethId,
"errorString", e.toString()), locale));
}
// Create the basic entity.
GenericValue estimate = delegator.makeValue("ShipmentCostEstimate");
estimate.set("shipmentCostEstimateId", delegator.getNextSeqId("ShipmentCostEstimate"));
estimate.set("productStoreShipMethId", productStoreShipMethId);
estimate.set("shipmentMethodTypeId", productStoreShipMeth.getString("shipmentMethodTypeId"));
estimate.set("carrierPartyId", productStoreShipMeth.getString("partyId"));
estimate.set("carrierRoleTypeId", "CARRIER");
estimate.set("productStoreId", productStoreShipMeth.getString("productStoreId"));
estimate.set("geoIdTo", context.get("toGeo"));
estimate.set("geoIdFrom", context.get("fromGeo"));
estimate.set("partyId", context.get("partyId"));
estimate.set("roleTypeId", context.get("roleTypeId"));
estimate.set("orderPricePercent", context.get("flatPercent"));
estimate.set("orderFlatPrice", context.get("flatPrice"));
estimate.set("orderItemFlatPrice", context.get("flatItemPrice"));
estimate.set("shippingPricePercent", context.get("shippingPricePercent"));
estimate.set("productFeatureGroupId", context.get("productFeatureGroupId"));
estimate.set("oversizeUnit", context.get("oversizeUnit"));
estimate.set("oversizePrice", context.get("oversizePrice"));
estimate.set("featurePercent", context.get("featurePercent"));
estimate.set("featurePrice", context.get("featurePrice"));
estimate.set("weightBreakId", context.get("weightBreakId"));
estimate.set("weightUnitPrice", context.get("wprice"));
estimate.set("weightUomId", context.get("wuom"));
estimate.set("quantityBreakId", context.get("quantityBreakId"));
estimate.set("quantityUnitPrice", context.get("qprice"));
estimate.set("quantityUomId", context.get("quom"));
estimate.set("priceBreakId", context.get("priceBreakId"));
estimate.set("priceUnitPrice", context.get("pprice"));
estimate.set("priceUomId", context.get("puom"));
storeAll.add(estimate);
if (!applyQuantityBreak(context, result, storeAll, delegator, estimate, "w", "weight", "Weight")) {
return result;
}
if (!applyQuantityBreak(context, result, storeAll, delegator, estimate, "q", "quantity", "Quantity")) {
return result;
}
if (!applyQuantityBreak(context, result, storeAll, delegator, estimate, "p", "price", "Price")) {
return result;
}
try {
delegator.storeAll(storeAll);
} catch (GenericEntityException e) {
result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
result.put(ModelService.ERROR_MESSAGE, "Problem reading product features: " + e.toString());
return result;
}
result.put("shipmentCostEstimateId", estimate.get("shipmentCostEstimateId"));
result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
return result;
}
public static Map<String, Object> removeShipmentEstimate(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
String shipmentCostEstimateId = (String) context.get("shipmentCostEstimateId");
Locale locale = (Locale) context.get("locale");
GenericValue estimate = null;
try {
estimate = delegator.findOne("ShipmentCostEstimate", UtilMisc.toMap("shipmentCostEstimateId", shipmentCostEstimateId), false);
estimate.remove();
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentCostEstimateRemoveError",
UtilMisc.toMap("errorString", e.toString()), locale));
}
/* Commented out this code because QuantityBreak may be used by other records
try {
if (estimate.get("weightBreakId") != null) {
delegator.removeRelated("WeightQuantityBreak", estimate);
}
} catch (GenericEntityException e) {
Debug.logInfo("Not removing WeightQuantityBreak records related to ShipmentCostEstimate [" + shipmentCostEstimateId + "] because they are used by other entities.", module);
}
try {
if (estimate.get("quantityBreakId") != null) {
delegator.removeRelated("QuantityQuantityBreak", estimate);
}
} catch (GenericEntityException e) {
Debug.logInfo("Not removing QuantityQuantityBreak records related to ShipmentCostEstimate [" + shipmentCostEstimateId + "] because they are used by other entities.", module);
}
try {
if (estimate.get("priceBreakId") != null) {
delegator.removeRelated("PriceQuantityBreak", estimate);
}
} catch (GenericEntityException e) {
Debug.logInfo("Not removing PriceQuantityBreak records related to ShipmentCostEstimate [" + shipmentCostEstimateId + "] because they are used by other entities.", module);
}
*/
return ServiceUtil.returnSuccess();
}
private static boolean applyQuantityBreak(Map<String, ? extends Object> context, Map<String, Object> result, List<GenericValue> storeAll, Delegator delegator,
GenericValue estimate, String prefix, String breakType, String breakTypeString) {
BigDecimal min = (BigDecimal) context.get(prefix + "min");
BigDecimal max = (BigDecimal) context.get(prefix + "max");
if (min != null || max != null) {
if (min != null && max != null) {
if (min.compareTo(max) <= 0 || max.compareTo(BigDecimal.ZERO) == 0) {
try {
String newSeqId = delegator.getNextSeqId("QuantityBreak");
GenericValue weightBreak = delegator.makeValue("QuantityBreak");
weightBreak.set("quantityBreakId", newSeqId);
weightBreak.set("quantityBreakTypeId", "SHIP_" + breakType.toUpperCase());
weightBreak.set("fromQuantity", min);
weightBreak.set("thruQuantity", max);
estimate.set(breakType + "BreakId", newSeqId);
estimate.set(breakType + "UnitPrice", context.get(prefix + "price"));
if (context.containsKey(prefix + "uom")) {
estimate.set(breakType + "UomId", context.get(prefix + "uom"));
}
storeAll.add(0, weightBreak);
}
catch (Exception e) {
Debug.logError(e, module);
}
}
else {
result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
result.put(ModelService.ERROR_MESSAGE, "Max " + breakTypeString +
" must not be less than Min " + breakTypeString + ".");
return false;
}
}
else {
result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
result.put(ModelService.ERROR_MESSAGE, breakTypeString+" Span Requires BOTH Fields.");
return false;
}
}
return true;
}
// ShippingEstimate Calc Service
public static Map<String, Object> calcShipmentCostEstimate(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
// prepare the data
String productStoreShipMethId = (String) context.get("productStoreShipMethId");
String productStoreId = (String) context.get("productStoreId");
String carrierRoleTypeId = (String) context.get("carrierRoleTypeId");
String carrierPartyId = (String) context.get("carrierPartyId");
String shipmentMethodTypeId = (String) context.get("shipmentMethodTypeId");
String shippingContactMechId = (String) context.get("shippingContactMechId");
String shippingPostalCode = (String) context.get("shippingPostalCode");
String shippingCountryCode = (String) context.get("shippingCountryCode");
List<Map<String, Object>> shippableItemInfo = UtilGenerics.checkList(context.get("shippableItemInfo"));
//Map shippableFeatureMap = (Map) context.get("shippableFeatureMap");
//List shippableItemSizes = (List) context.get("shippableItemSizes");
BigDecimal shippableTotal = (BigDecimal) context.get("shippableTotal");
BigDecimal shippableQuantity = (BigDecimal) context.get("shippableQuantity");
BigDecimal shippableWeight = (BigDecimal) context.get("shippableWeight");
BigDecimal initialEstimateAmt = (BigDecimal) context.get("initialEstimateAmt");
Locale locale = (Locale) context.get("locale");
if (shippableTotal == null) {
shippableTotal = BigDecimal.ZERO;
}
if (shippableQuantity == null) {
shippableQuantity = BigDecimal.ZERO;
}
if (shippableWeight == null) {
shippableWeight = BigDecimal.ZERO;
}
if (initialEstimateAmt == null) {
initialEstimateAmt = BigDecimal.ZERO;
}
// get the ShipmentCostEstimate(s)
Map<String, String> estFields = UtilMisc.toMap("productStoreId", productStoreId, "shipmentMethodTypeId", shipmentMethodTypeId,
"carrierPartyId", carrierPartyId, "carrierRoleTypeId", carrierRoleTypeId);
EntityCondition estFieldsCond = EntityCondition.makeCondition(estFields, EntityOperator.AND);
if (UtilValidate.isNotEmpty(productStoreShipMethId)) {
// if the productStoreShipMethId field is passed, then also get estimates that have the field set
List<EntityCondition> condList = UtilMisc.toList(EntityCondition.makeCondition("productStoreShipMethId", EntityOperator.EQUALS, productStoreShipMethId), estFieldsCond);
estFieldsCond = EntityCondition.makeCondition(condList, EntityOperator.AND);
}
Collection<GenericValue> estimates = null;
try {
estimates = delegator.findList("ShipmentCostEstimate", estFieldsCond, null, null, null, true);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentCostEstimateCannotRetrieve", locale));
}
if (estimates == null || estimates.size() < 1) {
if (initialEstimateAmt.compareTo(BigDecimal.ZERO) == 0) {
Debug.logWarning("No shipping estimates found; the shipping amount returned is 0! Condition used was: " + estFieldsCond + "; Using the passed context: " + context, module);
}
Map<String, Object> respNow = ServiceUtil.returnSuccess();
respNow.put("shippingEstimateAmount", BigDecimal.ZERO);
return respNow;
}
// Get the PostalAddress
GenericValue shipAddress = null;
if (shippingContactMechId != null) {
try {
shipAddress = delegator.findOne("PostalAddress", UtilMisc.toMap("contactMechId", shippingContactMechId), false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentCostEstimateCannotGetShippingAddress", locale));
}
} else if (shippingPostalCode != null) {
String countryGeoId = null;
try {
EntityCondition cond =EntityCondition.makeCondition(UtilMisc.toMap("geoTypeId", "COUNTRY", "geoCode", shippingCountryCode));
GenericValue countryGeo = EntityUtil.getFirst(delegator.findList("Geo", cond, null, null, null, true));
if (countryGeo != null) {
countryGeoId = countryGeo.getString("geoId");
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
shipAddress = delegator.makeValue("PostalAddress");
shipAddress.set("countryGeoId", countryGeoId);
shipAddress.set("postalCodeGeoId", shippingPostalCode);
}
// Get the possible estimates.
List<GenericValue> estimateList = FastList.newInstance();
for (GenericValue thisEstimate: estimates) {
String toGeo = thisEstimate.getString("geoIdTo");
if (UtilValidate.isNotEmpty(toGeo) && shipAddress ==null) {
// This estimate requires shipping address details. We don't have it so we cannot use this estimate.
continue;
}
List<GenericValue> toGeoList = GeoWorker.expandGeoGroup(toGeo, delegator);
// Make sure we have a valid GEOID.
if (UtilValidate.isEmpty(toGeoList) ||
GeoWorker.containsGeo(toGeoList, shipAddress.getString("countryGeoId"), delegator) ||
GeoWorker.containsGeo(toGeoList, shipAddress.getString("stateProvinceGeoId"), delegator) ||
GeoWorker.containsGeo(toGeoList, shipAddress.getString("postalCodeGeoId"), delegator)) {
/*
if (toGeo == null || toGeo.equals("") || toGeo.equals(shipAddress.getString("countryGeoId")) ||
toGeo.equals(shipAddress.getString("stateProvinceGeoId")) ||
toGeo.equals(shipAddress.getString("postalCodeGeoId"))) {
*/
GenericValue wv = null;
GenericValue qv = null;
GenericValue pv = null;
try {
wv = thisEstimate.getRelatedOne("WeightQuantityBreak", false);
} catch (GenericEntityException e) {
}
try {
qv = thisEstimate.getRelatedOne("QuantityQuantityBreak", false);
} catch (GenericEntityException e) {
}
try {
pv = thisEstimate.getRelatedOne("PriceQuantityBreak", false);
} catch (GenericEntityException e) {
}
if (wv == null && qv == null && pv == null) {
estimateList.add(thisEstimate);
} else {
// Do some testing.
boolean useWeight = false;
boolean weightValid = false;
boolean useQty = false;
boolean qtyValid = false;
boolean usePrice = false;
boolean priceValid = false;
if (wv != null) {
useWeight = true;
BigDecimal min = BigDecimal.ONE.movePointLeft(4);
BigDecimal max = BigDecimal.ONE.movePointLeft(4);
try {
min = wv.getBigDecimal("fromQuantity");
max = wv.getBigDecimal("thruQuantity");
} catch (Exception e) {
}
if (shippableWeight.compareTo(min) >= 0 && (max.compareTo(BigDecimal.ZERO) == 0 || shippableWeight.compareTo(max) <= 0)) {
weightValid = true;
}
}
if (qv != null) {
useQty = true;
BigDecimal min = BigDecimal.ONE.movePointLeft(4);
BigDecimal max = BigDecimal.ONE.movePointLeft(4);
try {
min = qv.getBigDecimal("fromQuantity");
max = qv.getBigDecimal("thruQuantity");
} catch (Exception e) {
}
if (shippableQuantity.compareTo(min) >= 0 && (max.compareTo(BigDecimal.ZERO) == 0 || shippableQuantity.compareTo(max) <= 0)) {
qtyValid = true;
}
}
if (pv != null) {
usePrice = true;
BigDecimal min = BigDecimal.ONE.movePointLeft(4);
BigDecimal max = BigDecimal.ONE.movePointLeft(4);
try {
min = pv.getBigDecimal("fromQuantity");
max = pv.getBigDecimal("thruQuantity");
} catch (Exception e) {
}
if (shippableTotal.compareTo(min) >= 0 && (max.compareTo(BigDecimal.ZERO) == 0 || shippableTotal.compareTo(max) <= 0)) {
priceValid = true;
}
}
// Now check the tests.
if ((useWeight && weightValid) || (useQty && qtyValid) || (usePrice && priceValid)) {
estimateList.add(thisEstimate);
}
}
}
}
if (estimateList.size() < 1) {
return ServiceUtil.returnFailure(UtilProperties.getMessage(resource,
"ProductShipmentCostEstimateCannotFoundForCarrier",
UtilMisc.toMap("carrierPartyId", carrierPartyId,
"shipmentMethodTypeId", shipmentMethodTypeId), locale));
}
// make the shippable item size/feature objects
List<BigDecimal> shippableItemSizes = FastList.newInstance();
Map<String, BigDecimal> shippableFeatureMap = FastMap.newInstance();
if (shippableItemInfo != null) {
for (Map<String, Object> itemMap: shippableItemInfo) {
// add the item sizes
if (itemMap.containsKey("size")) {
BigDecimal itemSize = (BigDecimal) itemMap.get("size");
if (itemSize != null) {
shippableItemSizes.add(itemSize);
}
}
// add the feature quantities
BigDecimal quantity = (BigDecimal) itemMap.get("quantity");
if (itemMap.containsKey("featureSet")) {
Set<String> featureSet = UtilGenerics.checkSet(itemMap.get("featureSet"));
if (UtilValidate.isNotEmpty(featureSet)) {
for (String featureId: featureSet) {
BigDecimal featureQuantity = shippableFeatureMap.get(featureId);
if (featureQuantity == null) {
featureQuantity = BigDecimal.ZERO;
}
featureQuantity = featureQuantity.add(quantity);
shippableFeatureMap.put(featureId, featureQuantity);
}
}
}
}
}
// Calculate priority based on available data.
double PRIORITY_PARTY = 9;
double PRIORITY_ROLE = 8;
double PRIORITY_GEO = 4;
double PRIORITY_WEIGHT = 1;
double PRIORITY_QTY = 1;
double PRIORITY_PRICE = 1;
int estimateIndex = 0;
if (estimateList.size() > 1) {
TreeMap<Integer, GenericValue> estimatePriority = new TreeMap<Integer, GenericValue>();
//int estimatePriority[] = new int[estimateList.size()];
for (GenericValue currentEstimate: estimateList) {
int prioritySum = 0;
if (UtilValidate.isNotEmpty(currentEstimate.getString("partyId"))) {
prioritySum += PRIORITY_PARTY;
}
if (UtilValidate.isNotEmpty(currentEstimate.getString("roleTypeId"))) {
prioritySum += PRIORITY_ROLE;
}
if (UtilValidate.isNotEmpty(currentEstimate.getString("geoIdTo"))) {
prioritySum += PRIORITY_GEO;
}
if (UtilValidate.isNotEmpty(currentEstimate.getString("weightBreakId"))) {
prioritySum += PRIORITY_WEIGHT;
}
if (UtilValidate.isNotEmpty(currentEstimate.getString("quantityBreakId"))) {
prioritySum += PRIORITY_QTY;
}
if (UtilValidate.isNotEmpty(currentEstimate.getString("priceBreakId"))) {
prioritySum += PRIORITY_PRICE;
}
// there will be only one of each priority; latest will replace
estimatePriority.put(Integer.valueOf(prioritySum), currentEstimate);
}
// locate the highest priority estimate; or the latest entered
Object[] estimateArray = estimatePriority.values().toArray();
estimateIndex = estimateList.indexOf(estimateArray[estimateArray.length - 1]);
}
// Grab the estimate and work with it.
GenericValue estimate = estimateList.get(estimateIndex);
//Debug.logInfo("[ShippingEvents.getShipEstimate] Working with estimate [" + estimateIndex + "]: " + estimate, module);
// flat fees
BigDecimal orderFlat = BigDecimal.ZERO;
if (estimate.getBigDecimal("orderFlatPrice") != null) {
orderFlat = estimate.getBigDecimal("orderFlatPrice");
}
BigDecimal orderItemFlat = BigDecimal.ZERO;
if (estimate.getBigDecimal("orderItemFlatPrice") != null) {
orderItemFlat = estimate.getBigDecimal("orderItemFlatPrice");
}
BigDecimal orderPercent = BigDecimal.ZERO;
if (estimate.getBigDecimal("orderPricePercent") != null) {
orderPercent = estimate.getBigDecimal("orderPricePercent");
}
BigDecimal itemFlatAmount = shippableQuantity.multiply(orderItemFlat);
BigDecimal orderPercentage = shippableTotal.multiply(orderPercent.movePointLeft(2));
// flat total
BigDecimal flatTotal = orderFlat.add(itemFlatAmount).add(orderPercentage);
// spans
BigDecimal weightUnit = BigDecimal.ZERO;
if (estimate.getBigDecimal("weightUnitPrice") != null) {
weightUnit = estimate.getBigDecimal("weightUnitPrice");
}
BigDecimal qtyUnit = BigDecimal.ZERO;
if (estimate.getBigDecimal("quantityUnitPrice") != null) {
qtyUnit = estimate.getBigDecimal("quantityUnitPrice");
}
BigDecimal priceUnit = BigDecimal.ZERO;
if (estimate.getBigDecimal("priceUnitPrice") != null) {
priceUnit = estimate.getBigDecimal("priceUnitPrice");
}
BigDecimal weightAmount = shippableWeight.multiply(weightUnit);
BigDecimal quantityAmount = shippableQuantity.multiply(qtyUnit);
BigDecimal priceAmount = shippableTotal.multiply(priceUnit);
// span total
BigDecimal spanTotal = weightAmount.add(quantityAmount).add(priceAmount);
// feature surcharges
BigDecimal featureSurcharge = BigDecimal.ZERO;
String featureGroupId = estimate.getString("productFeatureGroupId");
BigDecimal featurePercent = estimate.getBigDecimal("featurePercent");
BigDecimal featurePrice = estimate.getBigDecimal("featurePrice");
if (featurePercent == null) {
featurePercent = BigDecimal.ZERO;
}
if (featurePrice == null) {
featurePrice = BigDecimal.ZERO;
}
if (UtilValidate.isNotEmpty(featureGroupId) && shippableFeatureMap != null) {
for (Map.Entry<String, BigDecimal> entry: shippableFeatureMap.entrySet()) {
String featureId = entry.getKey();
BigDecimal quantity = entry.getValue();
GenericValue appl = null;
Map<String, String> fields = UtilMisc.toMap("productFeatureGroupId", featureGroupId, "productFeatureId", featureId);
try {
List<GenericValue> appls = delegator.findByAnd("ProductFeatureGroupAppl", fields, null, true);
appls = EntityUtil.filterByDate(appls);
appl = EntityUtil.getFirst(appls);
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to lookup feature/group" + fields, module);
}
if (appl != null) {
featureSurcharge = featureSurcharge.add(shippableTotal.multiply(featurePercent.movePointLeft(2)).multiply(quantity));
featureSurcharge = featureSurcharge.add(featurePrice.multiply(quantity));
}
}
}
// size surcharges
BigDecimal sizeSurcharge = BigDecimal.ZERO;
BigDecimal sizeUnit = estimate.getBigDecimal("oversizeUnit");
BigDecimal sizePrice = estimate.getBigDecimal("oversizePrice");
if (sizeUnit != null && sizeUnit.compareTo(BigDecimal.ZERO) > 0) {
if (shippableItemSizes != null) {
for (BigDecimal size: shippableItemSizes) {
if (size != null && size.compareTo(sizeUnit) >= 0) {
sizeSurcharge = sizeSurcharge.add(sizePrice);
}
}
}
}
// surcharges total
BigDecimal surchargeTotal = featureSurcharge.add(sizeSurcharge);
// shipping subtotal
BigDecimal subTotal = spanTotal.add(flatTotal).add(surchargeTotal);
// percent add-on
BigDecimal shippingPricePercent = BigDecimal.ZERO;
if (estimate.getBigDecimal("shippingPricePercent") != null) {
shippingPricePercent = estimate.getBigDecimal("shippingPricePercent");
}
// shipping total
BigDecimal shippingTotal = subTotal.add((subTotal.add(initialEstimateAmt)).multiply(shippingPricePercent.movePointLeft(2)));
// prepare the return result
Map<String, Object> responseResult = ServiceUtil.returnSuccess();
responseResult.put("shippingEstimateAmount", shippingTotal);
return responseResult;
}
public static Map<String, Object> fillShipmentStagingTables(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
String shipmentId = (String) context.get("shipmentId");
Locale locale = (Locale) context.get("locale");
GenericValue shipment = null;
if (shipmentId != null) {
try {
shipment = delegator.findOne("Shipment", UtilMisc.toMap("shipmentId", shipmentId), false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
}
if (shipment == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentNotFoundId", locale));
}
String shipmentStatusId = shipment.getString("statusId");
if ("SHIPMENT_PACKED".equals(shipmentStatusId)) {
GenericValue address = null;
try {
address = shipment.getRelatedOne("DestinationPostalAddress", false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (address == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentNoAddressFound", locale));
}
List<GenericValue> packages = null;
try {
packages = shipment.getRelated("ShipmentPackage", null, null, false) ;
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (UtilValidate.isEmpty(packages)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentNoPackagesAvailable", locale));
}
List<GenericValue> routeSegs = null;
try {
routeSegs = shipment.getRelated("ShipmentRouteSegment", null, null, false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
GenericValue routeSeg = EntityUtil.getFirst(routeSegs);
// to store list
List<GenericValue> toStore = FastList.newInstance();
//String shipGroupSeqId = shipment.getString("primaryShipGroupSeqId");
//String orderId = shipment.getString("primaryOrderId");
//String orderInfoKey = orderId + "/" + shipGroupSeqId;
// make the staging records
GenericValue stageShip = delegator.makeValue("OdbcShipmentOut");
stageShip.set("shipmentId", shipment.get("shipmentId"));
stageShip.set("partyId", shipment.get("partyIdTo"));
stageShip.set("carrierPartyId", routeSeg.get("carrierPartyId"));
stageShip.set("shipmentMethodTypeId", routeSeg.get("shipmentMethodTypeId"));
stageShip.set("toName", address.get("toName"));
stageShip.set("attnName", address.get("attnName"));
stageShip.set("address1", address.get("address1"));
stageShip.set("address2", address.get("address2"));
stageShip.set("directions", address.get("directions"));
stageShip.set("city", address.get("city"));
stageShip.set("postalCode", address.get("postalCode"));
stageShip.set("postalCodeExt", address.get("postalCodeExt"));
stageShip.set("countryGeoId", address.get("countryGeoId"));
stageShip.set("stateProvinceGeoId", address.get("stateProvinceGeoId"));
stageShip.set("numberOfPackages", Long.valueOf(packages.size()));
stageShip.set("handlingInstructions", shipment.get("handlingInstructions"));
toStore.add(stageShip);
for (GenericValue shipmentPkg: packages) {
GenericValue stagePkg = delegator.makeValue("OdbcPackageOut");
stagePkg.set("shipmentId", shipmentPkg.get("shipmentId"));
stagePkg.set("shipmentPackageSeqId", shipmentPkg.get("shipmentPackageSeqId"));
stagePkg.set("orderId", shipment.get("primaryOrderId"));
stagePkg.set("shipGroupSeqId", shipment.get("primaryShipGroupSeqId"));
stagePkg.set("shipmentBoxTypeId", shipmentPkg.get("shipmentBoxTypeId"));
stagePkg.set("weight", shipmentPkg.get("weight"));
toStore.add(stagePkg);
}
try {
delegator.storeAll(toStore);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
} else {
Debug.logWarning("Shipment #" + shipmentId + " is not available for shipment; not setting in staging tables.", module);
}
return ServiceUtil.returnSuccess();
}
public static Map<String, Object> updateShipmentsFromStaging(DispatchContext dctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
List<String> orderBy = UtilMisc.toList("shipmentId", "shipmentPackageSeqId", "voidIndicator");
Map<String, String> shipmentMap = FastMap.newInstance();
EntityListIterator eli = null;
try {
eli = delegator.find("OdbcPackageIn", null, null, null, orderBy, null);
GenericValue pkgInfo;
while ((pkgInfo = eli.next()) != null) {
String packageSeqId = pkgInfo.getString("shipmentPackageSeqId");
String shipmentId = pkgInfo.getString("shipmentId");
// locate the shipment package
GenericValue shipmentPackage = delegator.findOne("ShipmentPackage",
UtilMisc.toMap("shipmentId", shipmentId, "shipmentPackageSeqId", packageSeqId), false);
if (shipmentPackage != null) {
if ("00001".equals(packageSeqId)) {
// only need to do this for the first package
GenericValue rtSeg = null;
try {
rtSeg = delegator.findOne("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", "00001"), false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (rtSeg == null) {
rtSeg = delegator.makeValue("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", "00001"));
try {
delegator.create(rtSeg);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
}
rtSeg.set("actualStartDate", pkgInfo.get("shippedDate"));
rtSeg.set("billingWeight", pkgInfo.get("billingWeight"));
rtSeg.set("actualCost", pkgInfo.get("shippingTotal"));
rtSeg.set("trackingIdNumber", pkgInfo.get("trackingNumber"));
try {
delegator.store(rtSeg);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
}
Map<String, Object> pkgCtx = FastMap.newInstance();
pkgCtx.put("shipmentId", shipmentId);
pkgCtx.put("shipmentPackageSeqId", packageSeqId);
// first update the weight of the package
GenericValue pkg = null;
try {
pkg = delegator.findOne("ShipmentPackage", pkgCtx, false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (pkg == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentPackageNotFound",
UtilMisc.toMap("shipmentPackageSeqId", packageSeqId,
"shipmentId",shipmentId), locale));
}
pkg.set("weight", pkgInfo.get("packageWeight"));
try {
delegator.store(pkg);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
// need if we are the first package (only) update the route seg info
pkgCtx.put("shipmentRouteSegmentId", "00001");
GenericValue pkgRtSeg = null;
try {
pkgRtSeg = delegator.findOne("ShipmentPackageRouteSeg", pkgCtx, false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (pkgRtSeg == null) {
pkgRtSeg = delegator.makeValue("ShipmentPackageRouteSeg", pkgCtx);
try {
delegator.create(pkgRtSeg);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
}
pkgRtSeg.set("trackingCode", pkgInfo.get("trackingNumber"));
pkgRtSeg.set("boxNumber", pkgInfo.get("shipmentPackageSeqId"));
pkgRtSeg.set("packageServiceCost", pkgInfo.get("packageTotal"));
try {
delegator.store(pkgRtSeg);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
shipmentMap.put(shipmentId, pkgInfo.getString("voidIndicator"));
}
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
} finally {
if (eli != null) {
try {
eli.close();
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
}
// update the status of each shipment
for (Map.Entry<String, String> entry: shipmentMap.entrySet()) {
String shipmentId = entry.getKey();
String voidInd = entry.getValue();
Map<String, Object> shipCtx = FastMap.newInstance();
shipCtx.put("shipmentId", shipmentId);
if ("Y".equals(voidInd)) {
shipCtx.put("statusId", "SHIPMENT_CANCELLED");
} else {
shipCtx.put("statusId", "SHIPMENT_SHIPPED");
}
shipCtx.put("userLogin", userLogin);
Map<String, Object> shipResp = null;
try {
shipResp = dispatcher.runSync("updateShipment", shipCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (ServiceUtil.isError(shipResp)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(shipResp));
}
// remove the shipment info
Map<String, Object> clearResp = null;
try {
clearResp = dispatcher.runSync("clearShipmentStaging", UtilMisc.<String, Object>toMap("shipmentId", shipmentId, "userLogin", userLogin));
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (ServiceUtil.isError(clearResp)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(clearResp));
}
}
return ServiceUtil.returnSuccess();
}
public static Map<String, Object> clearShipmentStagingInfo(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
String shipmentId = (String) context.get("shipmentId");
try {
delegator.removeByAnd("OdbcPackageIn", UtilMisc.toMap("shipmentId", shipmentId));
delegator.removeByAnd("OdbcPackageOut", UtilMisc.toMap("shipmentId", shipmentId));
delegator.removeByAnd("OdbcShipmentOut", UtilMisc.toMap("shipmentId", shipmentId));
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess();
}
/**
* Whenever a ShipmentReceipt is generated, check the Shipment associated
* with it to see if all items were received. If so, change its status to
* PURCH_SHIP_RECEIVED. The check is accomplished by counting the
* products shipped (from ShipmentAndItem) and matching them with the
* products received (from ShipmentReceipt).
*/
public static Map<String, Object> updatePurchaseShipmentFromReceipt(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
String shipmentId = (String) context.get("shipmentId");
GenericValue userLogin = (GenericValue) context.get("userLogin");
try {
List<GenericValue> shipmentReceipts = delegator.findByAnd("ShipmentReceipt", UtilMisc.toMap("shipmentId", shipmentId), null, false);
if (shipmentReceipts.size() == 0) return ServiceUtil.returnSuccess();
// If there are shipment receipts, the shipment must have been shipped, so set the shipment status to PURCH_SHIP_SHIPPED if it's only PURCH_SHIP_CREATED
GenericValue shipment = delegator.findOne("Shipment", UtilMisc.toMap("shipmentId", shipmentId), false);
if ((! UtilValidate.isEmpty(shipment)) && "PURCH_SHIP_CREATED".equals(shipment.getString("statusId"))) {
Map<String, Object> updateShipmentMap = dispatcher.runSync("updateShipment", UtilMisc.<String, Object>toMap("shipmentId", shipmentId, "statusId", "PURCH_SHIP_SHIPPED", "userLogin", userLogin));
if (ServiceUtil.isError(updateShipmentMap)) {
return updateShipmentMap;
}
}
List<GenericValue> shipmentAndItems = delegator.findByAnd("ShipmentAndItem", UtilMisc.toMap("shipmentId", shipmentId, "statusId", "PURCH_SHIP_SHIPPED"), null, false);
if (shipmentAndItems.size() == 0) {
return ServiceUtil.returnSuccess();
}
// store the quantity of each product shipped in a hashmap keyed to productId
Map<String, BigDecimal> shippedCountMap = FastMap.newInstance();
for (GenericValue item: shipmentAndItems) {
BigDecimal shippedQuantity = item.getBigDecimal("quantity");
BigDecimal quantity = shippedCountMap.get(item.getString("productId"));
quantity = quantity == null ? shippedQuantity : shippedQuantity.add(quantity);
shippedCountMap.put(item.getString("productId"), quantity);
}
// store the quantity of each product received in a hashmap keyed to productId
Map<String, BigDecimal> receivedCountMap = FastMap.newInstance();
for (GenericValue item: shipmentReceipts) {
BigDecimal receivedQuantity = item.getBigDecimal("quantityAccepted");
BigDecimal quantity = receivedCountMap.get(item.getString("productId"));
quantity = quantity == null ? receivedQuantity : receivedQuantity.add(quantity);
receivedCountMap.put(item.getString("productId"), quantity);
}
// let Map.equals do all the hard comparison work
if (!shippedCountMap.equals(receivedCountMap)) {
return ServiceUtil.returnSuccess();
}
// now update the shipment
dispatcher.runSync("updateShipment", UtilMisc.<String, Object>toMap("shipmentId", shipmentId, "statusId", "PURCH_SHIP_RECEIVED", "userLogin", userLogin));
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
} catch (GenericServiceException se) {
Debug.logError(se, module);
return ServiceUtil.returnError(se.getMessage());
}
return ServiceUtil.returnSuccess();
}
public static Map<String, Object> duplicateShipmentRouteSegment(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String shipmentId = (String) context.get("shipmentId");
String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId");
Locale locale = (Locale) context.get("locale");
Map<String, Object> results = ServiceUtil.returnSuccess();
try {
GenericValue shipmentRouteSeg = delegator.findOne("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), false);
if (shipmentRouteSeg == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentRouteSegmentNotFound",
UtilMisc.toMap("shipmentId", shipmentId,
"shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
}
Map<String, Object> params = UtilMisc.<String, Object>toMap("shipmentId", shipmentId, "carrierPartyId", shipmentRouteSeg.getString("carrierPartyId"), "shipmentMethodTypeId", shipmentRouteSeg.getString("shipmentMethodTypeId"),
"originFacilityId", shipmentRouteSeg.getString("originFacilityId"), "originContactMechId", shipmentRouteSeg.getString("originContactMechId"),
"originTelecomNumberId", shipmentRouteSeg.getString("originTelecomNumberId"));
params.put("destFacilityId", shipmentRouteSeg.getString("destFacilityId"));
params.put("destContactMechId", shipmentRouteSeg.getString("destContactMechId"));
params.put("destTelecomNumberId", shipmentRouteSeg.getString("destTelecomNumberId"));
params.put("billingWeight", shipmentRouteSeg.get("billingWeight"));
params.put("billingWeightUomId", shipmentRouteSeg.get("billingWeightUomId"));
params.put("userLogin", userLogin);
Map<String, Object> tmpResult = dispatcher.runSync("createShipmentRouteSegment", params);
if (ServiceUtil.isError(tmpResult)) {
return tmpResult;
} else {
results.put("newShipmentRouteSegmentId", tmpResult.get("shipmentRouteSegmentId"));
return results;
}
} catch (GenericEntityException ex) {
return ServiceUtil.returnError(ex.getMessage());
} catch (GenericServiceException ex) {
return ServiceUtil.returnError(ex.getMessage());
}
}
/**
* Service to call a ShipmentRouteSegment.carrierPartyId's confirm shipment method asynchronously
*/
public static Map<String, Object> quickScheduleShipmentRouteSegment(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String shipmentId = (String) context.get("shipmentId");
String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId");
String carrierPartyId = null;
// get the carrierPartyId
try {
GenericValue shipmentRouteSegment = delegator.findOne("ShipmentRouteSegment",
UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), true);
carrierPartyId = shipmentRouteSegment.getString("carrierPartyId");
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
// get the shipment label. This is carrier specific.
// TODO: This may not need to be done asynchronously. The reason it's done that way right now is that calling it synchronously means that
// if we can't confirm a single shipment, then all shipment route segments in a multi-form are rolled back.
try {
Map<String, Object> input = UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId, "userLogin", userLogin);
// for DHL, we just need to confirm the shipment to get the label. Other carriers may have more elaborate requirements.
if (carrierPartyId.equals("DHL")) {
dispatcher.runAsync("dhlShipmentConfirm", input);
} else {
Debug.logError(carrierPartyId + " is not supported at this time. Sorry.", module);
}
} catch (GenericServiceException se) {
Debug.logError(se, se.getMessage(), module);
}
// don't return an error
return ServiceUtil.returnSuccess();
}
/**
* Calculates the total value of a shipment package by totalling the results of the getOrderItemInvoicedAmountAndQuantity
* service for the orderItem related to each ShipmentPackageContent, prorated by the quantity of the orderItem issued to the
* ShipmentPackageContent. Value is converted according to the incoming currencyUomId.
* @param dctx DispatchContext
* @param context Map
* @return Map
*/
public static Map<String, Object> getShipmentPackageValueFromOrders(DispatchContext dctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
String shipmentId = (String) context.get("shipmentId");
String shipmentPackageSeqId = (String) context.get("shipmentPackageSeqId");
String currencyUomId = (String) context.get("currencyUomId");
BigDecimal packageTotalValue = ZERO;
GenericValue shipment = null;
GenericValue shipmentPackage = null;
try {
shipment = delegator.findOne("Shipment", UtilMisc.toMap("shipmentId", shipmentId), false);
if (UtilValidate.isEmpty(shipment)) {
String errorMessage = UtilProperties.getMessage(resource, "ProductShipmentNotFoundId", locale);
Debug.logError(errorMessage, module);
return ServiceUtil.returnError(errorMessage);
}
shipmentPackage = delegator.findOne("ShipmentPackage", UtilMisc.toMap("shipmentId", shipmentId, "shipmentPackageSeqId", shipmentPackageSeqId), false);
if (UtilValidate.isEmpty(shipmentPackage)) {
String errorMessage = UtilProperties.getMessage(resource, "ProductShipmentPackageNotFound", context, locale);
Debug.logError(errorMessage, module);
return ServiceUtil.returnError(errorMessage);
}
List<GenericValue> packageContents = delegator.findByAnd("PackedQtyVsOrderItemQuantity", UtilMisc.toMap("shipmentId", shipmentId, "shipmentPackageSeqId", shipmentPackageSeqId), null, false);
for (GenericValue packageContent: packageContents) {
String orderId = packageContent.getString("orderId");
String orderItemSeqId = packageContent.getString("orderItemSeqId");
// Get the value of the orderItem by calling the getOrderItemInvoicedAmountAndQuantity service
Map<String, Object> getOrderItemValueResult = dispatcher.runSync("getOrderItemInvoicedAmountAndQuantity", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "userLogin", userLogin, "locale", locale));
if (ServiceUtil.isError(getOrderItemValueResult)) return getOrderItemValueResult;
BigDecimal invoicedAmount = (BigDecimal) getOrderItemValueResult.get("invoicedAmount");
BigDecimal invoicedQuantity = (BigDecimal) getOrderItemValueResult.get("invoicedQuantity");
// How much of the invoiced quantity does the issued quantity represent?
BigDecimal issuedQuantity = packageContent.getBigDecimal("issuedQuantity");
BigDecimal proportionOfInvoicedQuantity = invoicedQuantity.signum() == 0 ? ZERO : issuedQuantity.divide(invoicedQuantity, 10, rounding);
// Prorate the orderItem's invoiced amount by that proportion
BigDecimal packageContentValue = proportionOfInvoicedQuantity.multiply(invoicedAmount).setScale(decimals, rounding);
// Convert the value to the shipment currency, if necessary
GenericValue orderHeader = packageContent.getRelatedOne("OrderHeader", false);
Map<String, Object> convertUomResult = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", orderHeader.getString("currencyUom"), "uomIdTo", currencyUomId, "originalValue", packageContentValue));
if (ServiceUtil.isError(convertUomResult)) {
return convertUomResult;
}
if (convertUomResult.containsKey("convertedValue")) {
packageContentValue = ((BigDecimal) convertUomResult.get("convertedValue")).setScale(decimals, rounding);
}
// Add the value of the packed item to the package's total value
packageTotalValue = packageTotalValue.add(packageContentValue);
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("packageValue", packageTotalValue);
return result;
}
public static Map<String, Object> sendShipmentCompleteNotification(DispatchContext dctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String shipmentId = (String) context.get("shipmentId");
String sendTo = (String) context.get("sendTo");
String screenUri = (String) context.get("screenUri");
Locale localePar = (Locale) context.get("locale");
// prepare the shipment information
Map<String, Object> sendMap = FastMap.newInstance();
GenericValue shipment = null ;
GenericValue orderHeader = null;
try {
shipment = delegator.findOne("Shipment", UtilMisc.toMap("shipmentId", shipmentId), false);
orderHeader = delegator.findOne("OrderHeader", UtilMisc.toMap("orderId", shipment.getString("primaryOrderId")), false);
} catch (GenericEntityException e) {
Debug.logError(e, "Problem getting info from database", module);
}
GenericValue productStoreEmail = null;
try {
productStoreEmail = delegator.findOne("ProductStoreEmailSetting", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"), "emailType", "PRDS_ODR_SHIP_COMPLT"), false);
} catch (GenericEntityException e) {
Debug.logError(e, "Problem getting the ProductStoreEmailSetting for productStoreId =" + orderHeader.get("productStoreId") + " and emailType = PRDS_ODR_SHIP_COMPLT", module);
}
if (productStoreEmail == null) {
return ServiceUtil.returnFailure(UtilProperties.getMessage(resource,
"ProductProductStoreEmailSettingsNotValid",
UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"),
"emailType", "PRDS_ODR_SHIP_COMPLT"), localePar));
}
// the override screenUri
if (UtilValidate.isEmpty(screenUri)) {
String bodyScreenLocation = productStoreEmail.getString("bodyScreenLocation");
sendMap.put("bodyScreenUri", bodyScreenLocation);
} else {
sendMap.put("bodyScreenUri", screenUri);
}
String partyId = shipment.getString("partyIdTo");
// get the email address
String emailString = null;
GenericValue email = PartyWorker.findPartyLatestContactMech(partyId, "EMAIL_ADDRESS", delegator);
if (UtilValidate.isNotEmpty(email)) {
emailString = email.getString("infoString");
}
if (UtilValidate.isEmpty(emailString)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductProductStoreEmailSettingsNoSendToFound", localePar));
}
Locale locale = PartyWorker.findPartyLastLocale(partyId, delegator);
if (locale == null) {
locale = Locale.getDefault();
}
ResourceBundleMapWrapper uiLabelMap = UtilProperties.getResourceBundleMap("EcommerceUiLabels", locale);
uiLabelMap.addBottomResourceBundle("OrderUiLabels");
uiLabelMap.addBottomResourceBundle("CommonUiLabels");
Map<String, Object> bodyParameters = UtilMisc.<String, Object>toMap("partyId", partyId, "shipmentId", shipmentId, "orderId", shipment.getString("primaryOrderId"), "userLogin", userLogin, "uiLabelMap", uiLabelMap, "locale", locale);
sendMap.put("bodyParameters", bodyParameters);
sendMap.put("userLogin",userLogin);
sendMap.put("subject", productStoreEmail.getString("subject"));
sendMap.put("contentType", productStoreEmail.get("contentType"));
sendMap.put("sendFrom", productStoreEmail.get("fromAddress"));
sendMap.put("sendCc", productStoreEmail.get("ccAddress"));
sendMap.put("sendBcc", productStoreEmail.get("bccAddress"));
if ((sendTo != null) && UtilValidate.isEmail(sendTo)) {
sendMap.put("sendTo", sendTo);
} else {
sendMap.put("sendTo", emailString);
}
// send the notification
Map<String, Object> sendResp = null;
try {
sendResp = dispatcher.runSync("sendMailFromScreen", sendMap);
} catch (Exception e) {
Debug.logError(e, "Problem sending mail", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemSendingEmail", localePar));
}
// check for errors
if (sendResp != null && ServiceUtil.isError(sendResp)) {
sendResp.put("emailType", "PRDS_ODR_SHIP_COMPLT");
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemSendingEmail", localePar), null, null, sendResp);
}
return sendResp;
}
public static Map<String, Object> getShipmentGatewayConfigFromShipment(Delegator delegator, String shipmentId, Locale locale) {
Map<String, Object> shipmentGatewayConfig = ServiceUtil.returnSuccess();
try {
GenericValue shipment = delegator.findOne("Shipment", UtilMisc.toMap("shipmentId", shipmentId), false);
if (shipment == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentNotFoundId", locale) + shipmentId);
}
GenericValue primaryOrderHeader = shipment.getRelatedOne("PrimaryOrderHeader", false);
if (primaryOrderHeader == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentPrimaryOrderHeaderNotFound",
UtilMisc.toMap("shipmentId", shipmentId), locale));
}
String productStoreId = primaryOrderHeader.getString("productStoreId");
if (UtilValidate.isEmpty(productStoreId)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentPrimaryOrderHeaderProductStoreNotFound",
UtilMisc.toMap("productStoreId", productStoreId, "shipmentId", shipmentId), locale));
}
GenericValue primaryOrderItemShipGroup = shipment.getRelatedOne("PrimaryOrderItemShipGroup", false);
if (primaryOrderItemShipGroup == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductShipmentPrimaryOrderHeaderItemShipGroupNotFound",
UtilMisc.toMap("shipmentId", shipmentId), locale));
}
String shipmentMethodTypeId = primaryOrderItemShipGroup.getString("shipmentMethodTypeId");
String carrierPartyId = primaryOrderItemShipGroup.getString("carrierPartyId");
String carrierRoleTypeId = primaryOrderItemShipGroup.getString("carrierRoleTypeId");
List<EntityCondition> conditions = FastList.newInstance();
conditions.add(EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStoreId));
conditions.add(EntityCondition.makeCondition("shipmentMethodTypeId", EntityOperator.EQUALS, shipmentMethodTypeId));
conditions.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, carrierPartyId));
conditions.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, carrierRoleTypeId));
EntityConditionList<EntityCondition> ecl = EntityCondition.makeCondition(conditions, EntityOperator.AND);
List<GenericValue> productStoreShipmentMeths = delegator.findList("ProductStoreShipmentMeth", ecl, null, null, null, false);
GenericValue productStoreShipmentMeth = EntityUtil.getFirst(productStoreShipmentMeths);
if (UtilValidate.isNotEmpty(productStoreShipmentMeth)) {
shipmentGatewayConfig.put("shipmentGatewayConfigId", productStoreShipmentMeth.getString("shipmentGatewayConfigId"));
shipmentGatewayConfig.put("configProps", productStoreShipmentMeth.getString("configProps"));
} else {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductStoreShipmentMethodNotFound",
UtilMisc.toMap("shipmentId", shipmentId), locale));
}
} catch (Exception e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"FacilityShipmentGatewayConfigFromShipmentError",
UtilMisc.toMap("errorString", e.getMessage()), locale));
}
return shipmentGatewayConfig;
}
}