KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > product > product > ProductWorker


1 /*
2  * $Id: ProductWorker.java 6313 2005-12-13 18:48:25Z jaz $
3  *
4  * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.product.product;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.LinkedList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34 import javax.servlet.ServletRequest JavaDoc;
35 import javax.servlet.jsp.PageContext JavaDoc;
36
37 import org.apache.commons.collections.map.LinkedMap;
38
39 import org.ofbiz.base.util.Debug;
40 import org.ofbiz.base.util.UtilFormatOut;
41 import org.ofbiz.base.util.UtilMisc;
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.util.EntityUtil;
47 import org.ofbiz.product.config.ProductConfigWrapper;
48 import org.ofbiz.product.config.ProductConfigWrapper.ConfigOption;
49 import org.ofbiz.service.GenericServiceException;
50 import org.ofbiz.service.LocalDispatcher;
51 import org.ofbiz.service.ModelService;
52
53 /**
54  * Product Worker class to reduce code in JSPs.
55  *
56  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
57  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
58  * @version $Rev: 6313 $
59  * @since 2.0
60  */

61 public class ProductWorker {
62     
63     public static final String JavaDoc module = ProductWorker.class.getName();
64     public static final String JavaDoc resource = "ProductUiLabels";
65
66     public static void getProduct(PageContext JavaDoc pageContext, String JavaDoc attributeName) {
67         getProduct(pageContext, attributeName, null);
68     }
69
70     public static boolean shippingApplies(GenericValue product) {
71         String JavaDoc errMsg = null;
72         if (product != null) {
73             String JavaDoc productTypeId = product.getString("productTypeId");
74             if ("SERVICE".equals(productTypeId) || (ProductWorker.isDigital(product) && !ProductWorker.isPhysical(product))) {
75                 // don't charge shipping on services or digital goods
76
return false;
77             }
78             Boolean JavaDoc chargeShipping = product.getBoolean("chargeShipping");
79     
80             if (chargeShipping == null) {
81                 return true;
82             } else {
83                 return chargeShipping.booleanValue();
84             }
85         } else {
86             // todo: Hier noch Uebersetzungen einfuegen?
87
//errMsg = UtilProperties.getMessage(resource,"productworker.null_product_entity_not_valid", UtilHttp.getLocale(request));
88
throw new IllegalArgumentException JavaDoc(errMsg);
89         }
90     }
91     
92     public static boolean taxApplies(GenericValue product) {
93         String JavaDoc errMsg = null;
94         if (product != null) {
95             Boolean JavaDoc taxable = product.getBoolean("taxable");
96     
97             if (taxable == null) {
98                 return true;
99             } else {
100                 return taxable.booleanValue();
101             }
102         } else {
103             // todo: Hier noch Uebersetzungen einfuegen?
104
//errMsg = UtilProperties.getMessage(resource,"productworker.null_product_entity_not_valid", UtilHttp.getLocale(request));
105
throw new IllegalArgumentException JavaDoc(errMsg);
106         }
107     }
108     
109     public static void getProduct(PageContext JavaDoc pageContext, String JavaDoc attributeName, String JavaDoc productId) {
110         GenericDelegator delegator = (GenericDelegator) pageContext.getRequest().getAttribute("delegator");
111         ServletRequest JavaDoc request = pageContext.getRequest();
112
113         if (productId == null)
114             productId = UtilFormatOut.checkNull(request.getParameter("product_id"), request.getParameter("PRODUCT_ID"));
115
116         if (productId.equals(""))
117             return;
118
119         GenericValue product = null;
120
121         try {
122             product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
123         } catch (GenericEntityException e) {
124             Debug.logWarning(e.getMessage(), module);
125             product = null;
126         }
127         if (product != null)
128             pageContext.setAttribute(attributeName, product);
129     }
130
131     public static String JavaDoc getVariantVirtualId(GenericValue variantProduct) throws GenericEntityException {
132         List JavaDoc productAssocs = getVariantVirtualAssocs(variantProduct);
133         if (productAssocs == null)
134         {
135             return null;
136         }
137         GenericValue productAssoc = EntityUtil.getFirst(productAssocs);
138         if (productAssoc != null) {
139             return productAssoc.getString("productId");
140         } else {
141             return null;
142         }
143     }
144
145     public static List JavaDoc getVariantVirtualAssocs(GenericValue variantProduct) throws GenericEntityException {
146         if (variantProduct != null && "Y".equals(variantProduct.getString("isVariant"))) {
147             List JavaDoc productAssocs = EntityUtil.filterByDate(variantProduct.getRelatedByAndCache("AssocProductAssoc",
148                     UtilMisc.toMap("productAssocTypeId", "PRODUCT_VARIANT")), true);
149             return productAssocs;
150         }
151         return null;
152     }
153
154     /**
155      * invokes the getInventoryAvailableByFacility service, returns true if specified quantity is available, else false
156      * this is only used in the related method that uses a ProductConfigWrapper, until that is refactored into a service as well...
157      */

158     private static boolean isProductInventoryAvailableByFacility(String JavaDoc productId, String JavaDoc inventoryFacilityId, double quantity, LocalDispatcher dispatcher) throws GenericServiceException {
159         Double JavaDoc availableToPromise = null;
160
161         try {
162             Map JavaDoc result = dispatcher.runSync("getInventoryAvailableByFacility",
163                                             UtilMisc.toMap("productId", productId, "facilityId", inventoryFacilityId));
164
165             availableToPromise = (Double JavaDoc) result.get("availableToPromiseTotal");
166
167             if (availableToPromise == null) {
168                 Debug.logWarning("The getInventoryAvailableByFacility service returned a null availableToPromise, the error message was:\n" + result.get(ModelService.ERROR_MESSAGE), module);
169                 return false;
170             }
171         } catch (GenericServiceException e) {
172             Debug.logWarning(e, "Error invoking getInventoryAvailableByFacility service in isCatalogInventoryAvailable", module);
173             return false;
174         }
175
176         // check to see if we got enough back...
177
if (availableToPromise.doubleValue() >= quantity) {
178             if (Debug.infoOn()) Debug.logInfo("Inventory IS available in facility with id " + inventoryFacilityId + " for product id " + productId + "; desired quantity is " + quantity + ", available quantity is " + availableToPromise, module);
179             return true;
180         } else {
181             if (Debug.infoOn()) Debug.logInfo("Returning false because there is insufficient inventory available in facility with id " + inventoryFacilityId + " for product id " + productId + "; desired quantity is " + quantity + ", available quantity is " + availableToPromise, module);
182             return false;
183         }
184     }
185
186     /**
187      * Invokes the getInventoryAvailableByFacility service, returns true if specified quantity is available for all the selected parts, else false.
188      * Also, set the available flag for all the product configuration's options.
189      **/

190     public static boolean isProductInventoryAvailableByFacility(ProductConfigWrapper productConfig, String JavaDoc inventoryFacilityId, double quantity, LocalDispatcher dispatcher) throws GenericServiceException {
191         boolean available = true;
192         List JavaDoc options = productConfig.getSelectedOptions();
193         Iterator JavaDoc optionsIt = options.iterator();
194         while (optionsIt.hasNext()) {
195             ConfigOption ci = (ConfigOption)optionsIt.next();
196             List JavaDoc products = ci.getComponents();
197             Iterator JavaDoc productsIt = products.iterator();
198             while (productsIt.hasNext()) {
199                 GenericValue product = (GenericValue)productsIt.next();
200                 String JavaDoc productId = product.getString("productId");
201                 Double JavaDoc cmpQuantity = product.getDouble("quantity");
202                 double neededQty = 1.0;
203                 if (cmpQuantity != null) {
204                     neededQty = quantity * cmpQuantity.doubleValue();
205                 }
206                 if (!isProductInventoryAvailableByFacility(productId, inventoryFacilityId, neededQty, dispatcher)) {
207                     ci.setAvailable(false);
208                 }
209             }
210             if (!ci.isAvailable()) {
211                 available = false;
212             }
213         }
214         return available;
215     }
216
217     public static void getAssociatedProducts(PageContext JavaDoc pageContext, String JavaDoc productAttributeName, String JavaDoc assocPrefix) {
218         GenericDelegator delegator = (GenericDelegator) pageContext.getRequest().getAttribute("delegator");
219         GenericValue product = (GenericValue) pageContext.getAttribute(productAttributeName);
220
221         if (product == null)
222             return;
223
224         try {
225             List JavaDoc upgradeProducts = product.getRelatedByAndCache("MainProductAssoc",
226                     UtilMisc.toMap("productAssocTypeId", "PRODUCT_UPGRADE"));
227
228             List JavaDoc complementProducts = product.getRelatedByAndCache("MainProductAssoc",
229                     UtilMisc.toMap("productAssocTypeId", "PRODUCT_COMPLEMENT"));
230
231             List JavaDoc obsolescenceProducts = product.getRelatedByAndCache("AssocProductAssoc",
232                     UtilMisc.toMap("productAssocTypeId", "PRODUCT_OBSOLESCENCE"));
233
234             List JavaDoc obsoleteByProducts = product.getRelatedByAndCache("MainProductAssoc",
235                     UtilMisc.toMap("productAssocTypeId", "PRODUCT_OBSOLESCENCE"));
236
237             // since ProductAssoc records have a fromDate and thruDate, we can filter by now so that only assocs in the date range are included
238
upgradeProducts = EntityUtil.filterByDate(upgradeProducts, true);
239             complementProducts = EntityUtil.filterByDate(complementProducts, true);
240             obsolescenceProducts = EntityUtil.filterByDate(obsolescenceProducts, true);
241             obsoleteByProducts = EntityUtil.filterByDate(obsoleteByProducts, true);
242
243             if (upgradeProducts != null && upgradeProducts.size() > 0)
244                 pageContext.setAttribute(assocPrefix + "upgrade", upgradeProducts);
245             if (complementProducts != null && complementProducts.size() > 0)
246                 pageContext.setAttribute(assocPrefix + "complement", complementProducts);
247             if (obsolescenceProducts != null && obsolescenceProducts.size() > 0)
248                 pageContext.setAttribute(assocPrefix + "obsolescence", obsolescenceProducts);
249             if (obsoleteByProducts != null && obsoleteByProducts.size() > 0)
250                 pageContext.setAttribute(assocPrefix + "obsoleteby", obsoleteByProducts);
251         } catch (GenericEntityException e) {
252             Debug.logWarning(e, module);
253         }
254     }
255     
256     /**
257      * Gets ProductFeature GenericValue for all distinguishing features of a variant product.
258      * Distinguishing means all features that are selectable on the corresponding virtual product and standard on the variant plus all DISTINGUISHING_FEAT assoc type features on the variant.
259      */

260     public static Set JavaDoc getVariantDistinguishingFeatures(GenericValue variantProduct) throws GenericEntityException {
261         if (variantProduct == null) {
262             return new HashSet JavaDoc();
263         }
264         if (!"Y".equals(variantProduct.getString("isVariant"))) {
265             throw new IllegalArgumentException JavaDoc("Cannot get distinguishing features for a product that is not a variant (ie isVariant!=Y).");
266         }
267         GenericDelegator delegator = variantProduct.getDelegator();
268         String JavaDoc virtualProductId = getVariantVirtualId(variantProduct);
269         
270         // find all selectable features on the virtual product that are also standard features on the variant
271
Set JavaDoc distFeatures = new HashSet JavaDoc();
272         
273         List JavaDoc variantDistinguishingFeatures = delegator.findByAndCache("ProductFeatureAndAppl", UtilMisc.toMap("productId", variantProduct.get("productId"), "productFeatureApplTypeId", "DISTINGUISHING_FEAT"));
274         // Debug.logInfo("Found variantDistinguishingFeatures: " + variantDistinguishingFeatures, module);
275

276         Iterator JavaDoc variantDistinguishingFeatureIter = UtilMisc.toIterator(EntityUtil.filterByDate(variantDistinguishingFeatures));
277         while (variantDistinguishingFeatureIter != null && variantDistinguishingFeatureIter.hasNext()) {
278             GenericValue variantDistinguishingFeature = (GenericValue) variantDistinguishingFeatureIter.next();
279             GenericValue dummyFeature = delegator.makeValue("ProductFeature", null);
280             dummyFeature.setAllFields(variantDistinguishingFeature, true, null, null);
281             distFeatures.add(dummyFeature);
282         }
283
284         List JavaDoc virtualSelectableFeatures = delegator.findByAndCache("ProductFeatureAndAppl", UtilMisc.toMap("productId", virtualProductId, "productFeatureApplTypeId", "SELECTABLE_FEATURE"));
285         // Debug.logInfo("Found virtualSelectableFeatures: " + virtualSelectableFeatures, module);
286

287         Iterator JavaDoc virtualSelectableFeatureIter = UtilMisc.toIterator(EntityUtil.filterByDate(virtualSelectableFeatures));
288         Set JavaDoc virtualSelectableFeatureIds = new HashSet JavaDoc();
289         while (virtualSelectableFeatureIter != null && virtualSelectableFeatureIter.hasNext()) {
290             GenericValue virtualSelectableFeature = (GenericValue) virtualSelectableFeatureIter.next();
291             virtualSelectableFeatureIds.add(virtualSelectableFeature.get("productFeatureId"));
292         }
293         
294         List JavaDoc variantStandardFeatures = delegator.findByAndCache("ProductFeatureAndAppl", UtilMisc.toMap("productId", variantProduct.get("productId"), "productFeatureApplTypeId", "STANDARD_FEATURE"));
295         // Debug.logInfo("Found variantStandardFeatures: " + variantStandardFeatures, module);
296

297         Iterator JavaDoc variantStandardFeatureIter = UtilMisc.toIterator(EntityUtil.filterByDate(variantStandardFeatures));
298         while (variantStandardFeatureIter != null && variantStandardFeatureIter.hasNext()) {
299             GenericValue variantStandardFeature = (GenericValue) variantStandardFeatureIter.next();
300             if (virtualSelectableFeatureIds.contains(variantStandardFeature.get("productFeatureId"))) {
301                 GenericValue dummyFeature = delegator.makeValue("ProductFeature", null);
302                 dummyFeature.setAllFields(variantStandardFeature, true, null, null);
303                 distFeatures.add(dummyFeature);
304             }
305         }
306         
307         return distFeatures;
308     }
309
310     /**
311      * Get the name to show to the customer for GWP alternative options.
312      * If the alternative is a variant, find the distinguishing features and show those instead of the name; if it is not a variant then show the PRODUCT_NAME content.
313      */

314     public static String JavaDoc getGwpAlternativeOptionName(GenericDelegator delegator, String JavaDoc alternativeOptionProductId, Locale JavaDoc locale) {
315         try {
316             GenericValue alternativeOptionProduct = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", alternativeOptionProductId));
317             if (alternativeOptionProduct != null) {
318                 if ("Y".equals(alternativeOptionProduct.getString("isVariant"))) {
319                     Set JavaDoc distFeatures = getVariantDistinguishingFeatures(alternativeOptionProduct);
320                     if (distFeatures != null && distFeatures.size() > 0) {
321                         // Debug.logInfo("Found distinguishing features: " + distFeatures, module);
322

323                         StringBuffer JavaDoc nameBuf = new StringBuffer JavaDoc();
324                         Iterator JavaDoc distFeatIter = distFeatures.iterator();
325                         while (distFeatIter.hasNext()) {
326                             GenericValue productFeature = (GenericValue) distFeatIter.next();
327                             GenericValue productFeatureType = productFeature.getRelatedOneCache("ProductFeatureType");
328                             if (productFeatureType != null) {
329                                 nameBuf.append(productFeatureType.get("description", locale));
330                                 nameBuf.append(":");
331                             }
332                             nameBuf.append(productFeature.get("description", locale));
333                             if (distFeatIter.hasNext()) {
334                                 nameBuf.append(", ");
335                             }
336                         }
337                         return nameBuf.toString();
338                     }
339                 }
340
341                 // got to here, default to PRODUCT_NAME
342
String JavaDoc alternativeProductName = ProductContentWrapper.getProductContentAsText(alternativeOptionProduct, "PRODUCT_NAME", locale);
343                 // Debug.logInfo("Using PRODUCT_NAME: " + alternativeProductName, module);
344
return alternativeProductName;
345             }
346         } catch (GenericEntityException e) {
347             Debug.logError(e, module);
348         } catch (Exception JavaDoc e) {
349             Debug.logError(e, module);
350         }
351         // finally fall back to the ID in square braces
352
return "[" + alternativeOptionProductId + "]";
353     }
354
355     /**
356      * gets productFeatures given a productFeatureApplTypeId
357      * @param delegator
358      * @param productId
359      * @param productFeatureApplTypeId - if null, returns ALL productFeatures, regardless of applType
360      * @return List
361      */

362     public static List JavaDoc getProductFeaturesByApplTypeId(GenericDelegator delegator, String JavaDoc productId, String JavaDoc productFeatureApplTypeId) {
363         if (productId == null) {
364             return null;
365         }
366         try {
367             return getProductFeaturesByApplTypeId(delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId)),
368                     productFeatureApplTypeId);
369         } catch (GenericEntityException e) {
370             Debug.logError(e, module);
371         }
372         return null;
373     }
374
375     public static List JavaDoc getProductFeaturesByApplTypeId(GenericValue product, String JavaDoc productFeatureApplTypeId) {
376         if (product == null) {
377             return null;
378         }
379         List JavaDoc features = new ArrayList JavaDoc();
380         try {
381             if (product != null) {
382                 List JavaDoc productAppls;
383                 if (productFeatureApplTypeId == null) {
384                     productAppls = product.getRelated("ProductFeatureAppl");
385                 } else {
386                     productAppls = product.getRelatedByAnd("ProductFeatureAppl",
387                             UtilMisc.toMap("productFeatureApplTypeId", productFeatureApplTypeId));
388                 }
389                 for (int i = 0; i < productAppls.size(); i++) {
390                     GenericValue productAppl = (GenericValue)productAppls.get(i);
391                     features.add(productAppl.getRelatedOne("ProductFeature"));
392                 }
393                 features = EntityUtil.orderBy(features, UtilMisc.toList("description"));
394             }
395         } catch (GenericEntityException e) {
396             Debug.logError(e, module);
397         }
398         return features;
399     }
400
401     public static Map JavaDoc getOptionalProductFeatures(GenericDelegator delegator, String JavaDoc productId) {
402         Map JavaDoc featureMap = new LinkedMap();
403
404         List JavaDoc productFeatureAppls = null;
405         try {
406             productFeatureAppls = delegator.findByAnd("ProductFeatureAndAppl", UtilMisc.toMap("productId", productId, "productFeatureApplTypeId", "OPTIONAL_FEATURE"), UtilMisc.toList("productFeatureTypeId", "sequenceNum"));
407         } catch (GenericEntityException e) {
408             Debug.logError(e, module);
409         }
410
411         if (productFeatureAppls != null) {
412             Iterator JavaDoc i = productFeatureAppls.iterator();
413             while (i.hasNext()) {
414                 GenericValue appl = (GenericValue) i.next();
415                 String JavaDoc featureType = appl.getString("productFeatureTypeId");
416                 List JavaDoc features = (List JavaDoc) featureMap.get(featureType);
417                 if (features == null) {
418                     features = new LinkedList JavaDoc();
419                 }
420                 features.add(appl);
421                 featureMap.put(featureType, features);
422             }
423         }
424
425         return featureMap;
426     }
427
428     // product calc methods
429

