Author: hansbak
Date: Wed Apr 16 19:26:38 2008
New Revision: 648922

URL: http://svn.apache.org/viewvc?rev=648922&view=rev
Log:
now the feature explosion is complete, added demo data, show the feature prices 
in the selection dropdown boxes, variants and related data is created when not 
existing

Modified:
    ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml
    ofbiz/trunk/applications/ecommerce/data/DemoProductImages.xml
    
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
    
ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/productdetail.bsh
    
ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl
    
ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java
    
ofbiz/trunk/applications/product/webapp/catalog/product/EditProductFeatures.ftl

Modified: ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml (original)
+++ ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml Wed Apr 16 19:26:38 
2008
@@ -200,12 +200,14 @@
 
     <Product productId="WG-1111" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="20111" productName="Micro Chrome Widget" 
internalName="Micro Chrome Widget" description="Micro Widget - Chrome Colored" 
longDescription="This micro chrome widget makes a perfect gift. This one is so 
small that it floats in air." isVirtual="N" isVariant="N" 
quantityIncluded="50.0" weight="2.0"/>
     <Product productId="WG-5569" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="201" productName="Tiny Chrome Widget" 
internalName="Tiny Chrome Widget" description="Tiny Chrome Widget" 
longDescription="This tiny chrome widget makes a perfect gift. The shine will 
last forever. No pollishing required." isVirtual="N" isVariant="N" 
quantityIncluded="50.0" weight="4.0"/>
-    <Product productId="WG-9943" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget" internalName="Giant 
Widget" description="Giant Widget with Wheels" longDescription="This giant 
widget is mobile. It will seat one person safely. The wheels will never rust or 
break. Quite a unique item." quantityIncluded="10.0" weight="22.0" 
isVirtual="Y" isVariant="N"/>
+    <Product productId="WG-9943" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget with variant 
explosion" internalName="Giant Widget variant explosion" 
virtualVariantMethodEnum="VV_VARIANTTREE" description="Giant Widget with 
Wheels" longDescription="This giant widget is mobile. It will seat one person 
safely. The wheels will never rust or break. Quite a unique item." 
quantityIncluded="10.0" weight="22.0" isVirtual="Y" isVariant="N"/>
     <Product productId="WG-9943-B3" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget B3" 
internalName="Giant Widget B3" description="Black Giant Widget with 3 Wheels" 
longDescription="This giant widget is mobile. It will seat one person safely. 
The wheels will never rust or break. Quite a unique item." 
quantityIncluded="10.0" weight="22.0" isVirtual="N" isVariant="Y"/>
     <Product productId="WG-9943-B4" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget B4" 
internalName="Giant Widget B4" description="Black Giant Widget with 4 Wheels" 
longDescription="This giant widget is mobile. It will seat one person safely. 
The wheels will never rust or break. Quite a unique item." 
quantityIncluded="10.0" weight="22.0" isVirtual="N" isVariant="Y"/>
     <Product productId="WG-9943-S3" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget S3" 
internalName="Giant Widget S3" description="Silver Giant Widget with 3 Wheels" 
longDescription="This giant widget is mobile. It will seat one person safely. 
The wheels will never rust or break. Quite a unique item." 
quantityIncluded="10.0" weight="22.0" isVirtual="N" isVariant="Y"/>
     <Product productId="WG-9943-S4" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget S4" 
internalName="Giant Widget S4" description="Silver Giant Widget with 4 Wheels" 
longDescription="This giant widget is mobile. It will seat one person safely. 
The wheels will never rust or break. Quite a unique item." 
quantityIncluded="10.0" weight="22.0" isVirtual="N" isVariant="Y"/>
 
+    <Product productId="WG-9944" productTypeId="FINISHED_GOOD" 
primaryProductCategoryId="202" productName="Giant Widget with feature 
explosion" internalName="Giant Widget feature Explosion" 
virtualVariantMethodEnum="VV_FEATURETREE" description="Giant Widget with 
Wheels" longDescription="This giant widget is mobile. It will seat one person 
safely. The wheels will never rust or break. Quite a unique item especially as 
it can have (almost) as many variants as you like" quantityIncluded="10.0" 
weight="22.0" isVirtual="Y" isVariant="N"/>
+    
     <ProductPrice productId="GZ-1000" productPricePurposeId="PURCHASE" 
productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="15.99" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
     <ProductPrice productId="GZ-1000" productPricePurposeId="PURCHASE" 
productPriceTypeId="LIST_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" 
fromDate="2001-05-13 12:00:00.0" price="15.0" createdDate="2001-05-13 
12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" 
lastModifiedByUserLogin="admin"/>
     <ProductPrice productId="GZ-1001" productPricePurposeId="PURCHASE" 
productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="25.99" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
@@ -237,7 +239,10 @@
     <ProductPrice productId="WG-9943" productPricePurposeId="PURCHASE" 
productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="549.99" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
     <ProductPrice productId="WG-9943" productPricePurposeId="PURCHASE" 
productPriceTypeId="LIST_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" 
fromDate="2001-05-13 12:00:00.0" price="550.0" createdDate="2001-05-13 
12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" 
lastModifiedByUserLogin="admin"/>
     <ProductPrice productId="WG-9943" productPricePurposeId="PURCHASE" 
