30 October, 2017

API to update Project code on Requisition

Below API can be used in oracle apps to Update the project code on requisition.

set serveroutput on
DECLARE

l_req_hdr PO_REQUISIITON_UPDATE_PUB.req_hdr;
l_req_line_tbl  PO_REQUISIITON_UPDATE_PUB.req_line_tbl;
l_req_dist_tbl PO_REQUISIITON_UPDATE_PUB.req_dist_tbl;
l_return_status VARCHAR2(1);
l_msg_count NUMBER;
l_msg_data VARCHAR2(2000);

BEGIN

dbms_output.ENABLE(1000000);
   fnd_global.Apps_initialize(108970, 20707, 201);
   -- pass in user_id, responsibility_id, and application_id 
   oe_msg_pub.initialize;
   oe_debug_pub.initialize;
   mo_global.Init ('ONT'); -- Required for R12
   mo_global.Set_org_context (101, NULL, 'ONT');
   fnd_global.Set_nls_context ('AMERICAN');
   mo_global.Set_policy_context ('S', 101);
 
l_req_hdr.segment1 :='Test123';
l_req_hdr.org_id := 101;

l_req_dist_tbl.project_id := 344;

dbms_output.put_line('Before calling the API');

PO_REQUISIITON_UPDATE_PUB.update_requisition(1.0,
'F',
'N',
l_return_status,
l_msg_count,
l_msg_data,
'Y',
l_req_hdr,
    l_req_line_tbl,
    l_req_dist_tbl
);

dbms_output.put_line('After calling the API');
dbms_output.put_line('l_return_status'||l_return_status);
    dbms_output.put_line('l_msg_count'||      l_msg_count);
    dbms_output.put_line('l_msg_data'|| l_msg_data);

END;
/

Oracle apps Requisition Cancellation API

Below API can be used for Oracle apps Requisition cancellation.

DECLARE
   v_requisition_header_id po_requisition_headers_all.requisition_header_id%TYPE;
   v_requisition_line_id   po_requisition_lines_all.requisition_line_id%TYPE;
   v_REQ_HEADER_ID         PO_TBL_NUMBER;
   v_REQ_LINE_ID           PO_TBL_NUMBER;
   v_msg                   VARCHAR2(1000);
   x_returnstatus          VARCHAR2(10);
   x_msgcount              NUMBER;
   x_msgdata               VARCHAR2(200);
BEGIN
FND_GLOBAL.APPS_INITIALIZE(
user_id => 43867 -- User ID
, resp_id => 20707 -- Order Management Super User
, resp_appl_id => 201 -- Oracle Order Management
);
MO_GLOBAL.INIT('PO');
mo_global.set_policy_context('S', 101);


FOR i IN (SELECT         
               prh.requisition_header_id,
               prl.requisition_line_id
            FROM
               apps.po_requisition_lines_all prl
where <desired conditions .. >
             
)
LOOP
          v_requisition_header_id := i.requisition_header_id;
          v_requisition_line_id   := i.requisition_line_id;
--
            v_REQ_HEADER_ID := PO_TBL_NUMBER(v_requisition_header_id);
            v_REQ_LINE_ID   := PO_TBL_NUMBER(v_requisition_line_id);
            --Cancelling the requisition
            po_req_document_cancel_grp.cancel_requisition(p_api_version => 1.0,
                                                          p_req_header_id => v_REQ_HEADER_ID,
                                                          p_req_line_id => v_REQ_LINE_ID,
                                                          p_cancel_date => SYSDATE,
                                                          p_cancel_reason => 'QTY shipped',
                                                          p_source => NULL,
                                                          x_return_status => x_returnstatus,
                                                          x_msg_count => x_msgcount,
                                                          x_msg_data => x_msgdata);
END LOOP;
END;

COMMIT;
/

API to Cancel Sales order

Below API block is used for the Sales order cancellation.

