You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by le...@apache.org on 2009/07/28 14:13:28 UTC

svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro...

Author: lektran
Date: Tue Jul 28 12:13:28 2009
New Revision: 798500

URL: http://svn.apache.org/viewvc?rev=798500&view=rev
Log:
Implemented a services to keep track of products purchased together by creating ProductAssoc records of type ALSO_BOUGHT.  
These associated products are then shown to the customer on the product pages as "Customers who bought this item also bought: ..." sorted by popularity.

Modified:
    ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
    ofbiz/trunk/applications/order/servicedef/services.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReadHelper.java
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
    ofbiz/trunk/applications/product/config/ProductUiLabels.xml
    ofbiz/trunk/applications/product/servicedef/services_view.xml
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl

Modified: ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/data/OrderScheduledServices.xml?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/data/OrderScheduledServices.xml (original)
+++ ofbiz/trunk/applications/order/data/OrderScheduledServices.xml Tue Jul 28 12:13:28 2009
@@ -29,5 +29,6 @@
     <JobSandbox jobId="8005" jobName="Extend expired Subscriptions" runTime="2000-01-01 03:00:00.000" serviceName="runSubscriptionAutoReorders" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/>
     <JobSandbox jobId="8006" jobName="Cancels all orders after date" runTime="2009-12-03 03:00:00.000" serviceName="cancelAllBackOrders" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/>
     <JobSandbox jobId="8007" jobName="Replacement Held Order Auto-Cancel" runTime="2000-01-01 00:00:00.000" serviceName="autoCancelReplacementOrders" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/>
+    <JobSandbox jobId="8008" jobName="Create Also Bought Product Associations" runTime="2000-01-01 00:00:00.000" serviceName="createAlsoBoughtProductAssocs" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/>
 
 </entity-engine-xml>

Modified: ofbiz/trunk/applications/order/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services.xml?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/order/servicedef/services.xml Tue Jul 28 12:13:28 2009
@@ -1008,4 +1008,25 @@
         <attribute name="shipGroupSeqId" type="String" mode="IN" optional="false"/>
         <attribute name="giftMessage" type="String" mode="IN" optional="true"/>
     </service>
+    <service name="createAlsoBoughtProductAssocs" engine="java" auth="true" 
+            location="org.ofbiz.order.order.OrderServices" invoke="createAlsoBoughtProductAssocs">
+        <description>
+            Cycles through all newly created sales orders and creates ProductAssoc records (of type ALSO_BOUGHT) for products 
+            that were purchased together.  If a ProductAssoc record already exists then the quantity field is incremented by one.
+            Newly created orders are determined by looking for orders that were created after the JobSandbox.startDateTime of the
+            previous async execution of this service, alternatively the service can be supplied with a orderEntryFromDateTime 
+            parameter which will process all orders placed after that date/time or as a final option processAllOrders can be set
+            to true to force a calculation of all orders ever placed with orderEntryFromDateTime being ignored.
+        </description>
+        <attribute name="orderEntryFromDateTime" mode="IN" type="Timestamp" optional="true"/>
+        <attribute name="processAllOrders" mode="IN" type="Boolean" optional="true"/>
+    </service>
+    <service name="createAlsoBoughtProductAssocsForOrder" engine="java" auth="true"
+            location="org.ofbiz.order.order.OrderServices" invoke="createAlsoBoughtProductAssocsForOrder">
+        <description>
+            Creates ProductAssoc records (of type ALSO_BOUGHT) for products that were purchased together in the Order.  If a ProductAssoc record already exists then the quantity field is incremented by one.  If a variant product has
+            been ordered then the association is made to its parent product.
+        </description>
+        <attribute name="orderId" mode="IN" type="String" optional="false"/>
+    </service>
 </services>
\ No newline at end of file

Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReadHelper.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReadHelper.java?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReadHelper.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReadHelper.java Tue Jul 28 12:13:28 2009
@@ -75,7 +75,7 @@
 
     protected GenericValue orderHeader = null;
     protected List orderItemAndShipGrp = null;
-    protected List orderItems = null;
+    protected List<GenericValue> orderItems = null;
     protected List adjustments = null;
     protected List<GenericValue> paymentPrefs = null;
     protected List orderStatuses = null;