productPriceTypeId="COMPETITIVE_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="922.0" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
-
+    <ProductPrice productId="WG-9944" productPricePurposeId="PURCHASE" 
productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="523.99" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
+    <ProductPrice productId="WG-9944" productPricePurposeId="PURCHASE" 
productPriceTypeId="LIST_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" 
fromDate="2001-05-13 12:00:00.0" price="594.0" createdDate="2001-05-13 
12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" 
lastModifiedByUserLogin="admin"/>
+    <ProductPrice productId="WG-9944" productPricePurposeId="PURCHASE" 
productPriceTypeId="AVERAGE_COST" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2001-05-13 12:00:00.0" price="320.0" 
createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" 
lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
+    
     <!-- test Subscription product, a Gizmo Newsletter -->
     <Product productId="GZ-NEWS-1MO" productTypeId="DIGITAL_GOOD" 
primaryProductCategoryId="101" productName="Gizmo Newsletter 1 Month" 
internalName="Gizmo Newsletter 1 Month Subscription" description="A 1 month 
subscription to the Gizmo Newsletter: can be used immediately after purchase." 
longDescription="This newsletter will give you regular updates on the wonderful 
world of Gizmos!" taxable="Y" chargeShipping="N" autoCreateKeywords="Y" 
isVirtual="N" isVariant="N" createdDate="2001-05-13 12:00:00.0" 
createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" 
lastModifiedByUserLogin="admin"/>
     <SubscriptionResource subscriptionResourceId="GZ-NEWS" description="Gizmo 
Newsletter"/>
@@ -287,9 +292,17 @@
     <ProductFeatureCategoryAppl productFeatureCategoryId="9000" 
productCategoryId="CATALOG1_SEARCH" fromDate="2001-05-13 12:00:00.0"/>
 
     <ProductFeature productFeatureId="9000" productFeatureCategoryId="9000" 
productFeatureTypeId="COLOR" description="Black"/>
+    <ProductFeaturePrice productFeatureId="9000" 
productPriceTypeId="DEFAULT_PRICE" price="4.30" currencyUomId="USD" 
fromDate="2000-01-01 00:00:00.0"/>
+    <ProductFeaturePrice productFeatureId="9000" 
productPriceTypeId="LIST_PRICE" price="4.40" currencyUomId="USD" 
fromDate="2000-01-01 00:00:00.0"/>
+    <ProductFeaturePrice productFeatureId="9000" 
productPriceTypeId="AVERAGE_COST" price="2.30" currencyUomId="USD" 
fromDate="2000-01-01 00:00:00.0"/>
     <ProductFeature productFeatureId="9001" productFeatureCategoryId="9000" 
productFeatureTypeId="COLOR" description="Silver"/>
+    <ProductFeaturePrice productFeatureId="9001" price="4.30" 
productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" fromDate="2000-01-01 
00:00:00.0"/>
     <ProductFeature productFeatureId="9002" productFeatureCategoryId="9000" 
productFeatureTypeId="SIZE" description="3-Wheel"/>
+    <ProductFeaturePrice productFeatureId="9002" price="5.30" 
productPriceTypeId="LIST_PRICE" currencyUomId="USD" fromDate="2000-01-01 
00:00:00.0"/>
     <ProductFeature productFeatureId="9003" productFeatureCategoryId="9000" 
productFeatureTypeId="SIZE" description="4-Wheel"/>
+    <ProductFeaturePrice productFeatureId="9003" price="2.30" 
productPriceTypeId="AVERAGE_COST" currencyUomId="USD" fromDate="2000-01-01 
00:00:00.0"/>
+
+    <ProductFeatureIactn productFeatureId="9000" productFeatureIdTo="9002" 
productFeatureIactnTypeId="FEATURE_IACTN_INCOMP"/> 
 
     <ProductFeatureAppl productId="GZ-1006" productFeatureId="8000"
         productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="1"/>
@@ -317,7 +330,15 @@
         productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="3"/>
     <ProductFeatureAppl productId="WG-9943" productFeatureId="9003"
         productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="4"/>
-
+    <ProductFeatureAppl productId="WG-9944" productFeatureId="9000"
+        productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="1"/>
+    <ProductFeatureAppl productId="WG-9944" productFeatureId="9001"
+        productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="2"/>
+    <ProductFeatureAppl productId="WG-9944" productFeatureId="9002"
+        productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="3"/>
+    <ProductFeatureAppl productId="WG-9944" productFeatureId="9003"
+        productFeatureApplTypeId="SELECTABLE_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="4"/>
+    
     <ProductFeatureAppl productId="WG-9943-B3" productFeatureId="9000"
         productFeatureApplTypeId="STANDARD_FEATURE" fromDate="2001-05-13 
12:00:00.0" sequenceNum="1"/>
     <ProductFeatureAppl productId="WG-9943-B3" productFeatureId="9002"
@@ -408,6 +429,7 @@
     <ProductCategoryMember productCategoryId="201" productId="WG-5569" 
fromDate="2001-05-13 12:00:00.0"/>
     <ProductCategoryMember productCategoryId="20111" productId="WG-1111" 
fromDate="2001-05-13 12:00:00.0"/>
     <ProductCategoryMember productCategoryId="202" productId="WG-9943" 
fromDate="2001-05-13 12:00:00.0"/>
+    <ProductCategoryMember productCategoryId="202" productId="WG-9944" 
fromDate="2001-05-13 12:00:00.0"/>
     <ProductCategoryMember productCategoryId="CATALOG1_QUICKADD1" 
