svn commit: r797259 - in /ofbiz/trunk: applications/order/webapp/ordermgr/WEB-INF/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/order/webapp/ordermgr/entry/catalog/ applications/order/widget/ordermgr/ applications/prod...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r797259 - in /ofbiz/trunk: applications/order/webapp/ordermgr/WEB-INF/ applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/order/webapp/ordermgr/entry/catalog/ applications/order/widget/ordermgr/ applications/prod...

lektran
Author: lektran
Date: Thu Jul 23 23:28:32 2009
New Revision: 797259

URL: http://svn.apache.org/viewvc?rev=797259&view=rev
Log:
OFBIZ-2625 Ability to perform product comparisons in ecommerce and during order entry in ordermgr.  

Compares things like name, price, description, long description, brand name and standard, distinguishing and optional features.

Could do with some styling and would be nice to add customer ratings in there as well.

Added:
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy   (with props)
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl   (with props)
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl   (with props)
Modified:
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl
    ofbiz/trunk/applications/order/widget/ordermgr/CommonScreens.xml
    ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml
    ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCommonScreens.xml
    ofbiz/trunk/applications/product/config/ProductUiLabels.xml
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductServices.java
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
    ofbiz/trunk/specialpurpose/ecommerce/widget/CommonScreens.xml

Added: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy?rev=797259&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy Thu Jul 23 23:28:32 2009
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.ofbiz.product.product.*;
+import org.ofbiz.order.shoppingcart.*;
+import org.ofbiz.product.catalog.*;
+import org.ofbiz.product.store.*;
+import org.ofbiz.entity.condition.*;
+import org.ofbiz.entity.util.*;
+import org.ofbiz.base.util.*;
+
+compareList = ProductEvents.getProductCompareList(request);
+context.compareList = compareList;
+cart = ShoppingCartEvents.getCartObject(request);
+catalogId = CatalogWorker.getCurrentCatalogId(request);
+productStore = ProductStoreWorker.getProductStore(request);
+productStoreId = productStore.productStoreId;
+
+productDataMap = [:];
+context.productDataMap = productDataMap;
+productFeatureTypeIds = [] as LinkedHashSet;
+context.productFeatureTypeIds = productFeatureTypeIds;
+productFeatureTypeMap = [:];
+context.productFeatureTypeMap = productFeatureTypeMap;
+
+
+compareList.each { product ->
+    productData = [:];
+    productDataMap[product.productId] = productData;
+    
+    productData.productContentWrapper = ProductContentWrapper.makeProductContentWrapper(product, request);
+
+    priceContext = [product : product, currencyUomId : cart.getCurrency(),
+        autoUserLogin : autoUserLogin, userLogin : userLogin];
+    priceContext.webSiteId = webSiteId;
+    priceContext.prodCatalogId = catalogId;
+    priceContext.productStoreId = productStoreId;
+    priceContext.agreementId = cart.getAgreementId();
+    priceContext.partyId = cart.getPartyId();  // IMPORTANT: otherwise it'll be calculating prices using the logged in user which could be a CSR instead of the customer
+    priceContext.checkIncludeVat = "Y";
+    productData.priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+    
+    condList = [
+                EntityCondition.makeCondition("productId", product.productId),
+                EntityUtil.getFilterByDateExpr(),
+                EntityCondition.makeCondition("productFeatureApplTypeId", EntityOperator.IN, ["STANDARD_FEATURE", "DISTINGUISHING_FEAT", "SELECTABLE_FEATURE"])
+               ];
+    cond = EntityCondition.makeCondition(condList);
+    productFeatureAppls = delegator.findList("ProductFeatureAppl", cond, null, ["sequenceNum"], null, true);
+    productFeatureAppls.each { productFeatureAppl ->
+        productFeature = productFeatureAppl.getRelatedOneCache("ProductFeature");
+        if (!productData[productFeature.productFeatureTypeId]) {
+            productData[productFeature.productFeatureTypeId] = [:];
+        }
+        if (!productData[productFeature.productFeatureTypeId][productFeatureAppl.productFeatureApplTypeId]) {
+            productData[productFeature.productFeatureTypeId][productFeatureAppl.productFeatureApplTypeId] = [];
+        }
+        productData[productFeature.productFeatureTypeId][productFeatureAppl.productFeatureApplTypeId] << productFeature;
+        productFeatureTypeIds << productFeature.productFeatureTypeId;
+    }
+}
+productFeatureTypeIds.each { productFeatureTypeId ->
+    productFeatureTypeMap[productFeatureTypeId] = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeId], true);
+}
\ No newline at end of file

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml Thu Jul 23 23:28:32 2009
@@ -635,6 +635,27 @@
         <response name="success" type="view" value="product"/>
     </request-map>
 
