in applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java [84:594]
public static Map<String, Object> calculateProductPrice(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Map<String, Object> result = new HashMap<>();
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
GenericValue product = (GenericValue) context.get("product");
String productId = product.getString("productId");
String prodCatalogId = (String) context.get("prodCatalogId");
String webSiteId = (String) context.get("webSiteId");
String checkIncludeVat = (String) context.get("checkIncludeVat");
String surveyResponseId = (String) context.get("surveyResponseId");
Map<String, Object> customAttributes = UtilGenerics.cast(context.get("customAttributes"));
String findAllQuantityPricesStr = (String) context.get("findAllQuantityPrices");
boolean findAllQuantityPrices = "Y".equals(findAllQuantityPricesStr);
boolean optimizeForLargeRuleSet = "Y".equals(context.get("optimizeForLargeRuleSet"));
String agreementId = (String) context.get("agreementId");
String productStoreId = (String) context.get("productStoreId");
String productStoreGroupId = (String) context.get("productStoreGroupId");
Locale locale = (Locale) context.get("locale");
GenericValue productStore = null;
try {
// we have a productStoreId, if the corresponding ProductStore.primaryStoreGroupId is not empty, use that
productStore = EntityQuery.use(delegator).from("ProductStore").where("productStoreId", productStoreId).cache().queryOne();
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting product store info from the database while calculating price" + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"ProductPriceCannotRetrieveProductStore", UtilMisc.toMap("errorString", e.toString()), locale));
}
if (UtilValidate.isEmpty(productStoreGroupId)) {
if (productStore != null) {
try {
if (UtilValidate.isNotEmpty(productStore.getString("primaryStoreGroupId"))) {
productStoreGroupId = productStore.getString("primaryStoreGroupId");
} else {
// no ProductStore.primaryStoreGroupId, try ProductStoreGroupMember
List<GenericValue> productStoreGroupMemberList = EntityQuery.use(delegator).from("ProductStoreGroupMember")
.where("productStoreId", productStoreId).orderBy("sequenceNum", "-fromDate").cache(true).queryList();
productStoreGroupMemberList = EntityUtil.filterByDate(productStoreGroupMemberList, true);
if (!productStoreGroupMemberList.isEmpty()) {
GenericValue productStoreGroupMember = EntityUtil.getFirst(productStoreGroupMemberList);
productStoreGroupId = productStoreGroupMember.getString("productStoreGroupId");
}
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting product store info from the database while calculating price" + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"ProductPriceCannotRetrieveProductStore", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
// still empty, default to _NA_
if (UtilValidate.isEmpty(productStoreGroupId)) {
productStoreGroupId = "_NA_";
}
}
// if currencyUomId is null get from properties file, if nothing there assume USD (USD: American Dollar) for now
String currencyDefaultUomId = (String) context.get("currencyUomId");
String currencyUomIdTo = (String) context.get("currencyUomIdTo");
if (UtilValidate.isEmpty(currencyDefaultUomId)) {
if (productStore != null && UtilValidate.isNotEmpty(productStore.getString("defaultCurrencyUomId"))) {
currencyDefaultUomId = productStore.getString("defaultCurrencyUomId");
} else {
currencyDefaultUomId = EntityUtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD", delegator);
}
}
// productPricePurposeId is null assume "PURCHASE", which is equivalent to what prices were before the purpose concept
String productPricePurposeId = (String) context.get("productPricePurposeId");
if (UtilValidate.isEmpty(productPricePurposeId)) {
productPricePurposeId = "PURCHASE";
}
// termUomId, for things like recurring prices specifies the term (time/frequency measure for example) of the recurrence
// if this is empty it will simply not be used to constrain the selection
String termUomId = (String) context.get("termUomId");
// if this product is variant, find the virtual product and apply checks to it as well
String virtualProductId = null;
if ("Y".equals(product.getString("isVariant"))) {
try {
virtualProductId = ProductWorker.getVariantVirtualId(product);
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting virtual product id from the database while calculating price" + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"ProductPriceCannotRetrieveVirtualProductId", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
// get prices for virtual product if one is found; get all ProductPrice entities for this productId and currencyUomId
List<GenericValue> virtualProductPrices = null;
if (virtualProductId != null) {
try {
virtualProductPrices = EntityQuery.use(delegator).from("ProductPrice").where("productId", virtualProductId, "currencyUomId",
currencyDefaultUomId, "productStoreGroupId", productStoreGroupId).orderBy("-fromDate").cache(true).queryList();
} catch (GenericEntityException e) {
Debug.logError(e, "An error occurred while getting the product prices", MODULE);
}
virtualProductPrices = EntityUtil.filterByDate(virtualProductPrices, true);
}
// NOTE: partyId CAN be null
String partyId = (String) context.get("partyId");
if (UtilValidate.isEmpty(partyId) && context.get("userLogin") != null) {
GenericValue userLogin = (GenericValue) context.get("userLogin");
partyId = userLogin.getString("partyId");
}
// check for auto-userlogin for price rules
if (UtilValidate.isEmpty(partyId) && context.get("autoUserLogin") != null) {
GenericValue userLogin = (GenericValue) context.get("autoUserLogin");
partyId = userLogin.getString("partyId");
}
BigDecimal quantity = (BigDecimal) context.get("quantity");
if (quantity == null) quantity = BigDecimal.ONE;
BigDecimal amount = (BigDecimal) context.get("amount");
List<EntityCondition> productPriceEcList = new LinkedList<>();
productPriceEcList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId));
// this funny statement is for backward compatibility purposes; the productPricePurposeId is a new pk field on the ProductPrice entity and
// in order databases may not be populated, until the pk is updated and such; this will ease the transition somewhat
if ("PURCHASE".equals(productPricePurposeId)) {
productPriceEcList.add(EntityCondition.makeCondition(
EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId),
EntityOperator.OR,
EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, null)));
} else {
productPriceEcList.add(EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId));
}
productPriceEcList.add(EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, currencyDefaultUomId));
productPriceEcList.add(EntityCondition.makeCondition("productStoreGroupId", EntityOperator.EQUALS, productStoreGroupId));
if (UtilValidate.isNotEmpty(termUomId)) {
productPriceEcList.add(EntityCondition.makeCondition("termUomId", EntityOperator.EQUALS, termUomId));
}
EntityCondition productPriceEc = EntityCondition.makeCondition(productPriceEcList, EntityOperator.AND);
// for prices, get all ProductPrice entities for this productId and currencyUomId
List<GenericValue> productPrices = null;
try {
productPrices = EntityQuery.use(delegator).from("ProductPrice").where(productPriceEc).orderBy("-fromDate").cache(true).queryList();
} catch (GenericEntityException e) {
Debug.logError(e, "An error occurred while getting the product prices", MODULE);
}
productPrices = EntityUtil.filterByDate(productPrices, true);
// ===== get the prices we need: list, default, average cost, promo, min, max =====
// if any of these prices is missing and this product is a variant, default to the corresponding price on the virtual product
GenericValue listPriceValue = getPriceValueForType("LIST_PRICE", productPrices, virtualProductPrices);
GenericValue defaultPriceValue = getPriceValueForType("DEFAULT_PRICE", productPrices, virtualProductPrices);
// If there is an agreement between the company and the client, and there is
// a price for the product in it, it will override the default price of the
// ProductPrice entity.
if (UtilValidate.isNotEmpty(agreementId)) {
try {
GenericValue agreementPriceValue = EntityQuery.use(delegator).from("AgreementItemAndProductAppl").where("agreementId", agreementId,
"productId", productId, "currencyUomId", currencyDefaultUomId).queryFirst();
if (agreementPriceValue != null && agreementPriceValue.get("price") != null) {
defaultPriceValue = agreementPriceValue;
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting agreement info from the database while calculating price" + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"ProductPriceCannotRetrieveAgreementInfo", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
GenericValue competitivePriceValue = getPriceValueForType("COMPETITIVE_PRICE", productPrices, virtualProductPrices);
GenericValue averageCostValue = getPriceValueForType("AVERAGE_COST", productPrices, virtualProductPrices);
GenericValue promoPriceValue = getPriceValueForType("PROMO_PRICE", productPrices, virtualProductPrices);
GenericValue minimumPriceValue = getPriceValueForType("MINIMUM_PRICE", productPrices, virtualProductPrices);
GenericValue maximumPriceValue = getPriceValueForType("MAXIMUM_PRICE", productPrices, virtualProductPrices);
GenericValue wholesalePriceValue = getPriceValueForType("WHOLESALE_PRICE", productPrices, virtualProductPrices);
GenericValue specialPromoPriceValue = getPriceValueForType("SPECIAL_PROMO_PRICE", productPrices, virtualProductPrices);
// now if this is a virtual product check each price type, if doesn't exist get from variant with lowest DEFAULT_PRICE
if ("Y".equals(product.getString("isVirtual"))) {
// only do this if there is no default price, consider the others optional for performance reasons
if (defaultPriceValue == null) {
//use the cache to find the variant with the lowest default price
try {
List<GenericValue> variantAssocList = EntityQuery.use(delegator).from("ProductAssoc").where("productId", product.get("productId"),
"productAssocTypeId", "PRODUCT_VARIANT").orderBy("-fromDate").cache(true).filterByDate().queryList();
BigDecimal minDefaultPrice = null;
List<GenericValue> variantProductPrices = null;
for (GenericValue variantAssoc: variantAssocList) {
String curVariantProductId = variantAssoc.getString("productIdTo");
List<GenericValue> curVariantPriceList = EntityQuery.use(delegator).from("ProductPrice")
.where("productId", curVariantProductId).orderBy("-fromDate").cache(true).filterByDate(nowTimestamp).queryList();
List<GenericValue> tempDefaultPriceList = EntityUtil.filterByAnd(curVariantPriceList, UtilMisc.toMap("productPriceTypeId",
"DEFAULT_PRICE"));
GenericValue curDefaultPriceValue = EntityUtil.getFirst(tempDefaultPriceList);
if (curDefaultPriceValue != null) {
BigDecimal curDefaultPrice = curDefaultPriceValue.getBigDecimal("price");
if (minDefaultPrice == null || curDefaultPrice.compareTo(minDefaultPrice) < 0) {
// check to see if the product is discontinued for sale before considering it the lowest price
GenericValue curVariantProduct = EntityQuery.use(delegator).from("Product").where("productId", curVariantProductId)
.cache().queryOne();
if (curVariantProduct != null) {
Timestamp salesDiscontinuationDate = curVariantProduct.getTimestamp("salesDiscontinuationDate");
if (salesDiscontinuationDate == null || salesDiscontinuationDate.after(nowTimestamp)) {
minDefaultPrice = curDefaultPrice;
variantProductPrices = curVariantPriceList;
}
}
}
}
}
if (variantProductPrices != null) {
// we have some other options, give 'em a go...
if (listPriceValue == null) {
listPriceValue = getPriceValueForType("LIST_PRICE", variantProductPrices, null);
}
if (competitivePriceValue == null) {
competitivePriceValue = getPriceValueForType("COMPETITIVE_PRICE", variantProductPrices, null);
}
if (averageCostValue == null) {
averageCostValue = getPriceValueForType("AVERAGE_COST", variantProductPrices, null);
}
if (promoPriceValue == null) {
promoPriceValue = getPriceValueForType("PROMO_PRICE", variantProductPrices, null);
}
if (minimumPriceValue == null) {
minimumPriceValue = getPriceValueForType("MINIMUM_PRICE", variantProductPrices, null);
}
if (maximumPriceValue == null) {
maximumPriceValue = getPriceValueForType("MAXIMUM_PRICE", variantProductPrices, null);
}
if (wholesalePriceValue == null) {
wholesalePriceValue = getPriceValueForType("WHOLESALE_PRICE", variantProductPrices, null);
}
if (specialPromoPriceValue == null) {
specialPromoPriceValue = getPriceValueForType("SPECIAL_PROMO_PRICE", variantProductPrices, null);
}
defaultPriceValue = getPriceValueForType("DEFAULT_PRICE", variantProductPrices, null);
}
} catch (GenericEntityException e) {
Debug.logError(e, "An error occurred while getting the product prices", MODULE);
}
}
}
BigDecimal promoPrice = BigDecimal.ZERO;
if (promoPriceValue != null && promoPriceValue.get("price") != null) {
promoPrice = promoPriceValue.getBigDecimal("price");
}
BigDecimal wholesalePrice = BigDecimal.ZERO;
if (wholesalePriceValue != null && wholesalePriceValue.get("price") != null) {
wholesalePrice = wholesalePriceValue.getBigDecimal("price");
}
boolean validPriceFound = false;
BigDecimal defaultPrice = BigDecimal.ZERO;
BigDecimal listPrice = null;
BigDecimal discountRate = null;
List<GenericValue> orderItemPriceInfos = new LinkedList<>();
if (defaultPriceValue != null) {
// If a price calc formula (service) is specified, then use it to get the unit price
if ("ProductPrice".equals(defaultPriceValue.getEntityName()) && UtilValidate.isNotEmpty(defaultPriceValue
.getString("customPriceCalcService"))) {
GenericValue customMethod = null;
try {
customMethod = defaultPriceValue.getRelatedOne("CustomMethod", false);
} catch (GenericEntityException gee) {
Debug.logError(gee, "An error occurred while getting the customPriceCalcService", MODULE);
}
if (customMethod != null && UtilValidate.isNotEmpty(customMethod.getString("customMethodName"))) {
Map<String, Object> inMap = UtilMisc.toMap("userLogin", context.get("userLogin"), "product", product);
inMap.put("initialPrice", defaultPriceValue.getBigDecimal("price"));
inMap.put("currencyUomId", currencyDefaultUomId);
inMap.put("quantity", quantity);
inMap.put("amount", amount);
if (UtilValidate.isNotEmpty(surveyResponseId)) {
inMap.put("surveyResponseId", surveyResponseId);
}
if (UtilValidate.isNotEmpty(customAttributes)) {
inMap.put("customAttributes", customAttributes);
}
inMap.put("productStoreGroupId", productStoreGroupId);
inMap.put("partyId", partyId);
try {
Map<String, Object> outMap = dispatcher.runSync(customMethod.getString("customMethodName"), inMap);
if (ServiceUtil.isSuccess(outMap)) {
BigDecimal calculatedDefaultPrice = (BigDecimal) outMap.get("price");
BigDecimal calculatedListPrice = (BigDecimal) outMap.get("listPrice");
BigDecimal calculatedDiscountRate = (BigDecimal) outMap.get("discountRate");
orderItemPriceInfos = UtilGenerics.cast(outMap.get("orderItemPriceInfos"));
if (UtilValidate.isNotEmpty(calculatedDefaultPrice)) {
defaultPrice = calculatedDefaultPrice;
listPrice = calculatedListPrice;
discountRate = calculatedDiscountRate;
validPriceFound = true;
}
}
} catch (GenericServiceException gse) {
Debug.logError(gse, "An error occurred while running the customPriceCalcService ["
+ customMethod.getString("customMethodName") + "]", MODULE);
}
}
}
if (!validPriceFound && defaultPriceValue.get("price") != null) {
defaultPrice = defaultPriceValue.getBigDecimal("price");
validPriceFound = true;
}
}
boolean skipPriceRules = true;
if (listPrice == null && listPriceValue != null) {
listPrice = listPriceValue.getBigDecimal("price");
skipPriceRules = listPrice == null;
}
if (skipPriceRules) {
// no list price, use defaultPrice for the final price
// ========= ensure calculated price is not below minSalePrice or above maxSalePrice =========
BigDecimal maxSellPrice = maximumPriceValue != null ? maximumPriceValue.getBigDecimal("price") : null;
if (maxSellPrice != null && defaultPrice.compareTo(maxSellPrice) > 0) {
defaultPrice = maxSellPrice;
}
// min price second to override max price, safety net
BigDecimal minSellPrice = minimumPriceValue != null ? minimumPriceValue.getBigDecimal("price") : null;
if (minSellPrice != null && defaultPrice.compareTo(minSellPrice) < 0) {
defaultPrice = minSellPrice;
// since we have found a minimum price that has overriden a the defaultPrice, even if no valid one was found,
// we will consider it as if one had been...
validPriceFound = true;
}
result.put("listPrice", listPrice);
result.put("discountRate", discountRate);
result.put("basePrice", defaultPrice);
result.put("price", defaultPrice);
result.put("defaultPrice", defaultPrice);
result.put("competitivePrice", competitivePriceValue != null ? competitivePriceValue.getBigDecimal("price") : null);
result.put("averageCost", averageCostValue != null ? averageCostValue.getBigDecimal("price") : null);
result.put("promoPrice", promoPriceValue != null ? promoPriceValue.getBigDecimal("price") : null);
result.put("specialPromoPrice", specialPromoPriceValue != null ? specialPromoPriceValue.getBigDecimal("price") : null);
result.put("validPriceFound", validPriceFound);
result.put("isSale", Boolean.FALSE);
result.put("orderItemPriceInfos", orderItemPriceInfos);
Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore,
checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
if (errorResult != null) return errorResult;
} else {
try {
List<GenericValue> allProductPriceRules = makeProducePriceRuleList(delegator, optimizeForLargeRuleSet, productId, virtualProductId,
prodCatalogId, productStoreGroupId, webSiteId, partyId, currencyDefaultUomId);
allProductPriceRules = EntityUtil.filterByDate(allProductPriceRules, true);
List<GenericValue> quantityProductPriceRules = null;
List<GenericValue> nonQuantityProductPriceRules = null;
if (findAllQuantityPrices) {
// split into list with quantity conditions and list without, then iterate through each quantity cond one
quantityProductPriceRules = new LinkedList<>();
nonQuantityProductPriceRules = new LinkedList<>();
for (GenericValue productPriceRule: allProductPriceRules) {
List<GenericValue> productPriceCondList = EntityQuery.use(delegator).from("ProductPriceCond").where("productPriceRuleId",
productPriceRule.get("productPriceRuleId")).cache(true).queryList();
boolean foundQuantityInputParam = false;
// only consider a rule if all conditions except the quantity condition are true
boolean allExceptQuantTrue = true;
for (GenericValue productPriceCond: productPriceCondList) {
if ("PRIP_QUANTITY".equals(productPriceCond.getString("inputParamEnumId"))) {
foundQuantityInputParam = true;
} else {
if (!checkPriceCondition(productPriceCond, productId, virtualProductId, prodCatalogId, productStoreGroupId,
webSiteId, partyId, quantity, listPrice, currencyDefaultUomId, delegator, nowTimestamp)) {
allExceptQuantTrue = false;
}
}
}
if (foundQuantityInputParam && allExceptQuantTrue) {
quantityProductPriceRules.add(productPriceRule);
} else {
nonQuantityProductPriceRules.add(productPriceRule);
}
}
}
if (findAllQuantityPrices) {
List<Map<String, Object>> allQuantityPrices = new LinkedList<>();
// if findAllQuantityPrices then iterate through quantityProductPriceRules
// foreach create an entry in the out list and eval that rule and all nonQuantityProductPriceRules rather than a single rule
for (GenericValue quantityProductPriceRule: quantityProductPriceRules) {
List<GenericValue> ruleListToUse = new LinkedList<>();
ruleListToUse.add(quantityProductPriceRule);
ruleListToUse.addAll(nonQuantityProductPriceRules);
Map<String, Object> quantCalcResults = calcPriceResultFromRules(ruleListToUse, listPrice, defaultPrice, promoPrice,
wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound,
averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId,
webSiteId, partyId, null, currencyDefaultUomId, delegator, nowTimestamp, locale);
Map<String, Object> quantErrorResult = addGeneralResults(quantCalcResults, competitivePriceValue, specialPromoPriceValue,
productStore,
checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
if (quantErrorResult != null) return quantErrorResult;
// also add the quantityProductPriceRule to the Map so it can be used for quantity break information
quantCalcResults.put("quantityProductPriceRule", quantityProductPriceRule);
allQuantityPrices.add(quantCalcResults);
}
result.put("allQuantityPrices", allQuantityPrices);
// use a quantity 1 to get the main price, then fill in the quantity break prices
Map<String, Object> calcResults = calcPriceResultFromRules(allProductPriceRules, listPrice, defaultPrice, promoPrice,
wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound,
averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId,
webSiteId, partyId, BigDecimal.ONE, currencyDefaultUomId, delegator, nowTimestamp, locale);
result.putAll(calcResults);
// The orderItemPriceInfos out parameter requires a special treatment:
// the list of OrderItemPriceInfos generated by the price rule is appended to
// the existing orderItemPriceInfos list and the aggregated list is returned.
List<GenericValue> orderItemPriceInfosFromRule = UtilGenerics.cast(calcResults.get("orderItemPriceInfos"));
if (UtilValidate.isNotEmpty(orderItemPriceInfosFromRule)) {
orderItemPriceInfos.addAll(orderItemPriceInfosFromRule);
}
result.put("orderItemPriceInfos", orderItemPriceInfos);
Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore,
checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
if (errorResult != null) return errorResult;
} else {
Map<String, Object> calcResults = calcPriceResultFromRules(allProductPriceRules, listPrice, defaultPrice, promoPrice,
wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound,
averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId,
webSiteId, partyId, quantity, currencyDefaultUomId, delegator, nowTimestamp, locale);
result.putAll(calcResults);
// The orderItemPriceInfos out parameter requires a special treatment:
// the list of OrderItemPriceInfos generated by the price rule is appended to
// the existing orderItemPriceInfos list and the aggregated list is returned.
List<GenericValue> orderItemPriceInfosFromRule = UtilGenerics.cast(calcResults.get("orderItemPriceInfos"));
if (UtilValidate.isNotEmpty(orderItemPriceInfosFromRule)) {
orderItemPriceInfos.addAll(orderItemPriceInfosFromRule);
}
result.put("orderItemPriceInfos", orderItemPriceInfos);
Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore,
checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
if (errorResult != null) return errorResult;
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting rules from the database while calculating price", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"ProductPriceCannotRetrievePriceRules", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
// Convert the value to the price currency, if required
if ("true".equals(EntityUtilProperties.getPropertyValue("catalog", "convertProductPriceCurrency", delegator))) {
if (UtilValidate.isNotEmpty(currencyDefaultUomId) && UtilValidate.isNotEmpty(currencyUomIdTo)
&& !currencyDefaultUomId.equals(currencyUomIdTo)) {
if (UtilValidate.isNotEmpty(result)) {
Map<String, Object> convertPriceMap = new HashMap<>();
for (Map.Entry<String, Object> entry : result.entrySet()) {
BigDecimal tempPrice;
switch (entry.getKey()) {
case "basePrice":
case "price":
case "defaultPrice":
case "competitivePrice":
case "averageCost":
case "promoPrice":
case "specialPromoPrice":
case "listPrice":
tempPrice = (BigDecimal) entry.getValue();
break;
default:
tempPrice = BigDecimal.ZERO;
}
if (tempPrice != null && tempPrice != BigDecimal.ZERO) {
Map<String, Object> priceResults = new HashMap<>();
try {
priceResults = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", currencyDefaultUomId,
"uomIdTo", currencyUomIdTo,
"originalValue", tempPrice, "defaultDecimalScale", 2L, "defaultRoundingMode", "HalfUp"));
if (ServiceUtil.isError(priceResults) || (priceResults.get("convertedValue") == null)) {
Debug.logWarning("Unable to convert " + entry.getKey() + " for product " + productId, MODULE);
}
} catch (GenericServiceException e) {
Debug.logError(e, MODULE);
}
convertPriceMap.put(entry.getKey(), priceResults.get("convertedValue"));
} else {
convertPriceMap.put(entry.getKey(), entry.getValue());
}
}
if (UtilValidate.isNotEmpty(convertPriceMap)) {
convertPriceMap.put("currencyUsed", currencyUomIdTo);
result = convertPriceMap;
}
}
}
}
return result;
}