productId="GZ-2644" fromDate="2001-05-13 12:00:00.0"/>
     <ProductCategoryMember productCategoryId="CATALOG1_QUICKADD1" 
productId="GZ-8544" fromDate="2001-05-13 12:00:00.0"/>
     <ProductCategoryMember productCategoryId="CATALOG1_QUICKADD1" 
productId="WG-1111" fromDate="2001-05-13 12:00:00.0"/>

Modified: ofbiz/trunk/applications/ecommerce/data/DemoProductImages.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/ecommerce/data/DemoProductImages.xml?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- ofbiz/trunk/applications/ecommerce/data/DemoProductImages.xml (original)
+++ ofbiz/trunk/applications/ecommerce/data/DemoProductImages.xml Wed Apr 16 
19:26:38 2008
@@ -32,6 +32,7 @@
   <Product productId="GZ-9290" 
smallImageUrl="/images/products/small/green_burner.png" 
largeImageUrl="/images/products/large/green_burner.png"/>
   <Product productId="WG-1111" 
smallImageUrl="/images/products/small/calculator.png" 
largeImageUrl="/images/products/large/calculator.png"/>
   <Product productId="WG-9943" 
smallImageUrl="/images/products/small/big_truck.png" 
largeImageUrl="/images/products/large/big_truck.png"/>
+  <Product productId="WG-9944" 
smallImageUrl="/images/products/small/big_truck.png" 
largeImageUrl="/images/products/large/big_truck.png"/>
   <Product productId="WG-5569" 
smallImageUrl="/images/products/small/cellphone_shandy.png" 
largeImageUrl="/images/products/large/cellphone_shandy.png"/>
   <Product productId="PC001" 
smallImageUrl="/images/products/small/gis_computer_glen_rolla.png" 
largeImageUrl="/images/products/large/gis_computer_glen_rolla.png"/>
   <Product productId="GC-001" 
smallImageUrl="/images/products/small/certificate.png" 
largeImageUrl="/images/products/large/certificate.png"/>

Modified: 
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
 (original)
+++ 
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
 Wed Apr 16 19:26:38 2008