declare
      v_api_version_number NUMBER := 1;
      v_return_status      VARCHAR2(2000);
      v_msg_count          NUMBER;
      v_msg_data           VARCHAR2(2000);
 
      -- IN Variables --
      v_header_rec         oe_order_pub.header_rec_type;
      v_line_tbl           oe_order_pub.line_tbl_type;
      v_action_request_tbl oe_order_pub.request_tbl_type;
      v_line_adj_tbl       oe_order_pub.line_adj_tbl_type;
 
      -- OUT Variables --
      v_header_rec_out             oe_order_pub.header_rec_type;
      v_header_val_rec_out         oe_order_pub.header_val_rec_type;
      v_header_adj_tbl_out         oe_order_pub.header_adj_tbl_type;
      v_header_adj_val_tbl_out     oe_order_pub.header_adj_val_tbl_type;
      v_header_price_att_tbl_out   oe_order_pub.header_price_att_tbl_type;
      v_header_adj_att_tbl_out     oe_order_pub.header_adj_att_tbl_type;
      v_header_adj_assoc_tbl_out   oe_order_pub.header_adj_assoc_tbl_type;
      v_header_scredit_tbl_out     oe_order_pub.header_scredit_tbl_type;
      v_header_scredit_val_tbl_out oe_order_pub.header_scredit_val_tbl_type;
      v_line_tbl_out               oe_order_pub.line_tbl_type;
      v_line_val_tbl_out           oe_order_pub.line_val_tbl_type;
      v_line_adj_tbl_out           oe_order_pub.line_adj_tbl_type;
      v_line_adj_val_tbl_out       oe_order_pub.line_adj_val_tbl_type;
      v_line_price_att_tbl_out     oe_order_pub.line_price_att_tbl_type;
      v_line_adj_att_tbl_out       oe_order_pub.line_adj_att_tbl_type;
      v_line_adj_assoc_tbl_out     oe_order_pub.line_adj_assoc_tbl_type;
      v_line_scredit_tbl_out       oe_order_pub.line_scredit_tbl_type;
      v_line_scredit_val_tbl_out   oe_order_pub.line_scredit_val_tbl_type;
      v_lot_serial_tbl_out         oe_order_pub.lot_serial_tbl_type;
      v_lot_serial_val_tbl_out     oe_order_pub.lot_serial_val_tbl_type;
      v_action_request_tbl_out     oe_order_pub.request_tbl_type;
 
      v_user_id      NUMBER := apps.fnd_global.user_id;
      v_resp_id      NUMBER := apps.fnd_global.resp_id;
      v_resp_appl_id NUMBER := apps.fnd_global.resp_appl_id;
      v_org_id       NUMBER;
   BEGIN
 
      -- Setting the Enviroment --
     
      v_user_id      := 43867;
      v_resp_id      := 56633;
      v_resp_appl_id := 660;
      v_org_id       := 116919;
 
      mo_global.init('ONT');
      fnd_global.apps_initialize(user_id => v_user_id, resp_id => v_resp_id,
                                 resp_appl_id => v_resp_appl_id);
      mo_global.set_policy_context('S', v_org_id);
 
      FOR I IN (SELECT oh.header_id order_header_id
                FROM   oe_order_headers_all oh
                WHERE  oh.order_number IN ( 145054061)
                AND    oh.org_id = v_org_id)
      LOOP
        BEGIN
              -- CANCEL HEADER --
              Dbms_Output.put_line ('order header id : ' || i.order_header_id);
          v_header_rec                := oe_order_pub.g_miss_header_rec;
          v_header_rec.operation      := OE_GLOBALS.G_OPR_UPDATE;
          v_header_rec.header_id      := i.order_header_id;
          v_header_rec.cancelled_flag := 'Y';
          v_header_rec.change_reason  := 'Cancel for Test';
     
          dbms_output.put_line( 'Starting cancel of API');
     
          -- CALLING THE API TO CANCEL AN ORDER --
     
          OE_ORDER_PUB.PROCESS_ORDER(p_api_version_number => v_api_version_number,
                                     p_header_rec => v_header_rec,
                                     p_line_tbl => v_line_tbl,
                                     p_action_request_tbl => v_action_request_tbl,
                                     p_line_adj_tbl => v_line_adj_tbl
                                     -- OUT variables
                                    , x_header_rec => v_header_rec_out,
                                     x_header_val_rec => v_header_val_rec_out,
                                     x_header_adj_tbl => v_header_adj_tbl_out,
                                     x_header_adj_val_tbl => v_header_adj_val_tbl_out,
                                     x_header_price_att_tbl => v_header_price_att_tbl_out,
                                     x_header_adj_att_tbl => v_header_adj_att_tbl_out,
                                     x_header_adj_assoc_tbl => v_header_adj_assoc_tbl_out,
                                     x_header_scredit_tbl => v_header_scredit_tbl_out,
                                     x_header_scredit_val_tbl => v_header_scredit_val_tbl_out,
                                     x_line_tbl => v_line_tbl_out,
                                     x_line_val_tbl => v_line_val_tbl_out,
                                     x_line_adj_tbl => v_line_adj_tbl_out,
                                     x_line_adj_val_tbl => v_line_adj_val_tbl_out,
                                     x_line_price_att_tbl => v_line_price_att_tbl_out,
                                     x_line_adj_att_tbl => v_line_adj_att_tbl_out,
                                     x_line_adj_assoc_tbl => v_line_adj_assoc_tbl_out,
                                     x_line_scredit_tbl => v_line_scredit_tbl_out,
                                     x_line_scredit_val_tbl => v_line_scredit_val_tbl_out,
                                     x_lot_serial_tbl => v_lot_serial_tbl_out,
                                     x_lot_serial_val_tbl => v_lot_serial_val_tbl_out,
                                     x_action_request_tbl => v_action_request_tbl_out,
                                     x_return_status => v_return_status,
                                     x_msg_count => v_msg_count,
                                     x_msg_data => v_msg_data);
     
          dbms_output.put_line( 'Completion of API');
     
          IF v_return_status = fnd_api.g_ret_sts_success THEN
             COMMIT;
             dbms_output.put_line(
                               'Order Cancellation Success : ' ||
                                v_header_rec_out.header_id);
          else
             dbms_output.put_line(
                               'order cancellation failed:' || v_msg_data);
             rollback;
             for i in 1 .. v_msg_count
             loop
                v_msg_data := oe_msg_pub.get(p_msg_index => i, p_encoded => 'f');
                dbms_output.put_line( i || ') ' || v_msg_data);
             end loop;
          end if;
        exception
          when others then
             dbms_output.put_line('error in cancel_sales_order_api. reason is :' || sqlerrm);       
        end;
      end loop;
   exception
      when others then
         dbms_output.put_line('error in block. reason is :' || sqlerrm);
     
   end ;