+    <!-- Product Comparison Requests -->
+    <request-map uri="addToCompare">
+        <security auth="true" https="true"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="addProductToComparisonList"/>
+        <response name="success" type="view-last"/>
+    </request-map>
+    <request-map uri="removeFromCompare">
+        <security auth="true" https="true"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="removeProductFromComparisonList"/>
+        <response name="success" type="view-last"/>
+    </request-map>
+    <request-map uri="clearCompareList">
+        <security auth="true" https="true"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="clearProductComparisonList"/>
+        <response name="success" type="view-last"/>
+    </request-map>
+    <request-map uri="compareProducts">
+        <security auth="true" https="true"/>
+        <response name="success" type="view" value="compareProducts" save-last-view="true"/>
+    </request-map>
+
     <request-map uri="finalizeOrder">
         <security https="true" auth="true"/>
         <event type="java" path="org.ofbiz.order.shoppingcart.CheckOutEvents" invoke="finalizeOrderEntry"/>
@@ -1683,6 +1704,7 @@
 
     <view-map name="category" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#category"/>
     <view-map name="product" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#product"/>
+    <view-map name="compareProducts" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#compareProducts"/>
     <view-map name="quickadd" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#quickadd"/>
 
     <view-map name="custsetting" type="screen" page="component://order/widget/ordermgr/OrderEntryOrderScreens.xml#CustSettings"/>

