Login
Register

Home

Trainings

Fusion Blog

EBS Blog

Authors

Contact Us

Kishore Ryali
  • Register

Oracle Gold Partners, our very popular training packages, training schedule is listed here
Designed by Five Star Rated Oracle Press Authors & Oracle ACE's.

webinar new Click here to raise Support Ticket. Get reply within 48 hours.

Search Courses

User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

This is the last article in the series “Custom Defaulting and Validation in iProcurement”. Prior to this I implemented (not so successfully) my requirement of copying a DFF attribute value called ‘Fund’ on requisition header to a DFF attribute in requisition line during checkout process using POR_CUSTOM_PKG , and OAF extension of Application Module and Controller.

Limitations I had with the previous approaches are,

  • POR_CUSTOM_PKG - 'custom_default_req_line' procedure is executed only when requisition is first created. The changes made to fund in requisition header there after are not copied to line.
  • Extension of Application Module and Controller - By extending root application module (RequisitionAM) I faced a "Cannot Display Page" issue with all list of values in iProcurement. I was getting session time out on Lov regions. It is not advisable to extend rootAM unless you know your way out.


Before I implement my third approach, a short briefing on iProcurement architecture will help understand the interaction between different layers each time a page is displayed or information on page is submitted. 

iProcurement Architecture Overview:

(Courtesy: 11.5.10: Oracle iProcurement Architecture Overview. Metalink Note: 313195.1)

Page Display Execution Flow

A typical execution of the processRequest method is explained below.

1.    When a page is displayed, the OAF will automatically call the processRequest method on the Controller of a page. In certain cases, in addition to the statically rendered items on a page, there are dynamically controlled elements that are displayed based on other setup in the system. If this logic is simple, then the corresponding implementation would be in the Controller for the page (Step 1).

2.    In many cases, the logic to determine the state of the dynamic elements on the page is sufficiently complex to warrant new Server Commands (refer to the “Server Command” section on Page 7 for more details) to encapsulate the logic. In this scenario, a call is made from the Controller to the Server Command via the corresponding Application Module (AM) for the transaction. The Application Module maintains a mapping of the Server Command names and the corresponding classes. The Controller passes the name of the Server Command to the Application Module, which in turn uses the mapping to execute the Server Command (Step 2).

3.    The Server Command then calls the corresponding View Object (VO), which in turn calls the mapped Entity Object (EO), to retrieve the data required to determine which elements and data values to be displayed on the page (Steps 3, 4 and 5).

 

Page Submission Execution Flow

A typical execution of the processFormRequest method is explained below

1.    When the data on the page is submitted (for e.g. when a button on the page is clicked), OAF calls the processFormRequest on the Controller for the page. In most cases, all the processing that needs to be done once a page is submitted is implemented in Server Commands (Step 1).

2.    Depending on the event being processed by the Controller, the Controller passes the name of the Server Command to the Application Module, which in turn makes a call to the corresponding Server Command (Step 2).

3.    In most cases, the data submitted on a page needs to be validated before the user proceeds to the next page in the flow. All the validation logic is implemented in Helper classes (refer to the “Helper” section on Page 14), which can be associated with one or more Entity Objects. The Server Command calls methods in the Helper classes to perform all the required validations on the page. Helpers might use additional criteria (Business Attribute Sets and Business Views as explained in Pages 10 and 11) to determine which validation needs to be performed on a given page (Steps 3, 4, 5 and 6).


Server Command Classes

A Server Command is a class that contains code that would normally be placed in an Application Module.  The code is extracted out into a separate class to prevent the Application Module from becoming too big, ease maintenance, facilitate concurrent development and promote reuse (different Application Modules may be able to use the same Server Command class). For example, a Server Command class could contain the code used to populate/query the different VOs displayed on a particular page, or contain the code to apply changes to all the requisition lines.

Every Server Command should implement the ServerCommand interface (oracle.apps.icx.por.common.server). There is an abstract method 'execute' which has to be implemented in child classes.


At runtime, a Server Command is invoked by name.  There are two methods in the RequisitionAM (inherited from parent class oracle.apps.icx.por.common.server.PorBaseAMImpl) that are used to invoke the Server Commands by name.

public Serializable executeServerCommand(String cmd, ArrayList args)
Parameters: cmd – Name of the Server Command that needs to be executed
                   args – List of parameters that are input to the Server Command

public Serializable executeServerCommand(String cmd)

Parameter: cmd – Name of the Server Command that needs to be executed

The Server Command can be invoked from the client-tier (Controller) through one of the above methods in the Application Module. With this architecture, all the logic/events on the user interface is handled via methods in the Server Commands, providing modularity and reuse.
A mapping class (oracle.apps.icx.por.common.PorClassMap) is used to locate the Server Command class by name.

Some of the Server Commands used in requisition checkout flow are
CheckoutSummarySvrCmd, CheckoutLinesSvrCmd, ShoppingCartSvrCmd etc.

Helper Classes

There are 2 categories of Helpers – Entity Object Helpers and Server Command Helpers. Entity Object Helpers contain defaulting and validation logic for Entity Objects. Each EO Helper implements a particular interface related to the EO. An EO Helper can “help” more than one EO by implementing several EO Helper interfaces. Server Command Helpers (e.g. DataMappingHelper) contain reusable processing and validation logic that are part of a Server Command.

