1 24 package org.ofbiz.product.price; 25 26 import java.math.BigDecimal ; 27 import java.sql.Timestamp ; 28 import java.util.Collection ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.LinkedList ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.TreeSet ; 35 36 import javolution.util.FastList; 37 38 import org.ofbiz.base.util.Debug; 39 import org.ofbiz.base.util.UtilDateTime; 40 import org.ofbiz.base.util.UtilMisc; 41 import org.ofbiz.base.util.UtilProperties; 42 import org.ofbiz.base.util.UtilValidate; 43 import org.ofbiz.entity.GenericDelegator; 44 import org.ofbiz.entity.GenericEntityException; 45 import org.ofbiz.entity.GenericValue; 46 import org.ofbiz.entity.condition.EntityCondition; 47 import org.ofbiz.entity.condition.EntityConditionList; 48 import org.ofbiz.entity.condition.EntityExpr; 49 import org.ofbiz.entity.condition.EntityOperator; 50 import org.ofbiz.entity.util.EntityUtil; 51 import org.ofbiz.product.product.ProductWorker; 52 import org.ofbiz.service.DispatchContext; 53 import org.ofbiz.service.GenericServiceException; 54 import org.ofbiz.service.LocalDispatcher; 55 import org.ofbiz.service.ServiceUtil; 56 57 65 public class PriceServices { 66 67 public static final String module = PriceServices.class.getName(); 68 public static final BigDecimal ONE_BASE = new BigDecimal ("1.000"); 69 public static final BigDecimal PERCENT_SCALE = new BigDecimal ("100.000"); 70 71 85 public static Map calculateProductPrice(DispatchContext dctx, Map context) { 86 boolean optimizeForLargeRuleSet = false; 87 88 92 GenericDelegator delegator = dctx.getDelegator(); 93 LocalDispatcher dispatcher = dctx.getDispatcher(); 94 Map result = new HashMap (); 95 Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); 96 97 boolean isSale = false; 98 List orderItemPriceInfos = new LinkedList (); 99 100 GenericValue product = (GenericValue) context.get("product"); 101 String productId = product.getString("productId"); 102 String prodCatalogId = (String ) context.get("prodCatalogId"); 103 String webSiteId = (String ) context.get("webSiteId"); 104 String checkIncludeVat = (String ) context.get("checkIncludeVat"); 105 106 String productStoreId = (String ) context.get("productStoreId"); 107 String productStoreGroupId = (String ) context.get("productStoreGroupId"); 108 GenericValue productStore = null; 109 try { 110 productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId)); 112 } catch (GenericEntityException e) { 113 String errMsg = "Error getting product store info from the database while calculating price" + e.toString(); 114 Debug.logError(e, errMsg, module); 115 return ServiceUtil.returnError(errMsg); 116 } 117 if (UtilValidate.isEmpty(productStoreGroupId)) { 118 if (productStore != null) { 119 try { 120 if (UtilValidate.isNotEmpty(productStore.getString("primaryStoreGroupId"))) { 121 productStoreGroupId = productStore.getString("primaryStoreGroupId"); 122 } else { 123 List productStoreGroupMemberList = delegator.findByAndCache("ProductStoreGroupMember", UtilMisc.toMap("productStoreId", productStoreId), UtilMisc.toList("sequenceNum", "-fromDate")); 125 productStoreGroupMemberList = EntityUtil.filterByDate(productStoreGroupMemberList, true); 126 if (productStoreGroupMemberList.size() > 0) { 127 GenericValue productStoreGroupMember = EntityUtil.getFirst(productStoreGroupMemberList); 128 productStoreGroupId = productStoreGroupMember.getString("productStoreGroupId"); 129 } 130 } 131 } catch (GenericEntityException e) { 132 String errMsg = "Error getting product store info from the database while calculating price" + e.toString(); 133 Debug.logError(e, errMsg, module); 134 return ServiceUtil.returnError(errMsg); 135 } 136 } 137 138 if (UtilValidate.isEmpty(productStoreGroupId)) { 140 productStoreGroupId = "_NA_"; 141 } 142 } 143 144 String currencyUomId = (String ) context.get("currencyUomId"); 146 if (UtilValidate.isEmpty(currencyUomId)) { 147 currencyUomId = UtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD"); 148 } 149 150 String productPricePurposeId = (String ) context.get("productPricePurposeId"); 152 if (UtilValidate.isEmpty(productPricePurposeId)) { 153 productPricePurposeId = "PURCHASE"; 154 } 155 156 String termUomId = (String ) context.get("termUomId"); 159 160 String virtualProductId = null; 162 if ("Y".equals(product.getString("isVariant"))) { 163 try { 164 virtualProductId = ProductWorker.getVariantVirtualId(product); 165 } catch (GenericEntityException e) { 166 String errMsg = "Error getting virtual product id from the database while calculating price" + e.toString(); 167 Debug.logError(e, errMsg, module); 168 return ServiceUtil.returnError(errMsg); 169 } 170 } 171 172 List virtualProductPrices = null; 174 if (virtualProductId != null) { 175 try { 176 virtualProductPrices = delegator.findByAndCache("ProductPrice", UtilMisc.toMap("productId", virtualProductId, "currencyUomId", currencyUomId, "productStoreGroupId", productStoreGroupId), UtilMisc.toList("-fromDate")); 177 } catch (GenericEntityException e) { 178 Debug.logError(e, "An error occurred while getting the product prices", module); 179 } 180 virtualProductPrices = EntityUtil.filterByDate(virtualProductPrices, true); 181 } 182 183 String partyId = (String ) context.get("partyId"); 185 if (UtilValidate.isEmpty(partyId) && context.get("userLogin") != null) { 186 GenericValue userLogin = (GenericValue) context.get("userLogin"); 187 partyId = userLogin.getString("partyId"); 188 } 189 190 if (UtilValidate.isEmpty(partyId) && context.get("autoUserLogin") != null) { 192 GenericValue userLogin = (GenericValue) context.get("autoUserLogin"); 193 partyId = userLogin.getString("partyId"); 194 } 195 196 Double quantityDbl = (Double ) context.get("quantity"); 197 if (quantityDbl == null) quantityDbl = new Double (1.0); 198 double quantity = quantityDbl.doubleValue(); 199 200 List productPriceEcList = FastList.newInstance(); 201 productPriceEcList.add(new EntityExpr("productId", EntityOperator.EQUALS, productId)); 202 if ("PURCHASE".equals(productPricePurposeId)) { 204 productPriceEcList.add(new EntityExpr( 205 new EntityExpr("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId), 206 EntityOperator.OR, 207 new EntityExpr("productPricePurposeId", EntityOperator.EQUALS, null))); 208 } else { 209 productPriceEcList.add(new EntityExpr("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId)); 210 } 211 productPriceEcList.add(new EntityExpr("currencyUomId", EntityOperator.EQUALS, currencyUomId)); 212 productPriceEcList.add(new EntityExpr("productStoreGroupId", EntityOperator.EQUALS, productStoreGroupId)); 213 if (UtilValidate.isNotEmpty(termUomId)) { 214 productPriceEcList.add(new EntityExpr("termUomId", EntityOperator.EQUALS, termUomId)); 215 } 216 EntityCondition productPriceEc = new EntityConditionList(productPriceEcList, EntityOperator.AND); 217 218 List productPrices = null; 220 try { 221 productPrices = delegator.findByConditionCache("ProductPrice", productPriceEc, null, UtilMisc.toList("-fromDate")); 222 } catch (GenericEntityException e) { 223 Debug.logError(e, "An error occurred while getting the product prices", module); 224 } 225 productPrices = EntityUtil.filterByDate(productPrices, true); 226 227 List listPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "LIST_PRICE")); 229 GenericValue listPriceValue = EntityUtil.getFirst(listPrices); 230 if (listPrices != null && listPrices.size() > 1) { 231 if (Debug.infoOn()) Debug.logInfo("There is more than one LIST_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + listPriceValue.getDouble("price"), module); 232 } 233 234 List defaultPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE")); 235 GenericValue defaultPriceValue = EntityUtil.getFirst(defaultPrices); 236 if (defaultPrices != null && defaultPrices.size() > 1) { 237 if (Debug.infoOn()) Debug.logInfo("There is more than one DEFAULT_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + defaultPriceValue.getDouble("price"), module); 238 } 239 240 List competitivePrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "COMPETITIVE_PRICE")); 241 GenericValue competitivePriceValue = EntityUtil.getFirst(competitivePrices); 242 if (competitivePrices != null && competitivePrices.size() > 1) { 243 if (Debug.infoOn()) Debug.logInfo("There is more than one COMPETITIVE_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + competitivePriceValue.getDouble("price"), module); 244 } 245 246 List averageCosts = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "AVERAGE_COST")); 247 GenericValue averageCostValue = EntityUtil.getFirst(averageCosts); 248 if (averageCosts != null && averageCosts.size() > 1) { 249 if (Debug.infoOn()) Debug.logInfo("There is more than one AVERAGE_COST with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + averageCostValue.getDouble("price"), module); 250 } 251 252 List promoPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "PROMO_PRICE")); 253 GenericValue promoPriceValue = EntityUtil.getFirst(promoPrices); 254 if (promoPrices != null && promoPrices.size() > 1) { 255 if (Debug.infoOn()) Debug.logInfo("There is more than one PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + promoPriceValue.getDouble("price"), module); 256 } 257 258 List minimumPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "MINIMUM_PRICE")); 259 GenericValue minimumPriceValue = EntityUtil.getFirst(minimumPrices); 260 if (minimumPrices != null && minimumPrices.size() > 1) { 261 if (Debug.infoOn()) Debug.logInfo("There is more than one MINIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + minimumPriceValue.getDouble("price"), module); 262 } 263 264 List maximumPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "MAXIMUM_PRICE")); 265 GenericValue maximumPriceValue = EntityUtil.getFirst(maximumPrices); 266 if (maximumPrices != null && maximumPrices.size() > 1) { 267 if (Debug.infoOn()) Debug.logInfo("There is more than one MAXIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + maximumPriceValue.getDouble("price"), module); 268 } 269 270 List wholesalePrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "WHOLESALE_PRICE")); 271 GenericValue wholesalePriceValue = EntityUtil.getFirst(wholesalePrices); 272 if (wholesalePrices != null && wholesalePrices.size() > 1) { 273 if (Debug.infoOn()) Debug.logInfo("There is more than one WHOLESALE_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + wholesalePriceValue.getDouble("price"), module); 274 } 275 276 List specialPromoPrices = EntityUtil.filterByAnd(productPrices, UtilMisc.toMap("productPriceTypeId", "SPECIAL_PROMO_PRICE")); 277 GenericValue specialPromoPriceValue = EntityUtil.getFirst(specialPromoPrices); 278 if (specialPromoPrices != null && specialPromoPrices.size() > 1) { 279 if (Debug.infoOn()) Debug.logInfo("There is more than one SPECIAL_PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + productId + ", using the latest found with price: " + specialPromoPriceValue.getDouble("price"), module); 280 } 281 282 if (virtualProductPrices != null && virtualProductPrices.size() > 0) { 284 if (listPriceValue == null) { 285 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "LIST_PRICE")); 286 listPriceValue = EntityUtil.getFirst(virtualTempPrices); 287 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 288 if (Debug.infoOn()) Debug.logInfo("There is more than one LIST_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + listPriceValue.getDouble("price"), module); 289 } 290 } 291 if (defaultPriceValue == null) { 292 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE")); 293 defaultPriceValue = EntityUtil.getFirst(virtualTempPrices); 294 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 295 if (Debug.infoOn()) Debug.logInfo("There is more than one DEFAULT_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + defaultPriceValue.getDouble("price"), module); 296 } 297 } 298 if (averageCostValue == null) { 299 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "AVERAGE_COST")); 300 averageCostValue = EntityUtil.getFirst(virtualTempPrices); 301 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 302 if (Debug.infoOn()) Debug.logInfo("There is more than one AVERAGE_COST with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + averageCostValue.getDouble("price"), module); 303 } 304 } 305 if (promoPriceValue == null) { 306 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "PROMO_PRICE")); 307 promoPriceValue = EntityUtil.getFirst(virtualTempPrices); 308 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 309 if (Debug.infoOn()) Debug.logInfo("There is more than one PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + promoPriceValue.getDouble("price"), module); 310 } 311 } 312 if (minimumPriceValue == null) { 313 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "MINIMUM_PRICE")); 314 minimumPriceValue = EntityUtil.getFirst(virtualTempPrices); 315 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 316 if (Debug.infoOn()) Debug.logInfo("There is more than one MINIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + minimumPriceValue.getDouble("price"), module); 317 } 318 } 319 if (maximumPriceValue == null) { 320 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "MAXIMUM_PRICE")); 321 maximumPriceValue = EntityUtil.getFirst(virtualTempPrices); 322 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 323 if (Debug.infoOn()) Debug.logInfo("There is more than one MAXIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + maximumPriceValue.getDouble("price"), module); 324 } 325 } 326 if (wholesalePriceValue == null) { 327 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "WHOLESALE_PRICE")); 328 wholesalePriceValue = EntityUtil.getFirst(virtualTempPrices); 329 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 330 if (Debug.infoOn()) Debug.logInfo("There is more than one WHOLESALE_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + wholesalePriceValue.getDouble("price"), module); 331 } 332 } 333 if (specialPromoPriceValue == null) { 334 List virtualTempPrices = EntityUtil.filterByAnd(virtualProductPrices, UtilMisc.toMap("productPriceTypeId", "SPECIAL_PROMO_PRICE")); 335 specialPromoPriceValue = EntityUtil.getFirst(virtualTempPrices); 336 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 337 if (Debug.infoOn()) Debug.logInfo("There is more than one SPECIAL_PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + virtualProductId + ", using the latest found with price: " + specialPromoPriceValue.getDouble("price"), module); 338 } 339 } 340 } 341 342 if ("Y".equals(product.getString("isVirtual"))) { 344 if (defaultPriceValue == null) { 346 348 try { 350 List variantAssocList = EntityUtil.filterByDate(delegator.findByAndCache("ProductAssoc", UtilMisc.toMap("productId", product.get("productId"), "productAssocTypeId", "PRODUCT_VARIANT"), UtilMisc.toList("-fromDate"))); 351 Iterator variantAssocIter = variantAssocList.iterator(); 352 double minDefaultPrice = Double.MAX_VALUE; 353 List variantProductPrices = null; 354 String variantProductId = null; 355 while (variantAssocIter.hasNext()) { 356 GenericValue variantAssoc = (GenericValue) variantAssocIter.next(); 357 String curVariantProductId = variantAssoc.getString("productIdTo"); 358 List curVariantPriceList = EntityUtil.filterByDate(delegator.findByAndCache("ProductPrice", UtilMisc.toMap("productId", curVariantProductId), UtilMisc.toList("-fromDate")), nowTimestamp); 359 List tempDefaultPriceList = EntityUtil.filterByAnd(curVariantPriceList, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE")); 360 GenericValue curDefaultPriceValue = EntityUtil.getFirst(tempDefaultPriceList); 361 if (curDefaultPriceValue != null) { 362 Double curDefaultPrice = curDefaultPriceValue.getDouble("price"); 363 if (curDefaultPrice.doubleValue() < minDefaultPrice) { 364 GenericValue curVariantProduct = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", curVariantProductId)); 366 if (curVariantProduct != null) { 367 Timestamp salesDiscontinuationDate = curVariantProduct.getTimestamp("salesDiscontinuationDate"); 368 if (salesDiscontinuationDate == null || salesDiscontinuationDate.after(nowTimestamp)) { 369 minDefaultPrice = curDefaultPrice.doubleValue(); 370 variantProductPrices = curVariantPriceList; 371 variantProductId = curVariantProductId; 372 } 374 } 375 } 376 } 377 } 378 379 if (variantProductPrices != null) { 380 if (listPriceValue == null) { 382 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "LIST_PRICE")); 383 listPriceValue = EntityUtil.getFirst(virtualTempPrices); 384 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 385 if (Debug.infoOn()) Debug.logInfo("There is more than one LIST_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + listPriceValue.getDouble("price"), module); 386 } 387 } 388 if (defaultPriceValue == null) { 389 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE")); 390 defaultPriceValue = EntityUtil.getFirst(virtualTempPrices); 391 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 392 if (Debug.infoOn()) Debug.logInfo("There is more than one DEFAULT_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + defaultPriceValue.getDouble("price"), module); 393 } 394 } 395 if (competitivePriceValue == null) { 396 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "COMPETITIVE_PRICE")); 397 competitivePriceValue = EntityUtil.getFirst(virtualTempPrices); 398 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 399 if (Debug.infoOn()) Debug.logInfo("There is more than one COMPETITIVE_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + competitivePriceValue.getDouble("price"), module); 400 } 401 } 402 if (averageCostValue == null) { 403 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "AVERAGE_COST")); 404 averageCostValue = EntityUtil.getFirst(virtualTempPrices); 405 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 406 if (Debug.infoOn()) Debug.logInfo("There is more than one AVERAGE_COST with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + averageCostValue.getDouble("price"), module); 407 } 408 } 409 if (promoPriceValue == null) { 410 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "PROMO_PRICE")); 411 promoPriceValue = EntityUtil.getFirst(virtualTempPrices); 412 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 413 if (Debug.infoOn()) Debug.logInfo("There is more than one PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + promoPriceValue.getDouble("price"), module); 414 } 415 } 416 if (minimumPriceValue == null) { 417 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "MINIMUM_PRICE")); 418 minimumPriceValue = EntityUtil.getFirst(virtualTempPrices); 419 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 420 if (Debug.infoOn()) Debug.logInfo("There is more than one MINIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + minimumPriceValue.getDouble("price"), module); 421 } 422 } 423 if (maximumPriceValue == null) { 424 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "MAXIMUM_PRICE")); 425 maximumPriceValue = EntityUtil.getFirst(virtualTempPrices); 426 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 427 if (Debug.infoOn()) Debug.logInfo("There is more than one MAXIMUM_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + maximumPriceValue.getDouble("price"), module); 428 } 429 } 430 if (wholesalePriceValue == null) { 431 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "WHOLESALE_PRICE")); 432 wholesalePriceValue = EntityUtil.getFirst(virtualTempPrices); 433 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 434 if (Debug.infoOn()) Debug.logInfo("There is more than one WHOLESALE_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + wholesalePriceValue.getDouble("price"), module); 435 } 436 } 437 if (specialPromoPriceValue == null) { 438 List virtualTempPrices = EntityUtil.filterByAnd(variantProductPrices, UtilMisc.toMap("productPriceTypeId", "SPECIAL_PROMO_PRICE")); 439 specialPromoPriceValue = EntityUtil.getFirst(virtualTempPrices); 440 if (virtualTempPrices != null && virtualTempPrices.size() > 1) { 441 if (Debug.infoOn()) Debug.logInfo("There is more than one SPECIAL_PROMO_PRICE with the currencyUomId " + currencyUomId + " and productId " + variantProductId + ", using the latest found with price: " + wholesalePriceValue.getDouble("price"), module); 442 } 443 } 444 } 445 } catch (GenericEntityException e) { 446 Debug.logError(e, "An error occurred while getting the product prices", module); 447 } 448 } 449 } 450 451 double promoPrice = 0; 453 if (promoPriceValue != null && promoPriceValue.get("price") != null) { 454 promoPrice = promoPriceValue.getDouble("price").doubleValue(); 455 } 457 458 double wholesalePrice = 0; 460 if (wholesalePriceValue != null && wholesalePriceValue.get("price") != null) { 461 wholesalePrice = wholesalePriceValue.getDouble("price").doubleValue(); 462 } 464 465 boolean validPriceFound = false; 466 double defaultPrice = 0; 467 if (defaultPriceValue != null && defaultPriceValue.get("price") != null) { 468 defaultPrice = defaultPriceValue.getDouble("price").doubleValue(); 469 validPriceFound = true; 470 } 471 472 Double listPriceDbl = listPriceValue != null ? listPriceValue.getDouble("price") : null; 473 474 if (listPriceDbl == null) { 475 477 Double maxSellPrice = maximumPriceValue != null ? maximumPriceValue.getDouble("price") : null; 479 if (maxSellPrice != null && defaultPrice > maxSellPrice.doubleValue()) { 480 defaultPrice = maxSellPrice.doubleValue(); 481 } 482 Double minSellPrice = minimumPriceValue != null ? minimumPriceValue.getDouble("price") : null; 484 if (minSellPrice != null && defaultPrice < minSellPrice.doubleValue()) { 485 defaultPrice = minSellPrice.doubleValue(); 486 validPriceFound = true; 488 } 489 490 result.put("basePrice", new Double (defaultPrice)); 491 result.put("price", new Double (defaultPrice)); 492 result.put("defaultPrice", new Double (defaultPrice)); 493 result.put("competitivePrice", competitivePriceValue != null ? competitivePriceValue.getDouble("price") : null); 494 result.put("averageCost", averageCostValue != null ? averageCostValue.getDouble("price") : null); 495 result.put("promoPrice", promoPriceValue != null ? promoPriceValue.getDouble("price") : null); 496 result.put("specialPromoPrice", specialPromoPriceValue != null ? specialPromoPriceValue.getDouble("price") : null); 497 } else { 498 try { 499 double listPrice = listPriceDbl.doubleValue(); 501 double averageCost = (averageCostValue != null && averageCostValue.get("price") != null) ? averageCostValue.getDouble("price").doubleValue() : listPrice; 502 double margin = listPrice - averageCost; 503 504 double price = listPrice; 506 507 Collection productPriceRules = null; 508 509 if (optimizeForLargeRuleSet) { 514 TreeSet productPriceRuleIds = new TreeSet (); 517 518 520 Collection productCategoryIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PROD_CAT_ID")); 524 if (productCategoryIdConds != null && productCategoryIdConds.size() > 0) { 525 Iterator productCategoryIdCondsIter = productCategoryIdConds.iterator(); 526 while (productCategoryIdCondsIter.hasNext()) { 527 GenericValue productCategoryIdCond = (GenericValue) productCategoryIdCondsIter.next(); 528 productPriceRuleIds.add(productCategoryIdCond.getString("productPriceRuleId")); 529 } 530 } 531 532 Collection quantityConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_QUANTITY")); 536 if (quantityConds != null && quantityConds.size() > 0) { 537 Iterator quantityCondsIter = quantityConds.iterator(); 538 while (quantityCondsIter.hasNext()) { 539 GenericValue quantityCond = (GenericValue) quantityCondsIter.next(); 540 productPriceRuleIds.add(quantityCond.getString("productPriceRuleId")); 541 } 542 } 543 544 Collection roleTypeIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_ROLE_TYPE")); 546 if (roleTypeIdConds != null && roleTypeIdConds.size() > 0) { 547 Iterator roleTypeIdCondsIter = roleTypeIdConds.iterator(); 548 while (roleTypeIdCondsIter.hasNext()) { 549 GenericValue roleTypeIdCond = (GenericValue) roleTypeIdCondsIter.next(); 550 productPriceRuleIds.add(roleTypeIdCond.getString("productPriceRuleId")); 551 } 552 } 553 554 558 Collection listPriceConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_LIST_PRICE")); 560 if (listPriceConds != null && listPriceConds.size() > 0) { 561 Iterator listPriceCondsIter = listPriceConds.iterator(); 562 while (listPriceCondsIter.hasNext()) { 563 GenericValue listPriceCond = (GenericValue) listPriceCondsIter.next(); 564 productPriceRuleIds.add(listPriceCond.getString("productPriceRuleId")); 565 } 566 } 567 568 570 Collection productIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PRODUCT_ID", "condValue", productId)); 572 if (productIdConds != null && productIdConds.size() > 0) { 573 Iterator productIdCondsIter = productIdConds.iterator(); 574 while (productIdCondsIter.hasNext()) { 575 GenericValue productIdCond = (GenericValue) productIdCondsIter.next(); 576 productPriceRuleIds.add(productIdCond.getString("productPriceRuleId")); 577 } 578 } 579 580 if (virtualProductId != null) { 582 Collection virtualProductIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PRODUCT_ID", "condValue", virtualProductId)); 583 if (virtualProductIdConds != null && virtualProductIdConds.size() > 0) { 584 Iterator virtualProductIdCondsIter = virtualProductIdConds.iterator(); 585 while (virtualProductIdCondsIter.hasNext()) { 586 GenericValue virtualProductIdCond = (GenericValue) virtualProductIdCondsIter.next(); 587 productPriceRuleIds.add(virtualProductIdCond.getString("productPriceRuleId")); 588 } 589 } 590 } 591 592 if (UtilValidate.isNotEmpty(prodCatalogId)) { 594 Collection prodCatalogIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PROD_CLG_ID", "condValue", prodCatalogId)); 595 if (prodCatalogIdConds != null && prodCatalogIdConds.size() > 0) { 596 Iterator prodCatalogIdCondsIter = prodCatalogIdConds.iterator(); 597 while (prodCatalogIdCondsIter.hasNext()) { 598 GenericValue prodCatalogIdCond = (GenericValue) prodCatalogIdCondsIter.next(); 599 productPriceRuleIds.add(prodCatalogIdCond.getString("productPriceRuleId")); 600 } 601 } 602 } 603 604 if (UtilValidate.isNotEmpty(productStoreGroupId)) { 606 Collection storeGroupConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PROD_SGRP_ID", "condValue", productStoreGroupId)); 607 if (storeGroupConds != null && storeGroupConds.size() > 0) { 608 Iterator storeGroupCondsIter = storeGroupConds.iterator(); 609 while (storeGroupCondsIter.hasNext()) { 610 GenericValue storeGroupCond = (GenericValue) storeGroupCondsIter.next(); 611 productPriceRuleIds.add(storeGroupCond.getString("productPriceRuleId")); 612 } 613 } 614 } 615 616 if (UtilValidate.isNotEmpty(webSiteId)) { 618 Collection webSiteIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_WEBSITE_ID", "condValue", webSiteId)); 619 if (webSiteIdConds != null && webSiteIdConds.size() > 0) { 620 Iterator webSiteIdCondsIter = webSiteIdConds.iterator(); 621 while (webSiteIdCondsIter.hasNext()) { 622 GenericValue webSiteIdCond = (GenericValue) webSiteIdCondsIter.next(); 623 productPriceRuleIds.add(webSiteIdCond.getString("productPriceRuleId")); 624 } 625 } 626 } 627 628 if (UtilValidate.isNotEmpty(partyId)) { 630 Collection partyIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_PARTY_ID", "condValue", partyId)); 631 if (partyIdConds != null && partyIdConds.size() > 0) { 632 Iterator partyIdCondsIter = partyIdConds.iterator(); 633 while (partyIdCondsIter.hasNext()) { 634 GenericValue partyIdCond = (GenericValue) partyIdCondsIter.next(); 635 productPriceRuleIds.add(partyIdCond.getString("productPriceRuleId")); 636 } 637 } 638 } 639 640 Collection currencyUomIdConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("inputParamEnumId", "PRIP_CURRENCY_UOMID", "condValue", currencyUomId)); 642 if (currencyUomIdConds != null && currencyUomIdConds.size() > 0) { 643 Iterator currencyUomIdCondsIter = currencyUomIdConds.iterator(); 644 while (currencyUomIdCondsIter.hasNext()) { 645 GenericValue currencyUomIdCond = (GenericValue) currencyUomIdCondsIter.next(); 646 productPriceRuleIds.add(currencyUomIdCond.getString("productPriceRuleId")); 647 } 648 } 649 650 productPriceRules = new LinkedList (); 651 Iterator productPriceRuleIdsIter = productPriceRuleIds.iterator(); 652 while (productPriceRuleIdsIter.hasNext()) { 653 String productPriceRuleId = (String ) productPriceRuleIdsIter.next(); 654 GenericValue productPriceRule = delegator.findByPrimaryKeyCache("ProductPriceRule", UtilMisc.toMap("productPriceRuleId", productPriceRuleId)); 655 if (productPriceRule == null) continue; 656 productPriceRules.add(productPriceRule); 657 } 658 } else { 659 664 productPriceRules = delegator.findAllCache("ProductPriceRule"); 665 if (productPriceRules == null) productPriceRules = new LinkedList (); 666 } 667 668 int totalConds = 0; 671 int totalActions = 0; 672 int totalRules = 0; 673 674 Iterator productPriceRulesIter = productPriceRules.iterator(); 675 while (productPriceRulesIter.hasNext()) { 676 GenericValue productPriceRule = (GenericValue) productPriceRulesIter.next(); 677 String productPriceRuleId = productPriceRule.getString("productPriceRuleId"); 678 679 java.sql.Timestamp fromDate = productPriceRule.getTimestamp("fromDate"); 681 java.sql.Timestamp thruDate = productPriceRule.getTimestamp("thruDate"); 682 683 if (fromDate != null && fromDate.after(nowTimestamp)) { 684 continue; 686 } 687 if (thruDate != null && thruDate.before(nowTimestamp)) { 688 continue; 690 } 691 692 boolean allTrue = true; 694 StringBuffer condsDescription = new StringBuffer (); 695 Collection productPriceConds = delegator.findByAndCache("ProductPriceCond", UtilMisc.toMap("productPriceRuleId", productPriceRuleId)); 696 Iterator productPriceCondsIter = UtilMisc.toIterator(productPriceConds); 697 698 while (productPriceCondsIter != null && productPriceCondsIter.hasNext()) { 699 GenericValue productPriceCond = (GenericValue) productPriceCondsIter.next(); 700 701 totalConds++; 702 703 if (!checkPriceCondition(productPriceCond, productId, prodCatalogId, productStoreGroupId, webSiteId, partyId, quantity, listPrice, currencyUomId, delegator)) { 704 if (virtualProductId != null) { 706 if (!checkPriceCondition(productPriceCond, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, quantity, listPrice, currencyUomId, delegator)) { 707 allTrue = false; 708 break; 709 } 710 } else { 712 allTrue = false; 713 break; 714 } 715 } 716 717 condsDescription.append("["); 719 GenericValue inputParamEnum = productPriceCond.getRelatedOneCache("InputParamEnumeration"); 720 721 condsDescription.append(inputParamEnum.getString("enumCode")); 722 GenericValue operatorEnum = productPriceCond.getRelatedOneCache("OperatorEnumeration"); 724 725 condsDescription.append(operatorEnum.getString("description")); 726 condsDescription.append(productPriceCond.getString("condValue")); 728 condsDescription.append("] "); 729 } 730 731 condsDescription.append("[list:"); 733 condsDescription.append(listPrice); 734 condsDescription.append(";avgCost:"); 735 condsDescription.append(averageCost); 736 condsDescription.append(";margin:"); 737 condsDescription.append(margin); 738 condsDescription.append("] "); 739 740 boolean foundFlatOverride = false; 741 742 if (allTrue) { 744 if ("Y".equals(productPriceRule.getString("isSale"))) { 746 isSale = true; 747 } 748 749 Collection productPriceActions = delegator.findByAndCache("ProductPriceAction", UtilMisc.toMap("productPriceRuleId", productPriceRuleId)); 750 Iterator productPriceActionsIter = UtilMisc.toIterator(productPriceActions); 751 752 while (productPriceActionsIter != null && productPriceActionsIter.hasNext()) { 753 GenericValue productPriceAction = (GenericValue) productPriceActionsIter.next(); 754 755 totalActions++; 756 757 double modifyAmount = 0; 759 760 if ("PRICE_POD".equals(productPriceAction.getString("productPriceActionTypeId"))) { 761 if (productPriceAction.get("amount") != null) { 762 modifyAmount = defaultPrice * (productPriceAction.getDouble("amount").doubleValue() / 100.0); 763 } 764 } else if ("PRICE_POL".equals(productPriceAction.getString("productPriceActionTypeId"))) { 765 if (productPriceAction.get("amount") != null) { 766 modifyAmount = listPrice * (productPriceAction.getDouble("amount").doubleValue() / 100.0); 767 } 768 } else if ("PRICE_POAC".equals(productPriceAction.getString("productPriceActionTypeId"))) { 769 if (productPriceAction.get("amount") != null) { 770 modifyAmount = averageCost * (productPriceAction.getDouble("amount").doubleValue() / 100.0); 771 } 772 } else if ("PRICE_POM".equals(productPriceAction.getString("productPriceActionTypeId"))) { 773 if (productPriceAction.get("amount") != null) { 774 modifyAmount = margin * (productPriceAction.getDouble("amount").doubleValue() / 100.0); 775 } 776 } else if ("PRICE_FOL".equals(productPriceAction.getString("productPriceActionTypeId"))) { 777 if (productPriceAction.get("amount") != null) { 778 modifyAmount = productPriceAction.getDouble("amount").doubleValue(); 779 } 780 } else if ("PRICE_FLAT".equals(productPriceAction.getString("productPriceActionTypeId"))) { 781 foundFlatOverride = true; 783 if (productPriceAction.get("amount") != null) { 784 price = productPriceAction.getDouble("amount").doubleValue(); 785 } else { 786 Debug.logInfo("ProductPriceAction had null amount, using default price: " + defaultPrice + " for product with id " + productId, module); 787 price = defaultPrice; 788 isSale = false; } 790 } else if ("PRICE_PFLAT".equals(productPriceAction.getString("productPriceActionTypeId"))) { 791 foundFlatOverride = true; 793 price = promoPrice; 794 if (productPriceAction.get("amount") != null) { 795 price += productPriceAction.getDouble("amount").doubleValue(); 796 } 797 if (price == 0.00) { 798 if (defaultPrice != 0.00) { 799 Debug.logInfo("PromoPrice and ProductPriceAction had null amount, using default price: " + defaultPrice + " for product with id " + productId, module); 800 price = defaultPrice; 801 } else if (listPrice != 0.00) { 802 Debug.logInfo("PromoPrice and ProductPriceAction had null amount and no default price was available, using list price: " + listPrice + " for product with id " + productId, module); 803 price = listPrice; 804 } else { 805 Debug.logError("PromoPrice and ProductPriceAction had null amount and no default or list price was available, so price is set to zero for product with id " + productId, module); 806 price = 0.00; 807 } 808 isSale = false; } 810 } else if ("PRICE_WFLAT".equals(productPriceAction.getString("productPriceActionTypeId"))) { 811 foundFlatOverride = true; 813 price = wholesalePrice; 814 if (productPriceAction.get("amount") != null) { 815 price += productPriceAction.getDouble("amount").doubleValue(); 816 } 817 if (price == 0.00) { 818 if (defaultPrice != 0.00) { 819 Debug.logInfo("WholesalePrice and ProductPriceAction had null amount, using default price: " + defaultPrice + " for product with id " + productId, module); 820 price = defaultPrice; 821 } else if (listPrice != 0.00) { 822 Debug.logInfo("WholesalePrice and ProductPriceAction had null amount and no default price was available, using list price: " + listPrice + " for product with id " + productId, module); 823 price = listPrice; 824 } else { 825 Debug.logError("WholesalePrice and ProductPriceAction had null amount and no default or list price was available, so price is set to zero for product with id " + productId, module); 826 price = 0.00; 827 } 828 isSale = false; } 830 } 831 832 StringBuffer priceInfoDescription = new StringBuffer (); 834 835 priceInfoDescription.append(condsDescription.toString()); 836 priceInfoDescription.append("[type:"); 837 priceInfoDescription.append(productPriceAction.getString("productPriceActionTypeId")); 838 priceInfoDescription.append("]"); 839 840 GenericValue orderItemPriceInfo = delegator.makeValue("OrderItemPriceInfo", null); 841 842 orderItemPriceInfo.set("productPriceRuleId", productPriceAction.get("productPriceRuleId")); 843 orderItemPriceInfo.set("productPriceActionSeqId", productPriceAction.get("productPriceActionSeqId")); 844 orderItemPriceInfo.set("modifyAmount", new Double (modifyAmount)); 845 String priceInfoDescriptionString = priceInfoDescription.toString(); 847 848 if (priceInfoDescriptionString.length() > 250) { 849 priceInfoDescriptionString = priceInfoDescriptionString.substring(0, 250); 850 } 851 orderItemPriceInfo.set("description", priceInfoDescriptionString); 852 orderItemPriceInfos.add(orderItemPriceInfo); 853 854 if (foundFlatOverride) { 855 break; 856 } else { 857 price += modifyAmount; 858 } 859 } 860 } 861 862 totalRules++; 863 864 if (foundFlatOverride) { 865 break; 866 } 867 } 868 869 if (Debug.verboseOn()) { 870 Debug.logVerbose("Unchecked Calculated price: " + price, module); 871 Debug.logVerbose("PriceInfo:", module); 872 Iterator orderItemPriceInfosIter = orderItemPriceInfos.iterator(); 873 while (orderItemPriceInfosIter.hasNext()) { 874 GenericValue orderItemPriceInfo = (GenericValue) orderItemPriceInfosIter.next(); 875 876 Debug.logVerbose(" --- " + orderItemPriceInfo.toString(), module); 877 } 878 } 879 880 if (totalActions == 0) { 882 price = defaultPrice; 883 } else { 885 validPriceFound = true; 887 } 888 889 Double maxSellPrice = maximumPriceValue != null ? maximumPriceValue.getDouble("price") : null; 891 if (maxSellPrice != null && price > maxSellPrice.doubleValue()) { 892 price = maxSellPrice.doubleValue(); 893 } 894 Double minSellPrice = minimumPriceValue != null ? minimumPriceValue.getDouble("price") : null; 896 if (minSellPrice != null && price < minSellPrice.doubleValue()) { 897 price = minSellPrice.doubleValue(); 898 validPriceFound = true; 900 } 901 902 if (Debug.verboseOn()) Debug.logVerbose("Final Calculated price: " + price + ", rules: " + totalRules + ", conds: " + totalConds + ", actions: " + totalActions, module); 903 904 result.put("basePrice", new Double (price)); 905 result.put("price", new Double (price)); 906 result.put("listPrice", new Double (listPrice)); 907 result.put("defaultPrice", new Double (defaultPrice)); 908 result.put("averageCost", new Double (averageCost)); 909 } catch (GenericEntityException e) { 910 Debug.logError(e, "Error getting rules from the database while calculating price", module); 911 return ServiceUtil.returnError("Error getting rules from the database while calculating price: " + e.toString()); 912 } 913 } 914 915 result.put("competitivePrice", competitivePriceValue != null ? competitivePriceValue.getDouble("price") : null); 916 result.put("specialPromoPrice", specialPromoPriceValue != null ? specialPromoPriceValue.getDouble("price") : null); 917 result.put("orderItemPriceInfos", orderItemPriceInfos); 918 result.put("isSale", new Boolean (isSale)); 919 result.put("validPriceFound", new Boolean (validPriceFound)); 920 result.put("currencyUsed", currencyUomId); 921 922 if ("Y".equals(checkIncludeVat) && productStore != null && "Y".equals(productStore.getString("showPricesWithVatTax"))) { 924 Map calcTaxForDisplayContext = UtilMisc.toMap("productStoreId", productStoreId, 925 "productId", productId, "quantity", new BigDecimal (quantity), 926 "basePrice", new BigDecimal (((Double ) result.get("price")).doubleValue())); 927 if (UtilValidate.isNotEmpty(partyId)) { 928 calcTaxForDisplayContext.put("billToPartyId", partyId); 929 } 930 931 try { 932 Map calcTaxForDisplayResult = dispatcher.runSync("calcTaxForDisplay", calcTaxForDisplayContext); 933 if (ServiceUtil.isError(calcTaxForDisplayResult)) { 934 return ServiceUtil.returnError("Error calculating VAT tax (with calcTaxForDisplay service)", null, null, calcTaxForDisplayResult); 935 } 936 result.put("price", new Double (((BigDecimal ) calcTaxForDisplayResult.get("priceWithTax")).doubleValue())); 938 939 BigDecimal taxPercentage = (BigDecimal ) calcTaxForDisplayResult.get("taxPercentage"); 941 BigDecimal taxMultiplier = ONE_BASE.add(taxPercentage.divide(PERCENT_SCALE, 3)); 942 if (result.get("listPrice") != null) result.put("listPrice", new Double ((new BigDecimal (((Double ) result.get("listPrice")).doubleValue())).multiply(taxMultiplier).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 943 if (result.get("defaultPrice") != null) result.put("defaultPrice", new Double ((new BigDecimal (((Double ) result.get("defaultPrice")).doubleValue())).multiply(taxMultiplier).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 944 if (result.get("averageCost") != null) result.put("averageCost", new Double ((new BigDecimal (((Double ) result.get("averageCost")).doubleValue())).multiply(taxMultiplier).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 945 946 if (result.get("promoPrice") != null) result.put("promoPrice", new Double ((new BigDecimal (((Double ) result.get("promoPrice")).doubleValue())).multiply(taxMultiplier).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 947 if (result.get("competitivePrice") != null) result.put("competitivePrice", new Double ((new BigDecimal (((Double ) result.get("competitivePrice")).doubleValue())).multiply(taxMultiplier).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 948 949 } catch (GenericServiceException e) { 950 String errMsg = "Error calculating VAT tax (with calcTaxForDisplay service): " + e.toString(); 951 Debug.logError(e, errMsg, module); 952 return ServiceUtil.returnError(errMsg); 953 } 954 } 955 956 return result; 958 } 959 960 public static boolean checkPriceCondition(GenericValue productPriceCond, String productId, String prodCatalogId, 961 String productStoreGroupId, String webSiteId, String partyId, double quantity, double listPrice, 962 String currencyUomId, GenericDelegator delegator) throws GenericEntityException { 963 if (Debug.verboseOn()) Debug.logVerbose("Checking price condition: " + productPriceCond, module); 964 int compare = 0; 965 966 if ("PRIP_PRODUCT_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 967 compare = productId.compareTo(productPriceCond.getString("condValue")); 968 } else if ("PRIP_PROD_CAT_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 969 String productCategoryId = productPriceCond.getString("condValue"); 971 List productCategoryMembers = delegator.findByAndCache("ProductCategoryMember", 972 UtilMisc.toMap("productId", productId, "productCategoryId", productCategoryId)); 973 productCategoryMembers = EntityUtil.filterByDate(productCategoryMembers, true); 975 if (productCategoryMembers != null && productCategoryMembers.size() > 0) { 977 compare = 0; 978 } else { 979 compare = 1; 980 } 981 } else if ("PRIP_PROD_CLG_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 982 if (UtilValidate.isNotEmpty(prodCatalogId)) { 983 compare = prodCatalogId.compareTo(productPriceCond.getString("condValue")); 984 } else { 985 compare = 1; 987 } 988 } else if ("PRIP_PROD_SGRP_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 989 if (UtilValidate.isNotEmpty(productStoreGroupId)) { 990 compare = productStoreGroupId.compareTo(productPriceCond.getString("condValue")); 991 } else { 992 compare = 1; 993 } 994 } else if ("PRIP_WEBSITE_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 995 if (UtilValidate.isNotEmpty(webSiteId)) { 996 compare = webSiteId.compareTo(productPriceCond.getString("condValue")); 997 } else { 998 compare = 1; 999 } 1000 } else if ("PRIP_QUANTITY".equals(productPriceCond.getString("inputParamEnumId"))) { 1001 Double quantityValue = new Double (quantity); 1002 compare = quantityValue.compareTo(Double.valueOf(productPriceCond.getString("condValue"))); 1003 } else if ("PRIP_PARTY_ID".equals(productPriceCond.getString("inputParamEnumId"))) { 1004 if (UtilValidate.isNotEmpty(partyId)) { 1005 compare = partyId.compareTo(productPriceCond.getString("condValue")); 1006 } else { 1007 compare = 1; 1008 } 1009 } else if ("PRIP_PARTY_GRP_MEM".equals(productPriceCond.getString("inputParamEnumId"))) { 1010 if (UtilValidate.isEmpty(partyId)) { 1011 compare = 1; 1012 } else { 1013 String groupPartyId = productPriceCond.getString("condValue"); 1014 if (partyId.equals(groupPartyId)) { 1015 compare = 0; 1016 } else { 1017 List partyRelationshipList = delegator.findByAndCache("PartyRelationship", UtilMisc.toMap("partyIdFrom", groupPartyId, "partyIdTo", partyId, "partyRelationshipTypeId", "GROUP_ROLLUP")); 1019 partyRelationshipList = EntityUtil.filterByDate(partyRelationshipList, true); 1021 if (partyRelationshipList != null && partyRelationshipList.size() > 0) { 1023 compare = 0; 1024 } else { 1025 compare = 1; 1026 } 1027 } 1028 } 1029 } else if ("PRIP_PARTY_CLASS".equals(productPriceCond.getString("inputParamEnumId"))) { 1030 if (UtilValidate.isEmpty(partyId)) { 1031 compare = 1; 1032 } else { 1033 String partyClassificationGroupId = productPriceCond.getString("condValue"); 1034 List partyClassificationList = delegator.findByAndCache("PartyClassification", UtilMisc.toMap("partyId", partyId, "partyClassificationGroupId", partyClassificationGroupId)); 1036 partyClassificationList = EntityUtil.filterByDate(partyClassificationList, true); 1038 if (partyClassificationList != null && partyClassificationList.size() > 0) { 1040 compare = 0; 1041 } else { 1042 compare = 1; 1043 } 1044 } 1045 } else if ("PRIP_ROLE_TYPE".equals(productPriceCond.getString("inputParamEnumId"))) { 1046 if (partyId != null) { 1047 GenericValue partyRole = delegator.findByPrimaryKeyCache("PartyRole", 1049 UtilMisc.toMap("partyId", partyId, "roleTypeId", productPriceCond.getString("condValue"))); 1050 1051 if (partyRole != null) { 1053 compare = 0; 1054 } else { 1055 compare = 1; 1056 } 1057 } else { 1058 compare = 1; 1059 } 1060 } else if ("PRIP_LIST_PRICE".equals(productPriceCond.getString("inputParamEnumId"))) { 1061 Double listPriceValue = new Double (listPrice); 1062 1063 compare = listPriceValue.compareTo(Double.valueOf(productPriceCond.getString("condValue"))); 1064 } else if ("PRIP_CURRENCY_UOMID".equals(productPriceCond.getString("inputParamEnumId"))) { 1065 compare = currencyUomId.compareTo(productPriceCond.getString("condValue")); 1066 } else { 1067 Debug.logWarning("An un-supported productPriceCond input parameter (lhs) was used: " + productPriceCond.getString("inputParamEnumId") + ", returning false, ie check failed", module); 1068 return false; 1069 } 1070 1071 if (Debug.verboseOn()) Debug.logVerbose("Price Condition compare done, compare=" + compare, module); 1072 1073 if ("PRC_EQ".equals(productPriceCond.getString("operatorEnumId"))) { 1074 if (compare == 0) return true; 1075 } else if ("PRC_NEQ".equals(productPriceCond.getString("operatorEnumId"))) { 1076 if (compare != 0) return true; 1077 } else if ("PRC_LT".equals(productPriceCond.getString("operatorEnumId"))) { 1078 if (compare < 0) return true; 1079 } else if ("PRC_LTE".equals(productPriceCond.getString("operatorEnumId"))) { 1080 if (compare <= 0) return true; 1081 } else if ("PRC_GT".equals(productPriceCond.getString("operatorEnumId"))) { 1082 if (compare > 0) return true; 1083 } else if ("PRC_GTE".equals(productPriceCond.getString("operatorEnumId"))) { 1084 if (compare >= 0) return true; 1085 } else { 1086 Debug.logWarning("An un-supported productPriceCond condition was used: " + productPriceCond.getString("operatorEnumId") + ", returning false, ie check failed", module); 1087 return false; 1088 } 1089 return false; 1090 } 1091 1092 1095 public static Map calculatePurchasePrice(DispatchContext dctx, Map context) { 1096 1097 GenericDelegator delegator = dctx.getDelegator(); 1098 LocalDispatcher dispatcher = dctx.getDispatcher(); 1099 Map result = new HashMap (); 1100 Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); 1101 1102 List orderItemPriceInfos = new LinkedList (); 1103 boolean validPriceFound = false; 1104 double price = 0.0; 1105 1106 GenericValue product = (GenericValue)context.get("product"); 1107 String productId = product.getString("productId"); 1108 String currencyUomId = (String )context.get("currencyUomId"); 1109 String partyId = (String )context.get("partyId"); 1110 Double quantity = (Double )context.get("quantity"); 1111 1112 1115 if (!validPriceFound) { 1117 Map priceContext = UtilMisc.toMap("currencyUomId", currencyUomId, "partyId", partyId, "productId", productId, "quantity", quantity); 1118 List productSuppliers = null; 1119 try { 1120 Map priceResult = dispatcher.runSync("getSuppliersForProduct", priceContext); 1121 if (ServiceUtil.isError(priceResult)) { 1122 String errMsg = ServiceUtil.getErrorMessage(priceResult); 1123 Debug.logError(errMsg, module); 1124 return ServiceUtil.returnError(errMsg); 1125 } 1126 productSuppliers = (List ) priceResult.get("supplierProducts"); 1127 } catch(GenericServiceException gse) { 1128 Debug.logError(gse, module); 1129 return ServiceUtil.returnError(gse.getMessage()); 1130 } 1131 if (productSuppliers != null) { 1132 for (int i = 0; i < productSuppliers.size(); i++) { 1133 GenericValue productSupplier = (GenericValue) productSuppliers.get(i); 1134 if (!validPriceFound) { 1135 price = ((Double )productSupplier.get("lastPrice")).doubleValue(); 1136 validPriceFound = true; 1137 } 1138 StringBuffer priceInfoDescription = new StringBuffer (); 1140 priceInfoDescription.append("SupplierProduct "); 1141 priceInfoDescription.append("[minimumOrderQuantity:"); 1142 priceInfoDescription.append("" + productSupplier.getDouble("minimumOrderQuantity").doubleValue()); 1143 priceInfoDescription.append(", lastPrice: " + productSupplier.getDouble("lastPrice").doubleValue()); 1144 priceInfoDescription.append("]"); 1145 GenericValue orderItemPriceInfo = delegator.makeValue("OrderItemPriceInfo", null); 1146 String priceInfoDescriptionString = priceInfoDescription.toString(); 1151 if (priceInfoDescriptionString.length() > 250) { 1152 priceInfoDescriptionString = priceInfoDescriptionString.substring(0, 250); 1153 } 1154 orderItemPriceInfo.set("description", priceInfoDescriptionString); 1155 orderItemPriceInfos.add(orderItemPriceInfo); 1156 } 1157 } 1158 } 1159 1160 if (!validPriceFound) { 1162 List prices = null; 1163 try { 1164 prices = delegator.findByAnd("ProductPrice", UtilMisc.toMap("productId", productId, 1165 "productPricePurposeId", "PURCHASE"), UtilMisc.toList("-fromDate")); 1166 1167 if (prices == null || prices.size() == 0) { 1169 GenericValue parentProduct = ProductWorker.getParentProduct(productId, delegator); 1170 if (parentProduct != null) { 1171 String parentProductId = parentProduct.getString("productId"); 1172 prices = delegator.findByAnd("ProductPrice", UtilMisc.toMap("productId", parentProductId, 1173 "productPricePurposeId", "PURCHASE"), UtilMisc.toList("-fromDate")); 1174 } 1175 } 1176 } catch (GenericEntityException e) { 1177 Debug.logError(e, module); 1178 return ServiceUtil.returnError(e.getMessage()); 1179 } 1180 1181 prices = EntityUtil.filterByDate(prices); 1183 1184 List pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "AVERAGE_COST")); 1186 if (pricesToUse == null || pricesToUse.size() == 0) { 1187 pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE")); 1189 if (pricesToUse == null || pricesToUse.size() == 0) { 1190 pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "LIST_PRICE")); 1192 } 1193 } 1194 1195 GenericValue thisPrice = EntityUtil.getFirst(pricesToUse); 1197 if (thisPrice != null) { 1198 price = thisPrice.getDouble("price").doubleValue(); 1199 validPriceFound = true; 1200 } 1201 } 1202 1203 result.put("price", new Double (price)); 1204 result.put("validPriceFound", new Boolean (validPriceFound)); 1205 result.put("orderItemPriceInfos", orderItemPriceInfos); 1206 return result; 1207 } 1208} 1209 | Popular Tags |