Required Setups for MOAC

Below are the steps required for MOAC:

1.       To Define Security profile
·         Navigate to Security profile (see below screenshot)
·         Enter a unique name for the security profile(Test1 Multi OU).
·         To restrict access by discrete list of organizations, select ‘Secure organizations by organization hierarchy and/or organization list for the Security Type’.

·         In the organization name field, select the Operating Unit for which you want access.




1.       To Run the concurrent program “Security List Maintenance Program”
·         Run the concurrent program “Security List Maintenance Program” from the standard request submission form.
·         The “Security List Maintenance Program” can be run for a single named security profile to prevent impact to other security profiles.



1.       Assigning to MO: Security Profile
·         Assign appropriate security to the profile option “MO: Security Profile” for your users and responsibilities
·         Navigate to the “System Administrator” responsibility > System Profile Options, Assign the security profiles to MO: Security Profile for your responsibilities and/or users.


How to Re-trigger Oracle Business events


1.       Go to responsibility: Workflow Administrator Web Applications.
2.       Navigate to: Administrator Workflow à Business Event
3.       Search for the event name: oracle.apps.wsh.delivery.gen.shipconfirmed


1.       Click on “Test” Button.
Note: If Test button is not visible on screen then this is the access issue.
In this case, run below command.
update wf_resources set text='*' where name like 'WF_ADMIN_ROLE';            
commit;              
Re-open application.
Now you can see the Test button.
2.       In this screen, give details as below.
Event Key : <Delivery Id which needs to retrigger eg. 17190692>
Event parameters,
Label: DELIVERY_ID
Value: <Delivery Id which needs to retrigger eg. 17190692>