@@ -1366,7 +1366,7 @@
     // ========== Order Item Methods ==========
     // ========================================
 
-    public List getOrderItems() {
+    public List<GenericValue> getOrderItems() {
         if (orderItems == null) {
             try {
                 orderItems = orderHeader.getRelated("OrderItem", UtilMisc.toList("orderItemSeqId"));

Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java Tue Jul 28 12:13:28 2009
@@ -21,7 +21,6 @@
 import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.util.ArrayList;
-import com.ibm.icu.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
@@ -31,6 +30,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 
 import javax.transaction.Transaction;
 
@@ -56,10 +56,10 @@
 import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.condition.EntityConditionList;
 import org.ofbiz.entity.condition.EntityExpr;
-import org.ofbiz.entity.condition.EntityJoinOperator;
 import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.order.shoppingcart.CartItemModifyException;
@@ -81,6 +81,8 @@
 import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
 
+import com.ibm.icu.util.Calendar;
+
 /**
  * Order Processing Services
  */
@@ -91,8 +93,8 @@
     public static final String resource = "OrderUiLabels";
     public static final String resource_error = "OrderErrorUiLabels";
 
-    public static Map salesAttributeRoleMap = FastMap.newInstance();
-    public static Map purchaseAttributeRoleMap = FastMap.newInstance();
+    public static Map<String, String> salesAttributeRoleMap = FastMap.newInstance();
+    public static Map<String, String> purchaseAttributeRoleMap = FastMap.newInstance();
     static {
         salesAttributeRoleMap.put("placingCustomerPartyId", "PLACING_CUSTOMER");
         salesAttributeRoleMap.put("billToCustomerPartyId", "BILL_TO_CUSTOMER");
@@ -145,7 +147,7 @@
                     hasPermission = true;
                 } else {
                     // check sales agent/customer relationship
-                    List repsCustomers = new LinkedList();
+                    List<GenericValue> repsCustomers = new LinkedList<GenericValue>();
                     try {
                         repsCustomers = EntityUtil.filterByDate(userLogin.getRelatedOne("Party").getRelatedByAnd("FromPartyRelationship",
                                 UtilMisc.toMap("roleTypeIdFrom", "AGENT", "roleTypeIdTo", "CUSTOMER", "partyIdTo", partyId)));
@@ -5300,4 +5302,145 @@
         }
         return ServiceUtil.returnSuccess();
     }
+
+    public static Map<String, Object> createAlsoBoughtProductAssocs(DispatchContext dctx, Map context) {
+        GenericDelegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        // All orders with an entryDate > orderEntryFromDateTime will be processed
+        Timestamp orderEntryFromDateTime = (Timestamp) context.get("orderEntryFromDateTime");
+        // If true all orders ever created will be processed and any pre-existing ALSO_BOUGHT ProductAssocs will be expired 
+        boolean processAllOrders = context.get("processAllOrders") == null ? false : (Boolean) context.get("processAllOrders");
+        if (orderEntryFromDateTime == null && !processAllOrders) {
+            // No from date supplied, check to see when this service last ran and use the startDateTime
+            EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toMap("statusId", "SERVICE_FINISHED", "serviceName", "createAlsoBoughtProductAssocs"));
+            EntityFindOptions efo = new EntityFindOptions();
+            efo.setMaxRows(1);
+            try {
+                GenericValue lastRunJobSandbox = EntityUtil.getFirst(delegator.findList("JobSandbox", cond, null, UtilMisc.toList("startDateTime DESC"), efo, false));
+                if (lastRunJobSandbox != null) {
+                    orderEntryFromDateTime = lastRunJobSandbox.getTimestamp("startDateTime");
+                }
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
+            }
+            if (orderEntryFromDateTime == null) {
+                // Still null, process all orders
+                processAllOrders = true;
+            }
+        }
+        if (processAllOrders) {
+            // Expire any pre-existing ALSO_BOUGHT ProductAssocs in preparation for reprocessing
+            EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(
+                    EntityCondition.makeCondition("productAssocTypeId", "ALSO_BOUGHT"),
+                    EntityCondition.makeConditionDate("fromDate", "thruDate")
+            ));
+            try {
+                delegator.storeByCondition("ProductAssoc", UtilMisc.toMap("thruDate", UtilDateTime.nowTimestamp()), cond);
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
+            }
+        }
+        EntityListIterator eli = null;
+        try {
+            List<EntityExpr> orderCondList = UtilMisc.toList(EntityCondition.makeCondition("orderTypeId", "SALES_ORDER"));
+            if (!processAllOrders && orderEntryFromDateTime != null) {
+                orderCondList.add(EntityCondition.makeCondition("entryDate", EntityOperator.GREATER_THAN, orderEntryFromDateTime));
+            }
+            EntityCondition cond = EntityCondition.makeCondition(orderCondList);
+            eli = delegator.find("OrderHeader", cond, null, null, UtilMisc.toList("entryDate ASC"), null);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        if (eli != null) {
+            GenericValue orderHeader = null;
+            while ((orderHeader = eli.next()) != null) {
+                Map svcIn = FastMap.newInstance();
+                svcIn.put("userLogin", context.get("userLogin"));
+                svcIn.put("orderId", orderHeader.get("orderId"));
+                try {
+                    dispatcher.runSync("createAlsoBoughtProductAssocsForOrder", svcIn);
+                } catch (GenericServiceException e) {
+                    Debug.logError(e, module);
+                }
+            }
+            try {
+                eli.close();
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
+            }
+        }
+        return ServiceUtil.returnSuccess();
+    }
+    
+    public static Map<String, Object> createAlsoBoughtProductAssocsForOrder(DispatchContext dctx, Map context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        GenericDelegator delegator = dctx.getDelegator();
+        String orderId = (String) context.get("orderId");
+        OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
+        List<GenericValue> orderItems = orh.getOrderItems();
+        // In order to improve efficiency a little bit, we will always create the ProductAssoc records 
+        // with productId < productIdTo when the two are compared.  This way when checking for an existing
+        // record we don't have to check both possible combinations of productIds
+        TreeSet<String> productIdSet = new TreeSet<String>();
+        if (orderItems != null) {
+            for (GenericValue orderItem : orderItems) {
+                String productId = orderItem.getString("productId");
+                if (productId != null) {
+                    GenericValue parentProduct = ProductWorker.getParentProduct(productId, delegator);
+                    if (parentProduct != null) productId = parentProduct.getString("productId");
+                    productIdSet.add(productId);
+                }
+            }
+        }
+        TreeSet<String> productIdToSet = new TreeSet<String>(productIdSet);
+        for (String productId : productIdSet) {
+            productIdToSet.remove(productId);
+            for (String productIdTo : productIdToSet) {
+                EntityCondition cond = EntityCondition.makeCondition(
+                        UtilMisc.toList(
+                                EntityCondition.makeCondition("productId", productId),
+                                EntityCondition.makeCondition("productIdTo", productIdTo),
+                                EntityCondition.makeCondition("productAssocTypeId", "ALSO_BOUGHT"),
+                                EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.nowTimestamp()),
+                                EntityCondition.makeCondition("thruDate", null)
+                        )
+                );
+                GenericValue existingProductAssoc = null;
+                try {
+                    // No point in using the cache because of the filterByDateExpr
+                    existingProductAssoc = EntityUtil.getFirst(delegator.findList("ProductAssoc", cond, null, UtilMisc.toList("fromDate DESC"), null, false));
+                } catch (GenericEntityException e) {
+                    Debug.logError(e, module);
+                }
+                try {
+                    if (existingProductAssoc != null) {
+                        BigDecimal newQuantity = existingProductAssoc.getBigDecimal("quantity");
+                        if (newQuantity == null || newQuantity.compareTo(BigDecimal.ZERO) < 0) {
+                            newQuantity = BigDecimal.ZERO;
+                        }
+                        newQuantity = newQuantity.add(BigDecimal.ONE);
+                        ModelService updateProductAssoc = dctx.getModelService("updateProductAssoc");
+                        Map<String, Object> updateCtx = updateProductAssoc.makeValid(context, ModelService.IN_PARAM, true, null);
+                        updateCtx.putAll(updateProductAssoc.makeValid(existingProductAssoc, ModelService.IN_PARAM));
+                        updateCtx.put("quantity", newQuantity);
+                        dispatcher.runSync("updateProductAssoc", updateCtx);
+                    } else {
+                        Map<String, Object> createCtx = FastMap.newInstance();
+                        createCtx.put("userLogin", context.get("userLogin"));
+                        createCtx.put("productId", productId);
+                        createCtx.put("productIdTo", productIdTo);
+                        createCtx.put("productAssocTypeId", "ALSO_BOUGHT");
+                        createCtx.put("fromDate", UtilDateTime.nowTimestamp());
+                        createCtx.put("quantity", BigDecimal.ONE);
+                        dispatcher.runSync("createProductAssoc", createCtx);
+                    }
+                } catch (GenericServiceException e) {
+                    Debug.logError(e, module);
+                }
+            }
+        }
+        
+        return ServiceUtil.returnSuccess();
+    }
 }

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy Tue Jul 28 12:13:28 2009
@@ -379,6 +379,9 @@
     }
 
     // get product associations