Added: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl?rev=797259&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl Thu Jul 23 23:28:32 2009
@@ -0,0 +1,184 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<table>
+<#-- Header row, contains product small image, product name, price -->
+    <tr>
+        <td>&nbsp;</td>
+<#list compareList as product>
+    <#assign productData = productDataMap[product.productId]/>
+    <#assign productContentWrapper = productData.productContentWrapper/>
+    <#assign price = productData.priceMap/>
+    <#assign productUrl = StringUtil.wrapString(Static["org.ofbiz.product.category.CatalogUrlServlet"].makeCatalogUrl(request, product.productId, categoryId, ""))/>
+    <#assign smallImageUrl = productContentWrapper.get("SMALL_IMAGE_URL")/>
+    <#if smallImageUrl!?length == 0>
+        <#assign smallImageUrl = "/images/defaultImage.jpg"/>
+    </#if>
+        <td>
+            <img src="<@ofbizContentUrl>${contentPathPrefix?if_exists}${smallImageUrl}</@ofbizContentUrl>" alt="Small Image"/><br/>
+            ${productContentWrapper.get("PRODUCT_NAME")}<br/>
+    <#if totalPrice?exists>
+            <div>${uiLabelMap.ProductAggregatedPrice}: <span class='basePrice'><@ofbizCurrency amount=totalPrice isoCode=totalPrice.currencyUsed/></span></div>
+    <#else>
+        <#if price.isSale?exists && price.isSale>
+            <#assign priceStyle = "salePrice">
+        <#else>
+            <#assign priceStyle = "regularPrice">
+        </#if>
+
+        <#if (price.price?default(0) > 0 && product.requireAmount?default("N") == "N")>
+                <#if "Y" = product.isVirtual?if_exists> ${uiLabelMap.CommonFrom} </#if><span class="${priceStyle}"><@ofbizCurrency amount=price.price isoCode=price.currencyUsed/></span>
+        </#if>
+    </#if>
+            <div class="productbuy">
+    <#-- check to see if introductionDate hasn't passed yet -->
+    <#if product.introductionDate?exists && nowTimestamp.before(product.introductionDate)>
+                <div style="color: red;">${uiLabelMap.ProductNotYetAvailable}</div>
+    <#-- check to see if salesDiscontinuationDate has passed -->
+    <#elseif product.salesDiscontinuationDate?exists && nowTimestamp.after(product.salesDiscontinuationDate)/>
+                <div style="color: red;">${uiLabelMap.ProductNoLongerAvailable}</div>
+    <#-- check to see if it is a rental item; will enter parameters on the detail screen-->
+    <#elseif product.productTypeId?if_exists == "ASSET_USAGE"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderMakeBooking}...</a>
+    <#-- check to see if it is an aggregated or configurable product; will enter parameters on the detail screen-->
+    <#elseif product.productTypeId?if_exists == "AGGREGATED"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderConfigure}...</a>
+    <#-- check to see if the product is a virtual product -->
+    <#elseif product.isVirtual?exists && product.isVirtual == "Y"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderChooseVariations}...</a>
+    <#-- check to see if the product requires an amount -->
+    <#elseif product.requireAmount?exists && product.requireAmount == "Y"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderChooseAmount}...</a>
+    <#else/>
+                <form method="post" action="<@ofbizUrl secure="${request.isSecure()?string}">additem</@ofbizUrl>" name="compareFormAdd${product_index}">
+                    <input type="hidden" name="add_product_id" value="${product.productId}"/>
+                    <input type="text" size="5" name="quantity" value="1"/>
+                    <input type="hidden" name="clearSearch" value="N"/>
+                </form>
+                <a href="javascript:doPostViaParent('compareFormAdd${product_index}');" class="buttontext">${uiLabelMap.OrderAddToCart}</a>
+
+        <#if prodCatMem?exists && prodCatMem.quantity?exists && 0.00 < prodCatMem.quantity?double>
+                <form method="post" action="<@ofbizUrl secure="${request.isSecure()?string}">additem</@ofbizUrl>" name="compareFormAddDefault${product_index}" style="margin: 0;">
+                    <input type="hidden" name="add_product_id" value="${prodCatMem.productId?if_exists}"/>
+                    <input type="hidden" name="quantity" value="${prodCatMem.quantity?if_exists}"/>
+                    <input type="hidden" name="clearSearch" value="N"/>
+                </form>
+                <a href="javascript:doPostViaParent('compareFormAddDefault${product_index}');" class="buttontext">${uiLabelMap.CommonAddDefault}(${prodCatMem.quantity?string.number}) ${uiLabelMap.OrderToCart}</a>
+        </#if>
+    </#if>
+            </div>
+        </td>
+</#list>
+    </tr>
+    <#-- Brand name -->
+    <tr>
+        <td>${uiLabelMap.ProductBrandName}</td>
+<#list compareList as product>
+        <td>${product.brandName?default("&nbsp;")}</td>
+</#list>
+    </tr>
+    <#-- Description -->
+    <tr>
+        <td>${uiLabelMap.ProductProductDescription}</td>
+<#list compareList as product>
+    <#assign productData = productDataMap[product.productId]/>
+    <#assign productContentWrapper = productData.productContentWrapper/>
+        <td>${productContentWrapper.get("DESCRIPTION")?default("&nbsp;")}</td>
+</#list>
+    </tr>
+    <#-- Long Description -->
+    <tr>
+        <td>${uiLabelMap.ProductLongDescription}</td>
+<#list compareList as product>
+    <#assign productData = productDataMap[product.productId]/>
+    <#assign productContentWrapper = productData.productContentWrapper/>
+        <td>${productContentWrapper.get("LONG_DESCRIPTION")?default("&nbsp;")}</td>
+</#list>
+    </tr>
+<#list productFeatureTypeIds as productFeatureTypeId>
+    <#assign productFeatureType = productFeatureTypeMap[productFeatureTypeId]/>
+    <tr>
+        <td>${productFeatureType.get("description", locale)}</td>
+    <#list compareList as product>
+        <#assign productData = productDataMap[product.productId]/>
+        <#assign applMap = productData[productFeatureTypeId]?if_exists/>
+        <td>
+        <#if applMap.STANDARD_FEATURE?has_content>
+            <#assign features = applMap.STANDARD_FEATURE/>
+            <#list features as feature>
+            <div>${feature.get("description", locale)}</div>
+            </#list>
+        </#if>
+        <#if applMap.DISTINGUISHING_FEAT?has_content>
+            <#assign features = applMap.DISTINGUISHING_FEAT/>
+            <#list features as feature>
+            <div>${feature.get("description", locale)}</div>
+            </#list>
+        </#if>
+        <#if applMap.SELECTABLE_FEATURE?has_content>
+            <#assign features = applMap.SELECTABLE_FEATURE/>
+            <div>Available Options:</div>
+            <ul>
+            <#list features as feature>
+                <li>${feature.get("description", locale)}</li>
+            </#list>
+            </ul>
+        </#if>
+        </td>
+    </#list>
+    </tr>
+</#list>
+    <tr>
+        <td>&nbsp;</td>
+<#list compareList as product>
+        <td>
+            <div class="productbuy">
+    <#-- check to see if introductionDate hasn't passed yet -->
+    <#if product.introductionDate?exists && nowTimestamp.before(product.introductionDate)>
+                <div style="color: red;">${uiLabelMap.ProductNotYetAvailable}</div>
+    <#-- check to see if salesDiscontinuationDate has passed -->
+    <#elseif product.salesDiscontinuationDate?exists && nowTimestamp.after(product.salesDiscontinuationDate)/>
+                <div style="color: red;">${uiLabelMap.ProductNoLongerAvailable}</div>
+    <#-- check to see if it is a rental item; will enter parameters on the detail screen-->
+    <#elseif product.productTypeId?if_exists == "ASSET_USAGE"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderMakeBooking}...</a>
+    <#-- check to see if it is an aggregated or configurable product; will enter parameters on the detail screen-->
+    <#elseif product.productTypeId?if_exists == "AGGREGATED"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderConfigure}...</a>
+    <#-- check to see if the product is a virtual product -->
+    <#elseif product.isVirtual?exists && product.isVirtual == "Y"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderChooseVariations}...</a>
+    <#-- check to see if the product requires an amount -->
+    <#elseif product.requireAmount?exists && product.requireAmount == "Y"/>
+                <a href="javascript:doGetViaParent('${productUrl}');" class="buttontext">${uiLabelMap.OrderChooseAmount}...</a>
+    <#else/>
+                <form method="post" action="<@ofbizUrl secure="${request.isSecure()?string}">additem</@ofbizUrl>" name="compare2FormAdd${product_index}">
+                    <input type="hidden" name="add_product_id" value="${product.productId}"/>
+                    <input type="text" size="5" name="quantity" value="1"/>
+                    <input type="hidden" name="clearSearch" value="N"/>
+                </form>
+                <a href="javascript:doPostViaParent('compare2FormAdd${product_index}');" class="buttontext">${uiLabelMap.OrderAddToCart}</a>
+        <#if prodCatMem?exists && prodCatMem.quantity?exists && 0.00 < prodCatMem.quantity?double>
+                <a href="javascript:doPostViaParent('compareFormAddDefault${product_index}');" class="buttontext">${uiLabelMap.CommonAddDefault}(${prodCatMem.quantity?string.number}) ${uiLabelMap.OrderToCart}</a>
+        </#if>
+    </#if>
+            </div>
+        </td>
+</#list>
+    </tr>
+</table>

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproducts.ftl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl?rev=797259&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl Thu Jul 23 23:28:32 2009
@@ -0,0 +1,53 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div id="productcomparelist" class="screenlet">
+    <div class="screenlet-header">
+        <div class="boxhead">${uiLabelMap.ProductCompareProducts}</div>
+    </div>
+    <div class="screenlet-body">
+<#assign productCompareList = Static["org.ofbiz.product.product.ProductEvents"].getProductCompareList(request)/>
+<#if productCompareList?has_content>
+    <table>
+    <#list productCompareList as product>
+        <tr>
+            <td>
+                ${Static["org.ofbiz.product.product.ProductContentWrapper"].getProductContentAsText(product, "PRODUCT_NAME", request)}
+            </td>
+            <td>
+                <form method="post" action="<@ofbizUrl>removeFromCompare</@ofbizUrl>" name="removeFromCompare${product_index}form">
+                    <input type="hidden" name="productId" value="${product.productId}"/>
+                </form>
+                <a href="javascript:document.removeFromCompare${product_index}form.submit()" class="buttontext">${uiLabelMap.CommonRemove}</a>
+            </td>
+        </tr>
+    </#list>
+    </table>
+    <div>
+        <a href="<@ofbizUrl>clearCompareList</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonClearAll}</a>
+    </div>
+    <div>
+        <a href="javascript:popUp('<@ofbizUrl secure="${request.isSecure()?string}">compareProducts</@ofbizUrl>', 'compareProducts', '650', '750')" class="buttontext">${uiLabelMap.ProductCompareProducts}</a>
+    </div>
+<#else/>
+        <div>
+            ${uiLabelMap.ProductNoProductsToCompare}
+        </div>
+</#if>
+    </div>
+</div>

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/compareproductslist.ftl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl Thu Jul 23 23:28:32 2009
@@ -153,6 +153,10 @@
           <#if averageRating?exists && (averageRating?double > 0) && numRatings?exists && (numRatings?long > 2)>
               <div>${uiLabelMap.OrderAverageRating}: ${averageRating} (${uiLabelMap.CommonFrom} ${numRatings} ${uiLabelMap.OrderRatings})</div>
           </#if>
