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> <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> + + </div> + <div id="addCart2" style="display:block;> + <span style="white-space: nowrap;"><b>${uiLabelMap.CommonQuantity}:</b></span> + <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> </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"> |
Free forum by Nabble | Edit this page |