+    alsoBoughtProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "ALSO_BOUGHT", checkViewAllow : true, prodCatalogId : currentCatalogId, bidirectional : true, sortDescending : true]);
+    context.alsoBoughtProducts = alsoBoughtProducts.assocProducts;
+
     obsoleteProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_OBSOLESCENCE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.obsoleteProducts = obsoleteProducts.assocProducts;
 

Modified: ofbiz/trunk/applications/product/config/ProductUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/ProductUiLabels.xml?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/config/ProductUiLabels.xml (original)
+++ ofbiz/trunk/applications/product/config/ProductUiLabels.xml Tue Jul 28 12:13:28 2009
@@ -7061,6 +7061,9 @@
         <value xml:lang="th">Allow USPS Addr (PO Box, RR, etc)</value>
         <value xml:lang="zh">允许USPS地址 (邮箱、 退货率等)</value>
     </property>
+    <property key="ProductAlsoBought">
+        <value xml:lang="en">Customers who bought this item also bought:</value>
+    </property>
     <property key="ProductAlternate">
         <value xml:lang="de">Alternative</value>
         <value xml:lang="en">Alternate</value>

Modified: ofbiz/trunk/applications/product/servicedef/services_view.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services_view.xml?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services_view.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services_view.xml Tue Jul 28 12:13:28 2009
@@ -63,12 +63,19 @@
     </service>
     <service name="getAssociatedProducts" engine="java"
             location="org.ofbiz.product.product.ProductServices" invoke="prodFindAssociatedByType">