When an EO is created, each of the associated EO Helpers is responsible for providing the appropriate default values.  Similarly, when an EO is validated, the validation is delegated to the Helpers.

Approach 3: Extending Server Command

To implement my requirement to copy header fund value to line fund, I will follow below high level steps to create custom Server Command class:

  1. Create a new Server Command class 'XxCustomSvrCmd' which implements oracle.apps.icx.por.common.server.ServerCommand
  2. Add method copyFundFromHeader to do custom defaulting.
  3. Create a new class mapping class which extends oracle.apps.icx.por.common.PorClassMap
  4. Add property name 'PorClassMap' to map it to new class map in RequisitionAM.xml
  5. Extend CheckoutSummaryCO to call XxCustomSvrCmd during events ‘Save’, ‘Submit’, and ‘Edit Lines’.

Implementation

  • Create new Server Command class 'XxCustomSvrCmd' which implements oracle.apps.icx.por.common.server.ServerCommand
  • Implement execute and executeMethodByName methods. executeMethodByName calls copyFundFromHeader if string parameter equals 'customDefault'

  • copyFundFromHeader fetches header fund value in attribute15 from PoRequisitionHeadersVO and sets it to attribute15 in ReqSummaryVO. This logic is same as in previous article.

// Source File Name: XxCustomSvrCmd.java
package xx.oracle.apps.icx.por.req.server;

import oracle.apps.fnd.common.VersionInfo;
import oracle.apps.fnd.framework.OAException;
import com.sun.java.util.collections.ArrayList;
import java.io.Serializable;
import oracle.jbo.domain.Number;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.apps.fnd.framework.server.*;
import oracle.apps.icx.por.common.server.*;
import oracle.apps.icx.por.req.server.RequisitionAMImpl;
import oracle.apps.icx.por.req.server.PoRequisitionHeadersVOImpl;
import oracle.apps.icx.por.req.server.PoRequisitionHeadersVORowImpl;
import oracle.apps.icx.por.req.server.ReqSummaryVOImpl;
import oracle.apps.icx.por.req.server.ReqSummaryVORowImpl;