Now click on button: Raise in PLSQL


Thus, Event is re-triggered for the given delivery ID.
You can check the entry in event tables with below queries.
   select DEQ_TIME, DEQ_TID, a.* from WF_DEFERRED a WHERE CORRID = 'APPS:oracle.apps.wsh.delivery.gen.shipconfirmed';


If DEQ_TIME, DEQ_TID is not null then, Data is been dequeued to BPEL Queue.

If DEQ_TIME, DEQ_TID is null then, we need to raise ticket to bounce the workflow manager “Workflow agent listener”.
Retest the process after bounce.

  Now check below query.
      
select CONSUMER_NAME, MSG_STATE ,DEQ_TIME , DEQ_TIMESTAMP,
tab.* from apps.AQ$WF_BPEL_QTAB tab 
where tab.user_data.event_name = 'oracle.apps.wsh.delivery.gen.shipconfirmed' order by ENQ_TIME DESC   ;


If MSG_STATE is ‘PROCESSED’ then the Data is received at SOA end.
If MSG_STATE is other than Processed then ask SOA to restart the process.

Query to check parameters passed to event:

SELECT wd.user_data.event_name,
       wd.user_data.event_key,
       rank() over(PARTITION BY wd.user_data.event_name, wd.user_data.event_key ORDER BY n.NAME) AS serial_no,
       n.NAME parameter_name,
       n.VALUE parameter_value,
       wd.user_data.error_message,
       wd.user_data.error_stack,
       wd.msgid,
       wd.delay
  FROM apps.wf_deferred wd, TABLE(wd.user_data.parameter_list) n
 WHERE  1=1
 AND wd.user_data.event_name LIKE '%shipconfirmed%'
 ORDER BY wd.user_data.send_date DESC,
          wd.user_data.event_name,
          wd.user_data.event_key,
          n.NAME;


If you wish to re-trigger the event from database then use below block.
give the required delivery id for p_value and p_event_key parameters.

   declare
  l_parameters wf_parameter_list_t := wf_parameter_list_t();
begin

  wf_log_pkg.init(1, null, 1, 'wf%');
  wf_event.addparametertolist(p_name          => 'DELIVERY_ID',
                              p_value         => '9169530',
                              p_parameterlist => l_parameters);
  wf_event.raise(p_event_name => 'oracle.apps.wsh.delivery.gen.shipconfirmed',
                 p_event_key  => '9169530',
                 p_event_data => NULL,
                 p_parameters => l_parameters,
                 p_send_date  => sysdate);
  commit;

end;

How To Setup Oracle Business Event


The Oracle Workflow Business Event System is an application service that leverages the Oracle Advanced Queuing (AQ) infrastructure to communicate business events between systems. The Business Event System consists of the Event Manager and workflow process event activities.
The Event Manager contains a registry of business events, systems, named communication agents within those systems, and subscriptions indicating that an event is significant to a particular system. Events can be raised locally or received from an external system or the local system through AQ. When a local event occurs, the subscribing code is executed in the same transaction as the code that raised the event, unless the subscriptions are deferred.
Subscriptions can include the following types of processing:
  • Executing custom code on the event information
  • Sending event information to a workflow process
  • Sending event information to other queues or systems
  • Sending a notification based on the event information
  • Sending or receiving an Oracle XML Gateway message
  • Invoking a business process execution language (BPEL) process or other Web service