-        <description>Finds associated products by the defined type.</description>
+        <description>
+            Finds associated products by the defined type.  Only one of either productId or productIdTo can be supplied,
+            not both.  If bidirectional is set to true then the passed in productId will be treated as both a productId
+            and a productIdTo (defaults to false).  If sortDescending is true then assocProducts will be returned sorted
+            by sequenceNum descending (defaults to false).
+        </description>
         <attribute name="productId" type="String" mode="IN" optional="true"/>
         <attribute name="productIdTo" type="String" mode="IN" optional="true"/>
         <attribute name="checkViewAllow" type="Boolean" mode="IN" optional="true"/>
         <attribute name="prodCatalogId" type="String" mode="IN" optional="true"/>
         <attribute name="type" type="String" mode="IN"/>
+        <attribute name="bidirectional" type="Boolean" mode="IN" optional="true"/>
+        <attribute name="sortDescending" type="Boolean" mode="IN" optional="true"/>
         <attribute name="assocProducts" type="java.util.Collection" mode="OUT" optional="true"/>
     </service>
     <service name="getProductFeatures" engine="java"

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java Tue Jul 28 12:13:28 2009
@@ -43,6 +43,8 @@
 import org.ofbiz.entity.GenericDelegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityJoinOperator;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.product.image.ScaleImage;
 import org.ofbiz.product.catalog.CatalogWorker;
@@ -423,8 +425,12 @@
         String errMsg = null;
 
         Boolean cvaBool = (Boolean) context.get("checkViewAllow");
-        boolean checkViewAllow = (cvaBool == null ? false : cvaBool.booleanValue());
+        boolean checkViewAllow = (cvaBool == null ? false : cvaBool);
         String prodCatalogId = (String) context.get("prodCatalogId");
