svn commit: r648922 - in /ofbiz/trunk/applications: ecommerce/data/ order/src/org/ofbiz/order/shoppingcart/ order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ order/webapp/ordermgr/entry/catalog/ product/src/org/ofbiz/product/product/ product/webapp/...

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

svn commit: r648922 - in /ofbiz/trunk/applications: ecommerce/data/ order/src/org/ofbiz/order/shoppingcart/ order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ order/webapp/ordermgr/entry/catalog/ product/src/org/ofbiz/product/product/ product/webapp/...

hansbak-2
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">