The uses of the Business Event System include:
  • System integration messaging hubs - Oracle Workflow with the Business Event System can serve as a messaging hub for complex system integration scenarios. The Event Manager can be used to "hard-wire" routing between systems based on event and originator. Workflow process event activities can be used to model more advanced routing, content-based routing, transformations, error handling, and so on.
  • Distributed applications messaging - Applications can supply generate and receive event message handlers for their business entities. For example, message handlers can be used to implement master/copy replication for distributed applications.
  • Message-based system integration - You can set up subscriptions which cause messages to be sent from one system to another when business events occur. In this way, you can use the Event Manager to implement point-to-point messaging integration.
  • Business event-based workflow processes - You can develop sophisticated workflow processes that include advanced routing or processing based on the content of business events.
  • Non-invasive customization of packaged applications - Analysts can register interesting business events for their internet or intranet applications. Users of those applications can register subscriptions to those events to trigger custom code or workflow processes.
 Lets see in details, how to set up the business event.     
      
Go to system administrator responsibility.

Setup Event:

Navigate to workflow à Administrator workflowà Business events
Search for the below business event.
If event status is not enabled, then go to event details and make it enable.

oracle.apps.wsh.delivery.gen.shipconfirmed


Setup event subscription: 

Click on subscription.
                Click on create subscription. Give below details.
System: <System name from lookup>
Source type: Local
Event filter: oracle.apps.wsh.delivery.gen.shipconfirmed
Phase: 105 (enter some number greater than 100)
Status: Enabled
Rule Data: Key
Action Type: Custom
On Error: Stop and Rollback


Click on next.
PL/SQL Rule Function: WF_RULE.DEFAULT_RULE
Out agent: WF_BPEL_QAGENT@<System name>
Priority: Normal
Owner Name: Shipping Execution
Owner Tag: WSH
Description: Subscription for enqueuing event in WF_BPEL_Q


Apply and save the changes.

Setup event queue subscriber