public class XxCustomSvrCmd
       implements ServerCommand
{
  public XxCustomSvrCmd()
  { 
  }

  /*
   * Method: execute
   * Author: Kishore Ryali
   * Date:   11/24/2008
   * Purpose:
   *          Called from customValidation method in XxCheckoutSummaryCO
   */
  public Serializable execute(OAApplicationModuleImpl oaapplicationmoduleimpl, ArrayList arraylist)
    {       
        RequisitionAMImpl requisitionamimpl = (RequisitionAMImpl)oaapplicationmoduleimpl;
        OADBTransactionImpl oadbtransactionimpl = (OADBTransactionImpl)requisitionamimpl.getOADBTransaction(); 
       
        if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "execute.begin", 1);
           
        if(arraylist == null || arraylist.size() == 0)
        {
            if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "XxCustomSvrCmd executed with no method name.", 1);
           
            Exception exception = new Exception("XxCustomSvrCmd executed with no method name.");
            ErrorUtil.handleFatalException(oadbtransactionimpl, exception, this);
        }
       
        String s = (String)arraylist.get(0);
        if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "XxCustomSvrCmd - execute().begin, " + "methodName="+ s, 1);     
        arraylist.remove(0);
       
        Serializable serializable = executeMethodByName(oadbtransactionimpl, requisitionamimpl, s, arraylist);
       
        if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "execute.end", 1);
           
        return serializable;
    }
 

    protected Serializable executeMethodByName(OADBTransactionImpl oadbtransactionimpl, RequisitionAMImpl requisitionamimpl, String s, ArrayList arraylist)
    {
        if("customDefault".equals(s))
            customDefault(oadbtransactionimpl, requisitionamimpl);       
        return null;
    }

    protected void customDefault(OADBTransactionImpl oadbtransactionimpl, RequisitionAMImpl requisitionamimpl)
    {
      if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "customDefault.begin", 1);
      copyFundFromHeader(oadbtransactionimpl, requisitionamimpl);
      if(oadbtransactionimpl.isLoggingEnabled(1))
            oadbtransactionimpl.writeDiagnostics(this, "customDefault.end", 1);
    }

  /*
   * Method: copyFundFromHeader
   * Author: Kishore Ryali
   * Date:   11/24/2008
   * Purpose:
   *          Copies Header Fund Number Attr15 to Line Fund Number Att15
   */
    protected void copyFundFromHeader(OADBTransactionImpl oadbtransactionimpl, RequisitionAMImpl requisitionamimpl)
    {       
        if(oadbtransactionimpl.isLoggingEnabled(1))
        {    oadbtransactionimpl.writeDiagnostics(this, "copyFundFromHeader.begin", 1);       
            oadbtransactionimpl.writeDiagnostics(this, "*** Xx Code for coping Fund Number from Req Header to Line ***", 1);
        }
       
        try
        {
            // Fetch Header Fund Number i.e Attr15
            PoRequisitionHeadersVOImpl porequisitionheadersvoimpl = requisitionamimpl.getPoRequisitionHeadersVO();
            PoRequisitionHeadersVORowImpl porequisitionheadersvorowimpl = (PoRequisitionHeadersVORowImpl)porequisitionheadersvoimpl.getCurrentRow();
            String headerFund = porequisitionheadersvorowimpl.getAttribute15();
           
            Number reqHeaderId = null;
            String reqSumAtt15 = null;
            String defaultFund = null;
           
            ReqSummaryVOImpl reqsummaryvoimpl = requisitionamimpl.getReqSummaryVO();
            ReqSummaryVORowImpl reqsummaryvorowimpl = (ReqSummaryVORowImpl)reqsummaryvoimpl.getCurrentRow();
            reqHeaderId = reqsummaryvorowimpl.getRequisitionHeaderId();
            reqSumAtt15 = reqsummaryvorowimpl.getAttribute15();
            if(oadbtransactionimpl.isLoggingEnabled(1))
                oadbtransactionimpl.writeDiagnostics(this, "BEFORE> reqHeaderId=" + reqHeaderId + ",reqSumAtt15=" + reqSumAtt15, 1);

            // Modified by Kishore Ryali on 12/09/2008
            // Purpose: Fund DFF on Header is made not mandatory. So if Fund is left NULL,
            //          copy default fund number value i.e. 0000000000 i.e profile XX_DEFAULT_FUND_NUMBER to make
            //          account generation work.

            if (headerFund == null)
            {
              // Fetch default fund number from profile
              defaultFund = oadbtransactionimpl.getProfile("XX_DEFAULT_FUND_NUMBER");
              reqsummaryvorowimpl.setAttribute15(defaultFund);
            }
            else
            {
              // Set Header Fund Number to Line Fund Number i.e. Attr15
              reqsummaryvorowimpl.setAttribute15(headerFund);
            }
                       
            reqHeaderId = reqsummaryvorowimpl.getRequisitionHeaderId();
            reqSumAtt15 = reqsummaryvorowimpl.getAttribute15();
            if(oadbtransactionimpl.isLoggingEnabled(1))
                oadbtransactionimpl.writeDiagnostics(this, "AFTER> reqHeaderId=" + reqHeaderId + ",reqSumAtt15=" + reqSumAtt15, 1);
          
        }
        catch(Exception exception)
        {
            if(oadbtransactionimpl.isLoggingEnabled(1))
                oadbtransactionimpl.writeDiagnostics(this, "Error=" + exception, 1);
            throw new OAException("Error in XxCustomSvrCmd.copyFundFromHeader=" + exception);
            //ErrorUtil.handleFatalException(getOADBTransaction(), exception, this);
        }
       
        if(oadbtransactionimpl.isLoggingEnabled(1))
        {
            oadbtransactionimpl.writeDiagnostics(this, "*** End of Xx Code for coping Fund Number from Req Header to Line ***", 1);
            oadbtransactionimpl.writeDiagnostics(this, "copyFundFromHeader.end", 1);
        }       
    } 

    public static final String RCS_ID = "$Header: XxCustomSvrCmd.java 115.30 2008/11/24 13:31:39 kryali noship $";
    public static final boolean RCS_ID_RECORDED = VersionInfo.recordClassVersion("$Header: XxCustomSvrCmd.java 115.30 2008/11/24 13:31:39 kryali noship $", "xx.oracle.apps.icx.por.req.server");
}


  • After custom Server Command is implemented, create a new mapping class 'XxClassMap' which extends oracle.apps.icx.por.common.PorClassMap. This new class is stored in  xx.oracle.apps.icx.por.common directory.

  • Override getClass method to create mapping for new Server Command class 'XxCustomSvrCmd'. Since I extended PorClassMap, mapping for seeded Server Commands are inherited.

// Source File Name: XxClassMap.java
package xx.oracle.apps.icx.por.common;
import oracle.apps.icx.por.common.PorClassMap;
import oracle.apps.fnd.common.VersionInfo;

public class XxClassMap extends PorClassMap
{
  public XxClassMap()
    {
    }
  public String getClass(String name)
    {
      if ("XxCustomSvrCmd".equals(name))
      {
        return "xx.oracle.apps.icx.por.req.server.XxCustomSvrCmd";
      }
      else
      {
        return (String)s_classNames.get(name);
      }
    }

  public static final String RCS_ID = "$Header: XxClassMap.java 115.30 2008/11/24 13:31:39 kryali noship $";
  public static final boolean RCS_ID_RECORDED = VersionInfo.recordClassVersion("$Header: XxClassMap.java 115.30 2008/11/24 13:31:39 kryali noship $", "xx.oracle.apps.icx.por.common");
}


  • Now RequisitionAM should use mapping class 'XxClassMap' instead of 'PorClassMap' to get the location of Server Commands including 'XxCustomSvrCmd'. This is done by adding new property to RequisitionAM.xml. (Note: Take a copy of RequistionAM.xml in oracle.apps.icx.por.req.server, before changing it)
  • In Properties element, add new property name 'PorClasMap' with value pointing to location of custom class map 'XxClassMap'. Everything else in RequisitionAM.xml stays the same.
  • Extend CheckoutSummaryCO to override processFormRequest method to call XxServerCmd on the events ‘Save’, ‘Submit’, and ‘Edit Lines’.
  • Server Command name 'XxCustomSvrCmd' is passed as a parameter along with 'customDefault' method name to executeServerCommand. This method is inherited by RequisitionAM from PorBaseAM. Using XxClassMap, RequisitionAM locates XxCustomSvrCmd and executes the logic in customDefault method.