+          <form method="post" action="<@ofbizUrl secure="${request.isSecure()?string}">addToCompare</@ofbizUrl>" name="addToCompare${requestAttributes.listIndex?if_exists}form">
+              <input type="hidden" name="productId" value="${product.productId}"/>
+          </form>
+          <a href="javascript:document.addToCompare${requestAttributes.listIndex?if_exists}form.submit()" class="buttontext">${uiLabelMap.ProductAddToCompare}</a>
         </div>
     </div>
 <#else>

Modified: ofbiz/trunk/applications/order/widget/ordermgr/CommonScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/widget/ordermgr/CommonScreens.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/widget/ordermgr/CommonScreens.xml (original)
+++ ofbiz/trunk/applications/order/widget/ordermgr/CommonScreens.xml Thu Jul 23 23:28:32 2009
@@ -47,7 +47,7 @@
                 <set field="applicationMenuName" value="OrderAppBar" global="true"/>
                 <set field="applicationMenuLocation" value="component://order/widget/ordermgr/Menus.xml" global="true"/>
                 <set field="applicationTitle" value="${uiLabelMap.OrderManagerApplication}" global="true"/>
-                <!-- globally parametrize the link to a customer's detail information, to help with cases when such details are accessed via external application. -->
+                <!-- globally parameterize the link to a customer's detail information, to help with cases when such details are accessed via external application. -->
                 <set field="customerDetailLink" value="/partymgr/control/viewprofile?partyId=" global="true"/>
             </actions>
             <widgets>
