By default, in Core Commerce, the approvalRequired
property of the user is checked. If it is true, then all the orders placed by the user are set to the “approval required” state. We overrode this behavior in Motorprise by adding an extra condition that checks the orderPriceLimit
property of the user if his or her approvalRequired
property is true.
We implemented this new approval condition for Motorprise by creating a new component, /atg/commerce/approval/processor/CheckOrderLimitApprovalRequirements
, based on the class atg.commerce.expression.ProcPropertyRestriction
. This component checks to see whether the total amount of the order placed by the user is greater than the orderPriceLimit
of the user.
For more information on the ProcPropertyRestriction
class, see the Core Commerce Programming Guide.
The properties of CheckOrderLimitApprovalRequirements
are:
$class=atg.commerce.expression.ProcPropertyRestriction $description=This component creates new approval rule based on Order. $scope=global errorMessage=Order's total is greater than the approved order limit of user. expressionParser=/atg/commerce/util/ExpressionParser pipelineResultErrorMessageKey=checkOrderLimitApprovalRequirements returnValueForFalseEvaluation=1 returnValueForTrueEvaluation=0 ruleEvaluator=/atg/commerce/util/RuleEvaluator ruleExpression=Order.priceInfo.amount > Profile.orderPriceLimit
The ruleExpression
property defines the condition for approval. For Motorprise, this rule determines if the order total of any order created by the user, Order.priceInfo.amount
, exceeds his approval limit, Profile.orderPriceLimit
. If the order placed by the user exceeds their order limit, then the order is marked as requiring approval.
The returnValueForTrueEvaluation
and returnValueForFalseEvaluation
properties define what should be returned by this component if ruleExpression
is true or false. Later, in the approval pipeline we use these return values to determine which pipeline path to take depending on the approval condition.
We also created another approval condition that checks for requisition numbers in invoice payment methods. Users can enter either a P.O. number or requisition number when they choose invoice as their payment method. If the user uses a requisition number, then the order is placed in an “approval required” state if his or her approvalRequired
property is set to true. For more information, see the Payment Information section of the Processing Orders chapter.
We implemented this approval condition for Motorprise by creating a new component, /atg/commerce/approval/processor/CheckRequisitionNumbers
, based on a new pipeline processor atg.projects.b2bstore.approval.ProcCheckRequisitionNumbers
. This pipeline processor returns one of two values, depending on whether or not an order contains any payment group with an associated requisition number. For more information, please refer to the ATG Platform API Reference documentation for this class.
The properties of CheckRequisitionNumbers
are:
$class=atg.projects.b2bstore.approval.ProcCheckRequisitionNumbers # If requisitions were used, add an error to the pipeline result and # return STOP_CHAIN_EXECUTION_AND_COMMIT so the approval pipeline will # mark the order as requiring approval requisitionUsedValue=0 requisitionUsedAddsPipelineError=true requisitionUsedPipelineMessage=Requisition number found - order requires approval # Otherwise just return a value we can use in a transition link to # proceed to the next test for possible approval conditions. requisitionNotUsedValue=1
Once we have the approval condition, we have to include it in the approveOrder
pipeline chain, which is invoked when the order is submitted for checkout. Most of the approval pipeline framework has been developed and configured in the Oracle Commerce Core Platform layer; we just have to include our new custom approval condition in the approval pipeline framework. In Core Commerce, the approveOrder
pipeline chain is invoked during the order confirmation phase, which in turn invokes the checkRequiresApproval
chain to verify the order for the approval conditions. The following is the relevant approval pipeline code in <ATG11dir>/B2BCommerce/config/atg/commerce/approval/approvalPipeline.xml
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <!-- PipelineChain used to determine if a users order requires --> <!-- approval or not. --> <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <pipelinechain name="checkRequiresApproval" transaction="TX_REQUIRES_NEW" headlink="checkProfileApprovalRequirements"> <pipelinelink name="checkProfileApprovalRequirements" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/ CheckProfileApprovalRequirements"/> </pipelinelink> </pipelinechain>
As shown above, the checkRequiredApproval
chain determines whether or not the order requires approval. We overrode this chain in the Motorprise layer to include our new approval condition in <ATG11dir>/Motorprise/config/atg/commerce/approval/approvalPipeline.xml
as shown below:
<pipelinechain name="checkRequiresApproval" transaction="TX_REQUIRES_NEW" headlink="checkProfileApprovalRequirements" xml-combine="replace"> <pipelinelink name="checkProfileApprovalRequirements" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/CheckProfileApprovalRequirements"/> <transition returnvalue="1" link="checkOrderLimitApprovalRequirements"/> </pipelinelink> <pipelinelink name="checkOrderLimitApprovalRequirements" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/CheckOrderLimitApprovalRequirements"/> </pipelinelink> </pipelinechain>
<pipelinechain name="checkRequiresApproval" transaction="TX_REQUIRES_NEW" headlink="checkProfileApprovalRequirements" xml-combine="replace"> <pipelinelink name="checkProfileApprovalRequirements" transaction= "TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/ CheckProfileApprovalRequirements"/> <transition returnvalue="1" link="checkRequisitionNumbers"/> </pipelinelink> <pipelinelink name="checkRequisitionNumbers" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/ CheckRequisitionNumbers"/> <transition returnvalue="1" link="checkOrderLimitApprovalRequirements"/> </pipelinelink> <pipelinelink name="checkOrderLimitApprovalRequirements" transaction= "TX_MANDATORY"> <processor jndi="/atg/commerce/approval/processor/ CheckOrderLimitApprovalRequirements"/> </pipelinelink> </pipelinechain>
The first chain in approvalPipeline.xml
, checkRequiresApproval
, is invoked during the checkout process and the new approval conditions, checkRequisitionNumbers
and checkOrderLimitApprovalRequirements
, are invoked in this chain. First, the chain checks to see if the user requires approval for orders; if he does, then the checkRequisitionNumbers
condition is checked. If the order uses a requisition number in the invoice payment method, the pipeline is stopped and the order is marked as requiring approval. If the order doesn’t use a requisition number, then the control goes to checkOrderLimitApprovalRequirements
, which checks whether the order price is above or below the user’s approved order limit. If the order requires an approval, then a message is displayed to the user on the order confirmation page, thank_you.jsp
, indicating that the order requires approval.
The following is the code in thank_you.jsp
to determine whether the order requires approval or not:
<dsp:droplet name="Switch"> <dsp:param bean="ShoppingCart.last.state" name="value"/> <dsp:oparam name="5000"> <tr> <td><span class=smallb>Your order requires approval. A message has been sent to your approver to review your order.</span><p></td> </tr> </dsp:oparam> <dsp:oparam name="default"> </dsp:oparam> </dsp:droplet>
Whenever the user submits an order, it is moved into ShoppingCart.last
, so that its state property is checked to determine whether it requires approval or not as shown above.
We also created another approval condition that checks for requisition numbers in invoice payment methods. Users can enter either PO number or requisition number when they choose invoice as their payment method. If the user chooses requisition number, then the order is placed in an “approval required” state if his or her approvalRequired
property is set to true. For more information, see the Payment Information section of the Processing Orders chapter.