+        Boolean bidirectional = (Boolean) context.get("bidirectional");
+        bidirectional = bidirectional == null ? false : bidirectional;
+        Boolean sortDescending = (Boolean) context.get("sortDescending");
+        sortDescending = sortDescending == null ? false : sortDescending;
 
         if (productId == null && productIdTo == null) {
             errMsg = UtilProperties.getMessage(resource,"productservices.both_productId_and_productIdTo_cannot_be_null", locale);
@@ -462,11 +468,28 @@
 
         try {
             List<GenericValue> productAssocs = null;
+            
+            List<String> orderBy = FastList.newInstance();
+            if (sortDescending) {
+                orderBy.add("sequenceNum DESC");
+            } else {
+                orderBy.add("sequenceNum");
+            }
 
-            if (productIdTo == null) {
-                productAssocs = product.getRelatedCache("MainProductAssoc", UtilMisc.toMap("productAssocTypeId", type), UtilMisc.toList("sequenceNum"));
+            if (bidirectional) {
+                EntityCondition cond = EntityCondition.makeCondition(
+                        UtilMisc.toList(
+                                EntityCondition.makeCondition("productId", productId), 
+                                EntityCondition.makeCondition("productIdTo", productId)
+                        ), EntityJoinOperator.OR);
+                cond = EntityCondition.makeCondition(cond, EntityCondition.makeCondition("productAssocTypeId", type));
+                productAssocs = delegator.findList("ProductAssoc", cond, null, orderBy, null, true);
             } else {
-                productAssocs = product.getRelatedCache("AssocProductAssoc", UtilMisc.toMap("productAssocTypeId", type), UtilMisc.toList("sequenceNum"));
+                if (productIdTo == null) {
+                    productAssocs = product.getRelatedCache("MainProductAssoc", UtilMisc.toMap("productAssocTypeId", type), orderBy);
+                } else {
+                    productAssocs = product.getRelatedCache("AssocProductAssoc", UtilMisc.toMap("productAssocTypeId", type), orderBy);
+                }
             }
             // filter the list by date
             productAssocs = EntityUtil.filterByDate(productAssocs);

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl?rev=798500&r1=798499&r2=798500&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl Tue Jul 28 12:13:28 2009
@@ -696,13 +696,20 @@
 
     <div class="productsummary-container">
     <#list assocProducts as productAssoc>
+        <#if productAssoc.productId == product.productId>
+            <#assign assocProductId = productAssoc.productIdTo/>
+        <#else/>
+            <#assign assocProductId = productAssoc.productId/>
+        </#if>
         <div>
-          <a href="<@ofbizUrl>${targetRequest}/<#if categoryId?exists>~category_id=${categoryId}/</#...@ofbizUrl>" class="buttontext">
-            ${productAssoc.productIdTo?if_exists}
+          <a href="<@ofbizUrl>${targetRequest}/<#if categoryId?exists>~category_id=${categoryId}/</#...@ofbizUrl>" class="buttontext">
+            ${assocProductId}
           </a>
-          - <b>${productAssoc.reason?if_exists}</b>
+        <#if productAssoc.reason?has_content>
+          - <b>${productAssoc.reason}</b>
+        </#if>
         </div>
-      ${setRequestAttribute("optProductId", productAssoc.productIdTo)}
+      ${setRequestAttribute("optProductId", assocProductId)}
       ${setRequestAttribute("listIndex", listIndex)}
       ${setRequestAttribute("formNamePrefix", formNamePrefix)}
       <#if targetRequestName?has_content>
@@ -723,6 +730,8 @@
 <#assign listIndex = 1>
 ${setRequestAttribute("productValue", productValue)}
 <div id="associated-products">
+    <#-- also bought -->
+    <@associated assocProducts=alsoBoughtProducts beforeName="" showName="N" afterName="${uiLabelMap.ProductAlsoBought}" formNamePrefix="albt" targetRequestName=""/>
     <#-- obsolete -->
     <@associated assocProducts=obsoleteProducts beforeName="" showName="Y" afterName=" ${uiLabelMap.ProductObsolete}" formNamePrefix="obs" targetRequestName=""/>
     <#-- cross sell -->



Re: svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro

Posted by Divesh Dutta <di...@hotwaxmedia.com>.
Good to see you Jacques.  :-)

--
Divesh


Jacques Le Roux wrote:
> Hi All,
>
> And why not a note at  http://docs.ofbiz.org/x/-Qs ? ;o)
>
> Jacques
>
> From: "David E Jones" <de...@me.com>
>>
>> No problem. In addition to praise I'm also using you to increase  
>> awareness of this new feature for anyone who might be reading in on  
>> this list... ;)
>>
>> -David
>>
>>
>> On Aug 10, 2009, at 5:36 PM, Scott Gray wrote:
>>
>>> Thanks David, I'm always open to a little praise :-)
>>>
>>> Regards
>>> Scott
>>>
>>> On 11/08/2009, at 11:01 AM, David E Jones wrote:
>>>
>>>>
>>>> Very cool Scott! It's great to see this feature in place.
>>>>
>>>> -David
>>>>
>>>>
>>>> On Jul 28, 2009, at 6:13 AM, lektran@apache.org wrote:
>>>>
>>>>> Author: lektran
>>>>> Date: Tue Jul 28 12:13:28 2009
>>>>> New Revision: 798500
>>>>>
>>>>> URL: http://svn.apache.org/viewvc?rev=798500&view=rev
>>>>> Log:
>>>>> Implemented a services to keep track of products purchased  
>>>>> together by creating ProductAssoc records of type ALSO_BOUGHT.
>>>>> These associated products are then shown to the customer on the  
>>>>> product pages as "Customers who bought this item also bought: 
>>>>> ..."  sorted by popularity.
>>>>>
>>>>> Modified:
>>>>>  ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
>>>>>  ofbiz/trunk/applications/order/servicedef/services.xml
>>>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>>>> OrderReadHelper.java
>>>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>>>> OrderServices.java
>>>>>  ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/ 
>>>>> entry/catalog/ProductDetail.groovy
>>>>>  ofbiz/trunk/applications/product/config/ProductUiLabels.xml
>>>>>  ofbiz/trunk/applications/product/servicedef/services_view.xml
>>>>>  ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ 
>>>>> ProductServices.java
>>>>>  ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/ 
>>>>> productdetail.ftl
>>>>>
>>>>
>>>
>>
>


Re: svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro

Posted by Jacques Le Roux <ja...@les7arts.com>.
Hi All,

And why not a note at  http://docs.ofbiz.org/x/-Qs ? ;o)

Jacques

From: "David E Jones" <de...@me.com>
> 
> No problem. In addition to praise I'm also using you to increase  
> awareness of this new feature for anyone who might be reading in on  
> this list... ;)
> 
> -David
> 
> 
> On Aug 10, 2009, at 5:36 PM, Scott Gray wrote:
> 
>> Thanks David, I'm always open to a little praise :-)
>>
>> Regards
>> Scott
>>
>> On 11/08/2009, at 11:01 AM, David E Jones wrote:
>>
>>>
>>> Very cool Scott! It's great to see this feature in place.
>>>
>>> -David
>>>
>>>
>>> On Jul 28, 2009, at 6:13 AM, lektran@apache.org wrote:
>>>
>>>> Author: lektran
>>>> Date: Tue Jul 28 12:13:28 2009
>>>> New Revision: 798500
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=798500&view=rev
>>>> Log:
>>>> Implemented a services to keep track of products purchased  
>>>> together by creating ProductAssoc records of type ALSO_BOUGHT.
>>>> These associated products are then shown to the customer on the  
>>>> product pages as "Customers who bought this item also bought: ..."  
>>>> sorted by popularity.
>>>>
>>>> Modified:
>>>>  ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
>>>>  ofbiz/trunk/applications/order/servicedef/services.xml
>>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>>> OrderReadHelper.java
>>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>>> OrderServices.java
>>>>  ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/ 
>>>> entry/catalog/ProductDetail.groovy
>>>>  ofbiz/trunk/applications/product/config/ProductUiLabels.xml
>>>>  ofbiz/trunk/applications/product/servicedef/services_view.xml
>>>>  ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ 
>>>> ProductServices.java
>>>>  ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/ 
>>>> productdetail.ftl
>>>>
>>>
>>
>