@@ -165,5 +165,30 @@
             </widgets>
         </section>
     </screen>
+    <screen name="CommonPopUpDecorator">
+        <section>
+            <actions>
+                <!-- base/top/specific map first, then more common map added for shared labels -->
+                <property-map resource="OrderUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="OrderErrorUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="AccountingUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="ProductUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="ManufacturingUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="WorkEffortUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="PartyUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="ContentUiLabels" map-name="uiLabelMap" global="true"/>
+
+                <set field="layoutSettings.companyName" from-field="uiLabelMap.OrderCompanyName" global="true"/>
+                <set field="layoutSettings.companySubtitle" from-field="uiLabelMap.OrderCompanySubtitle" global="true"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="LookupDecorator" location="component://common/widget/CommonScreens.xml">
+                    <decorator-section name="body">
+                        <decorator-section-include name="body"/>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
 </screens>
 

Modified: ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml (original)
+++ ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml Thu Jul 23 23:28:32 2009
@@ -76,6 +76,13 @@
         </section>
     </screen>
 
+    <screen name="compareproductslist">
+        <section>
+            <widgets>
+                <platform-specific><html><html-template location="component://order/webapp/ordermgr/entry/catalog/compareproductslist.ftl"/></html></platform-specific>
+            </widgets>
+        </section>
+    </screen>
     <!-- =========== Top-Level and Stand-Alone Screens =========== -->
 
     <!-- Category Screens -->
@@ -272,4 +279,25 @@
             </widgets>
         </section>
     </screen>
+    <screen name="compareProducts">
+        <section>
+            <actions>
+                <set field="titleProperty" value="ProductCompareProducts"/>
+                <property-map resource="ProductUiLabels" map-name="uiLabelMap" global="true"/>
+                <set field="title" from-field="uiLabelMap.ProductCompareProducts"/>
+                <script location="component://order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="CommonPopUpDecorator" location="${parameters.mainDecoratorLocation}">
+                    <decorator-section name="body">
+                        <platform-specific>
+                            <html>
+                                <html-template location="component://order/webapp/ordermgr/entry/catalog/compareproducts.ftl"/>
+                            </html>
+                        </platform-specific>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
 </screens>

Modified: ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCommonScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCommonScreens.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCommonScreens.xml (original)
+++ ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCommonScreens.xml Thu Jul 23 23:28:32 2009
@@ -82,6 +82,7 @@
                     <include-screen name="choosecatalog" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
                     <include-screen name="keywordsearchbox" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
                     <include-screen name="sidedeepcategory" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
+                    <include-screen name="compareproductslist" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
                 </container>
             </widgets>
         </section>
@@ -93,6 +94,7 @@
                     <include-screen name="orderHeaderInfo" location="component://order/widget/ordermgr/OrderEntryCartScreens.xml"/>
                     <include-screen name="minicart" location="component://order/widget/ordermgr/OrderEntryCartScreens.xml"/>
                     <include-screen name="sidedeepcategory" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
