You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by do...@apache.org on 2010/04/08 22:47:57 UTC

svn commit: r932108 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/shoppingcart/product/ product/data/ product/entitydef/ product/webapp/catalog/promo/

Author: doogie
Date: Thu Apr  8 20:47:56 2010
New Revision: 932108

URL: http://svn.apache.org/viewvc?rev=932108&view=rev
Log:
Add new features, the ability to have promo conditions and actions both
as services, so that installations can do whatever kind of checking and
promotions that they want, without any modifications to ofbiz.

Modified:
    ofbiz/trunk/applications/order/servicedef/services_cart.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
    ofbiz/trunk/applications/product/data/ProductTypeData.xml
    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
    ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl

Modified: ofbiz/trunk/applications/order/servicedef/services_cart.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services_cart.xml?rev=932108&r1=932107&r2=932108&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/servicedef/services_cart.xml (original)
+++ ofbiz/trunk/applications/order/servicedef/services_cart.xml Thu Apr  8 20:47:56 2010
@@ -24,6 +24,21 @@ under the License.
     <vendor>OFBiz</vendor>
     <version>1.0</version>
 
+    <service name="interfaceProductPromoCond" engine="interface" location="" invoke="">
+        <attribute name="productPromoCond" type="org.ofbiz.entity.GenericValue" mode="IN"/>
+        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
+        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
+        <attribute name="directResult" type="Boolean" mode="OUT" optional="true"/>
+        <attribute name="compareBase" type="Integer" mode="OUT" optional="true"/>
+        <attribute name="operatorEnumId" type="String" mode="OUT" optional="true"/>
+    </service>
+    <service name="interfaceProductPromoAction" engine="interface" location="" invoke="">
+        <attribute name="productPromoAction" type="org.ofbiz.entity.GenericValue" mode="IN"/>
+        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
+        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
+        <attribute name="actionResultInfo" type="org.ofbiz.order.shoppingcart.product.ProductPromoWorker.ActionResultInfo" mode="IN"/>
+        <attribute name="cartItemModifyException" type="org.ofbiz.order.shoppingcart.CartItemModifyException" mode="OUT" optional="false"/>
+    </service>
     <service name="assignItemShipGroup" engine="java" auth="false"
             location="org.ofbiz.order.shoppingcart.ShoppingCartServices" invoke="assignItemShipGroup">
         <description>Assign a ShoppingCartItem -> Quantity to a ship group</description>

Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=932108&r1=932107&r2=932108&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Thu Apr  8 20:47:56 2010
@@ -789,7 +789,28 @@ public class ProductPromoWorker {
         if (Debug.verboseOn()) Debug.logVerbose("Checking promotion condition: " + productPromoCond, module);
         Integer compareBase = null;
 
-        if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
+        if ("PPIP_SERVICE".equals(inputParamEnumId)) {
+            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoCond", productPromoCond, "shoppingCart", cart, "nowTimestamp", nowTimestamp);
+            Map<String, Object> condResult;
+            try {
+                condResult = dispatcher.runSync(condValue, serviceCtx);
+            } catch (GenericServiceException e) {
+                Debug.logError(e, "Fatal error calling promo condition check service [" + condValue + "]", module);
+                return false;
+            }
+            if (ServiceUtil.isError(condResult)) {
+                Debug.logError("Error calling calling promo condition check service [" + condValue + "]", module);
+                return false;
+            }
+            Boolean directResult = (Boolean) condResult.get("directResult");
+            if (directResult != null) {
+                return directResult.booleanValue();
+            }
+            compareBase = (Integer) condResult.get("compareBase");
+            if (condResult.containsKey("operatorEnumId")) {
+                operatorEnumId = (String) condResult.get("operatorEnumId");
+            }
+        } else if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
             // for this type of promo force the operatorEnumId = PPC_EQ, effectively ignore that setting because the comparison is implied in the code
             operatorEnumId = "PPC_EQ";
 
@@ -1208,7 +1229,25 @@ public class ProductPromoWorker {
 
         String productPromoActionEnumId = productPromoAction.getString("productPromoActionEnumId");
 
-        if ("PROMO_GWP".equals(productPromoActionEnumId)) {
+        if ("PROMO_SERVICE".equals(productPromoActionEnumId)) {
+            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoAction", productPromoAction, "shoppingCart", cart, "nowTimestamp", nowTimestamp, "actionResultInfo", actionResultInfo);
+            String serviceName = productPromoAction.getString("serviceName");
+            Map<String, Object> actionResult;
+            try {
+                actionResult = dispatcher.runSync(serviceName, serviceCtx);
+            } catch (GenericServiceException e) {
+                Debug.logError("Error calling promo action service [" + serviceName + "]", module);
+                throw new CartItemModifyException("Error calling promo action service [" + serviceName + "]");
+            }
+            if (ServiceUtil.isError(actionResult)) {
+                Debug.logError("Error calling promo action service [" + serviceName + "], result is: " + actionResult, module);
+                throw new CartItemModifyException((String) actionResult.get(ModelService.ERROR_MESSAGE));
+            }
+            CartItemModifyException cartItemModifyException = (CartItemModifyException) actionResult.get("cartItemModifyException");
+            if (cartItemModifyException != null) {
+                throw cartItemModifyException;
+            }
+        } else if ("PROMO_GWP".equals(productPromoActionEnumId)) {
             String productStoreId = cart.getProductStoreId();
 
             // the code was in there for this, so even though I don't think we want to restrict this, just adding this flag to make it easy to change; could make option dynamic, but now implied by the use limit

Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=932108&r1=932107&r2=932108&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Thu Apr  8 20:47:56 2010
@@ -371,6 +371,7 @@ under the License.
     <Enumeration description="Order sub-total X since beginning of current year" enumCode="ORST_YEAR" enumId="PPIP_ORST_YEAR" sequenceId="12" enumTypeId="PROD_PROMO_IN_PARAM"/>
     <Enumeration description="Order sub-total X last year" enumCode="ORST_LAST_YEAR" enumId="PPIP_ORST_LAST_YEAR" sequenceId="13" enumTypeId="PROD_PROMO_IN_PARAM"/>
     <Enumeration description="Shipping Total" enumCode="ORDER_SHIP_TOTAL" enumId="PPIP_ORDER_SHIPTOTAL" sequenceId="14" enumTypeId="PROD_PROMO_IN_PARAM"/>
+    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PPIP_SERVICE" sequenceId="15" enumTypeId="PROD_PROMO_IN_PARAM"/>
 
     <EnumerationType description="Product Promotion Condition" enumTypeId="PROD_PROMO_COND" hasTable="N" parentTypeId="PROD_PROMO"/>
     <!-- old style very technical ...
@@ -403,6 +404,7 @@ under the License.
     <Enumeration description="Order Amount Flat" enumCode="ORDER_AMOUNT" enumId="PROMO_ORDER_AMOUNT" sequenceId="07" enumTypeId="PROD_PROMO_ACTION"/>
     <Enumeration description="Product for [Special Promo] Price" enumCode="PROD_SPPRC" enumId="PROMO_PROD_SPPRC" sequenceId="08" enumTypeId="PROD_PROMO_ACTION"/>
     <Enumeration description="Shipping X% discount" enumCode="SHIP_CHARGE" enumId="PROMO_SHIP_CHARGE" sequenceId="09" enumTypeId="PROD_PROMO_ACTION"/>
+    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PROMO_SERVICE" sequenceId="10" enumTypeId="PROD_PROMO_ACTION"/>
 
     <EnumerationType description="Product Rating Field Type" enumTypeId="PROD_RATING_TYPE" hasTable="N" parentTypeId=""/>
     <Enumeration description="Min Rating" enumCode="MIN" enumId="PRDR_MIN" sequenceId="01" enumTypeId="PROD_RATING_TYPE"/>

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=932108&r1=932107&r2=932108&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Thu Apr  8 20:47:56 2010
@@ -3385,6 +3385,7 @@ under the License.
       <field name="productPromoActionSeqId" type="id-ne"></field>
       <field name="productPromoActionEnumId" type="id-ne"></field>
       <field name="orderAdjustmentTypeId" type="id"></field>
+      <field name="serviceName" type="long-varchar"></field>
       <field name="quantity" type="fixed-point"></field>
       <field name="amount" type="fixed-point"></field>
       <field name="productId" type="id"></field>

Modified: ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl?rev=932108&r1=932107&r2=932108&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl Thu Apr  8 20:47:56 2010
@@ -279,6 +279,7 @@ under the License.
                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" value="${(productPromoAction.amount)?if_exists}" />
                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" value="${(productPromoAction.productId)?if_exists}" />
                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" value="${(productPromoAction.partyId)?if_exists}" />
+                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" value="${(productPromoAction.serviceName)?if_exists}" />
                                         <input type="submit" value="${uiLabelMap.CommonUpdate}" />
                                     </form>
                                     </div>
@@ -392,6 +393,7 @@ under the License.
                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" />
                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" />
                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" />
+                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" />
                                         <input type="submit" value="${uiLabelMap.CommonCreate}" />
                                     </form>
                                     </div>



Re: svn commit: r932108 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/shoppingcart/product/ product/data/ product/entitydef/ product/webapp/catalog/promo/

Posted by Adam Heath <do...@brainfood.com>.
Jacopo Cappellato wrote:
> On Apr 9, 2010, at 5:33 PM, Adam Heath wrote:
> 
>> Jacopo Cappellato wrote:
>>> Maybe here the usage of the "CustomMethod" pattern could fit well... not a big deal by the way.
>>> The idea is that you enter the customMethodId in place of the service name in the condValue field: condValue --> CustomMethod --> serviceName
>>> The nice thing with this approach is that you can define a new CustomMethodType for "product promo cond services" (and one for actions) and then use drop down to show the available list of services.
>>> This pattern is used in a few other screens.
>> Which would mean condValue is text for some variants, and a drop-down
>> for others.  Is that possible with ofbiz?
> 
> Well, it is rather easy to do.
> 
>> My full plan is to complete rip apart checkCondition and runAction, so
>> that their big if/else blocks go away completely.  At that point,
>> there type drop-down would be completely variable.
> 
> Agreed.
> 
>> It's possible we could change enumeration type PROD_PROMO_IN_PARAM, to
>> have it's own sub-table, then define the service that implements that
>> enumeration.
> 
> I don't get you but don't worry, I am just probably reading too fast because I am busy.
> BTW, I hope you got what I was saying about CustomMethod.

Yeah, I got what you were saying.  I just had a different suggestion/idea.

Enumeration is to Party, as ProdPromoInputEnumeration is to Person.

enumTypeId(PROD_PROMO_IN_PARAM).hasTable=Y would be similiar to
partyTypeId(PERSON).hasTable=Y.

Re: svn commit: r932108 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/shoppingcart/product/ product/data/ product/entitydef/ product/webapp/catalog/promo/

Posted by Jacopo Cappellato <ja...@gmail.com>.
On Apr 9, 2010, at 5:33 PM, Adam Heath wrote:

> Jacopo Cappellato wrote:
>> Maybe here the usage of the "CustomMethod" pattern could fit well... not a big deal by the way.
>> The idea is that you enter the customMethodId in place of the service name in the condValue field: condValue --> CustomMethod --> serviceName
>> The nice thing with this approach is that you can define a new CustomMethodType for "product promo cond services" (and one for actions) and then use drop down to show the available list of services.
>> This pattern is used in a few other screens.
> 
> Which would mean condValue is text for some variants, and a drop-down
> for others.  Is that possible with ofbiz?

Well, it is rather easy to do.

> 
> My full plan is to complete rip apart checkCondition and runAction, so
> that their big if/else blocks go away completely.  At that point,
> there type drop-down would be completely variable.

Agreed.

> 
> It's possible we could change enumeration type PROD_PROMO_IN_PARAM, to
> have it's own sub-table, then define the service that implements that
> enumeration.

I don't get you but don't worry, I am just probably reading too fast because I am busy.
BTW, I hope you got what I was saying about CustomMethod.

Jacopo

> 
>> 
>> Jacopo
>> 
>> On Apr 8, 2010, at 10:47 PM, doogie@apache.org wrote:
>> 
>>> Author: doogie
>>> Date: Thu Apr  8 20:47:56 2010
>>> New Revision: 932108
>>> 
>>> URL: http://svn.apache.org/viewvc?rev=932108&view=rev
>>> Log:
>>> Add new features, the ability to have promo conditions and actions both
>>> as services, so that installations can do whatever kind of checking and
>>> promotions that they want, without any modifications to ofbiz.
>>> 
>>> Modified:
>>>   ofbiz/trunk/applications/order/servicedef/services_cart.xml
>>>   ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
>>>   ofbiz/trunk/applications/product/data/ProductTypeData.xml
>>>   ofbiz/trunk/applications/product/entitydef/entitymodel.xml
>>>   ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
>>> 
>>> Modified: ofbiz/trunk/applications/order/servicedef/services_cart.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services_cart.xml?rev=932108&r1=932107&r2=932108&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/order/servicedef/services_cart.xml (original)
>>> +++ ofbiz/trunk/applications/order/servicedef/services_cart.xml Thu Apr  8 20:47:56 2010
>>> @@ -24,6 +24,21 @@ under the License.
>>>    <vendor>OFBiz</vendor>
>>>    <version>1.0</version>
>>> 
>>> +    <service name="interfaceProductPromoCond" engine="interface" location="" invoke="">
>>> +        <attribute name="productPromoCond" type="org.ofbiz.entity.GenericValue" mode="IN"/>
>>> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
>>> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
>>> +        <attribute name="directResult" type="Boolean" mode="OUT" optional="true"/>
>>> +        <attribute name="compareBase" type="Integer" mode="OUT" optional="true"/>
>>> +        <attribute name="operatorEnumId" type="String" mode="OUT" optional="true"/>
>>> +    </service>
>>> +    <service name="interfaceProductPromoAction" engine="interface" location="" invoke="">
>>> +        <attribute name="productPromoAction" type="org.ofbiz.entity.GenericValue" mode="IN"/>
>>> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
>>> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
>>> +        <attribute name="actionResultInfo" type="org.ofbiz.order.shoppingcart.product.ProductPromoWorker.ActionResultInfo" mode="IN"/>
>>> +        <attribute name="cartItemModifyException" type="org.ofbiz.order.shoppingcart.CartItemModifyException" mode="OUT" optional="false"/>
>>> +    </service>
>>>    <service name="assignItemShipGroup" engine="java" auth="false"
>>>            location="org.ofbiz.order.shoppingcart.ShoppingCartServices" invoke="assignItemShipGroup">
>>>        <description>Assign a ShoppingCartItem -> Quantity to a ship group</description>
>>> 
>>> Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=932108&r1=932107&r2=932108&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original)
>>> +++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Thu Apr  8 20:47:56 2010
>>> @@ -789,7 +789,28 @@ public class ProductPromoWorker {
>>>        if (Debug.verboseOn()) Debug.logVerbose("Checking promotion condition: " + productPromoCond, module);
>>>        Integer compareBase = null;
>>> 
>>> -        if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
>>> +        if ("PPIP_SERVICE".equals(inputParamEnumId)) {
>>> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoCond", productPromoCond, "shoppingCart", cart, "nowTimestamp", nowTimestamp);
>>> +            Map<String, Object> condResult;
>>> +            try {
>>> +                condResult = dispatcher.runSync(condValue, serviceCtx);
>>> +            } catch (GenericServiceException e) {
>>> +                Debug.logError(e, "Fatal error calling promo condition check service [" + condValue + "]", module);
>>> +                return false;
>>> +            }
>>> +            if (ServiceUtil.isError(condResult)) {
>>> +                Debug.logError("Error calling calling promo condition check service [" + condValue + "]", module);
>>> +                return false;
>>> +            }
>>> +            Boolean directResult = (Boolean) condResult.get("directResult");
>>> +            if (directResult != null) {
>>> +                return directResult.booleanValue();
>>> +            }
>>> +            compareBase = (Integer) condResult.get("compareBase");
>>> +            if (condResult.containsKey("operatorEnumId")) {
>>> +                operatorEnumId = (String) condResult.get("operatorEnumId");
>>> +            }
>>> +        } else if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
>>>            // for this type of promo force the operatorEnumId = PPC_EQ, effectively ignore that setting because the comparison is implied in the code
>>>            operatorEnumId = "PPC_EQ";
>>> 
>>> @@ -1208,7 +1229,25 @@ public class ProductPromoWorker {
>>> 
>>>        String productPromoActionEnumId = productPromoAction.getString("productPromoActionEnumId");
>>> 
>>> -        if ("PROMO_GWP".equals(productPromoActionEnumId)) {
>>> +        if ("PROMO_SERVICE".equals(productPromoActionEnumId)) {
>>> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoAction", productPromoAction, "shoppingCart", cart, "nowTimestamp", nowTimestamp, "actionResultInfo", actionResultInfo);
>>> +            String serviceName = productPromoAction.getString("serviceName");
>>> +            Map<String, Object> actionResult;
>>> +            try {
>>> +                actionResult = dispatcher.runSync(serviceName, serviceCtx);
>>> +            } catch (GenericServiceException e) {
>>> +                Debug.logError("Error calling promo action service [" + serviceName + "]", module);
>>> +                throw new CartItemModifyException("Error calling promo action service [" + serviceName + "]");
>>> +            }
>>> +            if (ServiceUtil.isError(actionResult)) {
>>> +                Debug.logError("Error calling promo action service [" + serviceName + "], result is: " + actionResult, module);
>>> +                throw new CartItemModifyException((String) actionResult.get(ModelService.ERROR_MESSAGE));
>>> +            }
>>> +            CartItemModifyException cartItemModifyException = (CartItemModifyException) actionResult.get("cartItemModifyException");
>>> +            if (cartItemModifyException != null) {
>>> +                throw cartItemModifyException;
>>> +            }
>>> +        } else if ("PROMO_GWP".equals(productPromoActionEnumId)) {
>>>            String productStoreId = cart.getProductStoreId();
>>> 
>>>            // the code was in there for this, so even though I don't think we want to restrict this, just adding this flag to make it easy to change; could make option dynamic, but now implied by the use limit
>>> 
>>> Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=932108&r1=932107&r2=932108&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
>>> +++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Thu Apr  8 20:47:56 2010
>>> @@ -371,6 +371,7 @@ under the License.
>>>    <Enumeration description="Order sub-total X since beginning of current year" enumCode="ORST_YEAR" enumId="PPIP_ORST_YEAR" sequenceId="12" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>>    <Enumeration description="Order sub-total X last year" enumCode="ORST_LAST_YEAR" enumId="PPIP_ORST_LAST_YEAR" sequenceId="13" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>>    <Enumeration description="Shipping Total" enumCode="ORDER_SHIP_TOTAL" enumId="PPIP_ORDER_SHIPTOTAL" sequenceId="14" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PPIP_SERVICE" sequenceId="15" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>> 
>>>    <EnumerationType description="Product Promotion Condition" enumTypeId="PROD_PROMO_COND" hasTable="N" parentTypeId="PROD_PROMO"/>
>>>    <!-- old style very technical ...
>>> @@ -403,6 +404,7 @@ under the License.
>>>    <Enumeration description="Order Amount Flat" enumCode="ORDER_AMOUNT" enumId="PROMO_ORDER_AMOUNT" sequenceId="07" enumTypeId="PROD_PROMO_ACTION"/>
>>>    <Enumeration description="Product for [Special Promo] Price" enumCode="PROD_SPPRC" enumId="PROMO_PROD_SPPRC" sequenceId="08" enumTypeId="PROD_PROMO_ACTION"/>
>>>    <Enumeration description="Shipping X% discount" enumCode="SHIP_CHARGE" enumId="PROMO_SHIP_CHARGE" sequenceId="09" enumTypeId="PROD_PROMO_ACTION"/>
>>> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PROMO_SERVICE" sequenceId="10" enumTypeId="PROD_PROMO_ACTION"/>
>>> 
>>>    <EnumerationType description="Product Rating Field Type" enumTypeId="PROD_RATING_TYPE" hasTable="N" parentTypeId=""/>
>>>    <Enumeration description="Min Rating" enumCode="MIN" enumId="PRDR_MIN" sequenceId="01" enumTypeId="PROD_RATING_TYPE"/>
>>> 
>>> Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=932108&r1=932107&r2=932108&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
>>> +++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Thu Apr  8 20:47:56 2010
>>> @@ -3385,6 +3385,7 @@ under the License.
>>>      <field name="productPromoActionSeqId" type="id-ne"></field>
>>>      <field name="productPromoActionEnumId" type="id-ne"></field>
>>>      <field name="orderAdjustmentTypeId" type="id"></field>
>>> +      <field name="serviceName" type="long-varchar"></field>
>>>      <field name="quantity" type="fixed-point"></field>
>>>      <field name="amount" type="fixed-point"></field>
>>>      <field name="productId" type="id"></field>
>>> 
>>> Modified: ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl?rev=932108&r1=932107&r2=932108&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl (original)
>>> +++ ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl Thu Apr  8 20:47:56 2010
>>> @@ -279,6 +279,7 @@ under the License.
>>>                                        ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" value="${(productPromoAction.amount)?if_exists}" />
>>>                                        ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" value="${(productPromoAction.productId)?if_exists}" />
>>>                                        ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" value="${(productPromoAction.partyId)?if_exists}" />
>>> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" value="${(productPromoAction.serviceName)?if_exists}" />
>>>                                        <input type="submit" value="${uiLabelMap.CommonUpdate}" />
>>>                                    </form>
>>>                                    </div>
>>> @@ -392,6 +393,7 @@ under the License.
>>>                                        ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" />
>>>                                        ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" />
>>>                                        ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" />
>>> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" />
>>>                                        <input type="submit" value="${uiLabelMap.CommonCreate}" />
>>>                                    </form>
>>>                                    </div>
>>> 
>>> 
>> 
> 


Re: svn commit: r932108 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/shoppingcart/product/ product/data/ product/entitydef/ product/webapp/catalog/promo/

Posted by Adam Heath <do...@brainfood.com>.
Jacopo Cappellato wrote:
> Maybe here the usage of the "CustomMethod" pattern could fit well... not a big deal by the way.
> The idea is that you enter the customMethodId in place of the service name in the condValue field: condValue --> CustomMethod --> serviceName
> The nice thing with this approach is that you can define a new CustomMethodType for "product promo cond services" (and one for actions) and then use drop down to show the available list of services.
> This pattern is used in a few other screens.

Which would mean condValue is text for some variants, and a drop-down
for others.  Is that possible with ofbiz?

My full plan is to complete rip apart checkCondition and runAction, so
that their big if/else blocks go away completely.  At that point,
there type drop-down would be completely variable.

It's possible we could change enumeration type PROD_PROMO_IN_PARAM, to
have it's own sub-table, then define the service that implements that
enumeration.

> 
> Jacopo
> 
> On Apr 8, 2010, at 10:47 PM, doogie@apache.org wrote:
> 
>> Author: doogie
>> Date: Thu Apr  8 20:47:56 2010
>> New Revision: 932108
>>
>> URL: http://svn.apache.org/viewvc?rev=932108&view=rev
>> Log:
>> Add new features, the ability to have promo conditions and actions both
>> as services, so that installations can do whatever kind of checking and
>> promotions that they want, without any modifications to ofbiz.
>>
>> Modified:
>>    ofbiz/trunk/applications/order/servicedef/services_cart.xml
>>    ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
>>    ofbiz/trunk/applications/product/data/ProductTypeData.xml
>>    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
>>    ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
>>
>> Modified: ofbiz/trunk/applications/order/servicedef/services_cart.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services_cart.xml?rev=932108&r1=932107&r2=932108&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/order/servicedef/services_cart.xml (original)
>> +++ ofbiz/trunk/applications/order/servicedef/services_cart.xml Thu Apr  8 20:47:56 2010
>> @@ -24,6 +24,21 @@ under the License.
>>     <vendor>OFBiz</vendor>
>>     <version>1.0</version>
>>
>> +    <service name="interfaceProductPromoCond" engine="interface" location="" invoke="">
>> +        <attribute name="productPromoCond" type="org.ofbiz.entity.GenericValue" mode="IN"/>
>> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
>> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
>> +        <attribute name="directResult" type="Boolean" mode="OUT" optional="true"/>
>> +        <attribute name="compareBase" type="Integer" mode="OUT" optional="true"/>
>> +        <attribute name="operatorEnumId" type="String" mode="OUT" optional="true"/>
>> +    </service>
>> +    <service name="interfaceProductPromoAction" engine="interface" location="" invoke="">
>> +        <attribute name="productPromoAction" type="org.ofbiz.entity.GenericValue" mode="IN"/>
>> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
>> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
>> +        <attribute name="actionResultInfo" type="org.ofbiz.order.shoppingcart.product.ProductPromoWorker.ActionResultInfo" mode="IN"/>
>> +        <attribute name="cartItemModifyException" type="org.ofbiz.order.shoppingcart.CartItemModifyException" mode="OUT" optional="false"/>
>> +    </service>
>>     <service name="assignItemShipGroup" engine="java" auth="false"
>>             location="org.ofbiz.order.shoppingcart.ShoppingCartServices" invoke="assignItemShipGroup">
>>         <description>Assign a ShoppingCartItem -> Quantity to a ship group</description>
>>
>> Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=932108&r1=932107&r2=932108&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original)
>> +++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Thu Apr  8 20:47:56 2010
>> @@ -789,7 +789,28 @@ public class ProductPromoWorker {
>>         if (Debug.verboseOn()) Debug.logVerbose("Checking promotion condition: " + productPromoCond, module);
>>         Integer compareBase = null;
>>
>> -        if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
>> +        if ("PPIP_SERVICE".equals(inputParamEnumId)) {
>> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoCond", productPromoCond, "shoppingCart", cart, "nowTimestamp", nowTimestamp);
>> +            Map<String, Object> condResult;
>> +            try {
>> +                condResult = dispatcher.runSync(condValue, serviceCtx);
>> +            } catch (GenericServiceException e) {
>> +                Debug.logError(e, "Fatal error calling promo condition check service [" + condValue + "]", module);
>> +                return false;
>> +            }
>> +            if (ServiceUtil.isError(condResult)) {
>> +                Debug.logError("Error calling calling promo condition check service [" + condValue + "]", module);
>> +                return false;
>> +            }
>> +            Boolean directResult = (Boolean) condResult.get("directResult");
>> +            if (directResult != null) {
>> +                return directResult.booleanValue();
>> +            }
>> +            compareBase = (Integer) condResult.get("compareBase");
>> +            if (condResult.containsKey("operatorEnumId")) {
>> +                operatorEnumId = (String) condResult.get("operatorEnumId");
>> +            }
>> +        } else if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
>>             // for this type of promo force the operatorEnumId = PPC_EQ, effectively ignore that setting because the comparison is implied in the code
>>             operatorEnumId = "PPC_EQ";
>>
>> @@ -1208,7 +1229,25 @@ public class ProductPromoWorker {
>>
>>         String productPromoActionEnumId = productPromoAction.getString("productPromoActionEnumId");
>>
>> -        if ("PROMO_GWP".equals(productPromoActionEnumId)) {
>> +        if ("PROMO_SERVICE".equals(productPromoActionEnumId)) {
>> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoAction", productPromoAction, "shoppingCart", cart, "nowTimestamp", nowTimestamp, "actionResultInfo", actionResultInfo);
>> +            String serviceName = productPromoAction.getString("serviceName");
>> +            Map<String, Object> actionResult;
>> +            try {
>> +                actionResult = dispatcher.runSync(serviceName, serviceCtx);
>> +            } catch (GenericServiceException e) {
>> +                Debug.logError("Error calling promo action service [" + serviceName + "]", module);
>> +                throw new CartItemModifyException("Error calling promo action service [" + serviceName + "]");
>> +            }
>> +            if (ServiceUtil.isError(actionResult)) {
>> +                Debug.logError("Error calling promo action service [" + serviceName + "], result is: " + actionResult, module);
>> +                throw new CartItemModifyException((String) actionResult.get(ModelService.ERROR_MESSAGE));
>> +            }
>> +            CartItemModifyException cartItemModifyException = (CartItemModifyException) actionResult.get("cartItemModifyException");
>> +            if (cartItemModifyException != null) {
>> +                throw cartItemModifyException;
>> +            }
>> +        } else if ("PROMO_GWP".equals(productPromoActionEnumId)) {
>>             String productStoreId = cart.getProductStoreId();
>>
>>             // the code was in there for this, so even though I don't think we want to restrict this, just adding this flag to make it easy to change; could make option dynamic, but now implied by the use limit
>>
>> Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=932108&r1=932107&r2=932108&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
>> +++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Thu Apr  8 20:47:56 2010
>> @@ -371,6 +371,7 @@ under the License.
>>     <Enumeration description="Order sub-total X since beginning of current year" enumCode="ORST_YEAR" enumId="PPIP_ORST_YEAR" sequenceId="12" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>     <Enumeration description="Order sub-total X last year" enumCode="ORST_LAST_YEAR" enumId="PPIP_ORST_LAST_YEAR" sequenceId="13" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>     <Enumeration description="Shipping Total" enumCode="ORDER_SHIP_TOTAL" enumId="PPIP_ORDER_SHIPTOTAL" sequenceId="14" enumTypeId="PROD_PROMO_IN_PARAM"/>
>> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PPIP_SERVICE" sequenceId="15" enumTypeId="PROD_PROMO_IN_PARAM"/>
>>
>>     <EnumerationType description="Product Promotion Condition" enumTypeId="PROD_PROMO_COND" hasTable="N" parentTypeId="PROD_PROMO"/>
>>     <!-- old style very technical ...
>> @@ -403,6 +404,7 @@ under the License.
>>     <Enumeration description="Order Amount Flat" enumCode="ORDER_AMOUNT" enumId="PROMO_ORDER_AMOUNT" sequenceId="07" enumTypeId="PROD_PROMO_ACTION"/>
>>     <Enumeration description="Product for [Special Promo] Price" enumCode="PROD_SPPRC" enumId="PROMO_PROD_SPPRC" sequenceId="08" enumTypeId="PROD_PROMO_ACTION"/>
>>     <Enumeration description="Shipping X% discount" enumCode="SHIP_CHARGE" enumId="PROMO_SHIP_CHARGE" sequenceId="09" enumTypeId="PROD_PROMO_ACTION"/>
>> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PROMO_SERVICE" sequenceId="10" enumTypeId="PROD_PROMO_ACTION"/>
>>
>>     <EnumerationType description="Product Rating Field Type" enumTypeId="PROD_RATING_TYPE" hasTable="N" parentTypeId=""/>
>>     <Enumeration description="Min Rating" enumCode="MIN" enumId="PRDR_MIN" sequenceId="01" enumTypeId="PROD_RATING_TYPE"/>
>>
>> Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=932108&r1=932107&r2=932108&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
>> +++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Thu Apr  8 20:47:56 2010
>> @@ -3385,6 +3385,7 @@ under the License.
>>       <field name="productPromoActionSeqId" type="id-ne"></field>
>>       <field name="productPromoActionEnumId" type="id-ne"></field>
>>       <field name="orderAdjustmentTypeId" type="id"></field>
>> +      <field name="serviceName" type="long-varchar"></field>
>>       <field name="quantity" type="fixed-point"></field>
>>       <field name="amount" type="fixed-point"></field>
>>       <field name="productId" type="id"></field>
>>
>> Modified: ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl?rev=932108&r1=932107&r2=932108&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl (original)
>> +++ ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl Thu Apr  8 20:47:56 2010
>> @@ -279,6 +279,7 @@ under the License.
>>                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" value="${(productPromoAction.amount)?if_exists}" />
>>                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" value="${(productPromoAction.productId)?if_exists}" />
>>                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" value="${(productPromoAction.partyId)?if_exists}" />
>> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" value="${(productPromoAction.serviceName)?if_exists}" />
>>                                         <input type="submit" value="${uiLabelMap.CommonUpdate}" />
>>                                     </form>
>>                                     </div>
>> @@ -392,6 +393,7 @@ under the License.
>>                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" />
>>                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" />
>>                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" />
>> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" />
>>                                         <input type="submit" value="${uiLabelMap.CommonCreate}" />
>>                                     </form>
>>                                     </div>
>>
>>
> 


Re: svn commit: r932108 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/shoppingcart/product/ product/data/ product/entitydef/ product/webapp/catalog/promo/

Posted by Jacopo Cappellato <ja...@hotwaxmedia.com>.
Maybe here the usage of the "CustomMethod" pattern could fit well... not a big deal by the way.
The idea is that you enter the customMethodId in place of the service name in the condValue field: condValue --> CustomMethod --> serviceName
The nice thing with this approach is that you can define a new CustomMethodType for "product promo cond services" (and one for actions) and then use drop down to show the available list of services.
This pattern is used in a few other screens.

Jacopo

On Apr 8, 2010, at 10:47 PM, doogie@apache.org wrote:

> Author: doogie
> Date: Thu Apr  8 20:47:56 2010
> New Revision: 932108
> 
> URL: http://svn.apache.org/viewvc?rev=932108&view=rev
> Log:
> Add new features, the ability to have promo conditions and actions both
> as services, so that installations can do whatever kind of checking and
> promotions that they want, without any modifications to ofbiz.
> 
> Modified:
>    ofbiz/trunk/applications/order/servicedef/services_cart.xml
>    ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
>    ofbiz/trunk/applications/product/data/ProductTypeData.xml
>    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
>    ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
> 
> Modified: ofbiz/trunk/applications/order/servicedef/services_cart.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services_cart.xml?rev=932108&r1=932107&r2=932108&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/order/servicedef/services_cart.xml (original)
> +++ ofbiz/trunk/applications/order/servicedef/services_cart.xml Thu Apr  8 20:47:56 2010
> @@ -24,6 +24,21 @@ under the License.
>     <vendor>OFBiz</vendor>
>     <version>1.0</version>
> 
> +    <service name="interfaceProductPromoCond" engine="interface" location="" invoke="">
> +        <attribute name="productPromoCond" type="org.ofbiz.entity.GenericValue" mode="IN"/>
> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
> +        <attribute name="directResult" type="Boolean" mode="OUT" optional="true"/>
> +        <attribute name="compareBase" type="Integer" mode="OUT" optional="true"/>
> +        <attribute name="operatorEnumId" type="String" mode="OUT" optional="true"/>
> +    </service>
> +    <service name="interfaceProductPromoAction" engine="interface" location="" invoke="">
> +        <attribute name="productPromoAction" type="org.ofbiz.entity.GenericValue" mode="IN"/>
> +        <attribute name="shoppingCart" type="org.ofbiz.order.shoppingcart.ShoppingCart" mode="IN"/>
> +        <attribute name="nowTimestamp" type="Timestamp" mode="IN"/>
> +        <attribute name="actionResultInfo" type="org.ofbiz.order.shoppingcart.product.ProductPromoWorker.ActionResultInfo" mode="IN"/>
> +        <attribute name="cartItemModifyException" type="org.ofbiz.order.shoppingcart.CartItemModifyException" mode="OUT" optional="false"/>
> +    </service>
>     <service name="assignItemShipGroup" engine="java" auth="false"
>             location="org.ofbiz.order.shoppingcart.ShoppingCartServices" invoke="assignItemShipGroup">
>         <description>Assign a ShoppingCartItem -> Quantity to a ship group</description>
> 
> Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=932108&r1=932107&r2=932108&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original)
> +++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Thu Apr  8 20:47:56 2010
> @@ -789,7 +789,28 @@ public class ProductPromoWorker {
>         if (Debug.verboseOn()) Debug.logVerbose("Checking promotion condition: " + productPromoCond, module);
>         Integer compareBase = null;
> 
> -        if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
> +        if ("PPIP_SERVICE".equals(inputParamEnumId)) {
> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoCond", productPromoCond, "shoppingCart", cart, "nowTimestamp", nowTimestamp);
> +            Map<String, Object> condResult;
> +            try {
> +                condResult = dispatcher.runSync(condValue, serviceCtx);
> +            } catch (GenericServiceException e) {
> +                Debug.logError(e, "Fatal error calling promo condition check service [" + condValue + "]", module);
> +                return false;
> +            }
> +            if (ServiceUtil.isError(condResult)) {
> +                Debug.logError("Error calling calling promo condition check service [" + condValue + "]", module);
> +                return false;
> +            }
> +            Boolean directResult = (Boolean) condResult.get("directResult");
> +            if (directResult != null) {
> +                return directResult.booleanValue();
> +            }
> +            compareBase = (Integer) condResult.get("compareBase");
> +            if (condResult.containsKey("operatorEnumId")) {
> +                operatorEnumId = (String) condResult.get("operatorEnumId");
> +            }
> +        } else if ("PPIP_PRODUCT_AMOUNT".equals(inputParamEnumId)) {
>             // for this type of promo force the operatorEnumId = PPC_EQ, effectively ignore that setting because the comparison is implied in the code
>             operatorEnumId = "PPC_EQ";
> 
> @@ -1208,7 +1229,25 @@ public class ProductPromoWorker {
> 
>         String productPromoActionEnumId = productPromoAction.getString("productPromoActionEnumId");
> 
> -        if ("PROMO_GWP".equals(productPromoActionEnumId)) {
> +        if ("PROMO_SERVICE".equals(productPromoActionEnumId)) {
> +            Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("productPromoAction", productPromoAction, "shoppingCart", cart, "nowTimestamp", nowTimestamp, "actionResultInfo", actionResultInfo);
> +            String serviceName = productPromoAction.getString("serviceName");
> +            Map<String, Object> actionResult;
> +            try {
> +                actionResult = dispatcher.runSync(serviceName, serviceCtx);
> +            } catch (GenericServiceException e) {
> +                Debug.logError("Error calling promo action service [" + serviceName + "]", module);
> +                throw new CartItemModifyException("Error calling promo action service [" + serviceName + "]");
> +            }
> +            if (ServiceUtil.isError(actionResult)) {
> +                Debug.logError("Error calling promo action service [" + serviceName + "], result is: " + actionResult, module);
> +                throw new CartItemModifyException((String) actionResult.get(ModelService.ERROR_MESSAGE));
> +            }
> +            CartItemModifyException cartItemModifyException = (CartItemModifyException) actionResult.get("cartItemModifyException");
> +            if (cartItemModifyException != null) {
> +                throw cartItemModifyException;
> +            }
> +        } else if ("PROMO_GWP".equals(productPromoActionEnumId)) {
>             String productStoreId = cart.getProductStoreId();
> 
>             // the code was in there for this, so even though I don't think we want to restrict this, just adding this flag to make it easy to change; could make option dynamic, but now implied by the use limit
> 
> Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=932108&r1=932107&r2=932108&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
> +++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Thu Apr  8 20:47:56 2010
> @@ -371,6 +371,7 @@ under the License.
>     <Enumeration description="Order sub-total X since beginning of current year" enumCode="ORST_YEAR" enumId="PPIP_ORST_YEAR" sequenceId="12" enumTypeId="PROD_PROMO_IN_PARAM"/>
>     <Enumeration description="Order sub-total X last year" enumCode="ORST_LAST_YEAR" enumId="PPIP_ORST_LAST_YEAR" sequenceId="13" enumTypeId="PROD_PROMO_IN_PARAM"/>
>     <Enumeration description="Shipping Total" enumCode="ORDER_SHIP_TOTAL" enumId="PPIP_ORDER_SHIPTOTAL" sequenceId="14" enumTypeId="PROD_PROMO_IN_PARAM"/>
> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PPIP_SERVICE" sequenceId="15" enumTypeId="PROD_PROMO_IN_PARAM"/>
> 
>     <EnumerationType description="Product Promotion Condition" enumTypeId="PROD_PROMO_COND" hasTable="N" parentTypeId="PROD_PROMO"/>
>     <!-- old style very technical ...
> @@ -403,6 +404,7 @@ under the License.
>     <Enumeration description="Order Amount Flat" enumCode="ORDER_AMOUNT" enumId="PROMO_ORDER_AMOUNT" sequenceId="07" enumTypeId="PROD_PROMO_ACTION"/>
>     <Enumeration description="Product for [Special Promo] Price" enumCode="PROD_SPPRC" enumId="PROMO_PROD_SPPRC" sequenceId="08" enumTypeId="PROD_PROMO_ACTION"/>
>     <Enumeration description="Shipping X% discount" enumCode="SHIP_CHARGE" enumId="PROMO_SHIP_CHARGE" sequenceId="09" enumTypeId="PROD_PROMO_ACTION"/>
> +    <Enumeration description="Call Service" enumCode="SERVICE" enumId="PROMO_SERVICE" sequenceId="10" enumTypeId="PROD_PROMO_ACTION"/>
> 
>     <EnumerationType description="Product Rating Field Type" enumTypeId="PROD_RATING_TYPE" hasTable="N" parentTypeId=""/>
>     <Enumeration description="Min Rating" enumCode="MIN" enumId="PRDR_MIN" sequenceId="01" enumTypeId="PROD_RATING_TYPE"/>
> 
> Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=932108&r1=932107&r2=932108&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
> +++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Thu Apr  8 20:47:56 2010
> @@ -3385,6 +3385,7 @@ under the License.
>       <field name="productPromoActionSeqId" type="id-ne"></field>
>       <field name="productPromoActionEnumId" type="id-ne"></field>
>       <field name="orderAdjustmentTypeId" type="id"></field>
> +      <field name="serviceName" type="long-varchar"></field>
>       <field name="quantity" type="fixed-point"></field>
>       <field name="amount" type="fixed-point"></field>
>       <field name="productId" type="id"></field>
> 
> Modified: ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl?rev=932108&r1=932107&r2=932108&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl (original)
> +++ ofbiz/trunk/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl Thu Apr  8 20:47:56 2010
> @@ -279,6 +279,7 @@ under the License.
>                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" value="${(productPromoAction.amount)?if_exists}" />
>                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" value="${(productPromoAction.productId)?if_exists}" />
>                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" value="${(productPromoAction.partyId)?if_exists}" />
> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" value="${(productPromoAction.serviceName)?if_exists}" />
>                                         <input type="submit" value="${uiLabelMap.CommonUpdate}" />
>                                     </form>
>                                     </div>
> @@ -392,6 +393,7 @@ under the License.
>                                         ${uiLabelMap.ProductAmount}:&nbsp;<input type="text" size="5" name="amount" />
>                                         ${uiLabelMap.ProductItemId}:&nbsp;<input type="text" size="15" name="productId" />
>                                         ${uiLabelMap.PartyParty}:&nbsp;<input type="text" size="10" name="partyId" />
> +                                        ${uiLabelMap.ServiceName}:&nbsp;<input type="text" size="20" name="serviceName" />
>                                         <input type="submit" value="${uiLabelMap.CommonCreate}" />
>                                     </form>
>                                     </div>
> 
>