Re: svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro...

Posted by David E Jones <de...@me.com>.
No problem. In addition to praise I'm also using you to increase  
awareness of this new feature for anyone who might be reading in on  
this list... ;)

-David


On Aug 10, 2009, at 5:36 PM, Scott Gray wrote:

> Thanks David, I'm always open to a little praise :-)
>
> Regards
> Scott
>
> On 11/08/2009, at 11:01 AM, David E Jones wrote:
>
>>
>> Very cool Scott! It's great to see this feature in place.
>>
>> -David
>>
>>
>> On Jul 28, 2009, at 6:13 AM, lektran@apache.org wrote:
>>
>>> Author: lektran
>>> Date: Tue Jul 28 12:13:28 2009
>>> New Revision: 798500
>>>
>>> URL: http://svn.apache.org/viewvc?rev=798500&view=rev
>>> Log:
>>> Implemented a services to keep track of products purchased  
>>> together by creating ProductAssoc records of type ALSO_BOUGHT.
>>> These associated products are then shown to the customer on the  
>>> product pages as "Customers who bought this item also bought: ..."  
>>> sorted by popularity.
>>>
>>> Modified:
>>>  ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
>>>  ofbiz/trunk/applications/order/servicedef/services.xml
>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>> OrderReadHelper.java
>>>  ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>>> OrderServices.java
>>>  ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/ 
>>> entry/catalog/ProductDetail.groovy
>>>  ofbiz/trunk/applications/product/config/ProductUiLabels.xml
>>>  ofbiz/trunk/applications/product/servicedef/services_view.xml
>>>  ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ 
>>> ProductServices.java
>>>  ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/ 
>>> productdetail.ftl
>>>
>>
>