+                    <include-screen name="compareproductslist" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
                 </container>
             </widgets>
         </section>

Modified: ofbiz/trunk/applications/product/config/ProductUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/ProductUiLabels.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/config/ProductUiLabels.xml (original)
+++ ofbiz/trunk/applications/product/config/ProductUiLabels.xml Thu Jul 23 23:28:32 2009
@@ -6874,6 +6874,12 @@
         <value xml:lang="th">เพิ่มไปยังหมวดหมู่</value>
         <value xml:lang="zh">添加到分类</value>
     </property>
+    <property key="ProductAddToCompare">
+        <value xml:lang="en">Add To Compare</value>
+    </property>
+    <property key="ProductAddToCompareListSuccess">
+        <value xml:lang="en">Product ${name} successfully added to compare list</value>
+    </property>
     <property key="ProductAddToPackage">
         <value xml:lang="de">Zu Paket hinzufügen</value>
         <value xml:lang="en">Add to Package</value>
@@ -8376,6 +8382,9 @@
         <value xml:lang="th">เลือกหมวดหมู่</value>
         <value xml:lang="zh">选择顶级分类</value>
     </property>
+    <property key="ProductClearCompareListSuccess">
+        <value xml:lang="en">Compare list successfully cleared</value>
+    </property>
     <property key="ProductComments">
         <value xml:lang="de">Kommentare</value>
         <value xml:lang="en">Comments</value>
@@ -8436,6 +8445,9 @@
         <value xml:lang="th">เปรียบเทียบ</value>
         <value xml:lang="zh">参考价格</value>
     </property>
+    <property key="ProductCompareProducts">
+        <value xml:lang="en">Compare Products</value>
+    </property>
     <property key="ProductComplete">
         <value xml:lang="de">Abschliessen</value>
         <value xml:lang="en">Complete</value>
@@ -13760,6 +13772,9 @@
         <value xml:lang="th">ไม่มีสินค้าในหมวดหมู่นี้</value>
         <value xml:lang="zh">在这个分类里没有产品</value>
     </property>
+    <property key="ProductNoProductsToCompare">
+        <value xml:lang="en">You have no products to compare.</value>
+    </property>
     <property key="ProductNoResultsFound">
         <value xml:lang="cs">Nenalezeny žádné výsledky</value>
         <value xml:lang="de">Es wurden keine Ergebnisse gefunden</value>
@@ -17009,6 +17024,9 @@
         <value xml:lang="th">ลบลักษณะจากผลลัพธ์</value>
         <value xml:lang="zh">从结果中删除特征</value>
     </property>
+    <property key="ProductRemoveFromCompareListSuccess">
+        <value xml:lang="en">Product ${name} successfully removed from compare list</value>
+    </property>
     <property key="ProductRemoveFromSite">
         <value xml:lang="de">Von Seite löschen</value>
         <value xml:lang="en">Remove From Site</value>

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java Thu Jul 23 23:28:32 2009
@@ -1052,6 +1052,104 @@
         }
         return Double.valueOf(doubleString);
     }