// Source File Name: XxCheckoutSummaryCO.java
package xx.oracle.apps.icx.por.req.webui;
import com.sun.java.util.collections.ArrayList;

import oracle.apps.fnd.common.*;
import oracle.apps.fnd.framework.*;
import oracle.apps.fnd.framework.webui.*;
import oracle.apps.fnd.framework.webui.beans.*;
import oracle.apps.icx.por.req.webui.*;

public class XxCheckoutSummaryCO extends CheckoutSummaryCO
{
    public XxCheckoutSummaryCO()
    {
    }
  
    public void processFormRequest(OAPageContext oapagecontext, OAWebBean oawebbean)
    {
        OAApplicationModule oaapplicationmodule = oapagecontext.getApplicationModule(oawebbean);         
        if(oapagecontext.isLoggingEnabled(2))
            oapagecontext.writeDiagnostics(this, "processFormRequest().begin", 2);   
           
        String s = oapagecontext.getParameter("event");
        if(oapagecontext.isLoggingEnabled(1))
            oapagecontext.writeDiagnostics(this, "*** Xx Code for Custom Defaulting and Validation in PFR event " + s + " ***", 1);          
       
        /*
         * Execute below custom code on Edit Lines/Save/Submit/Next events
         * Custom Validation on Deliver-To Location and Fund Number
         * Custom Defaulting for copying Fund Number for Header DFF to Line DFF
         */
        if("editLines".equals(s))
            customDefault(oapagecontext, oaapplicationmodule);
        if("save".equals(s))
            customDefault(oapagecontext, oaapplicationmodule);
        if("submit".equals(s))
            customDefault(oapagecontext, oaapplicationmodule);
        if("goto".equals(s))
            customDefault(oapagecontext, oaapplicationmodule);

        if(oapagecontext.isLoggingEnabled(1))
            oapagecontext.writeDiagnostics(this, "*** End of Xx Code for Custom Defaulting and Validation in PFR event " + s + " ***", 1);      
           
        if(oapagecontext.isLoggingEnabled(2))
            oapagecontext.writeDiagnostics(this, "processFormRequest().end", 2);

        // TODO:  Override this oracle.apps.icx.por.req.webui.CheckoutSummaryCO method   
        super.processFormRequest(oapagecontext, oawebbean);
    }

    /*
     * Method: customDefault
     * Author: Kishore Ryali
     * Date:   11/24/2008
     * Purpose:
     *          Custom Validation on Deliver-To Location and Fund Number
     *          Custom Defaulting for copying Fund Number for Header DFF to Line DFF
     */
    protected void customDefault(OAPageContext oapagecontext, OAApplicationModule oaapplicationmodule)
    {  
   
        ArrayList arraylist1 = new ArrayList(2);
        // Call Custom Server Cmd 'XxCustomSvrCmd'
        // RequisitionAM.xml is updated to Custom Property to include XxClassMap
        arraylist1.add("customDefault");
        executeServerCommand(oapagecontext, oaapplicationmodule, "XxCustomSvrCmd", arraylist1);
        return;
   
       // oaapplicationmodule.invokeMethod("copyFundFromHeader");
    }
 
  public static final String RCS_ID = "$Header: XxCheckoutSummaryCO.java 115.30 2008/11/24 13:31:39 kryali noship $";
  public static final boolean RCS_ID_RECORDED = VersionInfo.recordClassVersion("$Header: XxCheckoutSummaryCO.java 115.30 2008/11/24 13:31:39 kryali noship $", "xx.oracle.apps.icx.por.req.webui");

}


  • Upload custom files in JAVA_TOP into respective directories. Bounce Middle-Tier to reflect the changes.
  • In Checkout: Requisition Information page, Personalize page is used to substitute XxCheckoutSummaryCO.


Though this approach is fairly complex with many steps, I could successfully achieve my requirement without effecting standard functionality. We can follow similar approach for extending Helper classes. por_custom_pkg is in fact invoked from Helper classes which implement Helper Interfaces.

If you have any other methods for doing custom validation and defaulting in iProcurement, please share with us in the comments section.

Kishore Ryali

Comments   

0 #1 KrishnaKishoreT 2009-07-10 11:10
Hi Kishore,

The article is awesome! Thanks for your efforts again.

Thanks,
Krishna
Quote
0 #2 KrishnaKishoreT 2009-08-12 15:58
Hi Kishore,

I tried to use the approach you explained above to copy some Header DFFs to Line and I am getting an exception when the extended controller calls the 'executeServerC ommand' function from 'customDefault' .

I have created the XxCustomSvrCmd and XxClassMap as was explained above. I also updated the RequisitionAM.x ml file to have the below property:


The exception trace is as follows:
Fatal OAException:ora cle.apps.fnd.fr amework.OAExcep tion: Application: FND, Message Name: FND_GENERIC_MES SAGE. Tokens: MESSAGE = java.lang.NullP ointerException ;
at oracle.apps.fnd .framework.OAEx ception.wrapper Exception(OAExc eption.java:891 )
at oracle.apps.icx .por.common.ser ver.ErrorUtil.h andleFatalExcep tion(ErrorUtil. java:631)
at oracle.apps.icx .por.common.ser ver.PorBaseAMIm pl.executeServe rCommand(PorBas eAMImpl.java:12 6)
at sun.reflect.Gen eratedMethodAcc essor335.invoke (Unknown Source)
at sun.reflect.Del egatingMethodAc cessorImpl.invo ke(DelegatingMe thodAccessorImp l.java:25)
at java.lang.refle ct.Method.invok e(Method.java:3 24)
at oracle.apps.fnd .framework.serv er.OAUtility.in vokeMethod(OAUt ility.java:190)
at oracle.apps.fnd .framework.serv er.OAApplicatio nModuleImpl.inv okeMethod(OAApp licationModuleI mpl.java:708)
a t oracle.apps.icx .por.common.web ui.ClientUtil.i nvokeMethod(Cli entUtil.java:96 4)
at oracle.apps.icx .por.common.web ui.PorBaseCOImp l.invokeMethod( PorBaseCOImpl.j ava:194)
at oracle.apps.icx .por.common.web ui.PorBaseCOImp l.executeServer Command(PorBase COImpl.java:112 )
at oracle.apps.icx .por.req.webui. XxCheckoutSumma ryCO.customDefa ult(XxCheckoutS ummaryCO.java:6 5)
at oracle.apps.icx .por.req.webui. XxCheckoutSumma ryCO.processFor mRequest(XxChec koutSummaryCO.j ava:39)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equest(OAWebBea nHelper.java:81 0)
at oracle.apps.fnd .framework.webu i.OAWebBeanCont ainerHelper.pro cessFormRequest (OAWebBeanConta inerHelper.java :363)
at oracle.apps.fnd .framework.webu i.OAPageLayoutH elper.processFo rmRequest(OAPag eLayoutHelper.j ava:1159)
at oracle.apps.fnd .framework.webu i.beans.layout. OAPageLayoutBea n.processFormRe quest(OAPageLay outBean.java:15 79)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equestChildren( OAWebBeanHelper .java:1022)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equestChildren( OAWebBeanHelper .java:988)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equest(OAWebBea nHelper.java:84 3)
at oracle.apps.fnd .framework.webu i.OAWebBeanCont ainerHelper.pro cessFormRequest (OAWebBeanConta inerHelper.java :363)
at oracle.apps.fnd .framework.webu i.beans.form.OA FormBean.proces sFormRequest(OA FormBean.java:3 95)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equestChildren( OAWebBeanHelper .java:1022)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equestChildren( OAWebBeanHelper .java:988)
at oracle.apps.fnd .framework.webu i.OAWebBeanHelp er.processFormR equest(OAWebBea nHelper.java:84 3)
at oracle.apps.fnd .framework.webu i.OAWebBeanCont ainerHelper.pro cessFormRequest (OAWebBeanConta inerHelper.java :363)
at oracle.apps.fnd .framework.webu i.beans.OABodyB ean.processForm Request(OABodyB ean.java:363)
a t oracle.apps.fnd .framework.webu i.OAPageBean.pr ocessFormReques t(OAPageBean.ja va:2676)
at oracle.apps.fnd .framework.webu i.OAPageBean.pr eparePage(OAPag eBean.java:1683 )
at oracle.apps.fnd .framework.webu i.OAPageBean.pr eparePage(OAPag eBean.java:509)
at oracle.apps.fnd .framework.webu i.OAPageBean.pr eparePage(OAPag eBean.java:430)
at _oa__html._OA._ jspService(_OA. java:84)
at oracle.jsp.runt ime.HttpJsp.ser vice(HttpJsp.ja va:119)
at oracle.jsp.app. JspApplication. dispatchRequest (JspApplication .java:417)
at oracle.jsp.JspS ervlet.doDispat ch(JspServlet.j ava:267)
at oracle.jsp.JspS ervlet.internal Service(JspServ let.java:186)
a t oracle.jsp.JspS ervlet.service( JspServlet.java :156)
at javax.servlet.h ttp.HttpServlet .service(HttpSe rvlet.java:588)
at org.apache.jser v.JServConnecti on.processReque st(JServConnect ion.java:456)
a t org.apache.jser v.JServConnecti on.run(JServCon nection.java:29 4)
at java.lang.Threa d.run(Thread.ja va:534)
## Detail 0 ##
java.lang.Nu llPointerExcept ion
at oracle.apps.icx .por.common.ser ver.PorBaseAMIm pl.executeServe rCommand(PorBas eAMImpl.java:12 2)
at sun.reflect.Gen eratedMethodAcc essor335.invoke (Unknown Source)
at sun.reflect.Del egatingMethodAc cessorImpl.invo ke(DelegatingMe thodAccessorImp l.java:25)
at java.lang

Coul d you please let me know what the issue could be.

Thanks,
Kr ishna
Quote
0 #3 KrishnaKishoreT 2009-08-12 16:03
Hi Kishore,

The property that i specified in RequisitionAM.x ml is

Please find below the code for XxCustomSvrCmd and XxClassMap (its almost exactly your code)

XxClassM ap.java
------- --------------

// Source File Name: XxClassMap.java
package oracle.apps.icx .por.common;

i mport oracle.apps.icx .por.common.Por ClassMap;
impor t oracle.apps.fnd .common.Version Info;

