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

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

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

hansbak-2
Author: hansbak
Date: Wed Dec  1 09:26:47 2010
New Revision: 1040908

URL: http://svn.apache.org/viewvc?rev=1040908&view=rev
Log:
allow single pieces and boxes with a numkber of pieces share the same inventory location but can however be sold at optionally different prices. More explanation will be given in the new feature list of december 2010. Contribution of tukkata.

Added:
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl
Modified:
    ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
    ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl
    ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml
    ofbiz/trunk/applications/product/data/ProductTypeData.xml
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductWorker.java
    ofbiz/trunk/framework/common/data/UnitData.xml
    ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl

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=1040908&r1=1040907&r2=1040908&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 Dec  1 09:26:47 2010
@@ -549,6 +549,21 @@ public class ShoppingCartEvents {
                 Debug.logError(e.getMessage(), module);
             }
         }
+        
+        // check for alternative packing
+        if(ProductWorker.isAlternativePacking(delegator, productId , parentProductId)){
+            GenericValue parentProduct = null;
+            try {
+                parentProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", parentProductId));
+            } catch (GenericEntityException e) {
+                Debug.logError(e, "Error getting parent product", module);
+            }
+            BigDecimal piecesIncluded = BigDecimal.ZERO;
+            if(parentProduct != null){
+                piecesIncluded = new BigDecimal(parentProduct.getLong("piecesIncluded"));
+                quantity = quantity.multiply(piecesIncluded);
+            }
+        }
 
         // Translate the parameters and add to the cart
         result = cartHelper.addToCart(catalogId, shoppingListId, shoppingListItemSeqId, productId, productCategoryId,

Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java Wed Dec  1 09:26:47 2010
@@ -20,6 +20,7 @@ package org.ofbiz.order.shoppingcart;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
+import java.math.RoundingMode;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1112,9 +1113,21 @@ public class ShoppingCartItem implements
                 if (partyId != null) {
                     priceContext.put("partyId", partyId);
                 }
+                // check alternative packaging
+                boolean isAlternativePacking = ProductWorker.isAlternativePacking(delegator, this.productId , this.getParentProductId());
+                BigDecimal pieces = BigDecimal.ONE;
+                if(isAlternativePacking){
+                    GenericValue originalProduct = this.getParentProduct();
+                    if (originalProduct != null) pieces = new BigDecimal(originalProduct.getLong("piecesIncluded"));
+                    priceContext.put("product", originalProduct);
+                    this._parentProduct = null;
+                }else{
+                    priceContext.put("product", this.getProduct());
+                }
+                
                 priceContext.put("quantity", this.getQuantity());
                 priceContext.put("amount", this.getSelectedAmount());
-                priceContext.put("product", this.getProduct());
+                
                 if (cart.getOrderType().equals("PURCHASE_ORDER")) {
                     Map priceResult = dispatcher.runSync("calculatePurchasePrice", priceContext);
                     if (ServiceUtil.isError(priceResult)) {
@@ -1124,8 +1137,13 @@ public class ShoppingCartItem implements
                     if (!validPriceFound.booleanValue()) {
                         throw new CartItemModifyException("Could not find a valid price for the product with ID [" + this.getProductId() + "] and supplier with ID [" + partyId + "], not adding to cart.");
                     }
-
-                    this.setBasePrice(((BigDecimal) priceResult.get("price")));
+                    
+                    if(isAlternativePacking){
+                        this.setBasePrice(((BigDecimal) priceResult.get("price")).divide(pieces, RoundingMode.HALF_UP));
+                    }else{
+                        this.setBasePrice(((BigDecimal) priceResult.get("price")));
+                    }
+                    
                     this.setDisplayPrice(this.basePrice);
                     this.orderItemPriceInfos = (List) priceResult.get("orderItemPriceInfos");
                 } else {
@@ -1169,21 +1187,41 @@ public class ShoppingCartItem implements
                     if (Boolean.FALSE.equals(validPriceFound)) {
                         throw new CartItemModifyException("Could not find a valid price for the product with ID [" + this.getProductId() + "], not adding to cart.");
                     }
+                    
+                    //set alternative product price
+                    if(isAlternativePacking){
+                        int decimals = 2;
+                        if (priceResult.get("listPrice") != null) {
+                            this.listPrice = ((BigDecimal) priceResult.get("listPrice")).divide(pieces, decimals, RoundingMode.HALF_UP);
+                        }
 
-                    if (priceResult.get("listPrice") != null) {
-                        this.listPrice = ((BigDecimal) priceResult.get("listPrice"));
-                    }
+                        if (priceResult.get("basePrice") != null) {
+                            this.setBasePrice(((BigDecimal) priceResult.get("basePrice")).divide(pieces, decimals, RoundingMode.HALF_UP));
+                        }
 
-                    if (priceResult.get("basePrice") != null) {
-                        this.setBasePrice(((BigDecimal) priceResult.get("basePrice")));
-                    }
+                        if (priceResult.get("price") != null) {
+                            this.setDisplayPrice(((BigDecimal) priceResult.get("price")).divide(pieces, decimals, RoundingMode.HALF_UP));
+                        }
 
-                    if (priceResult.get("price") != null) {
-                        this.setDisplayPrice(((BigDecimal) priceResult.get("price")));
-                    }
+                        if (priceResult.get("specialPromoPrice") != null) {
+                            this.setSpecialPromoPrice(((BigDecimal) priceResult.get("specialPromoPrice")).divide(pieces, decimals, RoundingMode.HALF_UP));
+                        }
+                    }else{
+                        if (priceResult.get("listPrice") != null) {
+                            this.listPrice = ((BigDecimal) priceResult.get("listPrice"));
+                        }
 
-                    this.setSpecialPromoPrice((BigDecimal) priceResult.get("specialPromoPrice"));
+                        if (priceResult.get("basePrice") != null) {
+                            this.setBasePrice(((BigDecimal) priceResult.get("basePrice")));
+                        }
 
+                        if (priceResult.get("price") != null) {
+                            this.setDisplayPrice(((BigDecimal) priceResult.get("price")));
+                        }
+                        
+                        this.setSpecialPromoPrice((BigDecimal) priceResult.get("specialPromoPrice"));
+                    }
+                    
                     this.orderItemPriceInfos = (List) priceResult.get("orderItemPriceInfos");
 
                     // If product is configurable, the price is taken from the configWrapper.

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy Wed Dec  1 09:26:47 2010
@@ -26,6 +26,7 @@ import org.ofbiz.product.catalog.*;
 import org.ofbiz.product.category.*;
 import org.ofbiz.product.product.ProductWorker;
 import org.ofbiz.product.product.ProductContentWrapper;
+import org.ofbiz.entity.util.EntityUtil;
 
 contentPathPrefix = CatalogWorker.getContentPathPrefix(request);
 catalogName = CatalogWorker.getCatalogName(request);
@@ -54,6 +55,16 @@ if (productId) {
 if (productId) {
     product = delegator.findByPrimaryKeyCache("Product", [productId : productId]);
 
+    // first make sure this isn't a virtual-variant that has an associated virtual product, if it does show that instead of the variant
+    if("Y".equals(product.isVirtual) && "Y".equals(product.isVariant)){
+        virtualVariantProductAssocs = delegator.findByAndCache("ProductAssoc", ["productId": productId, "productAssocTypeId": "ALTERNATIVE_PACKAGE"], ["-fromDate"]);
+        virtualVariantProductAssocs = EntityUtil.filterByDate(virtualVariantProductAssocs);
+        if (virtualVariantProductAssocs) {
+            productAssoc = EntityUtil.getFirst(virtualVariantProductAssocs);
+            product = productAssoc.getRelatedOneCache("AssocProduct");
+        }
+    }
+    
     // first make sure this isn't a variant that has an associated virtual product, if it does show that instead of the variant
     virtualProductId = ProductWorker.getVariantVirtualId(product);
     if (virtualProductId) {

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy Wed Dec  1 09:26:47 2010
@@ -417,6 +417,50 @@ if (product) {
                             if (variantPriceMap && variantPriceMap.basePrice) {
                                 variantPriceJS.append("  if (sku == \"" + variant.productId + "\") return \"" + numberFormat.format(variantPriceMap.basePrice) + "\"; ");
                             }
+                            
+                            // make a list of virtual variants sku with requireAmount
+                            virtualVariantsRes = dispatcher.runSync("getAssociatedProducts", [productIdTo : variant.productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+                            virtualVariants = virtualVariantsRes.assocProducts;
+                            
+                            if(virtualVariants){
+                                virtualVariants.each { virtualAssoc ->
+                                    virtual = virtualAssoc.getRelatedOne("MainProduct");
+                                    // Get price from a virtual product
+                                    priceContext.product = virtual;
+                                    if (cart.isSalesOrder()) {
+                                        // sales order: run the "calculateProductPrice" service
+                                        virtualPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                                        BigDecimal calculatedPrice = (BigDecimal)virtualPriceMap.get("price");
+                                        // Get the minimum quantity for variants if MINIMUM_ORDER_PRICE is set for variants.
+                                        virtualPriceMap.put("minimumQuantity", ShoppingCart.getMinimumOrderQuantity(delegator, calculatedPrice, virtual.get("productId")));
+                                        Iterator treeMapIter = variantTree.entrySet().iterator();
+                                        while (treeMapIter.hasNext()) {
+                                            Map.Entry entry = treeMapIter.next();
+                                            if (entry.getValue() instanceof  Map) {
+                                                Iterator entryIter = entry.getValue().entrySet().iterator();
+                                                while (entryIter.hasNext()) {
+                                                    Map.Entry innerentry = entryIter.next();
+                                                    if (virtual.get("productId").equals(innerentry.getValue().get(0))) {
+                                                        virtualPriceMap.put("variantName", innerentry.getKey());
+                                                        virtualPriceMap.put("secondVariantName", entry.getKey());
+                                                        break;
+                                                    }
+                                                }
+                                            } else if (UtilValidate.isNotEmpty(entry.getValue())) {
+                                                if (virtual.get("productId").equals(entry.getValue().get(0))) {
+                                                    virtualPriceMap.put("variantName", entry.getKey());
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                        variantPriceList.add(virtualPriceMap);
+                                    } else {
+                                        virtualPriceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+                                    }
+                                    variantPriceJS.append("  if (sku == \"" + virtual.productId + "\") return \"" + numberFormat.format(virtualPriceMap.basePrice) + "\"; ");
+                                }
+                                
+                            }
                         }
                         amt.append(" } ");
                         variantPriceJS.append(" } ");

Added: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy?rev=1040908&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy Wed Dec  1 09:26:47 2010
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.ofbiz.base.util.*;
+
+product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", parameters.productId));
+if (product) {
+    productVirtualVariants = delegator.findByAndCache("ProductAssoc", UtilMisc.toMap("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE"));
+    if(productVirtualVariants){
+        def mainProducts = [];
+        productVirtualVariants.each { virtualVariantKey ->
+            mainProductMap = [:];
+            mainProduct = virtualVariantKey.getRelatedOneCache("MainProduct");
+            quantityUom = mainProduct.getRelatedOneCache("QuantityUom");
+            mainProductMap.productId = mainProduct.productId;
+            mainProductMap.piecesIncluded = mainProduct.piecesIncluded;
+            mainProductMap.uomDesc = quantityUom.description;
+            mainProducts.add(mainProductMap);
+        }
+        context.mainProducts = mainProducts;
+    }
+    context.product = product;
+}
\ No newline at end of file

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml Wed Dec  1 09:26:47 2010
@@ -1725,7 +1725,11 @@ under the License.
         <response name="error" type="view" value="advancedsearch"/>
     </request-map>
 
-
+    <request-map uri="ProductUomDropDownOnly">
+        <security auth="true" https="true"/>
+        <response name="success" type="view" value="ProductUomDropDownOnly" save-last-view="true"/>
+    </request-map>
+    
     <!--
         These are just examples of reports developed using JasperReport and not really
         useful reports. In order to run them you'll have to follow the notes in the
@@ -1920,5 +1924,6 @@ under the License.
     <view-map name="SendConfirmationMail" type="screen" page="component://order/widget/ordermgr/OrderViewScreens.xml#SendOrderConfirmation"/>
     <view-map name="SendCompletionMail" type="screen" page="component://order/widget/ordermgr/OrderViewScreens.xml#SendOrderCompletion"/>
     <view-map name="ReturnHistory" type="screen" page="component://order/widget/ordermgr/OrderReturnScreens.xml#OrderReturnHistory"/>
+    <view-map name="ProductUomDropDownOnly" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#ProductUomDropDownOnly"/>
     <!-- end of view mappings -->
 </site-conf>

Added: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl?rev=1040908&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl Wed Dec  1 09:26:47 2010
@@ -0,0 +1,26 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<#if product?exists && mainProducts?exists>
+    <select name="parentProductId" onchange="javascript:displayProductVirtualVariantId(this.value);">
+        <option value="">Select Unit Of Measure</option>
+        <#list mainProducts as mainProduct>
+            <option value="${mainProduct.productId}">${mainProduct.uomDesc} : ${mainProduct.piecesIncluded}</option>
+        </#list>
+    </select>
+</#if>
\ No newline at end of file

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=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productdetail.ftl Wed Dec  1 09:26:47 2010
@@ -171,6 +171,9 @@ ${virtualJavaScript?if_exists}
             // using the selected index locate the sku
             var sku = document.forms["addform"].elements[name].options[indexSelected].value;
 
+            // display alternative packaging dropdown
+            ajaxUpdateArea("product_uom", "<@ofbizUrl>ProductUomDropDownOnly</@ofbizUrl>", "productId=" + sku);
+
             // set the product ID
             setAddProductId(sku);
 
@@ -259,6 +262,18 @@ ${virtualJavaScript?if_exists}
             block2.style.display = "none";
         }
     </#if>
+    
+    function displayProductVirtualVariantId(variantId) {
+        document.addform.product_id.value = variantId;
+        var elem = document.getElementById('product_id_display');
+        var txt = document.createTextNode(variantId);
+        if(elem.hasChildNodes()) {
+            elem.replaceChild(txt, elem.firstChild);
+        } else {
+            elem.appendChild(txt);
+        }
+        setVariantPrice(variantId);
+    }
  //-->
  </script>
 
@@ -454,6 +469,7 @@ ${virtualJavaScript?if_exists}
                 </select>
               </div>
             </#list>
+            <span id="product_uom"></span>
             <input type="hidden" name="product_id" value="${product.productId}"/>
             <input type="hidden" name="add_product_id" value="NULL"/>
             <div>

Modified: ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml (original)
+++ ofbiz/trunk/applications/order/widget/ordermgr/OrderEntryCatalogScreens.xml Wed Dec  1 09:26:47 2010
@@ -291,4 +291,24 @@ under the License.
             </widgets>
         </section>
     </screen>
+    
+    <screen name="ProductUomDropDownOnly">
+        <section>
+            <actions>
+                <script location="component://order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy"/>
+            </actions>
+            <widgets>
+                <section>
+                    <condition>
+                        <not><if-empty field="product"/></not>
+                    </condition>
+                    <widgets>
+                        <platform-specific>
+                            <html><html-template location="component://order/webapp/ordermgr/entry/catalog/ProductUomDropDownOnly.ftl"/></html>
+                        </platform-specific>
+                    </widgets>
+                </section>
+            </widgets>
+        </section>
+    </screen>
 </screens>

Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Wed Dec  1 09:26:47 2010
@@ -195,6 +195,7 @@ under the License.
     <ProductAssocType description="Engineering Bill of Materials" hasTable="N" parentTypeId="PRODUCT_COMPONENT" productAssocTypeId="ENGINEER_COMPONENT"/>
     <ProductAssocType description="Product Manufactured As" hasTable="N" parentTypeId="" productAssocTypeId="PRODUCT_MANUFACTURED"/>
     <ProductAssocType description="Configurable product instance" hasTable="N" parentTypeId="" productAssocTypeId="PRODUCT_CONF"/>
+    <ProductAssocType description="Alternative Packaging" hasTable="N" parentTypeId="" productAssocTypeId="ALTERNATIVE_PACKAGE"/>
 
     <ProductCategoryType description="Catalog" hasTable="N" parentTypeId="" productCategoryTypeId="CATALOG_CATEGORY"/>
     <ProductCategoryType description="Industry" hasTable="N" parentTypeId="" productCategoryTypeId="INDUSTRY_CATEGORY"/>

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=1040908&r1=1040907&r2=1040908&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 Dec  1 09:26:47 2010
@@ -1124,4 +1124,18 @@ nextProd:
 
         return variantProductId;
     }
+    
+    public static boolean isAlternativePacking(Delegator delegator, String productId, String originalVirtualProductId) {
+        boolean isAlternativePacking = false;
+        if(productId != null && originalVirtualProductId != null){
+            List<GenericValue> alternativePackingProds = null;
+            try {
+                alternativePackingProds = delegator.findByAndCache("ProductAssoc", UtilMisc.toMap("productId", originalVirtualProductId , "productIdTo", productId, "productAssocTypeId", "ALTERNATIVE_PACKAGE"));
+                if(UtilValidate.isNotEmpty(alternativePackingProds)) isAlternativePacking = true;
+            } catch (GenericEntityException e) {
+                Debug.logWarning(e, "Could not found alternative product: " + e.getMessage(), module);
+            }
+        }
+        return isAlternativePacking;
+    }
 }

Modified: ofbiz/trunk/framework/common/data/UnitData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/data/UnitData.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/data/UnitData.xml (original)
+++ ofbiz/trunk/framework/common/data/UnitData.xml Wed Dec  1 09:26:47 2010
@@ -315,4 +315,6 @@ under the License.
 
     <Uom abbreviation="ea" description="Each" uomId="OTH_ea" uomTypeId="OTHER_MEASURE"/>
     <Uom abbreviation="pp" description="Per Person" uomId="OTH_pp" uomTypeId="OTHER_MEASURE"/>
+    <Uom abbreviation="bx" description="Box" uomId="OTH_box" uomTypeId="OTHER_MEASURE"/>
+    <Uom abbreviation="pk" description="Package" uomId="OTH_pk" uomTypeId="OTHER_MEASURE"/>
 </entity-engine-xml>

Modified: ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml Wed Dec  1 09:26:47 2010
@@ -967,4 +967,33 @@ under the License.
     <ProductFeature productFeatureId="EC_TANKER" description="Tanker" productFeatureCategoryId="1002" productFeatureTypeId="EQUIP_CLASS"/>
     <ProductFeature productFeatureId="EC_REEL_STAND" description="Reel Stand" productFeatureCategoryId="1002" productFeatureTypeId="EQUIP_CLASS"/>
 
+    <!-- Virtual-Variant Demo Product -->
+    <Product productId="WG-9943-B3-BX2" 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="Y" isVariant="Y" piecesIncluded="2" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-B3-BX5" 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="Y" isVariant="Y" piecesIncluded="5" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-B4-BX2" 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="Y" isVariant="Y" piecesIncluded="2" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-B4-BX5" 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="Y" isVariant="Y" piecesIncluded="5" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-S3-BX2" 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="Y" isVariant="Y" piecesIncluded="2" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-S3-BX5" 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="Y" isVariant="Y" piecesIncluded="5" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-S4-BX2" 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="Y" isVariant="Y" piecesIncluded="2" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    <Product productId="WG-9943-S4-BX5" 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="Y" isVariant="Y" piecesIncluded="5" quantityUomId="OTH_box" virtualVariantMethodEnum="VV_VARIANTTREE"/>
+    
+    <!-- Association between the alternative product and the variant product -->
+    <ProductAssoc productId="WG-9943-B3-BX2" productIdTo="WG-9943-B3" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-B3-BX5" productIdTo="WG-9943-B3" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-B4-BX2" productIdTo="WG-9943-B4" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-B4-BX5" productIdTo="WG-9943-B4" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-S3-BX2" productIdTo="WG-9943-S3" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-S3-BX5" productIdTo="WG-9943-S3" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-S4-BX2" productIdTo="WG-9943-S4" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    <ProductAssoc productId="WG-9943-S4-BX5" productIdTo="WG-9943-S4" productAssocTypeId="ALTERNATIVE_PACKAGE" fromDate="2000-01-01 00:00:00.0"/>
+    
+    <ProductPrice productId="WG-9943-B3-BX2" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="800.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-B3-BX5" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="2000.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-B4-BX2" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="800.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-B4-BX5" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="2000.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-S3-BX2" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="800.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-S3-BX5" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="2000.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-S4-BX2" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="800.0" createdDate="2000-01-01 00:00:00.0"/>
+    <ProductPrice productId="WG-9943-S4-BX5" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2000-01-01 00:00:00.0" price="2000.0" createdDate="2000-01-01 00:00:00.0"/>
+    
 </entity-engine-xml>

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml Wed Dec  1 09:26:47 2010
@@ -1902,6 +1902,10 @@ under the License.
         <response name="success" type="view" value="compareProducts" save-last-view="true"/>
     </request-map>
     
+    <request-map uri="ProductUomDropDownOnly">
+        <security auth="false" https="false"/>
+        <response name="success" type="view" value="ProductUomDropDownOnly" save-last-view="true"/>
+    </request-map>
     <!-- End of Request Mappings -->
 
     <!-- View Mappings -->
@@ -2044,5 +2048,8 @@ under the License.
     <view-map name="redirectToGoogleCheckout" type="screen" page="component://googlecheckout/widget/GoogleCheckoutScreens.xml#redirect"/>
     
     <view-map name="compareProducts" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#compareProducts"/>
+    
+    <!-- Product in the different UOM -->
+    <view-map name="ProductUomDropDownOnly" type="screen" page="component://order/widget/ordermgr/OrderEntryCatalogScreens.xml#ProductUomDropDownOnly"/>
     <!-- End of View Mappings -->
 </site-conf>

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl?rev=1040908&r1=1040907&r2=1040908&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl Wed Dec  1 09:26:47 2010
@@ -170,6 +170,9 @@ ${virtualJavaScript?if_exists}
 
             // using the selected index locate the sku
             var sku = document.forms["addform"].elements[name].options[indexSelected].value;
+            
+            // display alternative packaging dropdown
+            ajaxUpdateArea("product_uom", "<@ofbizUrl>ProductUomDropDownOnly</@ofbizUrl>", "productId=" + sku);
 
             // set the product ID
             setAddProductId(sku);
@@ -259,6 +262,18 @@ ${virtualJavaScript?if_exists}
             block2.style.display = "none";
         }
     </#if>
+    
+    function displayProductVirtualVariantId(variantId) {
+        document.addform.product_id.value = variantId;
+        var elem = document.getElementById('product_id_display');
+        var txt = document.createTextNode(variantId);
+        if(elem.hasChildNodes()) {
+            elem.replaceChild(txt, elem.firstChild);
+        } else {
+            elem.appendChild(txt);
+        }
+        setVariantPrice(variantId);
+    }
 //]]>
  </script>
 
@@ -505,6 +520,8 @@ ${virtualJavaScript?if_exists}
                 </select>
               </div>
             </#list>
+            <span id="product_uom"></span>
+            <input type="hidden" name="product_id" value="${product.productId}"/>
             <input type="hidden" name="add_product_id" value="NULL"/>
             <div>
               <strong><span id="product_id_display"> </span></strong>