Re: svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro...

Posted by Scott Gray <sc...@hotwaxmedia.com>.
Thanks David, I'm always open to a little praise :-)

Regards
Scott

On 11/08/2009, at 11:01 AM, David E Jones wrote:

>
> Very cool Scott! It's great to see this feature in place.
>
> -David
>
>
> On Jul 28, 2009, at 6:13 AM, lektran@apache.org wrote:
>
>> Author: lektran
>> Date: Tue Jul 28 12:13:28 2009
>> New Revision: 798500
>>
>> URL: http://svn.apache.org/viewvc?rev=798500&view=rev
>> Log:
>> Implemented a services to keep track of products purchased together  
>> by creating ProductAssoc records of type ALSO_BOUGHT.
>> These associated products are then shown to the customer on the  
>> product pages as "Customers who bought this item also bought: ..."  
>> sorted by popularity.
>>
>> Modified:
>>   ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
>>   ofbiz/trunk/applications/order/servicedef/services.xml
>>   ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>> OrderReadHelper.java
>>   ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
>> OrderServices.java
>>   ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/ 
>> entry/catalog/ProductDetail.groovy
>>   ofbiz/trunk/applications/product/config/ProductUiLabels.xml
>>   ofbiz/trunk/applications/product/servicedef/services_view.xml
>>   ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ 
>> ProductServices.java
>>   ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/ 
>> productdetail.ftl
>>
>


Re: svn commit: r798500 - in /ofbiz/trunk: applications/order/data/ applications/order/servicedef/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/product/config/ applications/pro...

Posted by David E Jones <de...@me.com>.
Very cool Scott! It's great to see this feature in place.

-David


On Jul 28, 2009, at 6:13 AM, lektran@apache.org wrote:

> Author: lektran
> Date: Tue Jul 28 12:13:28 2009
> New Revision: 798500
>
> URL: http://svn.apache.org/viewvc?rev=798500&view=rev
> Log:
> Implemented a services to keep track of products purchased together  
> by creating ProductAssoc records of type ALSO_BOUGHT.
> These associated products are then shown to the customer on the  
> product pages as "Customers who bought this item also bought: ..."  
> sorted by popularity.
>
> Modified:
>    ofbiz/trunk/applications/order/data/OrderScheduledServices.xml
>    ofbiz/trunk/applications/order/servicedef/services.xml
>    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
> OrderReadHelper.java
>    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/ 
> OrderServices.java
>    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/ 
> entry/catalog/ProductDetail.groovy
>    ofbiz/trunk/applications/product/config/ProductUiLabels.xml
>    ofbiz/trunk/applications/product/servicedef/services_view.xml
>    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ 
> ProductServices.java
>    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/ 
> productdetail.ftl
>