public class XxClassMap extends PorClassMap
{
public XxClassMap()
{
}
public String getClass(String name)
{
if ("XxCustomSvrCm d".equals(name) )
{
return "oracle.apps.ic x.por.req.serve r.XxCustomSvrCm d";
}
else
{
return (String)s_class Names.get(name) ;
}
}

public static final String RCS_ID = "$Header: XxClassMap.java 115.30 2009/08/12 13:31:39 kthatavarthy noship $";
public static final boolean RCS_ID_RECORDED = VersionInfo.rec ordClassVersion ("$Header: XxClassMap.java 115.30 2009/08/12 13:31:39 kthatavarthy noship $", "oracle.apps.ic x.por.common");
}

Thanks,
Kri shna
Quote
0 #4 KrishnaKishoreT 2009-08-12 16:11
XxCustomSvrCmd. java
---------- --------------- -----

package oracle.apps.icx .por.req.server ;
import....

p ublic class XxCustomSvrCmd implements ServerCommand
{
public XxCustomSvrCmd& #40;)
{
}

public Serializable execute(OAAppli cationModuleImp l oaapplicationmo duleimpl, ArrayList arraylist)
{
RequisitionAMIm pl requisitionamim pl = (RequisitionAMIm pl)oaapplicationmoduleimpl;
OADBTransaction Impl oadbtransaction impl = (OADBTransaction Impl)requisitionamim pl.getOADBTransaction();

if(arraylist == null || arraylist.size( ) == 0)
{
if(oadbtransaction impl.isLoggingEnabled(1))
oadbtransaction impl.writeDiagnostics(this, "XxCustomSvrCmd executed with no method name.", 1);

Exception exception = new Exception("XxCu stomSvrCmd executed with no method name.");
ErrorUtil.handleFatalException(oadbtransaction impl, exception, this);
}

String s = (String)arrayli st.get(0);
arraylist.remov e(0);

Serializable serializable = executeMethodByName(oadbtransaction impl, requisitionamim pl, s, arraylist);

return serializable;
}

protected Serializable executeMethodByName(OADBTransaction Impl oadbtransaction impl, RequisitionAMIm pl requisitionamim pl, String s, ArrayList arraylist)
{
if("customDefau lt".equals(s))
customDefault(oadbtransaction impl, requisitionamim pl);
return null;
}

protected void customDefault(OADBTransaction Impl oadbtransaction impl, RequisitionAMIm pl requisitionamim pl)
{
copyHeaderDff(oadbtransaction impl, requisitionamim pl);
}

protected void copyHeaderDff(OADBTransaction Impl oadbtransaction impl, RequisitionAMIm pl requisitionamim pl)
{

try
{
// Fetch Header Fund Number i.e Attr15
PoRequisitionHe adersVOImpl porequisitionhe adersvoimpl = requisitionamim pl.getPoRequisitionHeadersVO();
PoRequisitionHe adersVORowImpl porequisitionhe adersvorowimpl = (PoRequisitionHe adersVORowImpl)porequisitionhe adersvoimpl.getCurrentRow();
String headerDept = porequisitionhe adersvorowimpl.getAttribute6();
String headerAcct = porequisitionhe adersvorowimpl.getAttribute7();

ReqSummaryVOImp l reqsummaryvoimp l = requisitionamim pl.getReqSummaryVO();
ReqSummaryVORow Impl reqsummaryvorow impl = (ReqSummaryVORow Impl)reqsummaryvoimp l.getCurrentRow();

// Set Line DFFs Attr1 and Attr2 to Header Dept and Acct
reqsummaryvorow impl.setAttribute1(headerDept);
reqsummaryvorow impl.setAttribute2(headerAcct);

}
catch(Exception exception)
{
throw new OAException("Er ror in XxCustomSvrCmd. copyHeaderDff=" + exception);
//ErrorUtil.han dleFatalExcepti on(getOADBTrans action(), exception, this);
}

}

public static final String RCS_ID = "$Header: XxCustomSvrCmd. java 115.30 2009/08/12 13:31:39 kthatavarthy noship $";
public static final boolean RCS_ID_RECORDED = VersionInfo.rec ordClassVersion ("$Header: XxCustomSvrCmd. java 115.30 2009/08/12 13:31:39 kthatavarthy noship $", "oracle.apps.ic x.por.req.serve r");
}
Quote
0 #5 KrishnaKishoreT 2009-08-12 17:36
Hi Kishore,

The server command is now being executed without any any errors and the requisition header dffs are being copied to the lines without any issues.
I had the apache bounced and it is working now!

Thanks,
Krish na
Quote
0 #6 Steve 2009-12-01 14:57
Hello,

really nice written example. Thanks for sharing your ideas.
When I worked through this example a question comes up by mine.

You change the RequisitionAM.x ml. What is if Oracle will deliver a new version
of RequestionAM.xm l then the file will be overwritten.

Isn't it better or possible to make a substitution of this file in Jdeveloper
and after this use jpximport? Was it also necessary in your example using
jpximport because I can't read about this?

Thank you
Quote
0 #7 Kishore Ryali 2009-12-01 15:19
Steve,

Requisi tionAM is rootAM. Oracle advises not to extend root AM as you may get weird results. My article http://apps2fusion.com/at/64-kr/381-iprocurement-extensions does rootAM extension and kff didnt work.

Extendin g helper classes in this article is documented in metalink note 313195.1. I agree we run into risk of patching when changing standard file. We just to check if RequisitionAM.x ml is modified in the patch and add custom property after patching if patch effects it.

Kishore
Quote
0 #8 Steve 2009-12-02 07:24
Hi,