@@ -242,7 +242,6 @@
         if (ProductWorker.isVirtual(delegator, productId)) {
 
                        if 
("VV_FEATURETREE".equals(ProductWorker.getProductvirtualVariantMethod(delegator,
 productId))) {
-
                                // get the selected features.
                                List <String> selectedFeatures = new 
LinkedList<String>();
                        java.util.Enumeration paramNames = 
request.getParameterNames();
@@ -251,41 +250,28 @@
                                if (paramName.startsWith("FT")) {
                                        
selectedFeatures.add(request.getParameterValues(paramName)[0]);
                                }
-//                             Debug.log("********paramName/"+paramName+"/");
-//                             String[] paramValues = 
request.getParameterValues(paramName);
-//                             StringBuffer paraValue= new StringBuffer();
-//                             for(int i=0; i<paramValues.length; i++) {
-//                                     paraValue.append(paramValues[i]+",");   
                  
-//                         }
-//                             Debug.log(paraValue.toString());
                        }
                                try {
 
-                                       List<GenericValue> dependenciesVariants 
= delegator.findByAndCache("ProductFeatureIactn", UtilMisc.toMap("productId", 
productId,
-                                                                               
        "productFeatureIactnTypeId","FEATURE_IACTN_DEPEND"));
-                                       List<GenericValue> 
incompatibilityVariants = delegator.findByAndCache("ProductFeatureIactn", 
UtilMisc.toMap("productId", productId,
-                                                                               
        "productFeatureIactnTypeId","FEATURE_IACTN_INCOMP"));
-                                       // find incompatibilities or 
dependencies...
-                                       List <GenericValue> featureTypes = 
ProductWorker.getProductFeatureTypesBySeq(delegator, productId);
-                                       Iterator<GenericValue> featureIter = 
featureTypes.iterator();                                   
-                                       
+                                       Iterator<String> featureIter = 
selectedFeatures.iterator();                                     
                                        while (featureIter.hasNext()) {
-                                               String paramValue = (String) 
paramMap.get("FT") + featureIter.next();
-                                               Iterator<GenericValue> 
incompatibilityVariantIter = incompatibilityVariants.iterator(); 
-                                               while 
(incompatibilityVariantIter.hasNext()) {
-                                                       GenericValue 
incompatibilityVariant = incompatibilityVariantIter.next();
+                                               String paramValue = 
featureIter.next();
+                                               // find incompatibilities..
+                                               List<GenericValue> 
incompatibilityVariants = delegator.findByAndCache("ProductFeatureIactn", 
UtilMisc.toMap("productId", productId,
+                                                               
"productFeatureIactnTypeId","FEATURE_IACTN_INCOMP"));
+                                               Iterator<GenericValue> 
incompIter = incompatibilityVariants.iterator(); 
+                                               while (incompIter.hasNext()) {
+                                                       GenericValue 
incompatibilityVariant = incompIter.next();
                                                        String featur = 
incompatibilityVariant.getString("productFeatureId");
                                                        
if(paramValue.equals(featur)){
                                                                String featurTo 
= incompatibilityVariant.getString("productFeatureIdTo");
-                                                               
Iterator<GenericValue> featureToIter = featureTypes.iterator(); 
+                                                               
Iterator<String> featureToIter = selectedFeatures.iterator();   
                                                                while 
(featureToIter.hasNext()) {                                                     
          
-                                                                       String 
paramValueTo = (String) paramMap.get("FT" + featureToIter.next());
+                                                                       String 
paramValueTo = featureToIter.next();
                                                                        
if(featurTo.equals(paramValueTo)){
                                                                                
GenericValue featureFrom = (GenericValue) 
delegator.findByPrimaryKey("ProductFeature", UtilMisc.toMap("productFeatureId", 
featur));
                                                                                
GenericValue featureTo = (GenericValue) 
delegator.findByPrimaryKey("ProductFeature", UtilMisc.toMap("productFeatureId", 
featurTo));
-
                                                                                
String message = UtilProperties.getMessage(resource, 
"cart.addToCart.incompatibilityVariantFeature", locale) + ":/" + 
featureFrom.getString("description") + "/ => /" + 
featureTo.getString("description") +"/";
-                                                                               
Debug.log(">>>>>>>" + message);
                                                                                
request.setAttribute("_ERROR_MESSAGE_", message);
                                                                                
return "incompatibilityVariantFeature";
                                                                        }
@@ -293,58 +279,123 @@
 
                                                        }
                                                }
-
-                                       }
-
-                                       
request.setAttribute("_EVENT_MESSAGE_","all feature Variant accept");
-                                       Iterator<String> fIter = 
selectedFeatures.iterator();
-                                       Long lowestCount = null;
-                                       String lowestFeatureId = null;
-                                       while (fIter.hasNext()) {               
                                
-                                               String productFeatureId = 
fIter.next();
-                                               long r = 
delegator.findCountByAnd("ProductFeatureAppl", 
UtilMisc.toMap("productFeatureId", 
productFeatureId,"productFeatureApplTypeId","STANDARD_FEATURE"));
-                                               if (lowestCount == null || r < 
lowestCount) {
-                                                       lowestCount = r;
-                                                       lowestFeatureId = 
productFeatureId;
+                                               // find dependencies..
+                                               List<GenericValue> 
dependenciesVariants = delegator.findByAndCache("ProductFeatureIactn", 
UtilMisc.toMap("productId", productId,
+                                                               
"productFeatureIactnTypeId","FEATURE_IACTN_DEPEND"));
+                                               Iterator<GenericValue> dpIter = 
dependenciesVariants.iterator();        
+                                               while (dpIter.hasNext()) {
+                                                       GenericValue dpVariant 
= dpIter.next();
+                                                       String featur = 
dpVariant.getString("productFeatureId");
+                                                       
if(paramValue.equals(featur)){
+                                                               String featurTo 
= dpVariant.getString("productFeatureIdTo");
+                                                               
Iterator<String> featureToIter = selectedFeatures.iterator();
+                                                               boolean found = 
false;
+                                                               while 
(featureToIter.hasNext()) {                                                     
          
+                                                                       String 
paramValueTo = featureToIter.next();
+                                                                       
if(featurTo.equals(paramValueTo)){
+                                                                               
found = true;
+                                                                               
break;
+                                                                       }
+                                                               }
+                                                               if (!found) {
+                                                                       
GenericValue featureFrom = (GenericValue) 
delegator.findByPrimaryKey("ProductFeature", UtilMisc.toMap("productFeatureId", 
featur));
+                                                                       
GenericValue featureTo = (GenericValue) 
delegator.findByPrimaryKey("ProductFeature", UtilMisc.toMap("productFeatureId", 
featurTo));
+                                                                       String 
message = UtilProperties.getMessage(resource, 
"cart.addToCart.dependencyVariantFeature", locale) + ":/" + 
featureFrom.getString("description") + "/ => /" + 
featureTo.getString("description") +"/";
+                                                                       
request.setAttribute("_ERROR_MESSAGE_", message);
+                                                                       return 
"dependencyVariantFeature";
+                                                               }
+                                                       }
                                                }
                                        }
                                        // find variant
-                                       List <GenericValue> productAppls = 
delegator.findByAnd("ProductFeatureAppl", UtilMisc.toMap("productFeatureId", 
lowestFeatureId,"productFeatureApplTypeId","STANDARD_FEATURE"));
-                                       Iterator <GenericValue> pIter = 
productAppls.iterator();
+                                       // Debug.log("=====try to find variant 
for product: " + productId + " and features: " + selectedFeatures);
+                                       List  <GenericValue> productAssocs = 
EntityUtil.filterByDate(delegator.findByAnd("ProductAssoc", 
UtilMisc.toMap("productId", productId, 
"productAssocTypeId","PRODUCT_VARIANT")));
+                                       Iterator <GenericValue> assocIter = 
productAssocs.iterator();
                                        boolean productFound = false;
-       nextProd:               while(pIter.hasNext()) {
-                                               GenericValue productAppl = 
pIter.next();
-                                               fIter = 
selectedFeatures.iterator();
+       nextProd:               while(assocIter.hasNext()) {
+                                               GenericValue productAssoc = 
(GenericValue) assocIter.next();
+                                               Iterator <String> fIter = 
selectedFeatures.iterator();
                                                while (fIter.hasNext()) {
-                                                       String featureId = 
fIter.next();
-                                                       if 
(featureId.equals(lowestFeatureId)) continue;
-                                                       Debug.log("===check for 
product: " + productAppl.getString("productId") + "===check for feature: " + 
featureId);
-                                                       List <GenericValue> 
pAppls = delegator.findByAnd("ProductFeatureAppl", UtilMisc.toMap("productId", 
productAppl.getString("productId"), "productFeatureId", 
featureId,"productFeatureApplTypeId","STANDARD_FEATURE"));
+                                                       String featureId = 
(String) fIter.next();
+                                                       List <GenericValue> 
pAppls = delegator.findByAndCache("ProductFeatureAppl", 
UtilMisc.toMap("productId", productAssoc.getString("productIdTo"), 
"productFeatureId", featureId, "productFeatureApplTypeId","STANDARD_FEATURE"));
                                                        if 
(UtilValidate.isEmpty(pAppls)) {
                                                                continue 
nextProd;
                                                        }
                                                }
                                                productFound = true;
-                                               productId = 
productAppl.getString("productId");
+                                               productId = 
productAssoc.getString("productIdTo");
                                                break;
                                        }
-                                       
+//                                     if (productFound)
+//                                             Debug.log("=====product found:" 
+ productId + " and features: " + selectedFeatures);
+
+                                       /**
+                                        * 1. variant not found so create new 
variant product and use the virtual product as basis, new one  is a variant 
type and not a virtual type. 
+                                        *    adjust the prices according the 
selected features
+                                        */                                     
        
                                        if (!productFound) {
-                                               
request.setAttribute("_EVENT_MESSAGE_", "product variant could not be found.");
-                                               return "product";
+                                               // copy product to be variant
+                                               GenericValue product = 
delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId",  productId));
+                                               product.put("isVariant", "Y");
+                                               product.put("isVirtual", "N");
+                                               product.put("productId", 
delegator.getNextSeqId("Product"));
+                                               
product.remove("virtualVariantMethodEnum"); // not relevant for a non virtual 
product.
+                                               product.create();
+                                               // add the selected/standard 
features as 'standard features' to the 'ProductFeatureAppl' table
+                                               GenericValue productFeatureAppl 
= delegator.makeValue("ProductFeatureAppl", 
+                                                               
UtilMisc.toMap("productId", product.getString("productId"), 
"productFeatureApplTypeId", "STANDARD_FEATURE"));
+                                               
productFeatureAppl.put("fromDate", UtilDateTime.nowTimestamp());                
              
+                                               Iterator <String> 
selectedFeatureIter = selectedFeatures.iterator();                            
+                                               while 
(selectedFeatureIter.hasNext()) {
+                                                       String productFeatureId 
= selectedFeatureIter.next();
+                                                       
productFeatureAppl.put("productFeatureId",  productFeatureId);
+                                                       
productFeatureAppl.create();
+                                               }
+                                               //add standard features too
+                                               List <GenericValue> 
stdFeaturesAppls = 
EntityUtil.filterByDate(delegator.findByAnd("ProductFeatureAppl", 
UtilMisc.toMap("productId", productId, "productFeatureApplTypeId", 
"STANDARD_FEATURE")));
+                                               Iterator <GenericValue> 
stdFeatureIter = stdFeaturesAppls.iterator();                           
+                                               while 
(stdFeatureIter.hasNext()) {
+                                                       GenericValue 
stdFeaturesAppl = stdFeatureIter.next();
+                                                       
stdFeaturesAppl.put("productId",  product.getString("productId"));
+                                                       
stdFeaturesAppl.create();
+                                               }
+                                               /* 3. use the price of the 
virtual product(Entity:ProductPrice) as a basis and adjust according the prices 
in the feature price table.
+                                                *  take the default price from 
the vitual product, go to the productfeature table and retrieve all the prices 
for the difFerent features
+                                                *  add these to the price of 
the virtual product, store the result as the default price on the variant you 
created.
+                                                */
+                                               List <GenericValue> 
productPrices = EntityUtil.filterByDate(delegator.findByAnd("ProductPrice", 
UtilMisc.toMap("productId", productId)));
+                                               Iterator <GenericValue> ppIter 
= productPrices.iterator();
+                                               while (ppIter.hasNext()) {
+                                                       GenericValue 
productPrice = ppIter.next();
+                                                       Iterator <String> 
sfIter = selectedFeatures.iterator();                         
+                                                       while 
(sfIter.hasNext()) {
+                                                               List 
<GenericValue> productFeaturePrices = 
EntityUtil.filterByDate(delegator.findByAnd("ProductFeaturePrice", 
+                                                                               
UtilMisc.toMap("productFeatureId", sfIter.next(), "productPriceTypeId", 
productPrice.getString("productPriceTypeId"))));
+                                                               if 
(UtilValidate.isNotEmpty(productFeaturePrices)) {
+                                                                       
GenericValue productFeaturePrice = productFeaturePrices.get(0);
+                                                                       if 
(UtilValidate.isNotEmpty(productFeaturePrice)) {
+                                                                               
productPrice.put("price", productPrice.getDouble("price").doubleValue() + 
productFeaturePrice.getDouble("price").doubleValue());
+                                                                       }
+                                                               }
+                                                       }
+                                                       if 
(productPrice.get("price") == null) {
+                                                               
productPrice.put("price", productPrice.getDouble("price").doubleValue());
+                                                       }
+                                                       
productPrice.put("productId",  product.getString("productId"));
+                                                       productPrice.create();
+                                               }
+                                               // add the product association
+                                               GenericValue productAssoc = 
delegator.makeValue("ProductAssoc", UtilMisc.toMap("productId", productId, 
"productIdTo", product.getString("productId"), "productAssocTypeId", 
"PRODUCT_VARIANT"));
+                                               productAssoc.put("fromDate", 
UtilDateTime.nowTimestamp());
+                                               productAssoc.create();
+                                               Debug.log("set the productId 
to: " + product.getString("productId"));
+                                               // finally use the new 
productId to be added to the cart
+                                               productId = 
product.getString("productId"); // set to the new product
                                        }
-                                       
-                                       
 
                                } catch (GenericEntityException e) {
                                        Debug.logError(e, module);
                                }
-
-                               // find the related variant.....
-
-                               // if not found create it using the virt 
product and feature
-                               // prices.
-
                        } else {
                                request.setAttribute("product_id", productId);
                                
request.setAttribute("_EVENT_MESSAGE_",UtilProperties.getMessage(resource,"cart.addToCart.chooseVariationBeforeAddingToCart",locale));
@@ -621,9 +672,9 @@
             return "error";
         } else {
             if (cart.viewCartOnAdd()) {
-                return "viewcart";
+               return "viewcart";
             } else {
-                return "success";
+               return "success";
             }
         }
     }

Modified: 
ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/productdetail.bsh
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/productdetail.bsh?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/productdetail.bsh
 (original)
+++ 
ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/productdetail.bsh
 Wed Apr 16 19:26:38 2008
@@ -242,7 +242,7 @@
     // Special Variant Code
     if ("Y".equals(product.getString("isVirtual"))) {
         if 
("VV_FEATURETREE".equals(ProductWorker.getProductvirtualVariantMethod(delegator,
 productId))) {
-            context.put("featureLists", 
ProductWorker.getProductFeaturesByTypesAndSeq(product));
+            context.put("featureLists", 
ProductWorker.getSelectableProductFeaturesByTypesAndSeq(product));
         } else {
         featureMap = dispatcher.runSync("getProductFeatureSet", 
UtilMisc.toMap("productId", productId));
         featureSet = featureMap.get("featureSet");

Modified: 
ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl 
(original)
+++ 
ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl 
Wed Apr 16 19:26:38 2008
@@ -231,32 +231,32 @@
     }
 
     <#if product.virtualVariantMethodEnum?if_exists == "VV_FEATURETREE" && 
featureLists?has_content>   
-      function checkRadioButton() {
-        //alert("work");
-        var block = document.getElementById("addCart");
-      
-          <#list featureLists as featureList>
-          <#list featureList as feature>
-            <#if feature_index == 0>
-                var myList = 
document.getElementById("FT${feature.productFeatureTypeId}");
-                 if (myList.options[0].selected == true){
-                   block.style.display = "none";
-                   return;
-                 }
-  
-              <#break>
-            </#if>                 
-          </#list>
-          </#list>
-          block.style.display = "block";
-      }
+           function checkRadioButton() {
+                   var block1 = document.getElementById("addCart1");
+                   var block2 = document.getElementById("addCart2");
+               <#list featureLists as featureList>
+                           <#list featureList as feature>
+                                   <#if feature_index == 0>
+                                       var myList = 
document.getElementById("FT${feature.productFeatureTypeId}");
+                                        if (myList.options[0].selected == 
true){
+                                               block1.style.display = "none";
+                                               block2.style.display = "block";
+                                               return;
+                                        }
+                                       <#break>
+                                   </#if>                  
+                           </#list>
+               </#list>
+               block1.style.display = "block";
+               block2.style.display = "none";
+           }
     </#if>  
  //-->
  </script>
 
 <div id="productdetail">
 
-<table border="0" cellpadding="2" cellspacing="0">
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
   <#-- Category next/previous -->
   <#if category?exists>
     <tr>
@@ -425,21 +425,29 @@
                         <div class="tabletext">${feature.description}: <select 
id="FT${feature.productFeatureTypeId}" name="FT${feature.productFeatureTypeId}" 
onChange="javascript:checkRadioButton();">
                         <option value="select" selected="selected"> select 
option </option> 
                     <#else>
-                        <option 
value="${feature.productFeatureId}">${feature.description}</option> 
+                        <option 
value="${feature.productFeatureId}">${feature.description} <#if 
feature.price?exists>(+ <@ofbizCurrency amount=feature.price?string 
isoCode=feature.currencyUomId/>)</#if></option> 
                     </#if>
                 </#list>
                 </select>
                 </div>
             </#list>
-            <input type="hidden" name="add_product_id" 
value="${product.productId}"/>          
-            <div id="addCart" style="display:none;>
+              <input type="hidden" name="product_id" 
value="${product.productId}"/>
+              <input type="hidden" name="add_product_id" 
value="${product.productId}"/>
+            <div id="addCart1" style="display:none;>
               <span style="white-space: 
nowrap;"><b>${uiLabelMap.CommonQuantity}:</b></span>&nbsp;
               <input type="text" class="inputBox" size="5" name="quantity" 
value="1"/>
-              <a href="javascript:document.addform.submit();" 
class="buttontext"><span style="white-space: 
nowrap;">${uiLabelMap.EcommerceAddtoCart}</span></a>
+              <a href="javascript:javascript:addItem();" 
class="buttontext"><span style="white-space: 
nowrap;">${uiLabelMap.EcommerceAddtoCart}</span></a>
+              &nbsp;
+            </div>            
+            <div id="addCart2" style="display:block;>
+              <span style="white-space: 
nowrap;"><b>${uiLabelMap.CommonQuantity}:</b></span>&nbsp;
+              <input type="text" class="inputBox" size="5" value="1" 
disabled="disabled"/>
+              <a href="javascript:alert('Please select all features first');" 
class="buttontext"><span style="white-space: 
nowrap;">${uiLabelMap.EcommerceAddtoCart}</span></a>
               &nbsp;
             </div>            
           </#if>
-          <#if variantTree?exists && (variantTree.size() > 0)>
+          <#if !product.virtualVariantMethodEnum?exists || 
product.virtualVariantMethodEnum == "VV_VARIANTTREE">
+           <#if variantTree?exists && (variantTree.size() > 0)>
             <#list featureSet as currentType>
               <div class="tabletext">
                 <select name="FT${currentType}" 
onchange="javascript:getList(this.name, (this.selectedIndex-1), 1);">
@@ -459,6 +467,7 @@
             <div 
class="tabletext"><b>${uiLabelMap.ProductItemOutofStock}.</b></div>
             <#assign inStock = false>
           </#if>
+         </#if> 
         <#else>
           <input type="hidden" name="product_id" value="${product.productId}"/>
           <input type="hidden" name="add_product_id" 
value="${product.productId}"/>
@@ -482,7 +491,7 @@
         <#elseif product.salesDiscontinuationDate?exists && 
nowTimestamp.after(product.salesDiscontinuationDate)>
           <div class="tabletext" style="color: 
red;">${uiLabelMap.ProductProductNoLongerAvailable}.</div>
         <#-- check to see if the product requires inventory check and has 
inventory -->
-        <#else>
+        <#elseif product.virtualVariantMethodEnum?if_exists != 
"VV_FEATURETREE">
           <#if inStock>
             <#if product.requireAmount?default("N") == "Y">
               <#assign hiddenStyle = "visible">
@@ -692,7 +701,7 @@
     <#-- obsolete -->
     <@associated assocProducts=obsoleteProducts beforeName="" showName="Y" 
afterName=" ${uiLabelMap.ProductObsolete}" formNamePrefix="obs" 
targetRequestName=""/>
     <#-- cross sell -->
-    <@associated assocProducts=crossSellProducts beforeName="" showName="N" 
afterName="${uiLabelMap.ProductCrossSell}" formNamePrefix="cssl" 
targetRequestName="crosssell"/>
+    <@associated assocProducts=crossSellProducts beforeName="" showName="N" 
afterName="${uiLabelMap.ProducrCrossSell}" formNamePrefix="cssl" 
targetRequestName="crosssell"/>
     <#-- up sell -->
     <@associated assocProducts=upSellProducts 
beforeName="${uiLabelMap.ProductUpSell} " showName="Y" afterName=":" 
formNamePrefix="upsl" targetRequestName="upsell"/>
     <#-- obsolescence -->

Modified: 
ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java
 (original)
+++ 
ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java
 Wed Apr 16 19:26:38 2008
@@ -479,39 +479,7 @@
         }
         return features;
     }
-    /**
-     * 
-     * @param product
-     * @return list of featureTypes sorted by sequence for this product.
-     */
-    public static List getProductFeatureTypesBySeq(GenericDelegator delegator, 
String productId) {
-        if (productId == null) {
-            return null;
-        }
-        List featureTypes = new ArrayList();
-        try {
-            GenericValue product = delegator.findByPrimaryKeyCache("Product", 
UtilMisc.toMap("productId", productId));
-            if (product != null) {
-                List productAppls = null;
-                Map fields = UtilMisc.toMap("productId", 
product.getString("productId"), "productFeatureApplTypeId", 
"SELECTABLE_FEATURE");
-                List order = 
UtilMisc.toList("productFeatureTypeId","sequenceNum");
-                List features = 
delegator.findByAndCache("ProductFeatureAndAppl", fields, order);
-                Iterator it = features.iterator();
-                String oldType = null;
-                while(it.hasNext()) {
-                    GenericValue productFeatureAppl = (GenericValue) it.next();
-                    if (oldType == null || 
!oldType.equals(productFeatureAppl.getString("productFeatureTypeId"))) {
-                        
featureTypes.add(productFeatureAppl.getString("productFeatureTypeId")); 
-                        oldType = 
productFeatureAppl.getString("productFeatureTypeId");
-                    }
-                }
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        }
-        return featureTypes;
-    }
-    
+
     public static String getProductvirtualVariantMethod(GenericDelegator 
delegator, String productId) {
        GenericValue product = null;
         try {
@@ -530,31 +498,30 @@
     /**
      * 
      * @param product
-     * @return list featureType and related features for this product ordered 
by type and sequence
+     * @return list featureType and related featuresIds, description and 
feature price for this product ordered by type and sequence
      */
-    public static List getProductFeaturesByTypesAndSeq(GenericValue product) {
+    public static List<List<Map<String,String>>> 
getSelectableProductFeaturesByTypesAndSeq(GenericValue product) {
         if (product == null) {
             return null;
         }
-        List featureTypeFeatures = new ArrayList();
+        List <List<Map<String,String>>> featureTypeFeatures = new 
ArrayList<List<Map<String,String>>>();
         try {
             if (product != null) {
                 GenericDelegator delegator = product.getDelegator();
-                List productAppls = null;
-                Map fields = UtilMisc.toMap("productId", 
product.getString("productId"), "productFeatureApplTypeId", 
"SELECTABLE_FEATURE");
-                List order = 
UtilMisc.toList("productFeatureTypeId","sequenceNum");
+                Map<String,String> fields = UtilMisc.toMap("productId", 
product.getString("productId"), "productFeatureApplTypeId", 
"SELECTABLE_FEATURE");
+                List<String> order = UtilMisc.toList("productFeatureTypeId", 
"sequenceNum");
                 List features = 
delegator.findByAndCache("ProductFeatureAndAppl", fields, order);
-                List featuresSorted = UtilMisc.sortMaps(features, order);
-                Iterator it = featuresSorted.iterator();
+                List featuresSorted = (List) UtilMisc.sortMaps(features, 
order);
+                Iterator it = (Iterator) featuresSorted.iterator();
                 String oldType = null;
-                List featureList = new LinkedList();
+                List<Map<String,String>> featureList = new 
LinkedList<Map<String,String>>();
                 while(it.hasNext()) {
                     GenericValue productFeatureAppl = (GenericValue) it.next();
                     if (oldType == null || 
!oldType.equals(productFeatureAppl.getString("productFeatureTypeId"))) {
+                       // use first entry for type and description
                         if (oldType != null) {
                             featureTypeFeatures.add(featureList);
-                            featureList =  new LinkedList();
-                            Debug.log("=====add feature: " + oldType);
+                            featureList =  new 
LinkedList<Map<String,String>>();
                             } 
                         GenericValue productFeatureType = 
delegator.findByPrimaryKey("ProductFeatureType", 
UtilMisc.toMap("productFeatureTypeId", 
                                        
productFeatureAppl.getString("productFeatureTypeId")));
@@ -562,20 +529,32 @@
                                                         "description", 
productFeatureType.getString("description")));  
                         oldType = 
productFeatureAppl.getString("productFeatureTypeId");
                     }
-                    // featureId and description
-                    featureList.add(UtilMisc.toMap("productFeatureId", 
productFeatureAppl.getString("productFeatureId"), "description", 
productFeatureAppl.getString("description"))); 
+                    // fill other entries with featureId, description and 
default price and currency
+                    Map <String,String> featureData = 
UtilMisc.toMap("productFeatureId", 
productFeatureAppl.getString("productFeatureId"));
+                    if 
(UtilValidate.isNotEmpty(productFeatureAppl.get("description"))) {
+                               featureData.put("description", 
productFeatureAppl.getString("description"));
+                    } else {
+                       featureData.put("description", 
productFeatureAppl.getString("productFeatureId"));
+                    }
+                    List <GenericValue> productFeaturePrices = 
EntityUtil.filterByDate(delegator.findByAnd("ProductFeaturePrice", 
+                               UtilMisc.toMap("productFeatureId", 
productFeatureAppl.getString("productFeatureId"), "productPriceTypeId", 
"DEFAULT_PRICE")));
+                    if (UtilValidate.isNotEmpty(productFeaturePrices)) {
+                       GenericValue productFeaturePrice = 
productFeaturePrices.get(0);
+                        if 
(UtilValidate.isNotEmpty(productFeaturePrice.get("price"))) {
+                               featureData.put("price", 
productFeaturePrice.getBigDecimal("price").toString()); 
+                               featureData.put("currencyUomId", 
productFeaturePrice.getString("currencyUomId")); 
+                        }
+                    }
+                    featureList.add(featureData);
                 }
                 if (oldType != null) {
                     // last map
                     featureTypeFeatures.add(featureList);
-                    Debug.log("=====add feature: " + oldType);
                 }       
             }
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
         }
-        Debug.log("=====total list: " + featureTypeFeatures.toString());
-
         return featureTypeFeatures;
     }
 

Modified: 
ofbiz/trunk/applications/product/webapp/catalog/product/EditProductFeatures.ftl
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/product/EditProductFeatures.ftl?rev=648922&r1=648921&r2=648922&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/product/webapp/catalog/product/EditProductFeatures.ftl 
(original)
+++ 
ofbiz/trunk/applications/product/webapp/catalog/product/EditProductFeatures.ftl 
Wed Apr 16 19:26:38 2008
@@ -46,7 +46,8 @@
                     <input type="hidden" name="productId_o_${rowCount}" 
value="${(productFeatureAndAppl.productId)?if_exists}">
                     <input type="hidden" name="productFeatureId_o_${rowCount}" 
value="${(productFeatureAndAppl.productFeatureId)?if_exists}">
                     <input type="hidden" name="fromDate_o_${rowCount}" 
value="${(productFeatureAndAppl.fromDate)?if_exists}">
-                    
<td>${(productFeatureAndAppl.productFeatureId)?if_exists}</td>
+                    <td><a 
href="<@ofbizUrl>EditFeature?productFeatureId=${(productFeatureAndAppl.productFeatureId)?if_exists}</@ofbizUrl>"
 class="buttontext">
+                       
${(productFeatureAndAppl.productFeatureId)?if_exists}</a></td>
                     
<td>${(productFeatureAndAppl.get("description",locale))?if_exists}</td>
                     
<td>${(curProductFeatureType.get("description",locale))?default((productFeatureAndAppl.productFeatureTypeId)?if_exists)}</td>
                     <td><a 
href="<@ofbizUrl>EditFeatureCategoryFeatures?productFeatureCategoryId=${(productFeatureAndAppl.productFeatureCategoryId)?if_exists}&productId=${(productFeatureAndAppl.productId)?if_exists}</@ofbizUrl>"
 class="buttontext">


Reply via email to