Thank you for fixing it.

We looked seriously into your recommendation but found out there were too much basic differences to create a tree of product types.

Regards,
Hans

On 04/05/2012 04:47 PM, Jacopo Cappellato wrote:
Hi Hans,

with this code you have broken the ability to add "bulk products" (items 
without a product id) to a purchase order; I fixed the error happening in checkout in 
rev. but please make sure that there are no other parts of the systems affected by this.

Also, as I mentioned in another review (that you ignored) to one of your 
commits, we should avoid code like:

if ("SERVICE_PRODUCT".equals(product.get("productTypeId")) || 
"AGGREGATEDSERV_CONF".equals(product.get("productTypeId"))

because it makes the system less extensible, the code less readable and instead 
use the parentTypeId to define hierarchies of product types etc...

Jacopo


On Sep 8, 2011, at 9:07 AM, [email protected] wrote:

Author: hansbak
Date: Thu Sep  8 07:07:07 2011
New Revision: 1166543

URL: http://svn.apache.org/viewvc?rev=1166543&view=rev
Log:
New product type SERVICE_PRODUCT which was discussed in the mailing list. blog 
linked to the what is new file will be added later

Modified:
    ofbiz/trunk/applications/order/data/OrderTypeData.xml
    
ofbiz/trunk/applications/order/script/org/ofbiz/order/test/ShoppingCartTests.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
    ofbiz/trunk/applications/order/testdef/ShoppingCartTests.xml
    ofbiz/trunk/applications/product/data/ProductTypeData.xml
    ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml

Modified: ofbiz/trunk/applications/order/data/OrderTypeData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/data/OrderTypeData.xml?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/data/OrderTypeData.xml (original)
+++ ofbiz/trunk/applications/order/data/OrderTypeData.xml Thu Sep  8 07:07:07 
2011
@@ -322,6 +322,7 @@ under the License.
     <ReturnItemTypeMap returnHeaderTypeId="CUSTOMER_RETURN" 
returnItemMapKey="SURCHARGE_ADJUSTMENT" returnItemTypeId="RET_SURCHARGE_ADJ"/>
     <ReturnItemTypeMap returnHeaderTypeId="CUSTOMER_RETURN" 
returnItemMapKey="ADDITIONAL_FEATURE" returnItemTypeId="RET_ADD_FEATURE_ADJ"/>
     <ReturnItemTypeMap returnHeaderTypeId="CUSTOMER_RETURN" 
returnItemMapKey="WARRANTY_ADJUSTMENT" returnItemTypeId="RET_WARRANTY_ADJ"/>
+<ReturnItemTypeMap returnHeaderTypeId="CUSTOMER_RETURN" returnItemMapKey="SERVICE_PRODUCT" 
returnItemTypeId="RET_SPROD_ITEM"/>
     <ReturnItemTypeMap returnHeaderTypeId="VENDOR_RETURN" returnItemMapKey="FINISHED_GOOD" 
returnItemTypeId="RET_FPROD_ITEM"/>
     <ReturnItemTypeMap returnHeaderTypeId="VENDOR_RETURN" 
returnItemMapKey="MARKETING_PKG_AUTO" returnItemTypeId="RET_FPROD_ITEM"/>
     <ReturnItemTypeMap returnHeaderTypeId="VENDOR_RETURN" 
returnItemMapKey="MARKETING_PKG_PICK" returnItemTypeId="RET_FPROD_ITEM"/>

Modified: 
ofbiz/trunk/applications/order/script/org/ofbiz/order/test/ShoppingCartTests.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/script/org/ofbiz/order/test/ShoppingCartTests.xml?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/order/script/org/ofbiz/order/test/ShoppingCartTests.xml
 (original)
+++ 
ofbiz/trunk/applications/order/script/org/ofbiz/order/test/ShoppingCartTests.xml
 Thu Sep  8 07:07:07 2011
@@ -260,4 +260,119 @@ under the License.
         <assert><not><if-empty field="orderMap.orderId"/></not></assert>
         <check-errors/>
     </simple-method>
+
+<simple-method method-name="testCreateOrderServiceProduct" short-description="Test create an 
order using a service product" login-required="false">
+<entity-one entity-name="UserLogin" value-field="userLogin">
+<field-map field-name="userLoginId" value="DemoCustomer"/>
+</entity-one>
+
+<!-- Shopping Cart new Instance -->
+<set field="delegator" from-field="parameters.delegator" type="Object"/>
+<set field="dispatcher" from-field="parameters.dispatcher" type="Object"/>
+<set field="locale" from-field="parameters.locale" type="Object" />
+<set field="productStoreId" value="9000" type="String"/>
+<set field="currencyUom" value="USD" type="String"/>
+<set field="salesChannel" value="WEB_SALES_CHANNEL" type="String"/>
+
+<set field="partyId" value="DemoCustomer" type="String"/>
+
+<create-object class-name="org.ofbiz.order.shoppingcart.ShoppingCart" 
field="shoppingCart">
+<field field="delegator" type="org.ofbiz.entity.Delegator"/>
+<field field="productStoreId" type="String"/>
+<field field="locale" type="java.util.Locale"/>
+<field field="currencyUom" type="String"/>
+</create-object>
+
+<set field="orderType" value="SALES_ORDER" type="String"/>
+<call-object-method method-name="setOrderType" obj-field="shoppingCart">
+<field field="orderType" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setChannelType" obj-field="shoppingCart">
+<field field="salesChannel" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setProductStoreId" obj-field="shoppingCart">
+<field field="productStoreId" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setBillToCustomerPartyId" 
obj-field="shoppingCart">
+<field field="partyId" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setPlacingCustomerPartyId" 
obj-field="shoppingCart">
+<field field="partyId" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setShipToCustomerPartyId" 
obj-field="shoppingCart">
+<field field="partyId" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setEndUserCustomerPartyId" 
obj-field="shoppingCart">
+<field field="partyId" type="String"/>
+</call-object-method>
+
+<call-object-method method-name="setUserLogin" obj-field="shoppingCart">
+<field field="userLogin" type="org.ofbiz.entity.GenericValue"/>
+<field field="dispatcher" type="org.ofbiz.service.LocalDispatcher"/>
+</call-object-method>
+
+<set field="productId" value="SV-1001" type="String"/>
+<set field="prodCatalogId" value="DemoCatalog" type="String"/>
+<set field="quantity" value="1" type="BigDecimal"/>
+
+<call-object-method method-name="addOrIncreaseItem" obj-field="shoppingCart">
+<field field="productId" type="String"/>
+<field field="selectedAmount" type="BigDecimal"/>
+<field field="quantity" type="BigDecimal"/>
+<field field="reservStart" type="Timestamp"/>
+<field field="reservLength" type="BigDecimal"/>
+<field field="reservPersons" type="BigDecimal"/>
+<field field="shipBeforeDate" type="Timestamp"/>
+<field field="shipAfterDate" type="Timestamp"/>
+<field field="features" type="Map"/>
+<field field="attributes" type="Map"/>
+<field field="prodCatalogId" type="String"/>
+<field field="configWrapper" 
type="org.ofbiz.product.config.ProductConfigWrapper"/>
+<field field="itemType" type="String"/>
+<field field="itemGroupNumber" type="String"/>
+<field field="parentProductId" type="String"/>
+<field field="dispatcher" type="org.ofbiz.service.LocalDispatcher"/>
+</call-object-method>
+
+<call-object-method method-name="setDefaultCheckoutOptions" 
obj-field="shoppingCart">
+<field field="dispatcher" type="org.ofbiz.service.LocalDispatcher"/>
+</call-object-method>
+
+<create-object class-name="org.ofbiz.order.shoppingcart.CheckOutHelper" 
field="checkOutHelper">
+<field field="dispatcher" type="org.ofbiz.service.LocalDispatcher"/>
+<field field="delegator" type="org.ofbiz.entity.Delegator"/>
+<field field="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart"/>
+</create-object>
+
+<call-object-method method-name="createOrder" obj-field="checkOutHelper" 
ret-field="orderCreateResult">
+<field field="userLogin" type="org.ofbiz.entity.GenericValue"/>
+</call-object-method>
+<set field="orderId" from-field="orderCreateResult.orderId" type="String"/>
+<if-not-empty field="orderId">
+<call-class-method method-name="approveOrder" 
class-name="org.ofbiz.order.order.OrderChangeHelper" ret-field="approved">
+<field field="dispatcher" type="org.ofbiz.service.LocalDispatcher"/>
+<field field="userLogin" type="org.ofbiz.entity.GenericValue"/>
+<field field="orderId" type="String"/>
+</call-class-method>
+<log level="info" message="======== Test order with id: [${orderId}] has been 
approved: [${approved}]========"/>
+
+<entity-one entity-name="UserLogin" value-field="systemUserLogin">
+<field-map field-name="userLoginId" value="system"/>
+</entity-one>
+
+<set field="quickShipEntireOrderMap.orderId" from-field="orderId"/>
+<set field="quickShipEntireOrderMap.userLogin" from-field="systemUserLogin"/>
+<call-service service-name="quickShipEntireOrder" 
in-map-name="quickShipEntireOrderMap"/>
+<log level="info" message="========Test order with id: [${orderId}] has been 
shipped"/>
+</if-not-empty>
+
+<assert><not><if-empty field="orderId"/></not></assert>
+<check-errors/>
+</simple-method>
</simple-methods>

Modified: 
ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java 
(original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java 
Thu Sep  8 07:07:07 2011
@@ -1130,8 +1130,63 @@ public class OrderServices {
             // store line items, etc so that they will be there for the 
foreign key checks
             delegator.storeAll(toBeStored);

-            // START inventory reservation
             List<String>  resErrorMessages = new LinkedList<String>();
+
+            // add a product service to inventory
+            if (UtilValidate.isNotEmpty(orderItems)) {
+                for (GenericValue orderItem: orderItems) {
+                    String productId = (String) orderItem.get("productId");
+                    GenericValue product = delegator.getRelatedOne("Product", 
orderItem);
+
+                    if("SERVICE_PRODUCT".equals(product.get("productTypeId"))){
+                        String inventoryFacilityId = null;
+                        if 
("Y".equals(productStore.getString("oneInventoryFacility"))) {
+                            inventoryFacilityId = 
productStore.getString("inventoryFacilityId");
+
+                            if (UtilValidate.isEmpty(inventoryFacilityId)) {
+                                Debug.logWarning("ProductStore with id " + 
productStoreId + " has Y for oneInventoryFacility but inventoryFacilityId is empty, returning 
false for inventory check", module);
+                            }
+                        } else {
+                            List<GenericValue>  productFacilities = null;
+                            GenericValue productFacility = null;
+
+                            try {
+                                productFacilities = 
delegator.getRelatedCache("ProductFacility", product);
+                            } catch (GenericEntityException e) {
+                                Debug.logWarning(e, "Error invoking getRelatedCache 
in isCatalogInventoryAvailable", module);
+                            }
+
+                            if (UtilValidate.isNotEmpty(productFacilities)) {
+                                productFacility = 
EntityUtil.getFirst(productFacilities);
+                                inventoryFacilityId = (String) 
productFacility.get("facilityId");
+                            }
+                        }
+
+                        Map<String, Object>  ripCtx = FastMap.newInstance();
+                        if (UtilValidate.isNotEmpty(inventoryFacilityId)&&  
UtilValidate.isNotEmpty(productId)&&  
orderItem.getBigDecimal("quantity").compareTo(BigDecimal.ZERO)>  0) {
+                            // do something tricky here: run as the "system" 
user
+                            GenericValue permUserLogin = 
delegator.findByPrimaryKeyCache("UserLogin", UtilMisc.toMap("userLoginId", 
"system"));
+                            ripCtx.put("productId", productId);
+                            ripCtx.put("facilityId", inventoryFacilityId);
+                            ripCtx.put("inventoryItemTypeId", 
"NON_SERIAL_INV_ITEM");
+                            ripCtx.put("quantityAccepted", 
orderItem.getBigDecimal("quantity"));
+                            ripCtx.put("quantityRejected", 0.0);
+                            ripCtx.put("userLogin", permUserLogin);
+                            try {
+                                Map<String, Object>  ripResult = 
dispatcher.runSync("receiveInventoryProduct", ripCtx);
+                                if (ServiceUtil.isError(ripResult)) {
+                                    String errMsg = 
ServiceUtil.getErrorMessage(ripResult);
+                                    resErrorMessages.addAll((Collection<? extends String>) UtilMisc.<String, 
String>toMap("reasonCode", "ReceiveInventoryServiceError", "description", errMsg));
+                                }
+                            } catch (GenericServiceException e) {
+                                Debug.logWarning(e, "Error invoking 
receiveInventoryProduct service in createOrder", module);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // START inventory reservation
             try {
                 reserveInventory(delegator, dispatcher, userLogin, locale, 
orderItemShipGroupInfo, dropShipGroupIds, itemValuesBySeqId,
                         orderTypeId, productStoreId, resErrorMessages);

Modified: ofbiz/trunk/applications/order/testdef/ShoppingCartTests.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/testdef/ShoppingCartTests.xml?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/testdef/ShoppingCartTests.xml (original)
+++ ofbiz/trunk/applications/order/testdef/ShoppingCartTests.xml Thu Sep  8 
07:07:07 2011
@@ -25,4 +25,7 @@ under the License.
     <test-case case-name="shoppingCart-test">
         <simple-method-test 
location="component://order/script/org/ofbiz/order/test/ShoppingCartTests.xml" 
name="testCreateShoppingCart"/>
     </test-case>
+<test-case case-name="productServiceOrder-test">
+<simple-method-test 
location="component://order/script/org/ofbiz/order/test/ShoppingCartTests.xml" 
name="testCreateOrderServiceProduct"/>
+</test-case>
</test-suite>

Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Thu Sep  8 
07:07:07 2011
@@ -498,6 +498,7 @@ under the License.
     <ProductType description="Marketing Package: Pick Assembly" isPhysical="Y" isDigital="N" 
hasTable="N" parentTypeId="MARKETING_PKG" productTypeId="MARKETING_PKG_PICK"/>
     <ProductType description="Work In Process" isPhysical="Y" isDigital="N" hasTable="N" 
parentTypeId="GOOD" productTypeId="WIP"/>
     <ProductType description="Configurable Good Configuration" isPhysical="Y" isDigital="N" 
hasTable="N" parentTypeId="AGGREGATED" productTypeId="AGGREGATED_CONF"/>
+<ProductType description="Service a product which is received to- and shipped from inventory" isPhysical="Y" 
isDigital="N" hasTable="N" parentTypeId="" productTypeId="SERVICE_PRODUCT"/>

     <EnumerationType description="Product Requirement Method" enumTypeId="PROD_REQ_METHOD" 
hasTable="N" parentTypeId=""/>
     <!-- NONE: no requirement is created (default) -->

Modified: ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml?rev=1166543&r1=1166542&r2=1166543&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml Thu Sep  8 
07:07:07 2011
@@ -710,7 +710,7 @@ under the License.
     <ElectronicText dataResourceId="SERV-001-ALT" textData="service-product"/>
     <ElectronicText dataResourceId="DRSERV-001-ALTEN" textData="services"/>
     <ElectronicText dataResourceId="DRSERV-001-ALTEN" 
textData="service-product"/>
-
+
     <Content contentId="SERV-001-ALT" contentTypeId="DOCUMENT" 
dataResourceId="SERV-001-ALT" localeString="en"/>
     <Content contentId="CSERV-001-ALTEN" contentTypeId="DOCUMENT" 
dataResourceId="DRSERV-001-ALTEN" localeString="en_US"/>
     <Content contentId="SV-1000-ALT" contentTypeId="DOCUMENT" dataResourceId="SV-1000-ALT" 
localeString="en"/>
@@ -720,6 +720,22 @@ under the License.
     <ProductCategoryContent productCategoryId="SERV-001" contentId="SERV-001-ALT" 
prodCatContentTypeId="ALTERNATIVE_URL" fromDate="2001-05-13 12:00:00.0"/>
     <ProductContent productId="SV-1000" contentId="SV-1000-ALT" 
productContentTypeId="ALTERNATIVE_URL" fromDate="2001-05-13 12:00:00.0"/>

+<!-- test for service product type which is received to- and shipped from 
inventory-->
+<Product productId="SV-1001" productTypeId="SERVICE_PRODUCT" primaryProductCategoryId="SERV-001" productName="Laundry service" internalName="Service type product which is received to- 
and shipped from inventory" description="Service type product which is received to- and shipped from inventory for demonstration use" taxable="Y" chargeShipping="N" autoCreateKeywords="Y" 
isVirtual="N" isVariant="N" createdDate="2008-12-02 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2008-12-02 12:00:00.0" lastModifiedByUserLogin="admin"/>
+<ProductPrice productId="SV-1001" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" 
productStoreGroupId="_NA_" fromDate="2011-08-02 12:00:00.0" price="10.99" createdDate="2011-08-02 12:00:00.0" 
createdByUserLogin="admin"/>
+<ProductCategoryMember productCategoryId="SERV-001" productId="SV-1001" 
fromDate="2011-08-02 12:00:00.0"/>
+<ProductCategoryMember productCategoryId="CATALOG1_SEARCH" productId="SV-1001" 
fromDate="2011-08-02 12:00:00.0"/>
+<DataResource dataResourceId="SV-1001-ALT" dataResourceTypeId="LINK" 
objectInfo="lanudry-service-SV-1001-p"/>
+<DataResource dataResourceTypeId="ELECTRONIC_TEXT" dataResourceId="SV-1001-ALT" 
localeString="en"/>
+<DataResource dataResourceTypeId="ELECTRONIC_TEXT" dataResourceId="DRSV-1001-ALTEN" 
localeString="en_US"/>
+<ElectronicText dataResourceId="SV-1001-ALT" textData="service-product"/>
+<ElectronicText dataResourceId="DRSV-1001-ALTEN" textData="service-product"/>
+
+<Content contentId="SV-1001-ALT" contentTypeId="DOCUMENT" dataResourceId="SV-1001-ALT" 
localeString="en"/>
+<Content contentId="CSV-1001-ALTEN" contentTypeId="DOCUMENT" 
dataResourceId="DRSV-1001-ALTEN" localeString="en_US"/>
+<ContentAssoc contentId="SV-1001-ALT" contentIdTo="CSV-1001-ALTEN" 
contentAssocTypeId="ALTERNATE_LOCALE" fromDate="2011-08-02 12:00:00.0"/>
+<ProductContent productId="SV-1001" contentId="SV-1001-ALT" 
productContentTypeId="ALTERNATIVE_URL" fromDate="2011-08-02 12:00:00.0"/>
+
     <ProductFeatureCategory productFeatureCategoryId="8000" description="License 
Features"/>
     <ProductFeatureCategoryAppl productFeatureCategoryId="8000" 
productCategoryId="CATALOG1_SEARCH" fromDate="2001-05-13 12:00:00.0"/>

@@ -975,6 +991,7 @@ under the License.
     <ProductFacility productId="GZ-1000" facilityId="WebStoreWarehouse" minimumStock="2" 
reorderQuantity="10" daysToShip="1"/>
     <ProductFacility productId="GZ-1001" facilityId="WebStoreWarehouse" minimumStock="2" 
reorderQuantity="10" daysToShip="1"/>
     <ProductFacility productId="GZ-1004" facilityId="WebStoreWarehouse" minimumStock="2" 
reorderQuantity="10" daysToShip="1"/>
+<ProductFacility productId="SV-1001" facilityId="WebStoreWarehouse" minimumStock="2" 
reorderQuantity="10" daysToShip="1"/>

     <ProductFacilityLocation productId="GZ-2644" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLUL01"/>
     <ProductFacilityLocation productId="GZ-2644" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLLL01" minimumStock="2" moveQuantity="5"/>
@@ -987,6 +1004,7 @@ under the License.
     <ProductFacilityLocation productId="GZ-1000" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLUL01" minimumStock="5" moveQuantity="20"/>
     <ProductFacilityLocation productId="GZ-1001" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLLL02" minimumStock="5" moveQuantity="20"/>
     <ProductFacilityLocation productId="GZ-1004" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLLL04" minimumStock="5" moveQuantity="20"/>
+<ProductFacilityLocation productId="SV-1001" facilityId="WebStoreWarehouse" 
locationSeqId="TLTLTLLL04" minimumStock="5" moveQuantity="20"/>

     <!-- some default inventory quantities, things are a bit underutilized 
without these... -->
     <InventoryItem facilityId="WebStoreWarehouse" locationSeqId="TLTLTLUL01" 
datetimeReceived="2008-08-01 08:00:00.000"



Reply via email to