I'm recreating this example and stuck by substitution of XxCheckoutSumma ryCO. I've tried in Jdeveloper
unde r Project Properties/Busi ness Components/Subs titutions to substitute
oracle.apps.ic x.por.req.webui .CheckoutSummar yCO
with
xx.ora cle.apps.icx.po r.req.webui.XxC heckoutSummaryC O
and want after this using JPXImporter

bu t I can't see the package path
xx.oracle.apps .icx.por.req.we bui and
oracle.apps .icx.por.req.we bui

There is only oracle.apps.fnd .framework.* shown. The path of
myprojects contains oracle.apps.icx .por.req.webui. CheckoutSummary CO

I've also rebuilt this project in jdeveloper. How can I get displayed the icx-packages
fo r substitution in addition.

Than ks a lot
Quote
0 #9 Kishore Ryali 2009-12-02 09:26
Steve,

Substit utions are done only for BC4J components (AM, VO, EO). Extension of CO is done using OAF Personalization . Please refer to http://apps2fusion.com/apps/oa-framework/103-oa-framework-extending-controller-steps

Thanks
Kishor e
Quote
0 #10 Steve 2009-12-02 11:31
Kishore,

thank you very much for clarity.

regar ds Steve
Quote
0 #11 Kumar NK 2010-08-11 14:00
If any business logic requires setting the VO attributes or calling the database package when user click on a submit button, the oracle proposed way is to extend the AM, write a method in Custom AM, call it from Process form request of the controller. Instead, we can directly get the VO instance in the controller itself and we can set the attributes, which is lot easier because we need to only extend the controller NOT the AM.

1.So what is the point in extending the AM apart from the fact that AM is on the server side and controller is on the client side.
2. Mainly I want to know the CONS or disadvantages in writing the code in controller directly without extending the AM.
Quote
0 #12 Kishore Ryali 2010-08-11 15:32
Kumar,

I agree you can get instance of VO and even EO in Controller. Suggested approach is to leave the handling of VO/EO to AM. So it provides encapsulation of business logic at one place i.e. AM.

Kishore
Quote
0 #13 Kumar NK 2010-08-13 15:06
One last question for you.

When we add the mapping class property to RequisitionAm.x ml, We are altering the standard file. How is this an upgrade proof? Even a small patch might impact this.

I had a similar requirement as yours and I did it by extending the CO and wrote the logic there. So its very simple and upgrade proof. Just for the fact that oracle suggested approach is to leave handling of VO/EO to AM, do we have to take the pain of writing the server class, extending the mapper class, changing the AM?

Please understand that I am just trying to asses the risk of extending the CO directly without following oracle's suggested approach. I hope you have an answer for my question.

Fina lly, its been a good effort by you. I appreciate this.
Quote
0 #14 Kishore Ryali 2010-08-13 15:17
Kumar,

I agree it is not an upgrade proof. I followed this approach from iProcurement Architecture whitepaper. You may able to find it in metalink.

Kish ore
Quote
0 #15 Rajesh Gupta 2011-01-10 04:01
Hi,

I modified the PricingHelper class to modify the getDisplayTxnPr ice method to add Attribute11, it is working fine but when we check the Requisition in My Requisition Region of IProc Home Page I am getting error for Non-Catalogue Requisitions only:

Request URI:/OA_HTML/OA .jsp

Exception :
java.lang.NoS uchMethodError: oracle.apps.icx.por.schema.server.PricingHelper.getDisplayTxnPr ice(Loracle/apps/fnd/framework/server/OADBTransaction;Loracle/jbo/domain/Number;Loracle/jbo/domain/Number;)Loracle/jbo/domain/Number

Please Help.

Thanks,
Rajesh
Quote
0 #16 mb_denver_us 2011-10-20 05:49
Excellent article. I have successfully implemented this solution by copying the Need By Date to the Expenditure Item Date as long as the Need By Date is the same across all lines.

If this date is different across the requisition lines; how would I go about copying this to the expenditure item date after i hit the submit/edit lines/save buttons on check out. I have tried something like this but this does not seem to work.

Thanks
M B
Quote
0 #17 Abhijit 2012-07-17 07:33
Hi Kishor,

My requirement is similar to yours.

I want to avoid entering "HOME" as deliver to location on checkout summary page.

I extended the LOVVO - LocationOneTime PurchaseLovVO for Deliver to location. It is working correctly and is not allowing me to select HOME deliver to location.

Howe ver, when the Checkout Summary page loads the deliver to location is already defaulted to location "INDIA - HOME OFFICES" which is defined in my assignment.

I want to check if the default deliver to location is HOME location, If yes then set it to NULL so that user will need to select another location.

Can you please let me know how can I achieve this?

Thanks,
Abhijit
Quote
0 #18 Manohar Bikkumala 2012-11-13 19:15
Hi Kishore,

Is it possible to change the code combination id using this process for each line based on our custom logic

Thanks
M anohar
Quote
0 #19 Guy 2014-11-07 09:33
Hi,

Can you please get us the property specified in RequisitionAM.xml.

I've got Exception Details.
oracle.apps.fnd .framework.OAEx ception: java.lang.NullP ointerException

No more screen shot has available.

Best regards
Quote
0 #20 Guy 2014-11-07 15:48
Hi

the property specified in RequisitionAM.x ml is


