12 Implement Audit Reports

This chapter describes how to implement Audit Reports in Oracle Fusion Applications.

This chapter contains the following sections:

12.1 Introduction to Audit Reports

Audit Reports creates a history of the changes that have been made to data in Oracle Fusion Applications. Audit Reports includes information such as what operation was performed on an item, when it was performed, and how the value was changed. The audit information is logged without any interaction from the end user.

The auditing solution brings together multiple underlying auditing frameworks, such as Oracle Fusion Middleware auditing that is based on an Oracle Platform Security Services (OPSS) framework, and Oracle Fusion Applications auditing that is based on an Oracle Fusion Middleware Extensions for Applications framework. The OPSS framework captures audit information through events that applications raise during their processing. The Applications Core framework creates a "shadow" table to record all operations on the base table.

12.2 Implement Audit Reports in the Oracle Fusion Applications Framework

Database auditing involves observing a database to be aware of the actions of database users. Audit setup provides a user interface mechanism for administrators to choose and select the objects and the specific attributes that need to be audited. When an object has been set to be audited using the audit setup user interface, any Data Manipulation Language (DML) actions on this object, that is, its underlying database schema objects, are captured and stored for reporting purposes.

The Audit Setup UI page is a task flow that is made available through the Oracle Fusion Middleware Extensions for Applications library. This task flow is available in Functional Setup Manager and can be included in an application that is accessible by the administrator. The UI consists of an Applications Tree Table that holds the structure of the auditable application modules, the children application modules, if present, and all the auditable view objects and their children. The administrator selects the view object on which to start auditing and in the applications table components below the tree table, the administrator chooses to add the attributes that need to be audited.

You also can set up the Fusion Middleware auditing as described in How to Set Up Auditing.

Metadata

Two database schema tables, FND_AUDIT_WEBAPP_AM and FND_AUDIT_ATTRIBUTES, hold metadata information that is required for Auditing.

  • FND_AUDIT_WEBAPP_AM captures the list of application modules for an application.

    WEBAPP APPLICATION_MODULE

    VARCHAR2(80)

    VARCHAR2(240)

  • FND_AUDIT_ATTRIBUTES table data is populated during runtime when view objects are configured using the Audit Setup UI. This is an internal table and should not be changed.

    WEBAPP VIEW_OBJECT VIEW_ATTRIBUTE ENABLED_FLAG TABLE_NAME COLUMN_NAME

    VARCHAR2(80)

    VARCHAR2(240)

    VARCHAR2(80)

    VARCHAR2(1)

    VARCHAR2(30)

    VARCHAR2(30)

12.2.1 How to Set Metadata

This section covers the steps needed to populate and define metadata needed to run the Audit task flows.