+
+    public static List<GenericValue> getProductCompareList(HttpServletRequest request) {
+        HttpSession session = request.getSession();
+        Object compareListObj = session.getAttribute("productCompareList");
+        List<GenericValue> compareList = null;
+        if (compareListObj == null) {
+            compareList = FastList.newInstance();
+        } else if (!(compareListObj instanceof List)) {
+            Debug.logWarning("Session attribute productCompareList contains something other than the expected product list, overwriting.", module);
+            compareList = FastList.newInstance();
+        } else {
+            compareList = (List) compareListObj;
+        }
+        return compareList;
+    }
+
+    public static String addProductToComparisonList(HttpServletRequest request, HttpServletResponse response) {
+        HttpSession session = request.getSession();
+        GenericDelegator delegator = (GenericDelegator) request.getAttribute("delegator");
+        
+        String productId = request.getParameter("productId");
+        GenericValue product = null;
+        if (UtilValidate.isNotEmpty(productId)) {
+            try {
+                product = ProductWorker.findProduct(delegator, productId);
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
+            }
+        }
+        
+        if (product == null) {
+            String errMsg = UtilProperties.getMessage(resource, "productevents.product_with_id_not_found", UtilMisc.toMap("productId", productId), UtilHttp.getLocale(request));
+            request.setAttribute("_ERROR_MESSAGE_", errMsg);
+            return "error";
+        }
+        
+        List<GenericValue> compareList = getProductCompareList(request);
+        boolean alreadyInList = false;
+        for (GenericValue compProduct : compareList) {
+            if (product.getString("productId").equals(compProduct.getString("productId"))) {
+                alreadyInList = true;
+                break;
+            }
+        }
+        if (!alreadyInList) {
+            compareList.add(product);
+        }
+        session.setAttribute("productCompareList", compareList);
+        String productName = ProductContentWrapper.getProductContentAsText(product, "PRODUCT_NAME", request);
+        String eventMsg = UtilProperties.getMessage("ProductUiLabels", "ProductAddToCompareListSuccess", UtilMisc.toMap("name", productName), UtilHttp.getLocale(request));
+        request.setAttribute("_EVENT_MESSAGE_", eventMsg);
+        return "success";
+    }
+
+    public static String removeProductFromComparisonList(HttpServletRequest request, HttpServletResponse response) {
+        HttpSession session = request.getSession();
+        GenericDelegator delegator = (GenericDelegator) request.getAttribute("delegator");
+        
+        String productId = request.getParameter("productId");
+        GenericValue product = null;
+        if (UtilValidate.isNotEmpty(productId)) {
+            try {
+                product = ProductWorker.findProduct(delegator, productId);
+            } catch (GenericEntityException e) {
+                productId =  null;
+                Debug.logError(e, module);
+            }
+        }
+        
+        if (product == null) {
+            String errMsg = UtilProperties.getMessage(resource, "productevents.product_with_id_not_found", UtilMisc.toMap("productId", productId), UtilHttp.getLocale(request));
+            request.setAttribute("_ERROR_MESSAGE_", errMsg);
+            return "error";
+        }
+        
+        List<GenericValue> compareList = getProductCompareList(request);
+        Iterator<GenericValue> it = compareList.iterator();
+        while (it.hasNext()) {
+            GenericValue compProduct = it.next();
+            if (product.getString("productId").equals(compProduct.getString("productId"))) {
+                it.remove();
+                break;
+            }
+        }
+        session.setAttribute("productCompareList", compareList);
+        String productName = ProductContentWrapper.getProductContentAsText(product, "PRODUCT_NAME", request);
+        String eventMsg = UtilProperties.getMessage("ProductUiLabels", "ProductRemoveFromCompareListSuccess", UtilMisc.toMap("name", productName), UtilHttp.getLocale(request));
+        request.setAttribute("_EVENT_MESSAGE_", eventMsg);
+        return "success";
+    }
+
+    public static String clearProductComparisonList(HttpServletRequest request, HttpServletResponse response) {
+        HttpSession session = request.getSession();
+        session.setAttribute("productCompareList", FastList.newInstance());
+        String eventMsg = UtilProperties.getMessage("ProductUiLabels", "ProductClearCompareListSuccess", UtilHttp.getLocale(request));
+        request.setAttribute("_EVENT_MESSAGE_", eventMsg);
+        return "success";
+    }
     
     /**
      * Return nulls for empty strings, as the entity engine can deal with nulls. This will provide blanks

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=797259&r1=797258&r2=797259&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 Thu Jul 23 23:28:32 2009
@@ -329,7 +329,7 @@
      * Gets the product features of a product.
      */
     public static Map<String, Object> prodGetFeatures(DispatchContext dctx, Map<String, ? extends Object> context) {
-        // * String productId      -- Product ID to fond
+        // * String productId      -- Product ID to find
         // * String type           -- Type of feature (STANDARD_FEATURE, SELECTABLE_FEATURE)
         // * String distinct       -- Distinct feature (SIZE, COLOR)
         GenericDelegator delegator = dctx.getDelegator();

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml Thu Jul 23 23:28:32 2009
@@ -1851,6 +1851,27 @@
         <response name="error" type="view" value="main"/>
     </request-map>
     
+    <!-- Product Comparison Requests -->
+    <request-map uri="addToCompare">
+        <security https="false" auth="false"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="addProductToComparisonList"/>
+        <response name="success" type="view-last" value="main"/>
+    </request-map>
+    <request-map uri="removeFromCompare">
+        <security https="false" auth="false"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="removeProductFromComparisonList"/>
+        <response name="success" type="view-last"/>
+    </request-map>
+    <request-map uri="clearCompareList">
+        <security https="false" auth="false"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="clearProductComparisonList"/>
+        <response name="success" type="view-last"/>
+    </request-map>
+    <request-map uri="compareProducts">
+        <security https="false" auth="false"/>
+        <response name="success" type="view" value="compareProducts" save-last-view="true"/>
+    </request-map>
+    
     <!-- End of Request Mappings -->
 
     <!-- View Mappings -->
@@ -1988,5 +2009,7 @@
     <!-- Google Checkout View Mapping -->
     <view-map name="cartToGoogleCheckout" type="screen" page="component://googlecheckout/widget/GoogleCheckoutScreens.xml#redirect"/>
     <view-map name="redirectToGoogleCheckout" type="screen" page="component://googlecheckout/widget/GoogleCheckoutScreens.xml#redirect"/>
+    
+    <view-map name="compareProducts" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#compareProducts"/>
     <!-- End of View Mappings -->
 </site-conf>

Modified: ofbiz/trunk/specialpurpose/ecommerce/widget/CommonScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/widget/CommonScreens.xml?rev=797259&r1=797258&r2=797259&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/widget/CommonScreens.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/widget/CommonScreens.xml Thu Jul 23 23:28:32 2009
@@ -107,6 +107,7 @@
             <widgets>
                     <include-screen name="language"/>
                     <include-screen name="minicart" location="component://ecommerce/widget/CartScreens.xml"/>
+                    <include-screen name="compareproductslist" location="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml"/>
                     <include-screen name="minipromotext" location="component://ecommerce/widget/CartScreens.xml"/>
                     <include-screen name="miniassocprods" location="component://ecommerce/widget/CatalogScreens.xml"/>
                     <include-screen name="factoids" location="component://ecommerce/widget/ContentScreens.xml"/>
@@ -220,6 +221,55 @@
             </widgets>
         </section>
     </screen>
+    
+    <screen name="CommonPopUpDecorator">
+        <section>
+            <actions>
+                <!-- base/top/specific map first, then more common map added for shared labels -->
+                <property-map resource="EcommerceUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="ContentUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="ProductUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="AccountingUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="PartyUiLabels" map-name="uiLabelMap" global="true"/>
+                <property-map resource="OrderUiLabels" map-name="uiLabelMap" global="true"/>
+
+                <set field="MainColumnStyle" value="nocolumns" global="true"/>
+
+                <!-- The default (global) shortcut icon -->
+                <set field="layoutSettings.shortcutIcon" value="/images/ofbiz.ico" global="true"/>
+
+                <!-- The default (main) java scripts -->
+                <!-- NOTE: this should be included on each screen that uses it to avoid including it in all screens: -->
+                <set field="layoutSettings.javaScripts[]" value="/images/fieldlookup.js" global="true"/>
+                <set field="layoutSettings.javaScripts[]" value="/images/selectall.js" global="true"/>
+                <set field="layoutSettings.javaScripts[]" value="/images/calendar_date_select.js" global="true"/>
+                <set field="layoutSettings.javaScripts[+0]" value="/images/prototypejs/effects.js" global="true"/>
+                <set field="layoutSettings.javaScripts[+0]" value="/images/prototypejs/validation.js" global="true"/>
+                <set field="layoutSettings.javaScripts[+0]" value="/images/prototypejs/prototype.js" global="true"/>
+                <set field="layoutSettings.javaScripts[]" value="/images/prototypejs/popup.js" global="true"/>
+
+                <script location="component://ecommerce/widget/EcommerceSetup.groovy"/>
+
+                <!-- Get the store VisualTheme -->
+                <set field="visualThemeId" from-field="productStore.visualThemeId" default-value="EC_DEFAULT"/>
+                <service service-name="getVisualThemeResources">
+                    <field-map field-name="visualThemeId"/>
+                    <field-map field-name="themeResources" from-field="layoutSettings"/>
+                </service>
+                <set field="layoutSettings" from-field="themeResources" default-value="${layoutSettings}" global="true"/>
+            </actions>
+            <widgets>
+                <platform-specific><html><html-template location="component://ecommerce/webapp/ecommerce/includes/headerHead.ftl"/></html></platform-specific>
+                <platform-specific><html><html-template location="component://common/webcommon/includes/openhtmlbody.ftl"/></html></platform-specific>
+                <platform-specific><html><html-template location="component://common/webcommon/includes/messages.ftl"/></html></platform-specific>
+
+                <decorator-section-include name="body"/>
+
+                <platform-specific><html><html-template location="component://common/webcommon/includes/closehtmlbody.ftl"/></html></platform-specific>
+            </widgets>
+        </section>
+    </screen>
 
     <!-- Column Included Screens -->
     <screen name="language">