How can we do to Override this oracle.apps.icx .por.req.webui. CheckoutSummary CO method ?
The DFF is copy to line DFF, but when click on button "next" don't pass to the next step.

Best Regards
Quote
0 #21 Guy 2014-11-07 15:49
Hi

the property specified in RequisitionAM.x ml is


How can we do to Override this oracle.apps.icx .por.req.webui. CheckoutSummary CO method ?
The DFF is copy to line DFF, but when click on button "next" don't pass to the next step.

Best Regards
Quote
0 #22 Guy 2014-11-07 15:50
the property specified in RequisitionAM.x ml is
Property Name ="PorClassMap" Value ="xxap.oracle.a pps.icx.por.com mon.xxapClassMa p"
Quote
0 #23 execgrp sales 2014-11-17 10:41
Remarkable! Its really amazing article, I have got
much clear idea on the topic of from this post.
Quote
0 #24 Gayatri 2014-12-29 22:59
Hi Kishore,
Can you please let me if it is possible to copy 1 line's CCID to all other lines in the iProc Requisition.
Navigation:
Checkout -> Edit Lines -> Accounts tab -> select only 1 line and then after hitting a custom button, the line's CCID should get copied to the CCID of all other lines in the req.
Thanks,
Quote
0 #25 Moumita 2015-02-19 10:26
Hi ,

I want to update the Requisition Distributions DFF from Checkout screen where I have added an additional message input text field.(Not part of any DFF). Please help.

Thanks,
Moumita.
Quote
0 #26 Guy 2015-02-19 15:19
Hi,
If you want to input datat into Requisition Distributions DFF, You can add segments in the forms :
Application + Flexfield + Descriptive + Segement
Search title = "Requisition Distributions"
And Click on Segment and add DFF.

Set Rendered = True.

--- Building Blocks ---
• POR_CUSTOM_PKG PLSQL package
The standard custom procedure POR_CUSTOM_PKG. CUSTOM_VALIDATE _REQ_LINE will be modified to do the below validations.
Validation1:
o Get the code affaire field is required or not for the requisition organization, from the ‘Item Categories’ DFF  ‘201’ context  Attribute 6 to Attribute 10.
o If the code affaire field is required and the value is not provided at the requisition line, then raise the custom error message ‘Le code affaire est obligatoire pour cette catégorie d’achat’.
Validation2:
o Get the code affaire code value from XX_AFFAIRE value set and get the IPROC_ENABLED value for this, from ‘Flexfield Segment Values’ DFF ‘Global Data Elements’  Attribute2.
o If attribute value is N or null, then raise the custom error message ‘Le code affaire n’est pas ouvert pour iProc’.

• XXZZ_WF_ACCT_GENRTR_PK custom package used in workflow.
This package contains the procedures,
INTERNAL_SUPPLIER_CHECK to get the intra group value from the liability account of the internal supplier and assign this value to the workflow attribute XXZZ_ACCRUAL_ACC_SEGMENT4.
CHECK_CODE_AFFAIRE to check the code affaire value is null or not null.

• PoRequisitionLineEO extension
The oracle.apps.icx .por.schema.ser ver.PoRequisiti onLineEO has to be extended by setting the AccountLineBizA ttrSet property to ‘Y’ for attribute1. This is to trigger the account generator.
The extended EO is XXZZ.oracle.apps.icx.por.schema.server.XXZZPoRequisitionLineEO.
The extended EO has to be substituted in place of the standard EO using the JPX import.

--- WORKFLOW CUSTOMIZATION ---
POWFRQAG PO Requisition Account Generator Standard Workflow hab been modified...

+ Workflow Display Name PO Requisition Account Generator
Internal Name POWFRQAG
Process Internal Name BUILD_EXPENSE_CHARGE_ACCOUNT
Process Display Name Build Expense Charge Account


+ Workflow Display Name PO Requisition Account Generator
Internal Name POWFRQAG
Process Internal Name DEFAULT_ACCRUAL_ACC_GENERATION
Process Display Name Generate Default Accrual Account

+ Workflow Display Name PO Account Generator
Internal Name POWFPOAG
Process Internal Name DEFAULT_ACCRUAL_ACC_GENERATION
Process Display Name Generate Default Accrual Account
Quote
0 #27 Override method 2015-03-09 10:47
Hi,

Can you please give us a sample code to Override this oracle.apps.icx .por.req.webui. CheckoutSummary CO method.

For exemple, how to refresh the billing Charge Account ?

Best regards,
Quote
0 #28 pavan229 2015-07-13 08:58
Hi Kishore,

I had similar requirement in iprocurement. I need to change the Change button functionality when requisition is selected and clecked on Change Button. For that we extended RequisitionSumm aryCO and PorClassMap and ReqMgmtActionsS vrCmb files. But the Custom Server Command file was not triggered instead standard server command file got called. Its in R12 12.2.4. Our's is upgrade project and same worked in 11i but its not working in R12. Could you please suggest where the issue could be..
Quote

Add comment


Security code
Refresh

Search Trainings

Fully verifiable testimonials

Apps2Fusion - Event List

<<  Aug 2021  >>
 Mon  Tue  Wed  Thu  Fri  Sat  Sun 
        1
  2  3  4  5  6  7  8
  9101112131415
16171819202122
23242526272829
3031     

Enquire For Training

Related Items

Fusion Training Packages

Get Email Updates


Powered by Google FeedBurner