430     public static double calcOrderAdjustments(List JavaDoc orderHeaderAdjustments, double subTotal, boolean includeOther, boolean includeTax, boolean includeShipping) {
431         double adjTotal = 0.0;
432
433         if (orderHeaderAdjustments != null && orderHeaderAdjustments.size() > 0) {
434             List JavaDoc filteredAdjs = filterOrderAdjustments(orderHeaderAdjustments, includeOther, includeTax, includeShipping, false, false);
435             Iterator JavaDoc adjIt = filteredAdjs.iterator();
436
437             while (adjIt.hasNext()) {
438                 GenericValue orderAdjustment = (GenericValue) adjIt.next();
439
440                 adjTotal += calcOrderAdjustment(orderAdjustment, subTotal);
441             }
442         }
443         return adjTotal;
444     }
445     
446     public static double calcOrderAdjustment(GenericValue orderAdjustment, double orderSubTotal) {
447         double adjustment = 0.0;
448
449         if (orderAdjustment.get("amount") != null) {
450             adjustment += orderAdjustment.getDouble("amount").doubleValue();
451         }
452         if (orderAdjustment.get("percentage") != null) {
453             adjustment += (orderAdjustment.getDouble("percentage").doubleValue() * orderSubTotal);
454         }
455         return adjustment;
456     }
457     
458     public static List JavaDoc filterOrderAdjustments(List JavaDoc adjustments, boolean includeOther, boolean includeTax, boolean includeShipping, boolean forTax, boolean forShipping) {
459         List JavaDoc newOrderAdjustmentsList = new LinkedList JavaDoc();
460
461         if (adjustments != null && adjustments.size() > 0) {
462             Iterator JavaDoc adjIt = adjustments.iterator();
463
464             while (adjIt.hasNext()) {
465                 GenericValue orderAdjustment = (GenericValue) adjIt.next();
466
467                 boolean includeAdjustment = false;
468
469                 if ("SALES_TAX".equals(orderAdjustment.getString("orderAdjustmentTypeId"))) {
470                     if (includeTax) includeAdjustment = true;
471                 } else if ("SHIPPING_CHARGES".equals(orderAdjustment.getString("orderAdjustmentTypeId"))) {
472                     if (includeShipping) includeAdjustment = true;
473                 } else {
474                     if (includeOther) includeAdjustment = true;
475                 }
476
477                 // default to yes, include for shipping; so only exclude if includeInShipping is N, or false; if Y or null or anything else it will be included
478
if (forTax && "N".equals(orderAdjustment.getString("includeInTax"))) {
479                     includeAdjustment = false;
480                 }
481
482                 // default to yes, include for shipping; so only exclude if includeInShipping is N, or false; if Y or null or anything else it will be included
483
if (forShipping && "N".equals(orderAdjustment.getString("includeInShipping"))) {
484                     includeAdjustment = false;
485                 }
486
487                 if (includeAdjustment) {
488                     newOrderAdjustmentsList.add(orderAdjustment);
489                 }
490             }
491         }
492         return newOrderAdjustmentsList;
493     }
494
495     public static double getAverageProductRating(GenericDelegator delegator, String JavaDoc productId) {
496         return getAverageProductRating(delegator, productId, null);
497     }
498     
499     public static double getAverageProductRating(GenericDelegator delegator, String JavaDoc productId, String JavaDoc productStoreId) {
500         GenericValue product = null;
501         try {
502             product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
503         } catch (GenericEntityException e) {
504             Debug.logError(e, module);
505         }
506         return ProductWorker.getAverageProductRating(product, productStoreId);
507     }
508
509     public static double getAverageProductRating(GenericValue product, String JavaDoc productStoreId) {
510         return getAverageProductRating(product, null, productStoreId);
511     }
512
513     public static double getAverageProductRating(GenericValue product, List JavaDoc reviews, String JavaDoc productStoreId) {
514         if (product == null) {
515             Debug.logWarning("Invalid product entity passed; unable to obtain valid product rating", module);
516             return 0.00;
517         }
518
519         double productRating = 0.00;
520         Double JavaDoc productEntityRating = product.getDouble("productRating");
521         String JavaDoc entityFieldType = product.getString("ratingTypeEnum");
522
523         // null check
524
if (productEntityRating == null) {
525             productEntityRating = new Double JavaDoc(0);
526         }
527         if (entityFieldType == null) {
528             entityFieldType = new String JavaDoc();
529         }
530
531         if ("PRDR_FLAT".equals(entityFieldType)) {
532             productRating = productEntityRating.doubleValue();
533         } else {
534             // get the product rating from the ProductReview entity; limit by product store if ID is passed
535
Map JavaDoc reviewByAnd = UtilMisc.toMap("statusId", "PRR_APPROVED");
536             if (productStoreId != null) {
537                 reviewByAnd.put("productStoreId", productStoreId);
538             }
539
540             // lookup the reviews if we didn't pass them in
541
if (reviews == null) {
542                 try {
543                     reviews = product.getRelatedCache("ProductReview", reviewByAnd, UtilMisc.toList("-postedDateTime"));
544                 } catch (GenericEntityException e) {
545                     Debug.logError(e, module);
546                 }
547             }
548
549             // tally the average
550
double ratingTally = 0;
551             double numRatings = 0;
552             if (reviews != null) {
553                 Iterator JavaDoc i = reviews.iterator();
554                 while (i.hasNext()) {
555                     GenericValue productReview = (GenericValue) i.next();
556                     Double JavaDoc rating = productReview.getDouble("productRating");
557                     if (rating != null) {
558                         ratingTally += rating.doubleValue();
559                         numRatings++;
560                     }
561                 }
562             }
563             if (ratingTally > 0 && numRatings > 0) {
564                 productRating = ratingTally / numRatings;
565             }
566
567             if ("PRDR_MIN".equals(entityFieldType)) {
568                 // check for min
569
if (productEntityRating.doubleValue() > productRating) {
570                     productRating = productEntityRating.doubleValue();
571                 }
572             } else if ("PRDR_MAX".equals(entityFieldType)) {
573                 // check for max
574
if (productRating > productEntityRating.doubleValue()) {
575                     productRating = productEntityRating.doubleValue();
576                 }
577             }
578         }
579
580         return productRating;
581     }
582
583     public static List JavaDoc getCurrentProductCategories(GenericDelegator delegator, String JavaDoc productId) {
584         GenericValue product = null;
585         try {
586             product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
587         } catch (GenericEntityException e) {
588             Debug.logError(e, module);
589         }
590         return getCurrentProductCategories(delegator, product);
591     }
592
593     public static List JavaDoc getCurrentProductCategories(GenericDelegator delegator, GenericValue product) {
594         if (product == null) {
595             return null;
596         }
597         List JavaDoc categories = new ArrayList JavaDoc();
598         try {
599             List JavaDoc categoryMembers = product.getRelated("ProductCategoryMember");
600             categoryMembers = EntityUtil.filterByDate(categoryMembers);
601             categories = EntityUtil.getRelated("ProductCategory", categoryMembers);
602         } catch (GenericEntityException e) {
603             Debug.logError(e, module);
604         }
605         return categories;
606     }
607     
608     //get parent product
609
public static GenericValue getParentProduct(String JavaDoc productId, GenericDelegator delegator) {
610       GenericValue _parentProduct = null;
611       if (productId == null) {
612             Debug.logWarning("Bad product id", module);
613         }
614
615         try {
616             List JavaDoc virtualProductAssocs = delegator.findByAndCache("ProductAssoc", UtilMisc.toMap("productIdTo", productId, "productAssocTypeId", "PRODUCT_VARIANT"), UtilMisc.toList("-fromDate"));
617             virtualProductAssocs = EntityUtil.filterByDate(virtualProductAssocs, true);
618             if (virtualProductAssocs == null || virtualProductAssocs.size() == 0) {
619                 //okay, not a variant, try a UNIQUE_ITEM
620
virtualProductAssocs = delegator.findByAndCache("ProductAssoc", UtilMisc.toMap("productIdTo", productId, "productAssocTypeId", "UNIQUE_ITEM"), UtilMisc.toList("-fromDate"));
621                 virtualProductAssocs = EntityUtil.filterByDate(virtualProductAssocs, true);
622             }
623             if (virtualProductAssocs != null && virtualProductAssocs.size() > 0) {
624                 //found one, set this first as the parent product
625
GenericValue productAssoc = EntityUtil.getFirst(virtualProductAssocs);
626                 _parentProduct = productAssoc.getRelatedOneCache("MainProduct");
627             }
628         } catch (GenericEntityException e) {
629             throw new RuntimeException JavaDoc("Entity Engine error getting Parent Product (" + e.getMessage() + ")");
630         }
631         return _parentProduct;
632     }
633
634     public static boolean isDigital(GenericValue product) {
635         boolean isDigital = false;
636         if (product != null) {
637             GenericValue productType = null;
638             try {
639                 productType = product.getRelatedOneCache("ProductType");
640             } catch (GenericEntityException e) {
641                 Debug.logWarning(e.getMessage(), module);
642             }
643             String JavaDoc isDigitalValue = (productType != null? productType.getString("isDigital"): null);
644             isDigital = isDigitalValue != null && "Y".equalsIgnoreCase(isDigitalValue);
645         }
646         return isDigital;
647     }
648
649     public static boolean isPhysical(GenericValue product) {
650         boolean isPhysical = false;
651         if (product != null) {
652             GenericValue productType = null;
653             try {
654                 productType = product.getRelatedOneCache("ProductType");
655             } catch (GenericEntityException e) {
656                 Debug.logWarning(e.getMessage(), module);
657             }
658             String JavaDoc isPhysicalValue = (productType != null? productType.getString("isPhysical"): null);
659             isPhysical = isPhysicalValue != null && "Y".equalsIgnoreCase(isPhysicalValue);
660         }
661         return isPhysical;
662     }
663
664     public static String JavaDoc findProductId(GenericDelegator delegator, String JavaDoc idToFind, String JavaDoc goodIdentificationTypeId) throws GenericEntityException {
665         // first lookup and see if this is the Product PK
666
GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", idToFind));
667         String JavaDoc productId = null;
668
669         if (product == null) {
670             // no product record found; no check good identification
671
Map JavaDoc goodIdLookup = UtilMisc.toMap("idValue", idToFind);
672             if (UtilValidate.isNotEmpty(goodIdentificationTypeId)) {
673                 goodIdLookup.put("goodIdentificationTypeId", goodIdentificationTypeId);
674             }
675             List JavaDoc goodIds = delegator.findByAndCache("GoodIdentification", goodIdLookup, UtilMisc.toList("-createdStamp"));
676
677             // sorted by createdStamp; so pull out the most current entry
678
GenericValue lastGoodId = EntityUtil.getFirst(goodIds);
679             if (lastGoodId != null) {
680                 productId = lastGoodId.getString("productId");
681             }
682         } else {
683             productId = product.getString("productId");
684         }
685
686         if (productId != null) {
687             return productId;
688         } else {
689             return null;
690         }
691     }
692
693     public static String JavaDoc findProductId(GenericDelegator delegator, String JavaDoc idToFind) throws GenericEntityException {
694         return findProductId(delegator, idToFind, null);
695     }
696
697     public static GenericValue findProduct(GenericDelegator delegator, String JavaDoc idToFind, String JavaDoc goodIdentificationTypeId) throws GenericEntityException {
698         // first lookup and see if this is the Product PK
699
GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", idToFind));
700         String JavaDoc productId = null;
701
702         if (product == null) {
703             // no product record found; no check good identification
704
Map JavaDoc goodIdLookup = UtilMisc.toMap("idValue", idToFind);
705             if (UtilValidate.isNotEmpty(goodIdentificationTypeId)) {
706                 goodIdLookup.put("goodIdentificationTypeId", goodIdentificationTypeId);
707             }
708             List JavaDoc goodIds = delegator.findByAndCache("GoodIdentification", goodIdLookup, UtilMisc.toList("-createdStamp"));
709
710             // sorted by createdStamp; so pull out the most current entry
711
GenericValue lastGoodId = EntityUtil.getFirst(goodIds);
712             if (lastGoodId != null) {
713                 product = lastGoodId.getRelatedOneCache("Product");
714             }
715         }
716
717         if (product != null) {
718             return product;
719         } else {
720             return null;
721         }
722     }
723
724     public static GenericValue findProduct(GenericDelegator delegator, String JavaDoc idToFind) throws GenericEntityException {
725         return findProduct(delegator, idToFind, null);
726     }
727 }
728
729
Popular Tags