Now, we need to create the subscriber for the SOA Queue.
To create subscriber, Run below script.
DECLARE
subscriber sys.aq$_agent;
BEGIN
subscriber := sys.aq$_agent('WF_BPEL_Q', NULL, 0);
DBMS_AQADM.ADD_SUBSCRIBER(queue_name => 'APPS.WF_BPEL_Q',
subscriber => subscriber,
rule => 'tab.user_data.event_name=''' ||
'oracle.apps.wsh.delivery.gen.shipconfirmed' || '''');
END;
  

Restart the workflow agent listener service


Once finished with above steps.
Restart the workflow agent listened service.
Go to system administrator responsibility.
Navigate to: Concurrent à Manager à Administer
Search for: Workflow Agent Listener Service
And click on Restart.



Note: Whenever you change any setup on event/ event subscriptions/ queue subscriber, restart the Workflow Agent Listener Service to reflect the change. Else Event stops working.


Imp Queries related to events:

-------------- Query to Check the subscribers of the event ---------------

select * from wf_event_subscriptions wes
where wes.event_filter_guid in (select we.guid
from wf_events we where we.name= ‘oracle.apps.wsh.delivery.gen.shipconfirmed’
union
select weg.group_guid from wf_event_groups weg
where weg.member_guid in (select we.guid
from wf_events we where we.name= ‘oracle.apps.wsh.delivery.gen.shipconfirmed’)
);

--------------- Trigger business event from backend -----------------

   declare
  l_parameters wf_parameter_list_t := wf_parameter_list_t();
begin

  wf_log_pkg.init(1, null, 1, 'wf%');
  wf_event.addparametertolist(p_name          => 'DELIVERY_ID',
                              p_value         => '9169530',
                              p_parameterlist => l_parameters);
  wf_event.raise(p_event_name => 'oracle.apps.wsh.delivery.gen.shipconfirmed',
                 p_event_key  => '9169530',
                 p_event_data => NULL,
                 p_parameters => l_parameters,
                 p_send_date  => sysdate);
  commit;
end;

----------------- Event Error Table ---------------------------

SELECT * FROM WF_ERROR   ;

---------- Query to find event parameters/ key details --------------
SELECT wd.user_data.event_name,
       sender_name,
       sender_address,
       sender_protocol,
       wd.user_data.event_key,
       n.NAME parameter_name,
       n.VALUE parameter_value,
       wd.user_data.error_message,
       wd.user_data.error_stack,
       wd.msgid,
       wd.delay
  FROM apps.wf_deferred wd, TABLE(wd.user_data.parameter_list) n
 WHERE  1=1
AND wd.user_data.event_name LIKE '%oracle.apps.wsh.delivery.gen.shipconfirmed%'
 ORDER BY wd.user_data.send_date DESC,
          wd.user_data.event_name,
          wd.user_data.event_key,
          n.NAME

--------------- Query to get triggered event details -------------------

 select * from WF_DEFERRED WHERE CORRID = 'oracle.apps.wsh.delivery.gen.shipconfirmed';

   select CONSUMER_NAME, ADDRESS,  PROTOCOL,  EXPIRATION_REASON,
tab.* from AQ$WF_BPEL_QTAB tab  where tab.user_data.event_name = 'oracle.apps.wsh.delivery.gen.shipconfirmed' order by ENQ_TIME DESC   ;

    SELECT * FROM APPs.WF_BPEL_QTAB ;

--------------- Query to get queue subscriber details ----------------

 SELECT * FROM ALL_QUEUE_SUBSCRIBERS WHERE QUEUE_NAME = 'WF_BPEL_Q' ;


When, Event activity happens and Event is triggered for the given delivery ID.
You can check the entry in event tables with below queries.
   select DEQ_TIME, DEQ_TID, a.* from WF_DEFERRED a WHERE CORRID = 'APPS:oracle.apps.wsh.delivery.gen.shipconfirmed';


If DEQ_TIME, DEQ_TID is not null then, Data is been dequeued to BPEL Queue.

If DEQ_TIME, DEQ_TID is null then, we need to raise ticket to bounce the workflow manager “Workflow agent listener”.
Retest the process after bounce.

  Now check below query.
      
select CONSUMER_NAME, MSG_STATE ,DEQ_TIME , DEQ_TIMESTAMP,
tab.* from apps.AQ$WF_BPEL_QTAB tab 
where tab.user_data.event_name = 'oracle.apps.wsh.delivery.gen.shipconfirmed' order by ENQ_TIME DESC   ;


If MSG_STATE is ‘PROCESSED’ then the Data is received at SOA end.
If MSG_STATE is other than Processed then ask SOA to restart the process.

Query to check parameters passed to event:

SELECT wd.user_data.event_name,
       wd.user_data.event_key,
       rank() over(PARTITION BY wd.user_data.event_name, wd.user_data.event_key ORDER BY n.NAME) AS serial_no,
       n.NAME parameter_name,
       n.VALUE parameter_value,
       wd.user_data.error_message,
       wd.user_data.error_stack,
       wd.msgid,
       wd.delay
  FROM apps.wf_deferred wd, TABLE(wd.user_data.parameter_list) n
 WHERE  1=1
 AND wd.user_data.event_name LIKE '%shipconfirmed%'
 ORDER BY wd.user_data.send_date DESC,
          wd.user_data.event_name,
          wd.user_data.event_key,
          n.NAME;




27 October, 2017

How to implement Sales Order UDA in Oracle Apps

UDA Introduction


Oracle Order Management enables you to record additional information at order and line levels using user defined attributes (UDA). These attributes are aggregated in user-defined attribute groups. Each group can have several attributes.
You must associate attribute groups with a particular business classification, which in the case of Order Management is the predefined classification, ADMIN_DEFINED.
An attribute group can have a maximum of 40 character fields, 20 number fields, and 10 date fields. However, you can associate as many attribute groups as you want to an UDA page which makes the number of additional attributes to an order or line unlimited.




UDA Setup steps: 

Create Attribute Group


Go to order management Super User responsibility
Navigate to Setup à Orders à User Defined Attributes.


Choose the Entity: Header or Line and Click on Go in the OM UDA Setup page.












Click on 
Create Button.
Fill the details as required.
Internal Name: Used for technical purpose.
Display name: Actual name to be displayed on User Interface.
Behavior: An attribute group can be multi-row or single-row. Multi-row attribute groups enable association of multiple sets of attribute values with the same attribute group, whereas single-row attribute groups allow a single attribute value for the attribute group.
Number of columns in the page layout: Columns you want to display on UDA User Interface. It’s 2 by default.
Click on Apply and Add Attributes button.


Generate Database View


This is optional setup to create the database view.
Click on button Generate Database View. It will automatically create customized database view of a group based on the attributes under the particular attribute group.

For example: here we have created database view: ONT_TEST_GRP1_AGV


If we check this view in database, we will get below description of view.



The custom name Test_attr1 is populated for the actual column c_EXT_ATTR1.
Note: If you are using this auto created database view in any development, then generate the view every time you make any change (Changes can be addition/ deletion/ rename of attribute) to the attribute group. It will refresh the view to reflect the changes made in group.

Create Attributes


Internal Name: Used for technical purpose.
Display Name: Name displayed on UDA user interface.
Sequence: Sequence of attribute to be appear on user interface.
Tip: Tip is the information message which appears just below the attribute in user interface.
Data Type: Select appropriate data type.
Column: columns will be populated as per the data type selected.
Example: For char it will populate is c_EXT_ATTR1, for number, It will populate as N_EXT_ATTR1 etc.
Display As: Type of display field on UI.
You can additionally assign value set and default value to the attribute.
Click on Apply button.



Associate Attribute Group with A Classification


Click on association tab.










Click on Add Attribute Groups.










Select the attribute groups from the list of available attribute groups. Click on Apply.
It adds the attribute groups to the predefined classification, ADMIN_DEFINED.

Create UDA Page


In the OM UDA Page Setup page select Page tab.
Select Create Page to create pages for a particular Classification. An UDA page is a group of attribute groups associated to a classification.














Display Name: Name to be displayed on UI.
Internal Name: Used for technical purpose.
Description: Information for page usage.
Sequence: Sequence of page to be displayed in UDA UI selection list.
Click Apply.

Attach Attribute Group to Page


Click on create symbol. 
Give the Sequence. Click on Display name LOV.


























Click on Go.












It will populate the list of the attribute groups created.
Select the desired attribute group and click on Apply.





Note: If you want the additional attributes to appear in different regions, then create multiple attribute groups and associate them to the predefined classification, and then to an UDA page.



Import User Defined Attributes


You can add and associate UDA to the orders created through Order Import/HVOP using order interface tables and the Import User Defined Attributes concurrent program.

Steps

1.       Create the sample sales order.
2.       Populate data into the following UDA interface tables:
o    OE_HEADERS_EXT_IFACE_ALL
o    OE_LINES_EXT_IFACE_ALL
3.       After data is populated in the UDA interface tables, submit the Import User Defined Attributes concurrent program by providing the Data Set ID parameter to import data into the following Order Extension base tables:
o    OE_ORDER_HEADERS_ALL_EXT_B
o    OE_ORDER_LINES_ALL_EXT_B
4.       The import program reports errors in the MTL_INTERFACE_ERRORS table.
After completing these steps, you can record information in the user defined attributes from the Sales Order window as shown in topic: UDA on User Interface.

Base tables

Below are few important tables for attribute and group information:
1.       EGO_ATTR_GROUPS_V
2.       EGO_DATA_LEVEL_B
3.       EGO_ATTRS_V

UDA on User Interface


Open sample sales order.
Click on Actions button present on order Line tab.
Select User Defined Attributes from the list.





















Below screenshot shows the sample UDA page for sample order line entity.



Note: similarly the order header entity, UDA will be accessed using below path.
Order Header à Actions à User Defined Attributes.