To populate and define metadata:

  1. Make sure every application has the webApp defined and set. This is done by populating the Oracle Fusion Applications Functional Core (ASK) deployment tables. These tables are populated at deployment time through Oracle Fusion Functional Setup Manager tasks.

    The webApp value is your MODULE_SHORT_NAME from the ASK_MODULES table.

  2. Determine, for a given module, what are the applications modules that are to be registered in the metadata table (fnd_audit_webapp_am) for audit purposes. You can use the AuditServiceAM to register these applications modules. This service allows data to be extracted and uploaded.

    To use the AuditServiceAM, follow these steps:

    • Right-click your Model project.

    • Select Seed Date > Import/Export.

    • Select AuditServiceAM in the wizard that is displayed. If it is not available, make sure to import it to your project.

    • Click OK.

    If you do not have access to, or know how to use the AuditServiceAM, you can run this SQL example (using appropriate values).

    describe fnd_audit_webapp_am;
    insert into fnd_audit_webapp_am values ('ApplCoreCRMDemo', 'oracle.apps.fnd.applcore.crmdemo.model.CrmDemoAM', sysdate, 'pjl', sysdate, 'pjl', 'pjl',1);
    commit;
    select * from fnd_audit_webapp_am;
    
  3. Enable Audit on the Base Table.

    You need to create a shadow table for each base table that is being audited. To create the shadow table:

    • Open the .table file in JDeveloper.

    • Right-click this object and select Properties.

    • In the wizard that is displayed, select User Properties.

    • In the list that is displayed on the right, scroll down to select the property Enable Audit and set its value to Y, as shown in Figure 12-1.

      Figure 12-1 Setting Audit on a Table

      Setting Audit on A Table
    • Save your changes.

    • A new .table file will be created. This table will have an underscore (_) at the end of the name.

    • Check in this new file.

    Note: If your base table is enabled for multi tenant, make the same changes for the shadow table.

  4. Set the Shadow Table Name on the entity object.

    When a shadow table has been created, set this name on your base table EO.xml file as a schema-based property.

    Property Name - "FND_AUDIT_TABLENAME"
    Property Value - Shadow table name created in step 4.
     
    <Properties>
      <SchemaBasedProperties>
        <fnd:FND_AUDIT_TABLENAME
             Value="FND_SERVICE_REQUESTS_"/>
      </SchemaBasedProperties>
    </Properties>
    
  5. Determine which business objects of each application module may be audited. When the business objects are identified, set a non-translatable schema-based property, named FND_AUDIT_ENABLED, on it with Name="Auditable" and Value="Y". Only when this property is set will the business object be shown in the Audit Setup UI for auditing. This follows an opt-in policy.
    <Properties>
      <SchemaBasedProperties>
      <fnd:FND_AUDIT_ENABLED
           Value="true"/>
      </SchemaBasedProperties>
    </Properties>
    
  6. Determine which attributes of each business object you do want to audit and which ones you do not want to audit. By default:
    • Attributes with a schema-based property called FND_AUDIT_ATTR_ENABLED and Value="false" will not be shown in the attribute selection dialog (see Figure 12-4).

    • Attributes that are history columns are not shown (for example: Created By, Creation Date, Last Updated By)

    • Attributes with a schema-based property called FND_AUDIT_ATTR_ENABLED and Value="true" are on by default if the view object is audited. In the attribute selection dialog (see Figure 12-4), these attributes will be displayed on the right (selected) side of the shuttle.

    • If no value is set, the attribute will be available for selection in the attribute selection dialog (see Figure 12-4).

    <Entity
      xmlns="http://xmlns.oracle.com/bc4j"
      xmlns:fnd="http://xmlns.oracle.com/apps/entityview"
    ...
    <ViewAttribute
      Name="Attribute1"
      IsUpdateable="false"
      PrecisionRule="true"
      EntityAttrName="Attribute1"
      EntityUsage="AttributeEO"
      AliasName="ROWID">
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_ATTR_ENABLED
               Value="false"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    <ViewAttribute
      Name="Attribute2"
      IsUpdateable="false"
      PrecisionRule="true"
      EntityAttrName="Attribute2"
      EntityUsage="AttributeEO"
      AliasName="ROWID">
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_ATTR_ENABLED
               Value="true"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    
  7. Define user-friendly names for application modules, business objects and attributes.

    To have a user-friendly display name for all application modules, business objects and attribute names, the label property for each must be set. For application modules and business objects, you should add a tooltip, since the tooltip will be shown in the Audit Setup UI and also will give the administrator further information on the business objects and application module. The label and tooltip are available as properties.

    The following shows an example for a view object:

    <Properties>
      <SchemaBasedProperties>
        <fnd:FND_AUDIT_ENABLED
             Value="true"/>
        <LABEL
          ResId="ViewObjectVO_LABEL"/>
        <TOOLTIP
          ResId="ViewObjectVO_TOOLTIP"/>
      </SchemaBasedProperties>
    </Properties>
    <ResourceBundle>
      <XliffBundle
        id="oracle.apps.fnd.applcore.audit.test.model.view.common.ViewObjectVOMsgBundle"/>
    </ResourceBundle>
    

    The following shows an example for an attribute. Set the Label property under the UI Hints in the property inspector for an attribute.

    <ViewAttribute
      Name="TableName"
      PrecisionRule="true"
      EntityAttrName="TableName"
      EntityUsage="FndAuditAttributesEO"
      AliasName="TABLE_NAME">
      <Properties>
        <SchemaBasedProperties>
          <LABEL
             ResId="TableName_LABEL"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    
  8. Enable a User Key.

    The User Key is the value that will appear in the Description field in the Audit Reports. See Figure 12-5.

    If you need to be able to search based on a key other than the primary key of the view object, then you need to set a schema-based property called FND_AUDIT_USER_KEY on this attribute. This attribute must have a unique value and the new property should be set on only one attribute that is not the primary key. If you have a multi-part key, then you should use the one that is the most important as the User Key, and use the context name/value pairs for the others. Although end users may not be able to search down to just one item, they can see the context values to determine the ones in which they are interested.

    <ViewAttribute
      Name="TableName"
      IsUnique="true"
      IsNotNull="true"
      PrecisionRule="true"
      EntityAttrName="TableName"
      EntityUsage="FndTablesEO"
      AliasName="TABLE_NAME">
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_USER_KEY
               Value="true"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    
  9. Configure lookups on the User Key attribute.

    Foreign Key lookup can be configured on the User Key attribute. To do so, configure the User Key attribute and then configure the Foreign Key lookup. In addition, the annotation listed below needs to be mentioned at View Object level to derive the User Key from the lookup value (while a Description search is performed).

    The user key can be something other than a straight value. This is accomplished by allowing more tags to be used with the FND_AUDIT_USER_KEY tag:

    <fnd:FND_AUDIT_USER_KEY Value="true"/>
    <fnd:FND_AUDIT_FK_VIEWOBJECT Value=" "/>
    <fnd:FND_AUDIT_FK_DISPLAYATTR Value=" "/>
    <fnd:FND_AUDIT_FK_WHEREATTR Value=" "/>
    <fnd:FND_AUDIT_FK_WHEREATTR_ADDL Value=""/>
    <fnd:FND_AUDIT_VALUE_ADDL Value=" "/>
    <fnd:FND_AUDIT_USERKEY_LKP_COND Value=" "/> <!-- This attribute must be used if the FK tags are used. -->
     
    

    Example

    Assume the PersonId attribute is defined as the User Key and the Foreign Key lookup is defined on the User Key:

    <fnd:FND_AUDIT_USER_KEY Value="true"/>
    <fnd:FND_AUDIT_FK_VIEWOBJECT Value="abc.PersonVO"/>       
    <fnd:FND_AUDIT_FK_DISPLAYATTR Value="PersonName"/>
    <fnd:FND_AUDIT_FK_WHEREATTR Value="PersonId"/>
    <fnd:FND_AUDIT_USERKEY_LKP_COND Value="SELECT PERSON_ID FROM PERSONS WHERE PERSON_NAME LIKE ?"/>
    
  10. Configure custom objects.

    For custom business objects, identify the application module to which the custom business objects belong and add this to the metadata table as defined in step 5. Define the FND_AUDIT_ENABLED property as shown in step 4 on the custom business objects. If entity objects also are generated at a customer instance, set the property mentioned in step 4.

  11. If needed, configure the attribute lookup based on the FND_LOOKUPS table.

    For columns that show raw data of lookup codes instead of the meaning (such as "A034" instead of "washing machine"), you can specify annotation across the attribute specifying its lookup type. Audit Report internally queries the FND_LOOKUPS table for that lookup_type to show the column meaning. The schema-based property to use is FND_AUDIT_LOOKUP_TYPE as shown below:

    <ViewAttribute
    Name="ProblemDescription"IsNotNull="true"PrecisionRule="true"EntityAttrName="ProblemDescription"
      EntityUsage="ServiceRequestsEO"AliasName="PROBLEM_DESCRIPTION">&#160;&#160;
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_LOOKUP_TYPE
               Value="AHL_PLANNING_VISIT_TYPE"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    
  12. If needed, configure context descriptive attributes to show context attributes that define the context of a changed record.

    A maximum of 3 context descriptive attributes can be defined for a given view object. If context attributes were defined for both parent and child view objects, the report will show parent context information for parent records, and child context information for child records.

    Each context attribute must be defined with an annotation similar to that shown in the example but that has FND_AUDIT_CONTEXT2 and FND_AUDIT_CONTEXT3 as its prefix.

    If you need an additional WHERE condition to derive the context attribute value, you can use the _ADDL annotations, as shown in the example.

    <ViewObject ...
      <Properties>
        <CustomProperties>
          <Property Name="AUDIT_CONTEXT1_VIEWOBJECT" Value=""/> <!—fully qualified view object name, optional for same view -->
          <Property Name="AUDIT_CONTEXT1_DISPLAYATTR" Value=""/> <!-attribute of lookup view to display->
          <Property Name="AUDIT_CONTEXT1_WHEREATTR" Value=""/> <!-attribute of lookup view to apply WHERE condition->
          <Property Name="AUDIT_CONTEXT1_KEYATTR" Value=""/> <!- attribute of base view for WHERE condition key->
            <!- composite key specification - start->
            <Property Name="AUDIT_CONTEXT1_WHEREATTR_ADDL" Value=" "/> <!-attribute of lookup view to apply additional WHERE condition ->
            either <Property Name="AUDIT_CONTEXT1_VALUE_ADDL" Value=" "/>  <!- for hardcoded value ->
            or       <Property Name="AUDIT_CONTEXT1_KEYATTR_ADDL" Value=""/>  <!- attribute of base view for additional key->    
            <!- composite key specification - end->
        </CustomProperties>
      </Properties>
    </ViewObject>
    

    Example Use Case

    You want to specify Product as one of the context attributes for the Revenue view objects. But Product is composed of a composite key: InventoryItemId and InventoryOrgId.

    The specification will appear similar to:

    <ViewObject name="Revenue"...
      <Properties>
        <CustomProperties>
          <Property Name="AUDIT_CONTEXT1_VIEWOBJECT" Value="com.oracle…EgpSystemItemsVO"/> 
          <Property Name=" AUDIT_CONTEXT1_DISPLAYATTR" Value="Description"/>
          <Property Name="AUDIT_CONTEXT1_WHEREATTR" Value="InventoryOrgId"/>
          <Property Name="AUDIT_CONTEXT1_KEYATTR="InventoryOrgId"/>
            <!-- composite key specification - start-->
            <Property Name="AUDIT_CONTEXT1_WHEREATTR_ADDL" Value="InventoryItemId"/>
            <Property Name="AUDIT_CONTEXT1_KEYATTR_ADDL" Value="InventoryItemId"/>  <!-- for additional key attr -->    
            <!-- composite key specification - end-->
        </CustomProperties>
      </Properties>
    </ViewObject>
    

    The SQL statement that will be generated will be:

    SELECT Description from <table used by EgpSystemItemsVO> where (InventoryOrgId = Revenue.InventoryOrgId) AND (InventoryItemId = Revenue.InventoryItemId)
    
  13. If needed, configure attribute lookup based on Foreign Key tables.

    This works the same as Configure Attribute Lookup Based on the FND_LOOKUPS table, but is not limited to the FND_LOOKUPS table.

    <ViewObject ...
    <ViewAttribute Name="OWNER"IsNotNull="true"PrecisionRule="true"EntityAttrName="Owner"EntityUsage="ServiceRequestsEO"AliasName="Owner">
    <Properties>
      <SchemaBasedProperties>
        <fnd:FND_AUDIT_FK_VIEWOBJECT Value=" "/>
        <fnd:FND_AUDIT_FK_DISPLAYATTR Value=" "/>
        <fnd:FND_AUDIT_FK_WHEREATTR Value=" "/>
     
        <fnd:FND_AUDIT_FK_WHEREATTR_ADDL Value=""/>
        either <fnd:FND_AUDIT_VALUE_ADDL Value=" "/>
        or <fnd:FND_AUDIT_KEYATTR_ADDL Value=""/>
      </SchemaBasedProperties>
    </Properties>
    </ViewAttribute>
    </ViewObject>
    
  14. If needed, define View Criteria on Business Objects to filter the display of view objects. For instance, a table might be shared by three applications, and you need to filter based on only one of the applications.

    Simple query-based View Criteria:

    <ViewObject ...
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_VIEWCRITERIA_DBOBJECT Value=""/>
          <fnd:FND_AUDIT_VIEWCRITERIA_CONDITION Value=""/>
        </SchemaBasedProperties>
     </Properties>
    </ViewObject>
    

    Complex query-based View Criteria:

    <ViewObject ...
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_VIEWCRITERIA_DBOBJECT Value=""/>
          <fnd:FND_AUDIT_VIEWCRITERIA_KEYCOL Value=""/>
          <fnd:FND_AUDIT_VIEWCRITERIA_KEYATTR Value=""/>
        </SchemaBasedProperties>
      </Properties>
    </ViewObject>
    
  15. If needed, force writing attributes to the Shadow Table.

    The FND_AUDIT_FORCE_WRITE property co-exists with the normal audit properties.

    Product teams may want to write certain attributes to the shadow table all the time, even if the attribute is not enabled for auditing. This could be because Virtual Private Datasource policy is set up on the attribute, or the attribute participated in a WHERE condition. This sample code shows how to enable force writing of the attributes:

    <ViewAttribute
      Name="TableName"
      IsUnique="true"
      IsNotNull="true"
      PrecisionRule="true"
      EntityAttrName="TableName"
      EntityUsage="FndTablesEO"
      AliasName="TABLE_NAME">
      <Properties>
        <SchemaBasedProperties>
          <fnd:FND_AUDIT_FORCE_WRITE
          Value="true"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewAttribute>
    
    • If the property value is set to "true," and the attribute is not enabled for audit, it will not appear in the audit reports (unless it also is defined as the user key, context attribute, and so on).

    • If the property value is set to "true," and the attribute is enabled for audit, it will only appear when the value changes.

    <Properties>
      <SchemaBasedProperties>
        <fnd:FND_AUDIT_FORCE_WRITE
             Value="true"/>
      </SchemaBasedProperties>
    </Properties>
    

    Note that when a search is conducted on a view object, then the search result will include rows from even the child view objects.

  16. If needed, exclude a view object from a search in the Audit Report.

    The Audit Reports UI contains a search query panel in which a user can select a particular Product from the Product LOV and then filter the search further by selecting a view object from the Business Object LOV.

    The fnd:FND_AUDIT_REPORT_EXCLUDE audit annotation provides the ability to exclude a particular view object from the Business Object LOV, even if it may be marked as auditable. This is required for use cases in which a view object without the context of its parent will not make sense, so developers can expose the parent object and hide the children.

    <ViewObject
    xmlns="http://xmlns.oracle.com/bc4j"
    xmlns:fnd="http://xmlns.oracle.com/apps/entityview"
    ...
    <Properties>
       <SchemaBasedProperties>
          <fnd:FND_AUDIT_ENABLED
          Value="true"/>
          <fnd:FND_AUDIT_REPORT_EXCLUDE
          Value="true"/>
       </SchemaBasedProperties>
    </Properties>
    
  17. If needed, configure custom display names for Context attribute names.

    The custom display name of the Context attribute name in an Audit Report can be configured by using the annotation fnd:FND_AUDIT_CONTEXT1_LABEL_ID. The value provided to this annotation must be a resource ID in the resource bundle of the view object in which these context annotations are defined. If the annotation is not used, then the display name of the context view attribute itself is displayed in the Audit Report.

    <ViewObject ...
    <Properties>
      <SchemaBasedProperties>
        <fnd:FND_AUDIT_CONTEXT1_VIEWOBJECT Value=""/>
        <fnd:FND_AUDIT_CONTEXT1_DISPLAYATTR Value=""/>
        <fnd:FND_AUDIT_CONTEXT1_WHEREATTR Value=""/>
        <fnd:FND_AUDIT_CONTEXT1_KEYATTR Value=""/>
        <fnd:FND_AUDIT_CONTEXT1_LABEL_ID Value=""/>
      </SchemaBasedProperties>
    </Properties>
    </ViewObject>
    

    The custom display name can be configured to each Context attribute by using the FND_AUDIT_CONTEXT2_LABEL_ID and FND_AUDIT_CONTEXT3_LABEL_ID annotations.

  18. If needed, configure lookups on the User Key attribute.

    A Foreign Key lookup can be configured on a User Key attribute. Configure a User Key attribute as described in step 8. Then configure a Foreign Key lookup as described in step 13. Include this annotation at the view object level to derive a User Key from the lookup value while a Description search is performed.

    <ViewObject ...
    <Properties>
      <SchemaBasedProperties>
        ....
        <fnd:FND_AUDIT_USERKEY_LKP_COND Value="<condition>"/>
      </SchemaBasedProperties>
    </Properties>
    </ViewObject>
    

    Example

    Assume that the PersonId attribute is defined as a User Key, and Foreign Key lookup is defined on the User Key, as shown here:

    <fnd:FND_AUDIT_FK_VIEWOBJECT Value="abc.PersonVO"/>
    <fnd:FND_AUDIT_FK_DISPLAYATTR Value="PersonName"/>
    <fnd:FND_AUDIT_FK_WHEREATTR Value="PersonId"/>
    

    Define the User Key lookup condition as shown here:

    <ViewObject ...
    <Properties>
       <SchemaBasedProperties>
       ....
         <fnd:FND_AUDIT_USERKEY_LKP_COND Value="SELECT PERSON_ID FROM PERSONS WHERE PERSON_NAME LIKE ?"/>
       </SchemaBasedProperties>
    </Properties>
    </ViewObject>
    
  19. If needed, you can hide a view object under an application module in the Audit Setup UI

    If the view object contains the audit annotation <fnd:FND_AUDIT_ENABLED Value="true"/>, it will be displayed in the Setup UI. However, there are cases in which the view object that is owned by a different team is present under the application module and the user is not interested in seeing it under the application module in the Setup UI.

    For example, when Oracle Fusion CRM creates custom objects, it also creates an Attachment object as its child, by default. However, they do not want to see the Attachment object in the Setup UI. Since the Attachment view object is an FND object and is not owned by Oracle Fusion CRM, there is no way for them to remove the fnd:FND_AUDIT_ENABLED annotation from it.

    The annotation shown here can be specified in the application module which is registered for audit in the fnd_audit_webapp_am table. The user is expected to provide a comma-separated list of all view object names that is present in the Data Model of the application module and needs to be hidden in the Audit Setup UI. With this, in place the listed view objects and their children, if any, will be hidden.

    <AppModule...
    <Properties>
        ...
        <CustomProperties>
          <Property Name="fnd:FND_AUDIT_SETUP_HIDE_VIEWOBJECT_LIST"
                    Value = 'oracle.apps.fnd.applcore.audit.setup.view.FndTablespacesVO'/>
       </CustomProperties>
    <Properties>
    </AppModule>
    
  20. If needed, support audit-specific Data Security view criteria in a view object

    Audit considers the Data Security privilege for Business Object instances when specified in application modules (using view criteria in the format of FNDDS_privilegeNameobjectName_objectAlias) or if specified at the Entity level by enabling the "read" privilege in the Security section.

    If, for any reason, this cannot be done, audit supports the annotation shown here that allows the Data Security privilege to be specified in the view object. Audit History will consider this view object-level privilege as first priority.

    <ViewObject ...
     <Properties>
        <SchemaBasedProperties>
            ....
            <fnd:FND_AUDIT_DS_VIEWCRITERIA
              Value="FNDDS__read__FND_CRM_CASES__QRSLT,FNDDS__read__FND_CRM_CASES__CasesEO"/>
        </SchemaBasedProperties>
      </Properties>
    </ViewObject>
    
  21. If needed, there is audit support for PL/SQL-based Data Manipulation Language (DML) operations

    Audit maintains a history of changes done to business objects in Oracle Fusion Applications.

    During business transaction flows based on ADF Business Components, audited attribute values are stored in shadow tables. Audit automatically extends product transactions without needing to change product team code or business flows. For transaction flows using PL/SQL, data is not automatically saved to the shadow table. The changes shown here must be made in the PL/SQL procedures that write to the base tables.

    API Signature

    -------------------------------------------------------------------------------
    -- Type tr_data will contain data for only one of the variables based on the column's data type.
    -- If the column is varchar, varchar2_value needs to be set.
    -------------------------------------------------------------------------------
     TYPE tr_data IS RECORD(
        varchar2_value  VARCHAR2(4000),
        number_value    NUMBER,
        date_value      DATE,
        timestamp_value TIMESTAMP);
     
     TYPE tr_column_data IS RECORD(
           column_name VARCHAR2(30),
           column_type VARCHAR2(30),
           old_data    tr_data,
           new_data    tr_data);
     
     TYPE tt_columns_data is table of tr_column_data INDEX BY BINARY_INTEGER;
     
    -------------------------------------------------------------------------------
    -- get_audited_columns function returns the list of columns enabled for auditing for the passed in base table.
    -- Parameters
    --  p_base_table_name - pass the base table name on which the DML Operation occured
    -------------------------------------------------------------------------------
     FUNCTION get_audited_columns (p_base_table_name IN VARCHAR2) RETURN tt_column_names;
     
    -------------------------------------------------------------------------------
    -- Create_Audit_Row method writes to the audit shadow table
    -- Parameters
    -- p_base_table_name- pass the base table name on which the DML Operation occured
    -- p_event_type     - pass "INSERT", "UPDATE", or "DELETE" based on the DML operation on base table
    -- p_audit_data     - pass a table structure with each row(tr_column_data) contain the column,
    --                    its type and old and new value. All the columns returned from  get_audited_columns needs to be passed.
    --                    Additionally all the who columns (created_by, creation_date, last_update_date, last_updated_by,
    --                    last_update_login needs to be passed. In case of INSERT, only new data needs to be passed
    --                    and in case of DELETE, only old data. In case of UPDATE, pass both the old and new
    --                    value even for attributes that are not changed.
    ------------------------------------------------------------------------------------------------------------------------
     PROCEDURE create_audit_row(
        p_base_table_name IN VARCHAR2,
        p_event_type IN VARCHAR2,
        p_audit_data IN tt_columns_data);
    

    Coding Steps

    • Check if the table is enabled for Auditing

      FND_AUDIT_UTIL.is_table_audited(
      p_base_table_name in varchar2(30)  // input parameter - base table name
      ) return varchar2(5)               // returns "true" or "false"
      

      If the API returns false, do nothing.

    • If the table is audited and the DML type is INSERT for the base table, call the PL/SQL API, passing in all the values as new values.

      declare
        tt FND_AUDIT_UTIL.tt_columns_data;
        p_base_table_name varchar2(30);
       
      begin
        p_base_table_name := 'FND_LOOKUP_TYPES';
       
        if (FND_AUDIT_UTIL.is_table_audited(p_base_table_name) = 'false') then
          return;
        end if;
       
        tt(1).column_name := 'CUSTOMIZATION_LEVEL';
        tt(1).column_type := 'VARCHAR2';
        tt(1).new_data.varchar2_value := 'U';
       
        tt(2).column_name := 'ENTERPRISE_ID';
        tt(2).column_type := 'NUMBER';
        tt(2).new_data.NUMBER_value := '0';
       
        tt(3).column_name := 'LOOKUP_TYPE';
        tt(3).column_type := 'VARCHAR2';
        tt(3).new_data.varchar2_value := 'TEST11';
       
        tt(4).column_name := 'MODULE_ID';
        tt(4).column_type := 'VARCHAR2';
        tt(4).new_data.varchar2_value := '40B3FA7250D19380E040449823C67A1A';
       
        tt(5).column_name := 'VIEW_APPLICATION_ID';
        tt(5).column_type := 'NUMBER';
        tt(5).new_data.NUMBER_value := '0';
       
        tt(6).column_name := 'CREATED_BY';
        tt(6).column_type := 'VARCHAR2';
        tt(6).new_data.varchar2_value := 'ADMIN';
       
        tt(7).column_name := 'LAST_UPDATED_BY';
        tt(7).column_type := 'VARCHAR2';
        tt(7).NEW_data.varchar2_value := 'ADMIN';
       
        tt(8).column_name := 'CREATION_DATE';
        tt(8).column_type := 'TIMESTAMP';
        tt(8).new_data.timestamp_value := sysdate-10; 
       
        tt(9).column_name := 'LAST_UPDATE_DATE';
        tt(9).column_type := 'TIMESTAMP';
        tt(9).new_data.timestamp_value := sysdate-10; 
       
      FND_AUDIT_UTIL.CREATE_AUDIT_ROW(
          p_base_table_name,
          'INSERT',
          tt);
      end; 
      
    • If the table is audited and the DML type is UPDATE, call the PL/SQL API to get a list of audit-enabled attributes.

      TYPE tt_column_names  IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
       
      FND_AUDIT_UTIL.get_audited_columns(
      p_base_table_name in varchar2(30)  // input parameter - base table name
      ) return tt_column_names
      

      If any column that is updated in the current transaction is in the list returned from get_audited_columns, get the value for all the other columns in the table and call the PL/SQL API. Note that you need to pass in values (old and new) for all the columns returned from the get_audited_columns() function, and also for all the who columns, even if the values have not changed.

      declare
        tt FND_AUDIT_UTIL.tt_columns_data;
        p_base_table_name varchar2(30);
        col_list  FND_AUDIT_UTIL.tt_column_names;
        l_col_change_found varchar2(30);
      begin
        p_base_table_name := 'FND_LOOKUP_TYPES';
        l_col_change_found := 'false';
       
        if (FND_AUDIT_UTIL.is_table_audited(p_base_table_name) = 'false') then
          return;
        end if;
       
        col_list := FND_AUDIT_UTIL.get_audited_columns(p_base_table_name);
       
        -- assuming here that only customization_level has changed
        FOR i IN 1 .. col_list.count LOOP
          IF (col_list(i) = 'CUSTOMIZATION_LEVEL') THEN
            l_col_change_found := 'true';
          END IF;
        END LOOP;
       
        --if you dont have all the values, query the rest of the values from your base table
        --then pass the same value for old and new value.
        --if the old or new value is blank, audit code will assume that the value has been cleared out.
       
        if (l_col_change_found := 'true') THEN
              tt(1).column_name := 'CUSTOMIZATION_LEVEL';
              tt(1).column_type := 'VARCHAR2';
              tt(1).old_data.varchar2_value := 'U';
              tt(1).new_data.varchar2_value := 'S';
       
              tt(2).column_name := 'ENTERPRISE_ID';
              tt(2).column_type := 'NUMBER';
              tt(2).old_data.NUMBER_value := '0';
              tt(2).new_data.NUMBER_value := '0';
       
              tt(3).column_name := 'LOOKUP_TYPE';
              tt(3).column_type := 'VARCHAR2';
              tt(3).old_data.varchar2_value := 'TEST11';
              tt(3).new_data.varchar2_value := 'TEST11';
       
              tt(4).column_name := 'MODULE_ID';
              tt(4).column_type := 'VARCHAR2';
              tt(4).old_data.varchar2_value := '40B3FA7250D19380E040449823C67A1A';
              tt(4).new_data.varchar2_value := '40B3FA7250D19380E040449823C67A1A';
       
              tt(5).column_name := 'VIEW_APPLICATION_ID';
              tt(5).column_type := 'NUMBER';
              tt(5).old_data.NUMBER_value := '0';
              tt(5).new_data.NUMBER_value := '0';
       
              tt(6).column_name := 'CREATED_BY';
              tt(6).column_type := 'VARCHAR2';
              tt(6).old_data.varchar2_value := 'ADMIN';
              tt(6).new_data.varchar2_value := 'ADMIN';
       
              tt(7).column_name := 'LAST_UPDATED_BY';
              tt(7).column_type := 'VARCHAR2';
              tt(7).old_data.varchar2_value := 'ADMIN';
              tt(7).new_data.varchar2_value := 'APPLICATION_ADMINISTRATOR';
       
              tt(8).column_name := 'CREATION_DATE';
              tt(8).column_type := 'TIMESTAMP';
              tt(8).old_data.timestamp_value := sysdate -10;
              tt(8).new_data.timestamp_value := sysdate-10;  
       
              tt(9).column_name := 'LAST_UPDATE_DATE';
              tt(9).column_type := 'TIMESTAMP';
              tt(9).old_data.timestamp_value := sysdate -10;
              tt(9).new_data.timestamp_value := sysdate;  
       
          FND_AUDIT_UTIL.CREATE_AUDIT_ROW(
                  p_base_table_name,
                  'UPDATE',
                  tt);
          END IF;        
      end; 
      
    • If the table is audited and the DML type is DELETE for the base table, call PL/SQL API, passing in all the values (as old values) from the base table.

      declare
        tt FND_AUDIT_UTIL.tt_columns_data;
        p_base_table_name varchar2(30);
       
      begin
        p_base_table_name := 'FND_LOOKUP_TYPES';
       
        if (FND_AUDIT_UTIL.is_table_audited(p_base_table_name) = 'false') then
          return;
        end if;
       
        tt(1).column_name := 'CUSTOMIZATION_LEVEL';
        tt(1).column_type := 'VARCHAR2';
        tt(1).old_data.varchar2_value := 'S';
       
        tt(2).column_name := 'ENTERPRISE_ID';
        tt(2).column_type := 'NUMBER';
        tt(2).old_data.NUMBER_value := '0';
       
        tt(3).column_name := 'LOOKUP_TYPE';
        tt(3).column_type := 'VARCHAR2';
        tt(3).old_data.varchar2_value := 'TEST11';
       
        tt(4).column_name := 'MODULE_ID';
        tt(4).column_type := 'VARCHAR2';
        tt(4).old_data.varchar2_value := '40B3FA7250D19380E040449823C67A1A';
       
        tt(5).column_name := 'VIEW_APPLICATION_ID';
        tt(5).column_type := 'NUMBER';
        tt(5).old_data.NUMBER_value := '0';
       
        tt(6).column_name := 'CREATED_BY';
        tt(6).column_type := 'VARCHAR2';
        tt(6).old_data.varchar2_value := 'ADMIN';
       
        tt(7).column_name := 'LAST_UPDATED_BY';
        tt(7).column_type := 'VARCHAR2';
        tt(7).old_data.varchar2_value := 'APPLICATION_ADMINISTRATOR';
       
        tt(8).column_name := 'CREATION_DATE';
        tt(8).column_type := 'TIMESTAMP';
        tt(8).old_data.timestamp_value := sysdate -10;
       
        tt(9).column_name := 'LAST_UPDATE_DATE';
        tt(9).column_type := 'TIMESTAMP';
        tt(9).old_data.timestamp_value := sysdate;
       
      FND_AUDIT_UTIL.CREATE_AUDIT_ROW(
          p_base_table_name,
          'DELETE',
          tt);
      end; 
      

12.2.2 How to Set Up Auditing

As with most Oracle Fusion applications, Audit setup is done from Functional Setup Manager. When you start the setup, search in Functional Setup Manager for "Audit." When it is located, select Audit Setup.

A list of Oracle Fusion applications is displayed, as shown in Figure 12-2.

Figure 12-2 Initial Audit Setup Display

Described in the surrounding text.

You will notice that some have only an Audit Level drop-down list that lets you pick Low, Medium or High levels. These are Oracle Fusion Middleware products that generate event-based entries in the table that is read by the Audit system, and the user just sets the granularity that is desired. (Refer to the product documentation and to the online help for a description of how the levels work in each particular product.)

In the example figure, click the Configure Business Object Attributes button to display the Configure Business Objects Attributes dialog. When it first displays, the fields will be empty.

To populate the Objects list, open the Application drop-down list and select the name of the application you want to audit. The example shown in Figure 12-3 uses the Applications Core Setup application.

Figure 12-3 Selecting an Application to Audit

Described in the surrounding text.

There are three buttons at the top of the Configure Business Object Attributes dialog:

  • Click Save to save your work and remain in the Audit Setup dialog.

  • Click Save and Close to save your work and exit the Audit Setup dialog.

  • Click Cancel to cancel any changes you have made since the last Save action and exit the Audit Setup dialog.

Objects List

The Objects list has three columns:

  • Audit

    There is no limit to the number of levels that can be included in an audit.

    You will notice that items with the same name are displayed and can be selected. The item at the top of the tree is the root item; the other listed items of the same name are reflections of the root item and are not separate. That is, if a view object appears multiple times in the Setup list, there really is only one view object. Selecting or deselecting any instance of that view object will select or deselect all instances.

    Example:

    You pick a view object and select five of its attributes to audit and save. If you then choose the same view object, but somewhere else in the setup UI, it will have those five attributes already selected. Now select two more, so that there are seven attributes selected. When you return to the first instance of the view object, it also will show seven attributes selected.

    Similarly, if you delete one of the five selected attributes, all instances of the affected view object will show only four selected attributes.

    Another way of saying this is "last edit wins."

    Any item that is checked in the Audit column will have all its selected attributes audited. Unless the view objects' Attributes list has been edited, the attributes that will be audited are default attributes.

    If you edit a view object to select specific attributes, the Audit box must still be checked to audit the selected attributes. (You can edit the attributes, but that, by itself, does not mean they will be included in an audit, unless the Audit box is checked.)

  • Name

    The names of the application modules and view objects.

  • Description

    A brief description of the associated application module or view object.

The Objects list has two menus.

  • Actions menu

    The Actions menu provides the Synchronize option.

    Attributes of objects that are being audited are tracked. On a patch or update, or if customized attributes, such as flexfield attributes, have been added, they must be tracked if they are meant to be included in the audit. That is, the attribute was marked as <fnd:FND_AUDIT_ATTR_ENABLED Value="true"/>. Synchronize will do this.

    Note: Synchronization is carried out by product. That is, it will synchronize all objects in the current product shown in the UI, if those objects have been selected for audit at any time previously.

    Flexfield and custom attributes are always included by default (<fnd:FND_AUDIT_ATTR_ENABLED Value="true"/>), so with these you want to be sure to do a synchronization.

  • View menu

    Use the View menu to select the columns you want to display, and to expand and collapse entries in various combinations.

Audited Attributes List

When you click a view object entry in the Objects list, its attributes that will be included in an audit are displayed in the Audited Attributes fields. Note that the name of the selected object is added before the Audited Attributes heading; for example Document Entities: Audited Attributes.

Note:

The permitted limit on selected attributes is 20,000 bytes (num_attributes x attribute_size) for a given view object in the Audit Setup UI. This limit is checked during setup. Note that custom text attributes are pre-allocated with 1,500 chars per field. Therefore, it would only take 13 Text fields to consume the available character width.

These are not necessarily all the attributes of the selected view object; they either are the default attributes or the attributes selected during a previous edit. To see a list of all a view object's attributes, select Actions > Create, or click the Create icon. A dialog, similar to that shown in Figure 12-4, lists all the attributes and lets you shuttle them between the Available Attributes and the Selected Attributes.

Figure 12-4 Selecting Attributes to Audit

Described in the surrounding text.

Click Save and Close to save your selections. Remember that your selections will not be included in an audit unless the related Audit checkbox also is selected.

12.3 Using Audit Reports

Open Audit Reports from the Navigator menu.

The Audit Reports Search page, shown in Figure 12-5, is displayed.

Figure 12-5 Default Audit Reports Display

Described in the surrounding text.

To perform a search, a Date value and either a User or Product value are required. Use the Date picker to select the date, and the drop-down lists to select a User or a Product or both. The search results can be further fine-tuned by using the Event Type, Business Object and Description fields, and the Include child objects checkbox.

Note:

These parameters can be saved and recalled by selecting the user-supplied name in the Saved Search drop-down list. See also"If the search parameter set you are using is one that you expect to reuse, click Save to display the Create Saved Search dialog that has these options:"

12.3.1 How to Search in Audit Reports

To search for Audit Reports for an Oracle Fusion application, you must supply this information:

  • Date. Select an operator, such as Equals, Before, After or Between, and click the picker to display a calendar from which to choose a date.

  • User or Product or both.

    When you use the drop-down to select a User, you will notice a Search link at the bottom of the list. Click it to access all the available Users. The dialog, shown in Figure 12-6, is displayed.

    Figure 12-6 Searching for a User

    Described in the surrounding text.

    You can enter a name or part of a name in the User field and click Search. You also can click Advanced to add a search operators drop-down list, as shown in Figure 12-7.

    Figure 12-7 User Name Operators

    Described in the surrounding text.

    To select a user, highlight the name in the search results, shown in Figure 12-8, and click OK.

    Figure 12-8 Search Results for User

    Described in the surrounding text.
  • Event Type. Note that the first drop-down list always is set to Equals. Use the second drop-down list to select any or a combination of the available types. You also can select All.

    For Oracle Fusion applications, the Types are Object Data Insert, Object Data Update, and Object Data Delete.

    For Oracle Fusion Middleware, the Type selection is dynamic and depends on the selected Product.

  • Business Object Type. Note that this field applies only to Oracle Fusion applications and not to Oracle Fusion Middleware.

  • Description. You can further limit the search results display by entering a string in this field that matches a string in the Description column of the search results.

  • Include child objects. If there is a hierarchy of view objects, such as Opportunity > Revenue Line > Revenue Line Split, and the search is done on Opportunity, it only checks the Opportunity view object for changes. But if this option is checked, it will search all children. So if an Opportunity has five Revenue Lines and each has some Revenue Line Splits, then if anything in any of them changed, they also would be reported.

When the necessary fields are filled-in, click Search to display the results in the Search Results table.

Note:

When a search is performed for broad criteria, such as "Specific Product Before Today" or "All Products Before Today," Audit Report may take a long time to query Audit History.

To avoid intermittent connection reset errors, the search time is limited to 5 minutes. If the History search time exceeds 5 minutes, this message is displayed: "Query run time exceeded the permissible time limit and failed to display results. Refine the search criteria and try again."

Deleting an Object Referenced by a Foreign Key

In some instances, resolving a foreign key may fail when an audit row display name is trying to do a foreign key lookup of an object that has been deleted. It then will display the raw value or just leave it blank.

One example of this behavior involves trying to get a foreign key resolution from the same base object. If rows were deleted from an object, there will not be a row in the base table and foreign key resolution may fail.

Another example involves foreign key resolution with a parent table. For instance, given a person object, a person email object may use foreign key resolution to show a person's name instead of a person ID. If the person's name has been deleted in the base table, the foreign key resolution for the person email object may fail because there is no row in the corresponding base table.

Click Reset to clear all the fields so you can enter new search parameters.

If the search parameter set you are using is one that you expect to reuse, click Save to display the Create Saved Search dialog that has these options:

  • Name

    This option is mandatory.

    This field defaults to showing the name that is displayed in the Saved Search field. However, if the Saved Search displayed name is "My Recent Changes," the Name field here will show "My Recent Changes copy."

  • Set as Default

    Select this option to designate this named set of search parameters as the default instead of My Recent Changes.

    This option can be set and cleared by opening the Saved Search drop-down list and selecting Personalize.

  • Run Automatically

    Select this option to run this named set of search parameters automatically.

    This option can be set and cleared by opening the Saved Search drop-down list and selecting Personalize.

  • Show in Search List

    This option is available only from the Saved Search Personalize option, and is active only for the My Recent Changes named search.

12.3.1.1 Using the Search Results Table

The Search Results table has these components:

  • Actions menu

  • Export to Excel icon that duplicates the function of the Actions menu option of the same name

  • Detach icon

  • Show Attribute Details checkbox. This option becomes active when the Business Object Type field is populated and a search has been performed.

    When this option is selected, a dropdown list lets you select either All Attributes or Select Attribute.

    Figure 12-9 Attribute Scope Selection

    An image of the dropdown list allowing the user to select All Attributes or Select Attribute.
    • All Attributes

      When this option is selected, three columns are added to the table: Attribute, Old Value and New Value. Attribute contains the attribute name. An Old Value will be shown if there was an old value. New Value shows the current value. A scroll bar will become available at the bottom of the display so you can view all the columns.

    • Select Attribute

      Select this option when you want the information for only one specific attribute. When selected, a popup similar to this example is displayed.

      Figure 12-10 Select a Specific Attribute

      An example of the popup window displayed when the Select Attribute option has been chosen.

      You must click the Business Object to populate the Select Attribute list.

      Click OK to apply the change to the table.

      The search results table now shows only results with the selected attribute, plus the Old Value and New Value columns that are shown when the All Attributes option is selected

  • Show Extended Object Identifier Columns checkbox.

    When this option is selected, three new pairs of columns are added to the Search Results table: Context Name1 with Context Value1 through Context Name3 with Context Value3. These are additional information to help identify the object. For instance, if you need a 4-part key to uniquely identify an object, the Description could be 1 and these 3 context values could be the remaining.

Note that when a search is conducted on a view object, the search result also will include rows from the child view objects.

Actions Menu

The Actions menu has the Export to Excel option that is duplicated with the Export to Excel icon. Select the menu option or click the icon to export all the entries in the Search Results list to an Excel XLS file. When this option is selected, the standard Save prompts will guide you through the process.