You are on page 1of 127

Oracle

Approvals
Management
Developers Guide
RELEASE 11i10/AME.A

December 2004

Oracle Approvals Management Developers Guide 1


Oracle Approvals Management Release R11i
Copyright © 2001, 2002, 2003, 2004 Oracle Corporation. All
rights reserved.
Contributors: Todd Morley, Nilakshi Soni, Bill Kerr
The Programs (which include both the software and documentation)
contain proprietary information of Oracle Corporation; they are
provided under a license agreement containing restrictions on use and
disclosure and are also protected by copyright, patent and other
intellectual property law. Reverse engineering, disassembly or
decompilation of the Programs, except to the extent required to obtain
interoperability with other independently created software or as
specified by law, is prohibited.
Program Documentation is licensed for use solely to support the
deployment of the Programs and not for any other purpose.
The information contained in this document is subject to change without
notice. If you find any problems in the documentation, please report
them to us in writing. Oracle Corporation does not warrant that this
document is error free. Except as may be expressly permitted in your
license agreement for these Programs, no part of these Programs may be
reproduced or transmitted in any form or by any means, electronic or
mechanical, for any purpose, without the express written permission of
Oracle Corporation.
If the Programs are delivered to the US Government or anyone licensing
or using the Programs on behalf of the US Government, the following
notice is applicable:
RESTRICTED RIGHTS NOTICE
Programs delivered subject to the DOD FAR Supplement are
”commercial computer software” and use, duplication and disclosure of
the Programs, including documentation, shall be subject to the licensing
restrictions set forth in the applicable Oracle license agreement.
Otherwise, Programs delivered subject to the Federal Acquisition
Regulations are ”restricted computer software” and use, duplication,
and disclosure of the Programs shall be subject to the restrictions in FAR
52.227-19, Commercial Computer Software - Restricted Rights (June,
1987). Oracle Corporation, 500 Oracle Parkway, Redwood City, CA
94065.
The Programs are not intended for use in any nuclear, aviation, mass
transit, medical, or other inherently dangerous applications. It shall be
licensee’s responsibility to take all appropriate fail-safe, back up,
redundancy and other measures to ensure the safe use of such
applications if the Programs are used for such purposes, and Oracle
disclaims liability for any damages caused by such use of the Programs.
The Programs may provide links to Web sites and access to content,
products, and services from third parties. Oracle is not responsible for
the availability of, or any content provided on, third-party Web sites.
You bear all risks associated with the use of such content. If you choose
to purchase any products or services from a third party, the relationship
is directly between you and the third party. Oracle is not responsible
for: (a) the quality of third-party products or services; or (b) fulfilling
any of the terms of the agreement with the third party, including
delivery of products or services and warranty obligation related to
purchased products or services. Oracle is not responsible for any loss or
damage of any sort that you may incur from dealing with any third
party.
Oracle is a registered trademark and ConText, Enabling the Information
Age, Oracle7, Oracle8, Oracle8i, Oracle Access, Oracle Application
Object Library, Oracle HRMS, Oracle Discoverer, Oracle Web
Customers, Oracle Web Employees, Oracle Workflow, Oracle Work in

Oracle Approvals Management Developers Guide 2


Progress, PL/SQL, Pro*C, SmartClient, SQL*, SQL*Forms, SQL*Loader,
SQL*Menu, SQL*Net, SQL*Plus, and SQL*Reports are trademarks or
registered trademarks of Oracle Corporation. Other names may be
trademarks of their respective owners.

Oracle Approvals Management Developers Guide 3


Table of Contents
1 Integrating AME into an Application .................................................................7
Overview ...................................................................................................................8
Audience ................................................................................................................8
Steps Required to Integrate AME into an Application ..........................................8
AME Security ........................................................................................................9
Deciding how Many Transaction Types to Create ................................................9
Creating a Transaction Type..................................................................................9
2 Building an Action Type ....................................................................................11
Overview .................................................................................................................12
Important – Changes from 11i9 version of AME ................................................12
Deciding Whether to Create an Action Type.......................................................12
Creating an Action Type......................................................................................13
Coding an Action-Type Handler..........................................................................14
Registering an Action Type .................................................................................25
Major changes in the Engine/ Handler Interface since R11i9 .............................26
3 Defining an Approver Type ...............................................................................29
Overview .................................................................................................................30
Approver Types in AME .....................................................................................30
Registering an Approver Type.............................................................................30
4 Defining an Item Class ......................................................................................37
Overview .................................................................................................................38
When to Define an Item Class .............................................................................38
How to Define an Item Class ...............................................................................38
5 Integrating AME with Workflow.......................................................................39
Overview .................................................................................................................40
Notifications.........................................................................................................40
The Basic Algorithm............................................................................................40
Modifications to the Basic Algorithm..................................................................41
Frequently Asked Questions ................................................................................43
Sample Workflow ................................................................................................44
Appendix A API Functional Specifications ..........................................................53
Overview .................................................................................................................54
Calling AME API Routines .................................................................................54
ame_api2 ..............................................................................................................55
What New APIs Map to the 11.5.9 APIs? ...........................................................83
Appendix B ame_util Package ...............................................................................85
Overview .................................................................................................................86
Data Types ...........................................................................................................86
Appendix C The Action-Type-Handler Programming Interface........................107
Overview ...............................................................................................................108
The ame_engine.engStApprovers Data Structure..............................................108

Oracle Approvals Management Developers Guide 5


Engine Functions ...............................................................................................108
Engine Procedures .............................................................................................115
Appendix D Sample AME Objects .......................................................................122
Overview ...............................................................................................................123
Transaction Type ...............................................................................................123

Oracle Approvals Management Developers Guide 6


1
Integrating AME into
an Application

Integrating AME into an Application 7


Overview
AME is a powerful application. It provides a great deal of flexibility for
creating the approvals processes an organization needs, usually without
writing any custom code. AME is highly extensible. If an organization has
special requirements that AME’s seeded functionality does not provide, one
can often write AME extensions that meet the organization’s requirements.

Audience

This guide has two principle audiences: -

1. Customer requiring additional Action Types to those supplied by


Oracle Corporation

2. Development team wishing to integrate AME into their own


application module

For the second audience it is normally expected that such a development


team would be part of the Oracle E-Business Suite development. However, it
is possible that a customer may wish to provide approval management
capabilities to their own custom applications. It is for this reason that this
guide is supplied to customers.

For any Action Types that are not seeded or any Oracle Application module
that is not integrated with AME, please submit a request to your support
representative with a business case for this addition.

Your principle reference to AME is the Implementation Guide rather than


this Development Guide.

Steps Required to Integrate AME into an Application

1. Understand AME’s features and functionality. Study the AME


Implementation Guide carefully to understand the system’s various
intricacies.

2. Identify and document the types of approval processes that the


application’s customers typically require.

3. Determine how to configure AME to satisfy each of the requirements in


step two.

4. Document any requirements in step two that AME’s seeded functionality


does not satisfy.

5. Determine how to extend AME to satisfy the requirements in step four.

6. Define one or more transaction types for the application.

7. Build and test any AME extensions required by step five.

Integrating AME into an Application 8


8. Integrate the application’s workflow with AME’s runtime APIs.

Note: The remainder of this guide assumes that you have studied the
implementation guide.

AME Security

A developer must have the AME Developer or AME Application


Administrator ICX responsibility to use AME’s user interface to integrate an
application with AME. (The developer responsibility has all of the
administrator responsibility’s privileges, and some that the administrator
responsibility lacks. See “Security” in Chapter 1 of the implementation guide
for details.) Except where this guide indicates otherwise, it assumes that you
will use the administrator responsibility.

Deciding how Many Transaction Types to Create

An originating application always has at least one transaction type (by


definition). One of the main design decisions involved in integrating AME
into an originating application is deciding how many transaction types to
create for the application. Multiple transaction types may be necessary
whenever customers might have good business reasons to vary any of the
following, depending on the nature of a transaction generated by the
originating application:

• an attribute usage

• approval-process parallelization ordering numbers and modes that


are transaction-type specific

• an item class usage

• a configuration variable’s value(s)

Creating a Transaction Type

To create a transaction type, follow these steps:

1. Select the admin tab.

2. Select ‘application administration’ and then the ‘Continue’ button on the


‘Choose an Activity Type’ form.

3. Select ‘Maintain transaction types’ and then the ‘Continue’ button on the
‘Choose an Activity’ form.

4. Select the ‘Add a Transaction Type’ button at the bottom of the ‘All
Transaction Types’ form.

5. Select the originating application that will own the transaction type, and
then the ‘Continue’ button, on the ‘Choose an Application’ form.

Integrating AME into an Application 9


On the ‘Enter Transaction-Type Details’ form,

a. Enter the transaction type’s description. (This should be a short,


user-friendly description.)

b. Enter the transaction type’s ID. (This should be an acronym,


typically related to the originating application’s Workflow item
type.)

c. Select the transaction type’s sublist mode.

d. Select the ‘Continue’ button.

6. Use the ‘Mandatory-Attribute Queries’ form to enter a usage for each


mandatory attribute. For each usage you enter in a ‘Usage’ textarea, use
the following ‘Static Usage’ select list to indicate whether the usage is
static. Select the ‘Continue’ button at the bottom of the form to create the
transaction type.

The transaction type will be created with a default item-class usage for the
header item class. See Chapter 4 of this guide to learn how to add other item-
class usages to the transaction type. See Chapter 3 of the implementation
guide to learn how to edit your transaction type’s attribute usages. See
Chapter 11 of the implementation guide to learn how to edit your transaction
type’s configuration variables.

Integrating AME into an Application 10


2
Building an Action
Type

Building an ActionType 11
Overview

Note: Chapter 5 of the Oracle Approvals Management Implementation Guide


explains actions and action types. Please study that chapter carefully before
reading this one.

There are six categories of action type:

• chain of authority

• list–modification

• substitution

• pre-approval

• post-approval

• production

An action type in any of the first five categories is implemented as a PL/SQL


package called an action-type handler. (The AME engine processes
production actions without using a handler package, so you cannot create a
production action type.)

Important – Changes from 11i9 version of AME

The engine/handler interface has changed in AME 11.5.10 /


AME.A. As such the old custom handlers created and used in
AME 11.5.9 will have to be modified before it can be called in
AME 11.5.10.

Please review the section at the end of this chapter on changes to


the handler interface.

Deciding Whether to Create an Action Type

The programming interface between the AME engine and action-type


handlers has changed several times, and is likely to continue evolving. In
contrast, AME’s attribute and approval-group architecture is more stable.
These facts make custom action types more difficult to maintain than other
approaches to expressing an organization’s business rules in AME. Even
when you understand the action-type-handler programming interface,
coding an action-type handler that is both correct and efficient can be a
challenge. For these reasons, we encourage you to create a custom action
type only when you have no alternative.

To determine whether you need to create a custom action type, follow these

Building an ActionType 12
steps:

1. Review the seeded action types’ descriptions in Chapter 5 of the


implementation guide. Make sure you can’t express the approvals logic
you require with one or more existing action types.

2. If you need to use a hierarchy of approvers not supported by a seeded


action type, and the hierarchy does not exist outside AME, consider
using nested approval groups to create the approver hierarchy you need
in AME, and then using the approval-group chain-of-authority action
type to generate chains of authority from the nested approval groups.

3. If you need to use an approver hierarchy that resides outside of AME


(say in the schema of an originating application), consider using dynamic
approval groups to access the hierarchy, and the approval-group chain-
of-authority action type to generate chains of authority from the dynamic
approval groups.

4. If the approvers you want to use reside in a hierarchy supported by an


AME action type, but their signing limits reside elsewhere, consider
defining an attribute whose dynamic usage indicates the number or
levels of approvers required, and referencing that attribute in your rules’
conditions. The rules’ actions would then be of an action type using the
supported approver hierarchy. For example, the custom attribute might
be TRANSACTION_SUPERVISORY_LEVELS. Its usage could fetch a
function that ascended the hierarchy until it found an approver with
sufficient signing authority, and then it could return the number of
approvers it ascended. The rules would then have the form,
If TRANSACTION_SUPERVISORY_LEVELS = 4 then
require approvals up to the first four supervisors.

5. If the above approaches don’t meet your needs, contact AME


development and request that we consider building the action type.

If none of the above approaches meets your needs, you may elect to build a
custom action type.

NOTE: AME development and Oracle Support offer best effort support for
custom action types.

Creating an Action Type

Creating an action type takes five steps:

1. Identify the approver types that the action type is based on. (See Chapter
3 of this guide for details about approver types.)

2. Code the action type’s handler, and give the APPS account execute
privileges on it.

3. Register the action type in AME using the actions tab in the AME UI.

Building an ActionType 13
4. Create actions for the new action type. (See Chapter 5 of the
implementation guide for details.)

5. Test the action type. (See Chapter 10 of the implementation guide for
details.)

The remainder of this chapter explains how to do steps 2 and 3.

Coding an Action-Type Handler

Defining Action Parameters

Most action types have several actions, and each action has a set of (zero, one,
or two) parameters defined for it. How the action type’s handler interprets
an action’s parameters varies with the action type. The parameters of an
authority action type’s actions typically represent requirements for certain
levels of authority, and the handler typically generates a chain of authority
satisfying the most stringent of such requirement. The parameters of
approver–group action types’ actions typically identify approval groups.
The parameters of list–editing actions represent specific types of alterations
to an approver list, for example changes that reflect non–uniformities in an
organization’s signing–authority rules.

Before you code your handler, you should define the syntax and semantics
rules for the parameters of your action type’s actions. The rules should make
it easy for your handler efficiently to sort, aggregate, and interpret the
parameters of several actions.

Coding an Efficient Handler

AME may call your action-type handler very frequently. Recall that list-
modification and substitution rules apply to an entire transaction’s approver
list. As a result, AME’s engine invokes the handlers of the action types used
by these rules once per transaction. In contrast, The other rules types
(ignoring the production rule type) can apply to each item in a transaction’s
lists of subordinate items. AME’s engine may invoke the handlers of the
action types used by these rules once per item. So if, for example, a
transaction has 50 line items, AME’s engine may invoke an authority action
type’s handler 50 times for the transaction. If the originating application
generates 1,000 transactions of the same type per day, AME’s engine might
invoke the handler 50,000 times per day. So if the number of transactions
and items that use your action type may be substantial, it is critical that you
make your handler efficient.

Efficient PL/SQL architecture is far beyond the scope of this chapter. We


recommend you do at least three things to make your handler efficient:

1. Minimize the number of database queries your handler executes per


transaction using language features such as bulk fetches.

2. Tune your handler’s database queries.

Building an ActionType 14
3. Compare your handler’s asymptotic (long run) performance to that of
one of the seeded handlers.

In our experience, a test set of a few thousand transactions suffices to


measure asymptotic performance. Code a PL/SQL test procedure that
follows these steps:

1. Bulk fetch a set of several thousand test-transaction IDs into a local


PL/SQL table.

2. Loop through the test-transaction IDs, calling


ame_api2.getAllApprovers7 once for each ID, using
dbms_utility.get_time to measure the execution time to the nearest
hundredth of a second.

3. Calculate and output the mean execution time per transaction ID.

Set up your rules to use a seeded action type (and not use the action type
you’re testing), and run the test procedure. Then, change the rules using the
seeded action type to use your action type instead, and re-run the test
procedure. The results should be comparable.

Programming Interface

Appendix C of this guide documents AME’s action-type-handler


programming interface. Please review it carefully after reading this chapter.

Package Specification

Package Name

An action-type handler’s package name should be of the form

ame_actionType_handler

where actionType suggests the name of the action type. For


example, if your handler ascended an approver custom hierarchy
called the “functional” hierarchy, the handler package could be
named ‘ame_functional_handler’.

Entry-Point Procedure

Each handler must have a public entry-point procedure named


‘handler’. The procedure should take no arguments. (The AME
engine calls the handler procedure to invoke the handler.) The
handler procedure should be the only public feature of your handler
package. Thus your entire package specification might be:

create or replace package ame_functional_handler as

procedure handler;

Building an ActionType 15
end ame_function_handler;

Package Body

An action-type handler alters a transaction’s approver list in


response to a combination of required-attribute values and action-
parameter values. It should use AME-engine routines to fetch these
values as necessary (see Appendix C for details). AME’s
fundamental architectural principle is to encode in approval rules,
attribute usages, and configuration-variable values all decisions
about the general structure of a transaction’s approval process. While
writing an AME action–type handler, it is possible to violate this
principle by hard-coding business rules into the handler. Doing so
hides business logic from the end users whose responsibility it is to
define it, so please avoid the practice.

Handler-Procedure Architecture

There are three different kinds of action-type handler architectures:

1. Authority handlers generate chains of authority for action types


used by list-creation and exception rules.

2. Approval-group handlers add approval groups to an approver


list for action types used by pre- or post-approval rules.

3. List-editing handlers modify the approver list when a target


approver is in it, for action types used by list-modification or
substitution rules.

The following subsections describe the architecture appropriate for each type
of handler.

Authority-Handler Architecture

An authority handler translates required-attribute and action-


parameter values into one or more chains of authority, either for a
given subordinate item, or for the header item. For each approver
that the handler adds to the item’s approver list, the handler must
populate all but one of the fields in the approver’s
ame_util.approverRecord2. (AME’s engine calculates the value of
the record’s approver_order_number field.) The handler procedure
should implement the following pseudocode to generate the chains
of authority:

1. Call ame_engine.getHandlerRules2 to fetch the applicable rules’


IDs and action parameters, and the approver categories that the
rule usages assign them.

2. Call one of the engine’s attribute-value-fetching routines to fetch


any required attributes.

Building an ActionType 16
3. Analyze the action parameters to determine how many chains of
authority the rules require, and when to end each chain.

4. For each required chain, loop.

a. Fetch the chain’s first approver. Check for a non-default


first approver identified by a required attribute (in
analogy with the
JOB_LEVEL_NON_DEFAULT_STARTING_POINT_PER
SON_ID attribute for the seeded absolute-job-level action
type). Also check for an inserted first approver (by
calling ame_engine.getHandlerCOAFirstApprover). If
the required attribute has a non-null value, it should
override the default value. An inserted starting point
should override all others.

b. Make the first approver the current approver.

c. Populate the approver’s ame_util.approverRecord2 and


add it to the engine’s approver list using
ame_engine.addApprover().

d. Check whether the current approver has final authority.

e. Try to fetch the chain-of-authority insertion following


the current approver (by calling
ame_engine.getHandlerCOAInsertion).

f. If an insertion exists, make them the current approver


and go to step 4c

g. If final authority was found at step 4d, iterate at step 4.

h. Fetch the next approver in the chain of authority.

i. Make the next approver the current approver.

j. Go to step 4d.

Notes:

1. At step 3, you may eliminate duplicate action parameters, but if you do,
you should keep track of the IDs of all rules requiring a given parameter,
for use in populating each approver’s source field.

2. When a handler populates an approver’s ame_util.approverRecord2


fields at steps 4.a, 4.c, 4.e, and 4.h, it should follow the instructions in this
table:

Field Value

Building an ActionType 17
Field Value

name, orig_system, The handler fetches these values at steps 4.a, 4.e,
orig_system_id and 4.h. The handler may start by fetching an
approver’s wf_roles.name value, and then use
ame_approver_type_pkg.
getOrigSystemIdAndDisplayName to fetch the
other fields’ values. Or, the handler may start
by fetching the approver’s orig_system_id value
(such as a per_all_people_f.person_id value),
and then use ame_approver_type_pkg.
getWfRolesNameAndDisplayName to fetch the
other values.

approver_category The handler calculates this value from data


returned by ame_engine.getHandlerRules2 in
step 1, depending on which rules require the
approver. The value is
ame_util.approvalApproverCategory if any of
the rule usages requiring the approver is this
value; otherwise the value is
ame_util.fyiApproverCategory.

api_insertion For rule-generated approvers, the handler


should set this value to ame_util.oamGenerated.
For inserted approvers, the handler should set
this value to ame_util.apiAuthorityInsertion.

authority The handler should always set this value to


ame_util.authorityApprover.

approval_status The handler should call


ame_engine.getHandlerApprovalStatus once
per approver to fetch this value.

action_type_id The handler should call


ame_engine.getHandlerActionTypeId once per
handler cycle to fetch this value.

group_or_chain_id The handler should calculate this value by


setting it to once for the first chain it generates,
and incrementing the value once for each
iteration of the loop at step 4.

occurrence The handler should call


ame_engine.getHandlerOccurrence once per
approver to fetch this value.

Building an ActionType 18
Field Value

source For rule-generated approvers, the source value


should be a list of the IDs of the rules requiring
the approver, separated by
ame_util.fieldDelimiter. In this case, you
should use ame_util.appendRuleIdToSource to
build a valid source value. For inserted
approvers, the ame_engine.
getHandlerCOAFirstApprover or
ame_engine.getHandlerCOAInsertion
procedure outputs the correct source value for
each inserted approver.

item_class The handler should call


ame_engine.getHandlerItemClassName once
per handler cycle to fetch this value.

item_id The handler should call


ame_engine.getHandlerItemId once per handler
cycle to fetch this value.

item_class_order_number The handler should call


ame_engine.getHandlerItemClassOrderNumber
once per handler cycle to fetch this value.

item_order_number The handler should call


ame_engine.getHandlerItemOrderNumber once
per handler cycle to fetch this value.

sub_list_order_number The handler should call


ame_engine.getHandlerSublistOrderNum once
per handler cycle to fetch this value.

action_type_order_numb The handler should call


er ame_engine.getHandlerActionTypeOrderNum
once per handler cycle to fetch this value.

group_or_chain_order_n The handler should call ame_engine.


umber getActionTypeChainOrderMode once per
handler cycle to fetch the chain-ordering mode
of its action type. If the mode is
ame_util.serialChainsMode, the
group_or_chain_order_number should have the
same value as the group_or_chain_id. If the
mode is ame_util. parallelChainsMode, the
group_or_chain_order_number should always
be one.

Building an ActionType 19
Field Value

member_order_number The handler should call


ame_engine.getActionTypeVotingRegime once
per handler cycle to fetch the voting regime of
its action type. If the regime is
ame_util.consensusVoting or
ame_util.firstApproverVoting, the
member_order_number should always be one.
If the regime is ame_util.serializedVoting, the
member_order_number should be one for the
first approver in each chain, and should
increment at step 4.3.

approver_order_number The handler should leave this field null (AME’s


engine populates this field.)

You can help make your handler code efficient by re-using a


local ame_util.approverRecord2 variable for the current
approver, and calling the functions that return a constant value
for the handler’s cycle just once each at the start of the handler
cycle, to populate the constant fields of the current-approver
record.

3. If the handler only needs to generate one chain of authority, eliminate the
loop at step 4, and simply do invidual steps contained 4 once.

Approver-Group-Handler Architecture

An approval-group handler translates required-attribute and action-


parameter values into one or more pre-approval or post-approval
approval groups, either for a given subordinate item, or for the header
item. For each approver that the handler adds to the item’s approval list,
the handler must populate all but one of the fields in the approver’s
ame_util.approverRecord2. (AME’s engine calculates the value of the
record’s approver_order_number field.) The handler procedure should
implement the following pseudocode to generate the approval groups:

1. Call ame_engine.getHandlerRules to fetch the applicable rules’ IDs and


action parameters (which are the IDs of the approval groupsthat the rules
require), and the approver categories that the rule usages assign them.

2. Call one of the engine’s attribute-value-fetching routines to fetch the


values of any required attributes.

3. Remove any duplicate approver-group IDs from the list of action


parameters.

4. Fetch the required groups’ order numbers and ordering modes by calling
ame_engine.getApprovalGroupConfigs. (Note that this procedure sorts

Building an ActionType 20
the group IDs in place by group order number first, then by group ID.)

5. For each required approval group, loop.

a. Fetch the group’s membership by calling


ame_engine.getRuntimeGroupMembers.

b. For each approver returned by getRuntimeGroupMembers, loop

• Set the values of the fields of the approver’s


ame_util.approverRecord2.

• Call ame_engine.addApprover.

Notes:

1. At step 3, you may eliminate duplicate action parameters, but if you do,
you should preserve in your rule-ID list the IDs of all the applicable
rules, for use in populating each approver’s source field.

2. When a handler populates an approver’s ame_util.approverRecord2


fields at step 5b, it should follow the instructions in this table:

Field Value

name, orig_system, The ame_engine.getRuntimeGroupMembers


orig_system_id procedure returns all of these values.

approver_category The handler calculates this value from data


returned by ame_engine.getHandlerRules2 in
step a, depending on which rules require the
approver. The value is
ame_util.approvalApproverCategory if any of
the rule usages requiring the approver is this
value; otherwise the value is
ame_util.fyiApproverCategory.

api_insertion The handler should always set this value to


ame_util.oamGenerated.

authority The handler should set this value to


ame_util.preApprover or
ame_util.postApprover.

approval_status The handler should call


ame_engine.getHandlerApprovalStatus once
per approver to fetch this value.

Building an ActionType 21
Field Value

action_type_id The handler should call


ame_engine.getHandlerActionTypeId once per
handler cycle to fetch this value.

group_or_chain_id The parameters returned by


ame_engine.getHandlerRules at step 1 are
approver-group IDs. The loop at step 5 iterates
through the group IDs (typically after any
duplicates have been removed).

occurrence The handler should call


ame_engine.getHandlerOccurrence once per
approver to fetch this value.

source The source value should be a list of the IDs of


the rules requiring the approver, separated by
ame_util.fieldDelimiter. You should use
ame_util.appendRuleIdToSource to build a
valid source value.

item_class The handler should call


ame_engine.getHandlerItemClassName once
per handler cycle to fetch this value.

item_id The handler should call


ame_engine.getHandlerItemId once per handler
cycle to fetch this value.

item_class_order_number The handler should call


ame_engine.getHandlerItemClassOrderNumber
once per handler cycle to fetch this value.

item_order_number The handler should call


ame_engine.getHandlerItemOrderNumber once
per handler cycle to fetch this value.

sub_list_order_number The handler should call


ame_engine.getHandlerSublistOrderNum once
per handler cycle to fetch this value.

action_type_order_numb The handler should call


er ame_engine.getHandlerActionTypeOrderNum
once per handler cycle to fetch this value.

Building an ActionType 22
Field Value

group_or_chain_order_n The call to


umber ame_engine.getApprovalGroupConfigs at step
4 fetches each group’s order number.

member_order_number The call to


ame_engine.getApprovalGroupConfigs at step
4 fetches each group’s voting regime. If the
regime is ame_util.consensusVoting or
ame_util.firstApproverVoting, the
member_order_number should always be one.
If the regime is ame_util.serializedVoting, the
member_order_number should be the index of
the approver in the approverNamesOut output
argument of
ame_engine.getRuntimeGroupMembers. If the
regime is ame_util.orderNumberVoting, the
member_order_number should be the member
order number in the
approverOrderNumbersOut argument of
ame_engine.getRuntimeGroupMembers.

approver_order_number The handler should leave this field null (AME’s


engine populates this field.)

You can help make your handler code efficient by re-using a


local ame_util.approverRecord2 variable for the current
approver, and calling the functions that return a constant value
for the handler’s cycle just once each at the start of the handler
cycle, to populate the constant fields of the current-approver
record.

List-Editing-Handler Architecture

AME seeds three list-editing handlers, one each to reduce an


approver’s authority, extend it, and substitute one approver for
another. The first two of these operations are for list-modification
rules, the third is for substitution rules. The architectural feature
these handlers share is, they all modify the approver list only when a
target approver appears in an appropriate context in the list. Here is
the basic algorithm:

1. Call ame_engine.getHandlerRules3 to fetch the list of applicable


rules.

2. Optionally sort the values returned by


ame_engine.getHandlerRules3 to eliminate duplicates and leave
the values in an order that is meaningful to your handler.

Building an ActionType 23
3. For each (remaining) row in the output variables of
ame_engine.getHandlerRules3, loop.

a. Call ame_engine.getHandlerLMApprovers to fetch the


approvers that match the current list-modification
condition.

b. For each row in the output variables of


ame_engine.getHandlerLMApprovers, loop.

c. Perform some operation on the approver list targeting


the approver identified by the current approver.

Notes:

1. Call ame_engine.substituteApprover to effect substitututions.

2. Call ame_engine.truncateChain to truncate a chain of authority


after a target approver.

3. If your handler extends a chain of authority, it should populate


the new approvers’ ame_util.approverRecord2 fields according
to note 2 under “Authority-Handler Architecture” above.

4. Substituted approvers should have the same


ame_util.approverRecord2 field values as the approvers they
replace. The ame_engine.substituteApprover sets all of the fields
values; your handler code should not change any of them.

5. A list-modification handler that removes approvers from the


approver list should not change the ame_util.approverRecord2
fields of any remaining approvers.

PL/SQL Exceptions

Every routine in your handler should include an exception block. The


exception block should at least have a when-others exception handler. The
last two statements in each exception handler for an unhandled exception
should always be a call to ame_util.runtimeException, followed by a raise
statement or raise_application_error call. In the latter case it is idiomatic in
AME coding to have the enclosing routine declare the local variables
errorCode integer;
errorMessage ame_util.longestStringType

and then begin your exception handler by setting these variables’


values. Then the last two statements in the exception handler
can reference these variables, rather than their values. The
following example illustrates both kinds of exception handlers:
exception
when jobLevelException then
errorCode := -20001;
errorMessage :=

Building an ActionType 24
ame_util.getMessage(
applicationShortNameIn => 'PER',
messageNameIn =>
AME_400448_AJHA_JOB_NOT_ASSD');
ame_util.runtimeException(
packageNameIn =>
'ame_absolute_job_level_handler',
routineNameIn => 'getJobLevelAndSupervisor',
exceptionNumberIn => errorCode,
exceptionStringIn => errorMessage);
raise_application_error(errorCode,
errorMessage);
when others then
ame_util.runtimeException(
packageNameIn =>
'ame_absolute_job_level_handler',
routineNameIn => 'getJobLevelAndSupervisor',
exceptionNumberIn => sqlcode,
exceptionStringIn => sqlerrm);
raise;

Registering an Action Type

Once your handler is ready, you need to register it with AME using the
actions tab. Note that this tab requires administrative or developer
privileges.

To create an action type, follow these steps:

1. Select the actions tab.

2. Select the ‘Add Action Type’ button at the bottom of the list of actions.

3. Select the appropriate rule type from the ‘Create an Action Type-Step 1’
form, and then select the ‘Create Action Type’ button.

4. Enter and select the properties of the action type, and the current
transaction type’s configuration for it, on the ‘Create an Action Type-Step
2’ form. If you select ‘yes’ on the ‘Dynamic Action Description’ radio
button, you must enter a dynamic action-description query in the
‘Action-Description Query’ field below. Such queries can reference the
bind variables :parameterOne and (for list-editing action types)
:parameterTwo, which AME binds to an action’s parameter values. For
example,

select :parameterOne||' / '||:parameterTwo from dual

might be a dynamic action description for a list-modification action


type. (Note the absence of a semi-colon at the end of the query. Do
not include a semi-colon.) When you have entered and selected your
action type’s properties and configuration values for the current
action type, select the ‘Create Action Type’ button.

At this point the wizard creates the action type and takes you to the

Building an ActionType 25
‘Create an Action’ form. You can use this form to create the first
action for your action type. When you submit the form, the wizard
takes you to the new action type’s editing form, where you can add
more actions or change some of the action type’s properties and
configuration values.

See Chapter 5 of the implementation guide for additional information about


an action type’s properties and configuration values.

Major changes in the Engine/ Handler Interface since R11i9

As discussed at the start of this chapter there has been some


major changes to the way custom action type handlers are
required to be coded. The conversion steps to move handlers
developed on R11i9 and earlier and preceeding the patchset
AME.A, that was released in early Dec 2005.

Step AME 11.5.9 AME 11.5.10 / AME.A


1. The handler has 3 public routines The handler has only one public routine
which are called by the engine. They which is called by the engine. It is:
are: getFirstApprover(), handler()
getNextApprover() and
hasFinalAuthourity()
2. The handler returns at most one The handler does not have any
approver back to the engine. arguments being passed IN or OUT.
3. No special routines needed to define Special callable engine routines are
the handler context. The relevant available to set handler context.
information is passed in as arguments.
4. The engine makes multiple calls to a The engine calls the handler once. All
handler in order to get all the approvers are processed by this one
approvers. call.
5. The approver recovered is of type The approver record is of type
ame_util.approverRecord ame_util.approverRecord2
6. The approver list being maintained by The approver list being maintained by
the engine is stored in public tables the engine is private and cannot be
which can be directly accessed by the directly accessed by the handler.
handler. Special callable engine routines are
defined to do this.
7. The approver record is passed between No serialization of the approver record
the handler and the engine after is necessary.
serialization.
8. The logic to identify the starting point The logic to identify the starting point
approver is embedded partly in the approver is part of the handler code
engine and partly in the handler. only.
9. The logic to take into account COA The logic to take into account COA

Building an ActionType 26
insertions resides in the engine. insertions resides in the handler.
10. The logic to identify surrogate The logic to identify surrogate
approvers resides in the handler. approvers resides in the approver type
object layer.
11. The handler transaction state needs to Temporary tables/ global engine
be maintained in temporary tables/ variables are not needed to maintain
global engine variables. transaction state. This can be done by
using private handler package
variables.
12. The rules which require the approver The rules which require the approver to
to be part of the approver list are not be part of the approver list are
accurately identified. All applicable accurately identified. Only rules which
rules are included in the source require the approver to be included in
column of the approver record. the approver list are mentioned in the
source column of the approver record.
13. The List Modification actions which The List Modification actions which
truncates the approver list actually truncates the approver list will either set
delete the approvers from the approver the approvers approver_category to
list. ame_util.fyiApproverCategory, if
possible or will set the approvers
approval_status to
ame_util.suppressedStatus.

Environment to Migrate Custom Handler

The new custom handler code can be written and tested on an


AME 11.5.10 instance only. Hence it is recommended

• Upgrade a test instance to 11.5.10.


• Migrate/code the new custom handler on this
test instance
• System test the new custom handler on this test
instance
• Upgrade production instance to 11.5.10.
• Implement new custom handler on the
production instance

Building an ActionType 27
3
Defining an
Approver Type

Defining an Approver Type 29


Overview
An approver type is any Workflow Directory Services originating system that
defines entities that can receive Workflow notifications requesting approval.
For example, the HRMS application exports employees from its
per_all_people_f table to the PER Directory Services originating system so an
HR employee can be an approver in AME.

Approver Types in AME

For AME to use an approver type, it must be be registered with AME (not
merely Workflow Directory Services). Currently there is no user interface to
register an approver type. Rather, one must execute a set of SQL statements
that insert rows into the ame_approver_types and
ame_approver_type_usages tables, and you must customize several runtime
routines in AME code. (AME enhancement request 32767685 requests
eliminating the need to customize AME code when adding an approver
type.) If you need to use an approver type that AME does not yet seed, we
strongly encourage you to request that AME development release a patch
supporting the approver type, rather than registering it yourself.

Note: Unless AME development provides support for an approver type in


this fashion, you will have to modify an AME PL/SQL package each time
you patch AME. Oracle Support and AME development do not support
custom approver types other than through best effort.

Registering an Approver Type

Registering an approver type takes four steps:

1. Code a PL/SQL procedure that AME users can invoke to query for
approvers of the new type.

2. Insert a row into ame_approver_types for the approver type.

3. Identify the action types that can use the new approver type. For each
such action type, insert a row into ame_approver_type_usages.

4. Update certain routines in ame_approver_type_pkg that AME uses at


runtime.

The rest of this chapter explains how to perform each of these steps.

Coding an Approver-Query Procedure

AME’s user interface includes an approver-query wizard. AME uses the


wizard in various contexts where an end user must identify an approver, for
example while populating an approval group or creating a list-modification
condition. Each approver type registered with AME must provide an

Defining an Approver Type 30


approver-query procedure that the approver-query wizard can invoke. The
wizard can prompt end users to provide up to five query criteria (first name,
last name, etc.), which the wizard passes to the query procedure.

Procedure Signature

Procedure Name

The name of your approver-query procedure should have the


following form:

[approverType]ApproverQuery

where approverType suggests the approver type. For example,


‘PER’ is the originating system for HR employees, so that the
approver type’s approver-query procedure is
ame_approver_type_pkg.perApproverQuery.

Argument List

Your approver-query procedure’s signature should be:


procedure approverTypeApproverQuery(
criterion1In in varchar2 default null,
criterion2In in varchar2 default null,
criterion3In in varchar2 default null,
criterion4In in varchar2 default null,
criterion5In in varchar2 default null,
excludeListCountIn in integer,
approverNamesOut out nocopy varchar2,
approverDescriptionsOut out nocopy varchar2);

At run time, the first five arguments contain the query criteria
that the end user entered or selected on the approver-query form
of the approver-query wizard. The integer excludeListCountIn
sets appropriately the the number of rows that the procedure
may output, to account for a set of excluded approvers known to
the approver-query wizard at run time. The two output
arguments identify approvers that match the query criteria.

Functionality

When you register your approver type with AME, you provide a
set of query criteria that the approver-query wizard should
present when an end user queries for approvers of your
approver type. The end user may leave any or all of these blank,
so that your procedure may receive null values in any
combination of its criterion[n]In arguments. The simplest way to
accommodate such null query criteria is to have your cursor
define a cursor that encapsulates your approver query. The
cursor’s argument list should match exactly the input argument
list of the query procedure. The cursor’s where clause should
accommodate null query criteria like this:
where
(criterion1In is null or

Defining an Approver Type 31


some_column like ‘%’ || criterion1In || ‘%’) and
(criterion2In is null or
some_column like ‘%’ || criterion2In || ‘%’) and . .
.

Your procedure should limit the number of rows it returns by


including the following line in its main cursor’s where clause:
rownum < 52 + rowsToExcludeIn

The approver-query wizard checks your procedure’s output


values for a set of approvers to exclude. This set has
rowsToExcludeIn members. So worst case, the set of approvers
that the approver-query wizard presents to the end user, after
filtering out the approvers to exclude, should have 50 approvers
in it. The value 52 lets the cursor return one row too many. Your
code should check for this condition and raise an exception, as
follows (assuming the procedure fetches the cursor into a local
approverNames variable):
if(approverNames.count - rowsToExcludeIn > 50) then
raise ame_util.tooManyApproversException;
approverNamesOut := null;
approverDescriptionsOut := null;
return;
end if;

If the cursor does not select too many rows, your procedure
should check that it returns at least one:
if(approverNames.count = 0) then
raise ame_util.zeroApproversException;
approverNamesOut := null;
approverDescriptionsOut := null;
return;
end if;

If the cursor selects an apprpriate number of rows, your


procedure should serialize the lists of approver names and
descriptions selected by the query, and return the serialized lists
in the procedure’s output arguments, like this:
ame_util.serializeApprovers(
approverNamesIn => approverNames,
approverDescriptionsIn => approverDescriptions,
maxOutputLengthIn =>
ame_util.longestStringTypeLength,
approverNamesOut => approverNamesOut,
approverDescriptionsOut => approverDescriptionsOut);

Inserting a Row into ame_approver_types

Use the following insert statement to register the new approver type with
AME:
insert into ame_approver_types(
approver_type_id,
orig_system,
query_variable_1_label,
query_variable_2_label,

Defining an Approver Type 32


query_variable_3_label,
query_variable_4_label,
query_variable_5_label,
variable_1_lov_query,
variable_2_lov_query,
variable_3_lov_query,
variable_4_lov_query,
variable_5_lov_query,
query_procedure,
created_by,
creation_date,
last_updated_by,
last_update_date,
last_update_login,
start_date,
end_date)
values(
approverTypeId,
origSystem,
queryVariable1Label,
queryVariable2Label,
queryVariable3Label,
queryVariable4Label,
queryVariable5Label,
variable1LovQuery,
variable2LovQuery,
variable3LovQuery,
variable4LovQuery,
variable5LovQuery,
queryProcedure,
createdBy,
creationDate,
lastUpdatedBy,
lastUpdateDate,
lastUpdateLogin,
startDate,
endDate);

Below are descriptions of the values you must supply in the


above insert statement.

approverTypeId

To determine the appropriate approverTypeId value, execute the


following query:
select 1 + max(approver_type_id) from ame_approver_types;

origSystem

The origSystem value should be the wf_roles.orig_system value that


approvers of the new approver type have. You can view all of the
available orig_system values by executing the following query:

select distinct orig_system from wf_directory_partitions;

Defining an Approver Type 33


queryVariable[n]Label

If you want the approver-query wizard to present k query criteria for


your approver type, you must supply user-friendly labels for these
criteria in the first k queryVariable[n]Label columns, and null in the
remaining 5 – k queryVariable[n]Label columns. Each label may be
up to 50 bytes long.

variable[n]LovQuery

If you want the ith query criterion to be a select list,


variable[i]LovQuery should be an SQL query that returns the values
you want to appear in the select list. The query may be up to 4000
bytes long, and should not include a terminating semi-colon. If
variable[I]LovQuery is null, the ith query criterion will be a text-
entry input.

queryProcedure

This value should be the name of your query procedure. If the


procedure resides in a package, prepend the package name and a
period to the procedure’s name.

createdBy

This value should be the fnd_user.user_id value of the user that


inserts the row.

creationDate

Use sysdate for this value.

lastUpdatedBy

This value should be the same as the createdBy value.

lastUpdateDate

Use sysdate for this value.

lastUpdateLogin

This value should be the same as the createdBy value.

startDate

Use sysdate for this value.

endDate

The endDate value should be null.

Defining an Approver Type 34


Identifying the Action Types that can use the new Approver Type

Once you have inserted a row into ame_approver_types for your approver
type, you must tell AME which custom action types may use the approver
type. Do not include seeded action types in your list. For each action type in
your list, follow these steps:

1. Select the action tab.

2. Select the action type on the list of action types.

3. Select the ‘Add Approver Types’ button at the bottom of the ‘Edit Action
Type’ form.

4. Select the new approver type from the ‘Approver Type’ select list, and
then select the ‘Add’ button.

Updating ame_approver_type_pkg Runtime Routines

There are three runtime ame_approver_type_pkg routines that you must


modify to accommodate your new approver type. Be very careful not to alter
the existing code, and remember that you will have to repeat your additions
each time you install an AME patch. AME’s engine calls these procedures, so
your code should be as efficient as possible.

isASubordinate

The function ame_approver_type_pkg.isASubordinate returns true if the


approver possibleSubordApproverIn is a subordinate of the approver
approverIn (presumably within a common approver hierarchy), and false
otherwise. The function returns false by default. If your approver type does
not represent an organizational hierarchy, you do not need to modify the
procedure (because in this case no subordination relations exist among your
approver type’s approvers). Otherwise, you must modify the procedure so
that if the two input approvers belong to your approver type, the procedure
checks whether the one is a subordinate of the other.

getSuperior

The procedure ame_approver_type_pkg.getSuperior returns in superiorOut


the superior of the input approver approverIn, raising the procedure’s
noSurrogateException exception if no superior exists. The procedure raises
the exception by default, so if your approver type does not represent an
organizational hierarchy, you do not need to modify the procedure (because
in this case no subordination relations exist among your approver type’s
approvers). Otherwise, you must modify the procedure so that when the
input approver belongs to your approver type, the procedure returns the
input approver’s superior.

getSurrogate

The ame_approver_type_pkg.getSurrogate procedure outputs the surrogate


approver that AME should substitute for the unresponsive approver
identified by the procedure’s input arguments, raising the local exception

Defining an Approver Type 35


noSurrogateException if no surrogate exists. The procedure raises the
exception by default, so if your approver type does not admit surrogate-
approver functionality, you do not need to modify the procedure.
Otherwise, you must modify the procedure so that when the input approver
belongs to your approver type, the procedure returns the input approver’s
surrogate.

Defining an Approver Type 36


4
Defining an Item
Class

Defining an Item Class 37


Overview
This chapter explains when and how to define an item class. You must have
the AME Developer responsibility to define an item class. See Chapter 8 of
the Oracle Approvals Management Implementation Guide for more
information about item classes.

When to Define an Item Class

AME currently seeds item classes for a transaction’s header, line items, cost
centers, and project codes. Your originating application may recognize other
entities having a many-to-one relation to a transaction. For example, your
application may divide a transaction’s cost among several entities of the same
kind. If you want to enable any of your transaction types to define attributes
for these entities, or to generate one approver list per entity, you should
define an AME item class for the entity.

How to Define an Item Class

To define an item class, follow these steps:

1. Select the admin tab.

2. Select ‘transaction-type administration’, and then the ‘Continue’ button.

3. Select ‘Maintain item classes’, and then the ‘Continue’ button.

4. Select the ‘Add Item Class’ button.

5. Select the ‘Create New Item Class’ button on the ‘Add an Item Class—
Step 1’ form.

6. Enter the item class’ name on the ‘Add an Item Class—Step 2’ form.

7. Enter the properties of the current transaction type’s usage of the new
item class on the ‘Add an Item Class—Step 3’ form, and then select the
‘Continue’ button to create the item class.

The item class will now appear on the list of item classes you reached at step
3 above.

Defining an Item Class 38


5
Integrating AME
with Workflow

Integrating AME with Workflow 39


Overview
AME’s basic design imperative is to locate all approvals–related logic in a
single module, rather than having each application provide its own
approvals logic. This chapter explains how you can integrate AME into your
application’s Workflow processes.

Notifications

Information to Include in Notifications

AME’s APIs provide a variety of information you can include in the


notifications you send the approvers in a transaction’s approver list:

• whether the notification should be informational or should


request the approver’s approval

• which subordinate items require the approver’s attention

• which approval rules required that the approver receive the


notification

• which productions appy to the approver

• which productions apply to the transaction.

(See Appendix A for details.) Your application should interpret the


productions before presenting them to an end user in a notification.

Encoding Responses to Notifications Requesting Approval

Appendix B’s description of the approval_status field of the


ame_util.approverRecord2 data type lists and describes the ame_util
constants your code may use to represent an approver’s response to a
notification requesting approval. If you try to pass any other approval_status
value to AME’s APIs, AME will raise an exception.

The Basic Algorithm

Here is the basic algorithm that an application should implement in its


Workflow processes, to let AME manage the approval processes of a
transaction type that the application owns.

1. Call one of the ame_api2.getNextApprovers[n] procedures to get the


wf_role.name values of any approvers that currently require
notification, and to determine whether the transaction’s approval
process is complete.

2. If ame_api2.getNextApprovers[n] outputs the value

Integrating AME with Workflow 40


ame_util.booleanTrue in approvalProcessCompleteYNOut, stop (the
transaction is approved).

3. Notify any approvers output by ame_api2.getNextApprovers[n] at


step two above, and wait for a response from each approver who
must approve.

4. When an approver who must approve responds, communicate the


response to AME by calling ame_api2.updateApprovalStatus or
ame_api2.updateApprovalStatus2, and go to step one above.

Telling AME that an Approver has been Notified

Usually you should pass ame_util.booleanTrue in


flagApproversAsNotifiedIn. Otherwise you must update each notified
approver’s status to ame_util.notifiedStatus upon notifying the approver at
step three.

Exception Handling

AME complies with the Workflow exception-handling model by raising all


runtime exceptions to the originating application’s Workflow processes,
without issuing a rollback. To clear an exception from a transaction’s
approval-process state in AME, you need to pass the status
ame_util.clearExceptionsStatus at step four in the basic algorithm. Note that
this only clears the transaction’s exception status within AME. It does not
affect the transaction’s status in its Workflow process.

Modifications to the Basic Algorithm

There are several ways to enhance the basic algorithm. This section describes
some of them. To learn about other ways to enhance the basic algorithm,
review the API specifications in Appendix A.

Handling Rejections

The basic algorithm does not terminate if one of the approvers rejects the
transaction. In the event of a rejection, you may wish to stop at step four to
make sure the algorithm terminates.

Inserting Approvers into the Default Approver List

In the basic algorithm, your application does not determine the membership
of a transaction’s approver list. It leaves all such decisions to AME. If your
application needs to let an end user insert approvers into the approver list
that AME generates for a given transaction, modify the basic algorithm as
follows:

1. Call ame_api2.getAllApprovers[n] to get a transaction’s default


approver list.

2. Display the approver list to the end user. Include suppressed and

Integrating AME with Workflow 41


repeated approvers, but flag them as such (perhaps by greying out
their names).

3. Prompt the user to choose a location (index) in the approver list at


which to perform the insertion, or to stop.

4. If the user chooses to stop, stop.

5. Call ame_api3.getAvailableInsertions for that location.

6. Display the resulting list of available insertions.

7. Prompt the user to choose one of the available insertions.

8. Prompt the user to query for an approver to insert.

9. Call ame_api2.validateApprover to validate the approver chosen at


step seven above.

10. If the approver is invalid, go to step 8 above.

11. If the insertion type is ame_util.firstAuthority, call


ame_api2.setFirstAuthorityApprover to perform the insertion.
Otherwise, call ame_api3.insertApprover to perform the insertion.

Suppressing Approvers in the Default Approver List

If your application needs to let an end user suppress approvers in the


approver list that AME generates for a given transaction, modify the basic
algorithm as follows:

1. Call ame_api2.getAllApprovers[n] to get a transaction’s default


approver list.

2. Display the approver list to the end user. (You don’t need to include
suppressed or repeated approvers, but you should track internally
the indexes of the approvers you display.)

3. Prompt the user to choose an approver to suppress, or to stop.

4. If the user chooses to stop, stop.

5. Call ame_api3.suppressApprover to suppress the approver.

6. Go to step one.

Accounting for Unresponsive Approvers

You may wish to account for notification timeouts in your


application’s Workflow process. To do so, modify step three of the
basic algorithm by timing each notification. Modify step four to
catch timeouts as well as responses, and to pass
ame_util.noResponseStatus to ame_api2.updateApprovalStatus or
ame_api2.updateApprovalStatus2 in the event of an unresponsive
approver.

Integrating AME with Workflow 42


Forcing an Approver who has Already Approved an Item to Approve it Again

If you want to force a single approver to re-approve an item they


have already approved, update the approver’s status to null.

Frequently Asked Questions

What does final (signing) authority mean in AME?

The basic algorithm only uses Workflow to send and receive


notifications. It does not use Workflow to determine which approver
has final or signing authority (in any sense). AME determines final
authority internally. Your application’s Workflow process knows
that a transaction has been approved when AME so indicates (at step
two of the basic algorithm).

AME can generate an approver list for each item in a transaction.


Each approver list can have several chains of authority. Each chain
of authority has at least one approver with final (signing) authority
(arriving at such an approver is how AME decides to end the chain).
So in general, no single approver has final authority for the overall
approver list. Furthermore, AME’s parallel-approvals functionality
makes it possible for an approver having signing authority to be
notified along with previous approvers in the chain of authority. So
the temporal order of notifications does not generally reveal which
approver is a final approver.

Why call AME each time an approver responds to a notification requesting


approval?

Calling ame_api2.getNextApprovers[n] each time an approver


responds to a notification requesting is natural in several ways.

1. It accounts for the possibility that a transaction’s approver list


will change during the transaction’s approval process. Several
phenomena can cause the approver list to change:

• An attribute value can change.

• A currency conversion rate can change.

• An organizational hierarchy can change.

• An approval group can change.

• The rules that apply to a transaction can change.

• The relevant transaction type’s configuration-variable


values can change.

• The relevant transaction type’s mandatory-attribute


values can change.

Integrating AME with Workflow 43


2. An approver may be unresponsive long enough for your
application to tell AME that the approver was unresponsive, in
which case AME will add the approver’s surrogate to the
approver list.

3. An approver may reject some but not all items, and AME may
stop those items’ approval processes while continuing the
approval processes of remaining items.

4. It checks for more approvers to notify at the exact moment when


their existence becomes likely.

5. It is efficient with respect to performance overhead in the sense


that the least upper bound on the number of different
approver_order_number values is the number of approvers, and
in the typical scenario (where each approver approves), the
number of approver responses is the same as the number of
approvers.

Does AME do transaction management?

AME does not perform any commits or rollbacks while responding


to an API call originating within a workflow. (Where necessary,
AME determines whether it has been called from within a workflow
by checking the value of the useWorkflow configuration variable.) If
the calling application does not use Workflow, the only transaction
management that AME performs at runtime is to commit inserts into
its exception log within autonomous transactions. Thus, if an
application integrates AME without using Workflow, it must commit
or rollback AME’s work within the code that calls AME’s APIs.

Sample Workflow

This section explains how to implement the basic algorithm in Workflow.

Overview

To implement the basic algorithm in Workflow, you need to do three things:

1. Create a Workflow item type to manage your transaction type’s


approval processes.

2. Create the following things within your item type:

• Create an item attribute of type text (say ‘Approver’) to


contain notification performer data.

• Create an item attribute of type text (say ‘Master Item


Key’) to contain the master process’ item-key value.

• Create a lookup type (say ‘Approval Status’), and add to


it the approval_status values that your item type will
use. (See ‘Encoding Responses to Notifications

Integrating AME with Workflow 44


Requesting Approval’ above.)

• Create a message of type response (say ‘Response


Message’) by attaching the result to its result tab, with
the display name ‘Result’, the description ‘Response
Result’, and the lookup type ‘Approval Status’.

3. Create two processes, one each for master and detail. (See below
for details.)

4. Create a PL/SQL package whose procedures call AME’s API


routines on behalf of your Workflow.

Workflow Processes

The master process essentially does the following:

1. Fetch the next approvers to notify (if any) using


ame_api2.getNextApprovers4.

2. For each approver fetched, spawn a child process.

3. Wait for a response from at least one child process to


continue.

4. When a child process receives a response, process the


response and go to step one above.

The child process essentially does the following:

1. Send a notification to the approver.

2. If the notification requests a response, wait for a


response from the approver.

3. When the response arrives, so indicate to the master


process.

The Master Process

The master process has four nodes. Here are descriptions of each
node:

Start Node

The first node is a standard function activity that simply marks the
start of the process.

Function WF_STANDARD.NOOP

Result Type none

Required yes

Prerequisite Activities none

Integrating AME with Workflow 45


Item Attributes Set by Function none

Item Attributes Retrieved by Function none

Is-Approval-Complete Node

The second node fetches the next set of approvers (if any) by calling
your PL/SQL package’s wrapper procedure for
ame_api2.getNextApprovers4. The node also checks whether the
transaction’s approval process is complete. If the process is
incomplete, the node creates and starts a child process for each
approver requiring notification.

Function <package_name>.<procedure_name>

Result Type yes/no (determines whether the transaction is


completed or not)

Required yes

Prerequisite Activities none (initially none, subsequently waits


for the response from the notified approver at the third node)

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

The following pseudocode describes this node’s logic:

1. Call your ame_api2.getNextApprovers4 wrapper procedure


to get the next set of approvers to notify (if any).

2. If approvalProcessCompleteYN = ame_util.booleanTrue, end


the process.

3. Loop through the approvers returned at step one. Follow


these steps for each approver:

• A - Create a child processes by calling

wf_engine.createProcess(

itemType => <itemType>,

itemKey => <childItemKey>,

process => <childProcessName>);

• B - Set the item Approver attribute to the approver’s


wf_roles.name value by calling

wf_engine.SetItemAttrText(

itemType => <itemType>,

Integrating AME with Workflow 46


itemKey => <childItemKey>,

aName => ‘Approver’,

aValue => <approver’s wf_roles.name>);


C - Set the item Master Item Key attribute to the master
item’s item key by calling

wf_engine.SetItemAttrText(

itemType => <itemType>,

itemKey => <childItemKey>,

aName => ‘Master Item Key’,

aValue => <itemKey>);


D - Start the child processes by calling

wf_engine.StartProcess(

<itemType>,

<childItemKey>);

Each child process’ item key must be unique.

Wait-for-Approver-Response Node

The third node is a customized standard function activity that


waits for a response from the child processes.

Function WF_STANDARD.BLOCK

Result Type none

Required yes

Prerequisite Activities third node of child process (Get


Approver Response)

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

End Node

This is a standard function activity that marks the end of the


process.

Function WF_STANDARD.BLOCK

Result Type none

Required yes

Integrating AME with Workflow 47


Prerequisite Activities node two, if result type = Y

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

The Child Process

Start Node

The start node is a standard function activity that marks the start
of the process.

Function WF_STANDARD.NOOP

Result Type none

Required yes

Prerequisite Activities none

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

Send-Notification Node

The send-notification node is a standard notification activity that


notifies the approver.

Function none

Message response message

Result Type Approval Status

Required yes

Prerequisite Activities none

Item Attributes Set by Function Set the performer attribute to


the approver’s wf_roles.name value.

Item Attributes Retrieved by Function none

Get-Approver-Response Node

This activity node should call a procedure in your PL/SQL


package that gets the approver’s response, passes it to AME, and
then completes the master process’ waiting activity (its Wait for
Approver Response node).

Function <package_name>.<procedure_name>

Result Type none

Integrating AME with Workflow 48


Required yes

Prerequisite Activities none

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

The following pseudocode describes this node’s logic:

1. Get approver attribute’s value by calling

wf_engine.GetItemAttrText(

itemType => <itemType>,

itemKey => <childItemKey>,

aName => ‘Approver’);

2. Get the approver’s response notification response for the


above approver

3. Update the approver’s status calling

ame_api2.updateApprovalStatus or

ame_api2.updateApprovalStatus2.

4. Communicate the response to the master process’


waiting node by setting

masterItemKey := wf_engine.GetItemAttrText(

itemType => <itemType>,

itemKey => <childItemKey>,

aName => 'Master Item Key');

and then calling

wf_engine.CompleteActivity(

itemType => <itemType>,

itemKey => <masterItemKey>,

activity => <Wait for Approver Response>,

result => null);

End Node

This is a standard function activity that marks the end of the


process.

Integrating AME with Workflow 49


Function WF_STANDARD.BLOCK

Result Type none

Required yes

Prerequisite Activities none

Item Attributes Set by Function none

Item Attributes Retrieved by Function none

Integrating AME with Workflow 50


Integrating AME with Workflow 51
Appendix A
API Functional
Specifications

Appendix A API Functional Specifications 53


Overview
AME provides three runtime API packages. The ame_api2 package contains
routines that a typical workflow uses to process a typical approval process,
while ame_api3 contains ancillary routines. The ame_api package is
available for backwards compatibility only. If you are integrating AME into
your product for the first time, use ame_api2 and ame_api3 only. This
chapter explains how to call AME API routines.

Calling AME API Routines

Arguments

Many of AME’s API routines share certain arguments. Here are


brief descriptions of each.

applicationIdIn is the fnd_application.application_id value of


the originating application calling the AME API routine.

transactionTypeIn is a string up to 50 bytes long. It


distinguishes one transaction type from another, within a given
originating application. It can be null, but you must always pass
its value explicitly.

transactionIdIn is a string up to 50 bytes long. It identifies a


transaction within a transaction type. Its value must not contain
white-space characters, and must not be the character
representation of a negative integer.

approverIn is an ame_util.approverRecord2 (or an


ame_util.approverRecord in ame_api) that represents an
approver.

For ame_api2 and ame_api3, the above four arguments always


appear at the top of a procedure’s input in the above order, when
they appear at all.

Passing Arguments by Name

Always pass arguments by name to AME’s APIs. This lets AME


development add default-null arguments to an API routine
without breaking pre-existing code that references the routine.

Approver Comparisons

When AME must determine whether two


ame_util.approverRecord2 records represent the same
occurrence of an approver in a given transaction’s approver list,
it compares the following fields:

• item_class

Appendix A API Functional Specifications 54


• item_id

• name

• action_type_id

• group_or_chain_id

• occurrence.

The two records represent the same occurrence of the approver if


and only if all of these fields have the same values.

ame_api2

validateApprover

Syntax
function validateApprover(
approverIn in ame_util.approverRecord2)
return boolean;

Description

The validateApprover function returns true if the approver


represented by approverIn has a current wf_roles entry,
otherwise returns false. Use this API to check whether an
ame_util.approverRecord2 that your application generates is
valid, especially before passing an ame_util.approverRecord2 to
an AME API routine. (AME always validates approvers before
returning them via its APIs, so your code need not do so)

clearAllApprovals

Syntax
procedure clearAllApprovals(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2);

Description

The clearAllApprovals procedure clears a transaction’s approval-


process state. Restores the default approver list (removing
approver insertions, suppressions, forwardings, etc.). Use this
API to restart a transaction’s approval process from scratch,
undoing any operations that have already modified the approval
process.

Appendix A API Functional Specifications 55


getAdminApprover

Syntax
procedure getAdminApprover(
applicationIdIn in number default null,
transactionTypeIn in varchar2,
adminApproverOut out nocopy
ame_util.approverRecord2);

Description

The getAdminApprover procedure outputs in


adminApproverOut an ame_util.approverRecord2 representing
the input transaction type’s administrative approver. An
originating application may wish to notify this approver when
AME raises an exception.

getAllApprovers1

Syntax
procedure getAllApprovers1(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy
ame_util.longStringList);

Description

The getAllApprovers1 procedure Outputs in approversOut a


transaction’s current approver list, including both rule–
generated and inserted approvers. The approvers’ indexes in
approversOut are consecutive ascending integers starting at one.
The order induced by the indexes is consistent with the ordering
inducd by the approvers’ approver_order_number values (which
AME’s parallel-approval-process functionality generates). The
approvers’ approval_status values reflect the approvers’ latest
responses to requests for approvals, assuming the originating
application has communicated such responses to AME via
ame_api2.updateApprovalStatus or
ame_api2.updateApprovalStatus2.

If approvalProcessCompleteYNOut is ame_util.booleanTrue, the


transaction’s approval process is complete; otherwise it is
incomplete. If an approver’s item_id value is null, several items
require the approver. If such an approver is at index i in
approversOut, and itemIndexesOut(j) = i, then itemIdsOut(j) is
the ID of an item requiring the approver, itemClassesOut(i) is the
item’s item class, and itemSourcesOut(j) is the source field
indicating which rules required the approver for the same item.

Appendix A API Functional Specifications 56


(There will be at least two such entries in itemIndexesOut,
itemIdsOut, itemClassesOut, and itemSourcesOut, for an
approver in approversOut required by multiple items.)

Use this API to fetch and display the entire approver list, either
for information or to prompt for approver insertions or
suppresions. Do not use getAllApprovers1 by calling it, storing
its output approver list, and then iterating through that list in
your application. Doing so would risk inaccuracies in the
approver list introduced by changes in transaction values,
organizational structures, approval rules, etc.

GetAllApprovers2

Syntax
procedure getAllApprovers2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList,
productionIndexesOut out nocopy ame_util.idList,
variableNamesOut out nocopy ame_util.stringList,
variableValuesOut out nocopy ame_util.stringList);

Description

The getAllApprovers2 procedure has the same functionality as


getAllApprovers1, but it also returns per-approver productions
stored in variableNamesOut and variableValuesOut. Several
productions can be assigned a single approver, so
productionIndexesOut contains for each production the index of
the approver in approversOut to which the production is
assigned. That is, if productionIndexesOut(i) = j, then the
production in variableNamesOut(i) and variableValuesOut(i) is
assigned to approversOut(j). Use getAllApprovers2 as you
would getAllApprovers1, when you need to display per-
approver productions with the approvers. See also
ame_api2.getAllApprovers1.

getAllApprovers3

Syntax
procedure getAllApprovers3(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,

Appendix A API Functional Specifications 57


itemSourcesOut out nocopy ame_util.longStringList,
productionIndexesOut out nocopy ame_util.idList,
variableNamesOut out nocopy ame_util.stringList,
variableValuesOut out nocopy ame_util.stringList,
transVariableNamesOut out nocopy
ame_util.stringList,
transVariableValuesOut out nocopy
ame_util.stringList);

Description

The getAllApprovers3 procedure has the same functionality as


getAllApprovers2, but it also returns per-transaction
productions. Use getAllApprovers3 as you would
getAllApprovers2, when you need to display per-transaction
productions as well as the approver list. See also
ame_api2.getAllApprovers1 and ame_api2.getAllApprovers2.

getAllApprovers4

Syntax
procedure getAllApprovers4(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopyame_util.longStringList,
ruleIndexesOut out nocopy ame_util.idList,
sourceTypesOut out nocopy ame_util.stringList,
ruleIdsOut out nocopy ame_util.idList);

Description

The getAllApprovers4 procedure has the same functionality as


getAllApprovers1, but it also classifies the approvers in
approversOut according to the reasons for their occurrence in the
approver list. When one or more rules require an approver,
ruleIdsOut identifies the rules. More particularly: every
approver in approversOut has at least one row in
ruleIndexesOut, sourceTypesOut and ruleIdsOut. If
ruleIndexesOut(i) = j, then the values in sourceTypesOut(i) and
ruleIdsOut(i) pertain to the approver in approversOut(j). Every
approver in approversOut has only one source value, no matter
how many rules required the approver. That is, if
ruleIndexesOut(i1) = j and ruleIndexesOut(i2) = j for i1 ¹ i2,
sourceTypesOut(i1) = sourceTypesOut(i2). Some source values
indicate that an approver is not required by any rules, but is
present for other reasons. In such cases, if the approver is at
index i, then if sourceTypesOut(j) = i, then ruleIdsOut(j) = null.
Use getAllApprovers4 when you need to display the approver
list, along with the rules requiring each approver. See also
ame_api2.getAllApprovers1. Note that getAllApprovers4

Appendix A API Functional Specifications 58


requires significantly more performance overhead than some of
its sibling getAllApprovers[n] procedures.

getAllApprovers5

Syntax
procedure getAllApprovers5(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList,
ruleIndexesOut out nocopy ame_util.idList,
sourceTypesOut out nocopy ame_util.stringList,
ruleDescriptionsOut out nocopy
ame_util.stringList);

Description

The getAllApprovers5 procedure has the same functionality as


getAllApprovers4, but it returns rule descriptions rather than
rule IDs. See also ame_api2.getAllApprovers4.

getAllApprovers6

Syntax
procedure getAllApprovers6(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList,
ruleIndexesOut out nocopy ame_util.idList,
sourceTypesOut out nocopy ame_util.stringList,
ruleIdsOut out nocopy ame_util.idList,
ruleDescriptionsOut out nocopy
ame_util.stringList);

Description

The getAllApprovers6 procedure has the same functionality as


getAllApprovers4, but it returns both rule IDs and rule
descriptions. See also ame_api2.getAllApprovers4.

Appendix A API Functional Specifications 59


getAllApprovers7

Syntax
procedure getAllApprovers7(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2);

Description

The getAllApprovers7 procedure has the same functionality as


getAllApprovers1, but omitting the per-item outputs. This is the
lowest-overhead getAllApprovers[n] procedure. See also
ame_api2.getAllApprovers1.

getAllItemApprovers

Syntax
procedure getAllItemApprovers1(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
itemClassIdIn in number,
itemIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,

approversOut outnocopy ame_util.approversTable2);

Description

The getAllItemApprovers1 procedure has the same functionality


as getAllApprovers1, but for the single item with ID itemIdIn of
the item class with the ID itemClassIdIn. See also
ame_api2.getAllApprovers1.

getAllItemApprovers2

Syntax
procedure getAllItemApprovers2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
itemClassNameIn in varchar2,
itemIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2);

Description

The getAllItemApprovers2 procedure has the same functionality


as getAllItemApprovers1, but it identifies the input item class by
name in itemClassNameIn. See also ame_api2.getAllApprovers1

Appendix A API Functional Specifications 60


and ame_api2.getAllItemApprovers1.

getAndRecordAllApprovers

Syntax
procedure getAndRecordAllApprovers(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy
ame_util.longStringList);

Description

The getAndRecordAllApprovers procedure has the same


functionality as getAllApprovers1, but it also updates the state of
the transaction’s approval process in AME (in particular
accounting for any approver insertions or suppressions made via
the API since the last AME engine cycle). You can call this API
to make sure AME has accounted for an approver insertion or
suppression before calling ame_api3.getOldApprovers.
Otherwise, calling getAndRecordAllApprovers is generally not
necessary. See also ame_api2.getAllApprovers1.

getItemStatus1

Syntax
procedure getItemStatus1(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
itemClassIdIn in integer,
itemIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2);

Description

The getItemStatus1 procedure outputs the status of the approval


process of the item identified by itemIdIn of the item class
identified by itemClassIdIn for the input transaction. If
approvalProcessCompleteYNOut is ame_util.booleanTrue, the
item has been approved; otherwise the item’s approval process is
incomplete.

getItemStatus2

Syntax
procedure getItemStatus2(
applicationIdIn in number,
transactionTypeIn in varchar2,

Appendix A API Functional Specifications 61


transactionIdIn in varchar2,
itemClassNameIn in varchar2,
itemIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2);

Description

The getItemStatus2 procedure outputs the status of the approval


process of the item identified by itemIdIn for the item class
identified by its name in itemClassNameIn. See also
ame_api2.getItemStatus1.

getItemStatuses

Syntax
procedure getItemStatuses(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
itemClassNamesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
approvalProcessesCompleteYNOut out nocopy
ame_util.charList);

Description

The getItemStatuses procedure outputs the statuses of the


approval processes of the input transaction’s items. If
approvalProcessesCompleteYNOut(i) is ame_util.booleanTrue,
the item with ID itemIdsOut(i) of the item class
itemClassNamesOut(i) has been approved; otherwise the item’s
approval process is incomplete.

getNextApprovers1

Syntax
procedure getNextApprovers1(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
flagApproversAsNotifiedIn in varchar2 default
ame_util.booleanTrue,
approvalProcessCompleteYNOut out varchar2,
nextApproversOut out nocopy
ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList)

Description

The getNextApprovers1 procedure outputs in


nextApproversOut the approvers requiring notification for the
current stage of the input transaction’s approval process. Once

Appendix A API Functional Specifications 62


an originating application updates an approver’s status to
ame_util.notifiedStatus, getNextApprovers1 excludes the
approver from nextApproversOut. An originating application
can update an approver’s status to ame_util.notifiedStatus by
passing ame_util.booleanTrue as flagApproversAsNotifiedIn to a
call to getNextApprovers1 that includes the approver in
nextApproversOut. Or the originating application can pass
ame_util.booleanFalse in flagApproversAsNotifiedIn, and
instead call updateApprovalStatus or updateApprovalStatus2 to
update the approver’s status independently of a call to
getNextApprovers. When getNextApprovers1 outputs
ame_util.booleanTrue in approvalProcessCompleteYNOut, the
input transaction’s approval process is complete. Until then, the
approval process is incomplete, even if nextApproversOut.count
is zero. (See getAllApprovers1 above for an explanation of
itemIndexesOut, itemClassesOut, itemIdsOut, and
itemSourcesOut.) Use getNextApprovers1 to iterate through a
transaction’s approval process one stage at a time. See also
ame_api2.getAllApprovers1.

getNextApprovers2

Syntax
procedure getNextApprovers2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
flagApproversAsNotifiedIn in varchar2 default
ame_util.booleanTrue,
approvalProcessCompleteYNOut out varchar2,
nextApproversOut out nocopy
ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList,

productionIndexesOut out nocopy ame_util.idList,


variableNamesOut out nocopy ame_util.stringList,
variableValuesOut out nocopy ame_util.stringList);

Description

The getNextApprovers2 procedure has the same functionality as


as getNextApprovers1, but it also returns per-approver
productions. Use getNextApprovers2 to iterate through a
transaction’s approval process one stage at a time when your
application enables per-approver productions, for example to
track per-approver eSignature requirements. See also
ame_api2.getAllApprovers2 and ame_api2.getNextApprovers1.

getNextApprovers3

Syntax
procedure getNextApprovers3(

Appendix A API Functional Specifications 63


applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
flagApproversAsNotifiedIn in varchar2 default
ame_util.booleanTrue,
approvalProcessCompleteYNOut out varchar2,
nextApproversOut out nocopy
ame_util.approversTable2,
itemIndexesOut out nocopy ame_util.idList,
itemClassesOut out nocopy ame_util.stringList,
itemIdsOut out nocopy ame_util.stringList,
itemSourcesOut out nocopy ame_util.longStringList,

productionIndexesOut out nocopy ame_util.idList,


variableNamesOut out nocopy ame_util.stringList,
variableValuesOut out nocopy ame_util.stringList,
transVariableNamesOut out nocopy
ame_util.stringList,
transVariableValuesOut out nocopy
ame_util.stringList);

Description

The getNextApprovers3 procedure has the same functionality as


getNextApprovers2, but it also returns per-transaction
productions. Use getNextApprovers3 when your application
enables per-approver and per-transaction productions, for
example to track eSignature requirements per approver and
transaction. See also ame_api2.getAllApprovers3 and
ame_api2.getNextApprovers2.

getNextApprovers4

Syntax
procedure getNextApprovers4(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
flagApproversAsNotifiedIn in varchar2 default
ame_util.booleanTrue,
approvalProcessCompleteYNOut out varchar2,
nextApproversOut out nocopy
ame_util.approversTable2);

Description

The getNextApprovers4 procedure has the same functionality as


getNextApprovers1, but it omits per-item outputs. This is the
lowest-overhead getNextApprovers[n] procedure. See also
ame_api2.getAllApprovers7 and ame_api2.getNextApprovers1.

getPendingApprovers

Syntax
procedure getPendingApprovers(
applicationIdIn in number,

Appendix A API Functional Specifications 64


transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalProcessCompleteYNOut out varchar2,
approversOut out nocopy ame_util.approversTable2);

Description

The getPendingApprovers procedure outputs in approversOut


the approvers with approver_category
ame_util.approvalApproverCategory and approval_status
ame_util.notifiedStatus. These are the approvers who must
approve before the input transaction’s approval process will
continue to the next stage. If approvalProcessCompleteYNOut is
ame_util.booleanTrue, the transaction’s approval process is
complete. If approvalProcessCompleteYNOut is
ame_util.booleanFalse and approversOut.count is zero, the
application should call one of the getNextApprovers[n]
procedures, and notify the approvers returned by that
procedure.

getTransactionProductions

Syntax
procedure getTransactionProductions(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
variableNamesOut out nocopy ame_util.stringList,
variableValuesOut out nocopy ame_util.stringList);

Description

The getTransactionProductions procedure outputs all per-


transaction productions for the input transaction. Use this API
when your application uses AME as a general-purpose
production-rule engine. See also ame_api2.getAllApprovers3.

initializeApprovalProcess

Syntax
procedure initializeApprovalProcess(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
recordApproverListIn in boolean default false);

Description

The initializeApprovalProcess procedure causes AME’s engine to


prepare a transaction’s approval process, if it has not already
done so. In particular, the engine sets the approval process’ start
date to sysdate. This API does not clear the state of the approval
process; use clearAllApprovals for that. When
recordApproverListIn is true, this API has the same effect as

Appendix A API Functional Specifications 65


getAndRecordAllApprovers. Calling initializeApprovalProcess
guarantees that subsequent calls to getAllApprovers1 will be
read only.

setFirstAuthorityApprover

Syntax
procedure setFirstAuthorityApprover(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2,
clearChainStatusYNIn in varchar2);

Description

The setFirstAuthorityApprover procedure sets the approver


represented by approverIn as the first chain-of-authority
approver in the chain of authority identified by the
action_type_id and group_or_chain_id fields of approverIn. This
procedure succeeds only if the approval_status field of
approverIn is null, and all the approvers in the target chain of
authority also have null approval statuses. If
clearChainStatusYNIn is ame_util.booleanTrue, AME clears the
target chain of authority’s approval status before making
approverIn the chain’s new first approver. Use this API to force
AME to generate a chain of authority that satisfies a given set of
rules, but that starts from an unusual first approver.

updateApprovalStatus

Syntax
procedure updateApprovalStatus(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2,
forwardeeIn in ame_util.approverRecord2 default
ame_util.emptyApproverRecord2,
updateItemIn in boolean default false);

Description

The updateApprovalStatus procedure updates the approval


status of the approver identified by approverIn to
approverIn.approval_status. If the approval-status value
indicates that the approver forwarded (with or without
approving), forwardeeIn identifies the forwardee. If the
approval_status value is ame_util.clearExceptionsStatus, the
procedure clears the transaction’s exception log in AME without
changing any approver’s status, regardless of the approver
identified by approverIn. When a chain-of-authority approver
forwards, the forwardee is also a chain–of–authority approver.
Otherwise, the forwardee has the api_insertion value

Appendix A API Functional Specifications 66


ame_util.apiInsertion, and the same authority value as the
forwarder. Use this API to update the state of a transaction’s
approval process when an approver responds to a notification
requesting approval.

updateApprovalStatus2

Syntax
procedure updateApprovalStatus2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalStatusIn in varchar2,
approverNameIn in varchar2,
itemClassIn in varchar2 default null,
itemIdIn in varchar2 default null,
actionTypeIdIn in number default null,
groupOrChainIdIn in number default null,
occurrenceIn in number default null,
forwardeeIn in ame_util.approverRecord2 default
ame_util.emptyApproverRecord2);

Description

The updateApprovalStatus2 procedure has the same


functionality as updateApprovalStatus, but it lets you identify
the target approver by their wf_roles.name value, and as many
other approver-distinguishing ame_util.approverRecord2 fields
as you care to specify. When you leave one or more of the fields
null, AME matches updates the status of the first occurrence of
the approver having an approval status that does not indicate
approval or forwarding. See also
ame_api2.updateApprovalStatus.

updateApprovalStatuses

Syntax
procedure updateApprovalStatuses(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2,
approvalStatusesIn in ame_util.stringList default
ame_util.emptyStringList,
itemClassesIn in ame_util.stringList default
ame_util.emptyStringList,
itemIdsIn in ame_util.stringList default
ame_util.emptyStringList,
forwardeesIn in ame_util.approversTable2 default
ame_util.emptyApproversTable2);

Description

The updateApprovalStatuses procedure is currently a stub, and


has no present functionality. Do not use it.

Appendix A API Functional Specifications 67


updateApprovalStatuses2

Syntax
procedure updateApprovalStatuses2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approvalStatusIn in varchar2,
approvalStatusIn in varchar2,
approverNameIn in varchar2,
itemClassIn in varchar2 default null,
itemIdIn in varchar2 default null,
actionTypeIdIn in number default null,
groupOrChainIdIn in number default null,
occurrenceIn in number default null,
approvalStatusesIn in ame_util.stringList default
ame_util.emptyStringList,
itemClassesIn in ame_util.stringList default
ame_util.emptyStringList,
itemIdsIn in ame_util.stringList default
ame_util.emptyStringList,
forwardeesIn in ame_util.approversTable2 default
ame_util.emptyApproversTable2);

Description

The updateApprovalStatuses2 procedure is currently a stub, and


has no present functionality. Do not use it.

ame_api3

getRuleDescription

Syntax
function getRuleDescription(
ruleIdIn in varchar2)
return varchar2;

Description

The getRuleDescription function returns the description of the


rule with ID ruleIdIn. Rule descriptions are at most 100 bytes
long.

clearSuppression

Syntax
procedure clearSuppression(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2);

Appendix A API Functional Specifications 68


Description

The clearSuppression procedure clears an approver suppression


previously submitted by a call to suppressApprover or
suppressApprovers, as long as approverIn is an AME generated
approver. Use this API to reactivate an AME-generated
approver who has been suppressed from the input transaction’s
approver list. See also ame_api3.suppressApprover and
ame_api3.suppressApprovers.

clearSuppressions

Syntax
procedure clearSuppressions(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2);

Description

The clearSuppressions procedure has the effect of


clearSuppression for all suppressed AME-generated approvers.
See also ame_api3.suppressApprover,
ame_api3.suppressApprovers, and ame_api3.clearSuppression.

clearInsertion

Syntax
procedure clearInsertion(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2);

Description

The clearInsertion procedure removes the input approver from


the input transaction’s approver list. Use this API to remove an
inserted approver from a transaction’s approver list.

clearInsertions

Syntax
procedure clearInsertions(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2);

Description

The clearInsertions procedure has the effect of clearInsertion for


all inserted approvers in the input transaction’s approver list.
Use this API to remove all previously inserted approvers from a

Appendix A API Functional Specifications 69


transaction’s approver list. See also ame_api3.clearInsertion.

getAllApprovalGroups

Syntax
procedure getAllApprovalGroups(
groupIdsOut out nocopy ame_util.idList,
groupNamesOut out nocopy ame_util.stringList);

Description

The getAllApprovalGroups procedure outputs all current AME


approval groupsin ascending order of their names.

getApplicableRules1

Syntax
procedure getApplicableRules1(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
ruleIdsOut out nocopy ame_util.idList);

Description

The getApplicableRules1 procedure outputs in ruleIdsOut the


IDs of the rules that apply to the input transaction. Use this API
when you only need the rule IDs. See also
ame_api3.getApplicableRules2 and getApplicableRules3.

getApplicableRules2

Syntax
procedure getApplicableRules2(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,

ruleDescriptionsOut out nocopy ame_util.stringList);

Description

The getApplicableRules2 procedure outputs in


ruleDescriptionsOut the descriptions of the rules that apply to
the input transaction. Use this API when you only need the rule
descriptions. See also ame_api3.getApplicableRules1 and
ame_api3.getApplicableRules3.

Appendix A API Functional Specifications 70


getApplicableRules3

Syntax

procedure getApplicableRules3(

applicationIdIn in number,

transactionTypeIn in varchar2,

transactionIdIn in varchar2,

ruleIdsOut out nocopy ame_util.idList,

ruleDescriptionsOut out nocopy ame_util.stringList);

Description

The getApplicableRules3 procedure outputs in ruleIdsOut and


ruleDescriptionsOut the IDs and descriptions of the rules that
apply to the input transaction. This procedure is useful to
construct a displayable list of descriptiosn of applicable rules,
where each rule description hyperlinks to a more detailed
description of the rule (generated by one of the
ame_api3.getRuleDetails[n] procedures). See also
ame_api3.getApplicableRules1, ame_api3.getApplicableRules1,
and the three ame_api3.getRuleDetails[n] procedures.

getApprovalGroupId

Syntax
procedure getApprovalGroupId(
groupNameIn ame_util.stringType,
groupIdOut out nocopy number);

Description

The getApprovalGroupId procedure outputs in groupIdOut the


ID of the approval group with the name groupNameIn.

getAttributeValue

Syntax
procedure getAttributeValue(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
attributeNameIn in varchar2,
itemIdIn in varchar2,
attributeValue1Out out varchar2,
attributeValue2Out out varchar2,
attributeValue3Out out varchar2);

Appendix A API Functional Specifications 71


Description

The getAttributeValue procedure outputs in attributeValue1Out,


attributeValue2Out, and attributeValue3Out the values of the
attribute with the name attributeNameIn for the item with ID
itemIdIn, for the input transaction. An attribute is always
associated with an item classes, and attribute names are unique
across item classes; so it is not necessary to input the item class.
If the attribute pertains to the header item class, itemIdIn should
have the same value as transactionIdIn. For all attribute types
other than currency attributes, attributeValue1Out contains the
attribute’s value, and attributeValue2Out and
attributeValue3Out are null. For currency attributes,
attributeValue1Out is the amount, attributeValue2Out is the
General Ledger currency code, and attributeValue3Out is the
General Ledger conversion type.

getConditionDetails

Syntax
procedure getConditionDetails(
conditionIdIn in number,
attributeNameOut out nocopy varchar2,
attributeTypeOut out nocopy varchar2,
attributeh4 DescriptionOut out nocopy varchar2,
lowerLimitOut out nocopy varchar2,
upperLimitOut out nocopy varchar2,
includeLowerLimitOut out nocopy varchar2,
includeUpperLimitOut out nocopy varchar2,
currencyCodeOut out nocopy varchar2,
allowedValuesOut out nocopy
ame_util.longestStringList);

Description

The getConditionsDetails procedure outputs various descriptive


details about the condition with ID conditionIdIn.

getGroupMembers1

Syntax
procedure getGroupMembers1(
applicationIdIn in number default null,
transactionTypeIn in varchar2 default null,
transactionIdIn in varchar2 default null,
groupIdIn in number,
memberDisplayNamesOut out nocopy
ame_util.longStringList);

Description

The getGroupMembers procedure outputs the display names of


the members of the AME approval group with ID groupIdIn. If
applicationIdIn, transactionIdIn, and transactionTypeIn default
null, the ID must be for a static approval group. If the group is

Appendix A API Functional Specifications 72


dynamic, these three inputs must identify the transaction for
which AME should calculate the group’s membership.

getGroupMembers2

Syntax
procedure getGroupMembers2(
applicationIdIn in number default null,
transactionTypeIn in varchar2 default null,
transactionIdIn in varchar2 default null,
groupIdIn in number,
memberNamesOut out nocopy ame_util.longStringList,
memberDisplayNamesOut out nocopy
ame_util.longStringList);

Description

The getGroupMembers2 procedure has the same functionality as


getGroupMembers, but it also outputs the group members’
wf_roles.name values. See also ame_api3.getGroupMembers1.

getGroupMembers3

Syntax
procedure getGroupMembers3(
applicationIdIn in number default null,
transactionTypeIn in varchar2 default null,
transactionIdIn in varchar2 default null,
groupIdIn in number,
memberNamesOut out nocopy ame_util.longStringList,
memberOrderNumbersOut out nocopy ame_util.idList,
memberDisplayNamesOut out nocopy
ame_util.longStringList);

Description

The getGroupMembers3 procedure has the same functionality as


getGroupMembers2, but it also outputs the members’ order
numbers. See also ame_api3.getGroupMembers2.

getGroupMembers4

Syntax
procedure getGroupMembers4(
applicationIdIn in number default null,
transactionTypeIn in varchar2 default null,
transactionIdIn in varchar2 default null,
groupIdIn in number,
memberNamesOut out nocopy ame_util.longStringList,
memberOrderNumbersOut out nocopy ame_util.idList,
memberDisplayNamesOut out nocopy
ame_util.longStringList,
memberOrigSystemIdsOut out nocopy ame_util.idList,
memberOrigSystemsOut out nocopy
ame_util.stringList);

Appendix A API Functional Specifications 73


Description

The getGroupMembers4 procedure has the same functionality as


getGroupMembers3, but it also outputs the members’
wf_roles.orig_system and wf_roles.orig_system_id values. See
also ame_api3.getGroupMembers3.

getItemClasses

Syntax
procedure getItemClasses(
applicationIdIn in number default null,
transactionTypeIn in varchar2 default null,
transactionIdIn in varchar2 default null,
itemClassIdsOut out nocopy ame_util.idList,
itemClassNamesOut out nocopy ame_util.stringList);

Description

The getItemClasses procedure outputs the IDs and names of the


item classes used by the input transaction.

getItemClassId

Syntax
procedure getItemClassId(
itemClassNameIn in varchar2,
itemClassIdOut out number);

Description

The getItemClassId procedure outputs in itemClassIdOut the


item-class ID of the item class with the name itemClassNameIn.

getItemClassName

Syntax
procedure getItemClassName(
itemClassIdIn in number,
itemClassNameOut out varchar2);

Description

The getItemClassName procedure outputs in


itemClassNameOut the name of the item class with the ID
itemClassIdIn.

getOldApprovers

Syntax
procedure getOldApprovers(
applicationIdIn in number,

Appendix A API Functional Specifications 74


transactionTypeIn in varchar2,
transactionIdIn in varchar2,
oldApproversOut out nocopy
ame_util.approversTable2);

Description

The getOldApprovers procedure outputs in oldApproversOut


the approver list that AME calculated most recently for the input
transaction. This approver list may not be the transaction’s
current list. That is, simultaneous calls to getAllApprovers1 and
getOldApprovers could return different approver lists (and the
list returned by getOldApprovers would then be outdated). This
API is a deprecated routine available only for the sake of
backwards compatibility.

getRuleDetails1

Syntax
procedure getRuleDetails1(
ruleIdIn in number,
ruleTypeOut out nocopy varchar2,
ruleDescriptionOut out nocopy varchar2,
conditionIdsOut out nocopy ame_util.idList,
actionTypeNamesOut out nocopy ame_util.stringList,
actionTypeDescriptionsOut out nocopy
ame_util.stringList,

actionDescriptionsOut out nocopy ame_util.stringList);

Description

The getRuleDetails1 procedure outputs various descriptive


details about the rule with ID ruleIdIn. Use getRuleDetails1 in
connection with one of the getApplicableRules procedures. See
also the getApplicableRules[n] procedures.

getRuleDetails2

Syntax
procedure getRuleDetails2(
ruleIdIn in number,
ruleTypeOut out nocopy varchar2,
ruleDescriptionOut out nocopy varchar2,
conditionDescriptionsOut out nocopy
ame_util.longestStringList,
actionTypeNamesOut out nocopy ame_util.stringList,
actionTypeDescriptionsOut out nocopy
ame_util.stringList,

actionDescriptionsOut out nocopy ame_util.stringList);

Description

The getRuleDetails2 procedure has the same functionality as

Appendix A API Functional Specifications 75


getRuleDetails1, but it outputs condition descriptions rather than
condition IDs. See also ame_api3.getRuleDetails1.

getRuleDetails3

Syntax
procedure getRuleDetails3(
ruleIdIn in number,
ruleTypeOut out nocopy varchar2,
ruleDescriptionOut out nocopy varchar2,
conditionIdsOut out nocopy ame_util.idList,
conditionDescriptionsOut out nocopy
ame_util.longestStringList,
conditionHasLOVsOut out nocopy ame_util.charList,
actionTypeNamesOut out nocopy ame_util.stringList,
actionTypeDescriptionsOut out nocopy
ame_util.stringList,

actionDescriptionsOut out nocopy ame_util.stringList);

Description

The getRuleDetails3 procedure has the same functionality as


getRuleDetails1, but it outputs condition ID and descriptions,
and indicates whether each condition has a list of allowed values.
See also ame_api3.getRuleDetails2.

insertApprover

Syntax
procedure insertApprover(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2,
positionIn in number,
insertionIn in ame_util.insertionRecord2);

Description

The insertApprover procedure inserts approverIn into the input


transaction’s approver list at the approver-list index positionIn
using the insertion parameter and order relation in insertionIn.
See also ame_api3.getAvailableInsertions.

parseApproverSource

Syntax
procedure parseApproverSource(
approverSourceIn in varchar2,
sourceTypeOut out varchar2,
ruleIdsOut out nocopy ame_util.idList);

Appendix A API Functional Specifications 76


Description

The parseApproverSource procedure parses the


ame_util.approverRecord2 source field in approverSourceIn into
a source designator in sourceTypeOut and a possibly empty rule-
ID list in ruleIdsOut. When the list is non-empty, it contains the
IDs of the rules requiring the approver having the input source
value. Use this API to determine (and optionally display) the
reason an approver occurs in a transaction’s approver list.

suppressApprover

Syntax
procedure suppressApprover(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord2);

Description

The suppressApprover procedure suppresses approverIn from


the input transaction’s approver list. The approver must match
an approver in the transaction’s approver list according to the
comparison rules explained earlier in this appendix. If
approverIn matches a rule-generated approver from the
transaction’s approver list and the mandatory boolean attribute
ALLOW_DELETING_RULE_GENERATED_APPROVERS has
the value ’true’, the target approver’s status is set to
ame_util.suppressedStatus. If approverIn matches an inserted
approver, the approver is deleted (undoing the insertion
entirely).

suppressApprovers

Syntax
procedure suppressApprovers(
applicationIdIn in number,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
approverIn in ame_util.approversTable2);

Description

The suppressApprovers procedure has the same effect as


suppressApprover, but for each approver in approversIn. See
also ame_api3.suppressApprover.

Appendix A API Functional Specifications 77


ame_api

validateApprover

Syntax
function validateApprover(
approverIn in ame_util.approverRecord)
return boolean;

Description

The validateApprover function returns true if the approver is


valid, otherwise false. AME’s APIs always return valid
approvers, so you don’t need to validate approvers returned by
AME. You should call validateApprover to validate an approver
you plan to insert into a transaction’s approver list. See also
ame_api2.validateApprover.

clearAllApprovals

Syntax
procedure clearAllApprovals(
applicationIdIn in integer,
transactionIdIn in varchar2,
transactionTypeIn in varchar2 default null);

Description

The clearAllApprovals procedure has the same functionality as


ame_api2.clearAllApprovers. See also
ame_api2.clearAllApprovers.

deleteApprover

Syntax
procedure deleteApprover(
applicationIdIn in integer,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord,
transactionTypeIn in varchar2 default null);

Description

The deleteApprover procedure suppresses the approver


represented by approverIn in the input transaction’s approver
list. See also ame_api3.suppressApprover.

deleteApprovers

Syntax
procedure deleteApprovers(
applicationIdIn in integer,

Appendix A API Functional Specifications 78


transactionIdIn in varchar2,
approversIn in ame_util.approversTable,
transactionTypeIn in varchar2 default null);

Description

The deleteApprovers procedure suppresses the approvers


represented by approversIn in the input transaction’s approver
list. See also ame_api3.suppressApprovers.

getAdminApprover

Syntax
procedure getAdminApprover(
applicationIdIn in integer default null,
transactionTypeIn in varchar2 default null,
adminApproverOut out ame_util.approverRecord);

Description

The getAdminApprover procedure outputs an


ame_util.approverRecord identifying the administrative
administrator for the input transaction type. See also
ame_api3.getAdminApprover.

getAllApprovers

Syntax
procedure getAllApprovers(
applicationIdIn in integer,
transactionIdIn in varchar2,
transactionTypeIn in varchar2 default null,
approversOut out ame_util.approversTable);

Description

The getAllApprovers procedure outputs the input transaction’s


current approver list, including rule–generated, inserted,
suppressed, and repeated approvers. The rows in approversOut
are indexed by consecutive ascending integers starting at one.
The approval_status values in approversOut reflect each
approver’s most recent response to any request for approval they
have received, assuming the originating application has passed
such responses to AME via updateApprovalStatus or
updateApprovalStatus2. In AME 11.5.9, the AME engine
excluded from the approver list any approvers deleted by calls to
ame_api.deleteApprover(s), or suppressed to account for the
value of the repeatedApprovers configuration variable. In AME
11.5.10, this behavior has changed. The approver list in
approversOut now includes deleted and repeated approvers, but
assigns them one of the approval_status values
ame_util.suppressedStatus and ame_util.repeatedStatus. Your
code should treat these statuses as logically equivalent to
ame_util.approvedStatus. The ame_api.getNextApprover will

Appendix A API Functional Specifications 79


skip approvers with either status when it iterates through the
approver list to find the first approver that has not yet approved.
See also the ame_api2.getAllApprovers[n] procedures.

getAvailableInsertions

Syntax
procedure getAvailableInsertions(
applicationIdIn in integer,
transactionIdIn in varchar2,
positionIn in integer,
transactionTypeIn in varchar2 default null,
availableInsertionsOut out nocopy
ame_util.insertionsTable);

Description

The getAvailableInsertions procedure outputs a list of


ame_util.insertionRecord records representing the approver
insertions possible at the index positionIn in the transaction’s
current approver list. See also ame_api3.getAvailableInsertions.

getAvailableOrders

Syntax
procedure getAvailableOrders(
applicationIdIn in integer,
transactionIdIn in varchar2,
positionIn in integer,
transactionTypeIn in varchar2 default null,
availableOrdersOut out ame_util.ordersTable);

Description

The getAvailableOrders procedure outputs a list of


ame_util.orderType records. Each orderType record indicates a
possible order type for an approver insertion at the index
positionIn in the transaction’s current approver list. This
procedure is deprecated. Use getAvailableInsertions instead.
See also ame_api3.getAvailableInsertions.

getNextApprover

Syntax
procedure getNextApprover(
applicationIdIn in integer,
transactionIdIn in varchar2,
transactionTypeIn in varchar2 default null,

nextApproverOut out ame_util.approverRecord);

Description

The getNextApprover procedure outputs the next approver that

Appendix A API Functional Specifications 80


should approve the input transaction. Unlike the
ame_api2.getNextApprovers[n] procedures,
ame_api.getNextApprover outputs the same approver each time
the procedure is called for a given transaction, until the approver
approves the input transaction.

getGroupMembers

Syntax
procedure getGroupMembers(
applicationIdIn in integer,
transactionTypeIn in varchar2,
transactionIdIn in varchar2,
groupIdIn in number,
memberOrderNumbersOut out nocopy ame_util.idList,
memberPersonIdsOut out nocopy ame_util.idList,
memberUserIdsOut out nocopy ame_util.idList);

Description

The getGroupMembers procedure outputs the members of the


approval group with ID groupIdIn. See also
ame_api3.getGroupMembers.

getOldApprovers

Syntax
procedure getOldApprovers(
applicationIdIn in integer,
transactionIdIn in varchar2,
transactionTypeIn in varchar2 default null,
oldApproversOut out ame_util.approversTable);

Description

The getOldApprovers procedure outputs the approver list that


AME calculated the last time it generated the input transaction’s
approver list. See also ame_api3.getOldApprovers.

insertApprover

Syntax
procedure insertApprover(
applicationIdIn in integer,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord,
positionIn in integer,
orderIn in ame_util.orderRecord,
transactionTypeIn in varchar2 default null);

Description

The insertApprover procedure inserts approverIn into the input


transaction’s approver list at the index positionIn using the

Appendix A API Functional Specifications 81


insertion parameter and order relation in insertionIn. See also
ame_api3.insertApprover.

setFirstAuthorityApprover

Syntax
procedure setFirstAuthorityApprover(
applicationIdIn in Integer,
transactionIdIn in varchar2
approverIn in ame_util.approverRecord,
transactionTypeIn in varchar2 default null);

Description

The setFirstAuthorityApprover procedure sets the first approver


for each chain of authority in the input transaction’s approver
list. Thus if the approver list includes several chains of authority,
they will all start with approverIn. See also
ame_api2.setFirstAuthorityApprover.

updateApprovalStatus

Syntax
procedure updateApprovalStatus(
applicationIdIn in integer,
transactionIdIn in varchar2,
approverIn in ame_util.approverRecord,
transactionTypeIn in varchar2 default null,
forwardeeIn in ame_util.approverRecord default
ame_util.emptyApproverRecord);

Description

The updateApprovalStatus procedure updates the status of the


approver approverIn in the input transaction’s approver list. A
given person ID or user ID can appear several times in a
transaction’s approver list, so AME uses all of the approver-
comparison fields that occur in ame_util.approverRecord to
match approverIn to an ame_util.approverRecord in the input
transaction’s approver list. See also
ame_api2.updateApprovalStatus and
ame_api.updateApprovalStatus2.

updateApprovalStatus2

Syntax
procedure updateApprovalStatus2(
applicationIdIn in integer,
transactionIdIn in varchar2,
approvalStatusIn in varchar2,
approverPersonIdIn in integer default null,
approverUserIdIn in integer default null,
transactionTypeIn in varchar2 default null,
forwardeeIn in ame_util.approverRecord default

Appendix A API Functional Specifications 82


ame_util.emptyApproverRecord);

Description

The updateApprovalStatus2 procedure has the same


functionality as updateApprovalStatus, except that it updates the
first ame_util.approverRecord in the input transaction’s
approver list that matches whichever of approverPersonIdIn and
approverUserIdIn is non-null, if the record’s status is not already
an approving or forwarding response. See also
ame_api2.updateApprovalStatus2 and
ame_api.updateApprovalStatus.

What New APIs Map to the 11.5.9 APIs?

Most of the ame_api routines are essentially wrappers for


ame_api2 or ame_api3 routines, with modifications to preserve
pre-existing ame_api functionality. The following table tells you
which ame_api routine serves as a wrapper for a given ame_api2
or ame_api3 routine.

ame_api Routine Equivalent ame_api2 or ame_api3


Routine

getRuleDescription ame_api3.getRuleDescription

validateApprover ame_api2.validateApprover

clearAllApprovals ame_api2.clearAllApprovals

clearDeletion ame_api3.clearSuppression

clearDeletions ame_api3.clearSuppressions

clearInsertion ame_api3.clearInsertion

clearInsertions ame_api3.clearInsertions

deleteApprover ame_api3.suppressApprover

deleteApprovers ame_api3.suppressApprovers

getAdminApprover ame_api2.getAdminApprover

getAllApprovers ame_api2.getAllApprovers7

getAndRecordAllApprovers ame_api2.getAndRecordAllApprovers

Appendix A API Functional Specifications 83


ame_api Routine Equivalent ame_api2 or ame_api3
Routine

getApplicableRules1 ame_api3.getApplicableRules1

getApplicableRules2 ame_api3.getApplicableRules2

getApplicableRules3 ame_api3.getApplicableRules3

getApproversAndRules1 ame_api2.getAllApprovers4

getApproversAndRules2 ame_api2.getAllApprovers5

getApproversAndRules3 ame_api2.getAllApprovers6

getAvailableInsertions ame_api3.getAvailableInsertions

getAvailableOrders Not available anymore

getConditionDetails ame_api3.getConditionDetails

getGroupMembers ame_api3.getGroupMembers4

getNextApprover ame_api2.getNextApprovers4

getOldApprovers ame_api3.getOldApprovers

getRuleDetails1 ame_api3.getRuleDetails1

getRuleDetails2 ame_api3.getRuleDetails2

getRuleDetails3 ame_api3.getRuleDetails3

initializeApprovalProcess ame_api2.initializeApprovalProcess

insertApprover ame_api3.insertApprover

setFirstAuthorityApprover ame_api2.setFirstAuthorityApprover

updateApprovalStatus ame_api2.updateApprovalStatus

updateApprovalStatus2 ame_api2.updateApprovalStatus2

Appendix A API Functional Specifications 84


Appendix B
ame_util Package

Appendix B ame_util Package 85


Overview
Many of the constants, data types, and routines in ame_util can
be useful to originating applications. In fact, it’s important that
you use appropriate ame_util features in your code, so that
changes to AME functionality do not break your code. This
appendix documents the ame_util features that your code should
incorporate where appropriate.

Data Types

All of the AME data types your code requires are declared in
ame_util’s package specification (in the package-header file
ameoutil.pkh). This section describes the data types you may
find useful.

approverRecord2

The ame_api2 and ame_api3 packages use the approverRecord2


record to represent an approver. This type has the declaration

type approverRecord2 is record(

name varchar2(320),

orig_system varchar2(30),

orig_system_id number,

display_name varchar2(360),

approver_category varchar2(1),

api_insertion varchar2(1),

authority varchar2(1),

approval_status varchar2(50),

action_type_id integer,

group_or_chain_id integer,

occurrence integer,

source varchar2(500),

item_class ame_item_classes.name%type,

item_id ame_temp_old_approver_lists.item_id%type,

item_class_order_number integer,

Appendix B ame_util Package 86


item_order_number integer,

sub_list_order_number integer,

action_type_order_number integer,

group_or_chain_order_number integer,

member_order_number integer,

approver_order_number integer);

Here are explanations of the allowed values and semantics of the


record’s fields.

name

This is the approver’s wf_roles.name value, which essentially


identifies the approver uniquely in wf_roles.

orig_system

This is the approver's wf_roles.orig_system value, which


represents the system in which the approver originates. For
example, the orig_system ‘PER’ is for approvers originating in
the HRMS per_all_approvers_f table (that is, HR employees).

orig_system_id

This is the approver's wf_roles.orig_system_id value. The


combination of the approver's orig_system and orig_system_id
values also essentially identifies the approver uniquely in
wf_roles.

display_name

This is the approver's wf_roles.display_name value.

approver_category

This field may contain either of two constants.

• ame_util.approvalApproverCategory indicates that this


occurrence of the approver must approve one or more items
of the transaction in whose approver list the record occurs.

• ame_util.fyiApproverCategory indicates that this


occurrence of the approver should just receive an
informational notification describing the transaction in
whose approver list the record occurs, and does not need to
approve any of the transaction’s items.

Appendix B ame_util Package 87


api_insertion

This field may contain any of three constants:

• ame_util.apiAuthorityInsertion indicates that the approver


was inserted into a chain of authority as a chain-of-authority
approver, so that the chain should continue with the
superior of the inserted approver. The inserted approver
must be from an originating system consistent with the
action type that generated the chain of authority. This
situation often arises when one chain-of-authority approver
forwards a request for approval to the inserted approver.

• ame_util.apiInsertion indicates that the approver was


inserted into a transaction’s approver list as an ad hoc
approver—that is, an approver who is not part of a chain of
authority (even if the approver occurs between two chain-of-
authority approvers who belong to the same approver list).

• ame_util.oamGenerated indicates that the rules applying to


the transaction in whose approver list the approver occurs,
required the approver’s presence in the transaction’s
approver list. In this case the approver’s source field
contains a value that includes the requiring rules’ IDs. (See
ame_api3.parseApproverSource in Appendix A.)

authority

This field may contain any of three constants:

• ame_util.preApprover identifies a pre–approver.

• ame_util.authorityApprover identifies an authority


approver.

• ame_util.postApprover identifies a post–approver.

approval_status

This field may contain any of twelve constants. Some of these


represent possible approver responses to notifications requesting
approval, and so are allowed values in the approval-status input
arguments of the ame_api2.updateApprovalStatus and
ame_api2.updateApprovalStatus2 procedures. Others must be
generated by AME. The items within the relevant transaction to
which the approver’s approval_status value applies are
identified by certain output arguments of the
ame_api[n].getAllApprovers[n] and getNextApprovers[n]
procedures.

• ame_util.approvedStatus means the approver approved


one or more of the relevant transaction’s items, without
forwarding the notification requesting approval. You
can pass this status to ame_api2.updateApprovalStatus
and ame_api2.updateApprovalStatus2.

Appendix B ame_util Package 88


• ame_util.approveAndForwardStatus means the
approver approved one or more of the relevant
transaction’s items, and also forwarded the notification
requesting approval. You can pass this status to
ame_api2.updateApprovalStatus and
ame_api2.updateApprovalStatus2.

• ame_util.beatByFirstResponderStatus means the


approver either has not responded, or responded after
the first responder in the approval group or chain of
authority containing the approver. (In the latter case,
AME logs the approver's response and otherwise ignores
it.) AME generates this status when the first-responder-
wins voting regime is in force for the group or chain
containing the approver. You cannot pass this status to
ame_api2.updateApprovalStatus or
ame_api2.updateApprovalStatus2.

• ame_util.clearExceptionsStatus should be passed to


ame_api[n].updateApprovalStatus or
ame_api[n].updateApprovalStatus2 to clear a
transaction’s exception log when the transaction’s
workflow is restarted. This is necessary when the
approver's status is ame_util.exceptionStatus.

• ame_util.exceptionStatus is sometimes returned by the


API routines when AME raises an unhandled exception
in the process of calculating a transaction’s approver list.
(You cannot pass this status to
ame_api2.updateApprovalStatus or
ame_api2.updateApprovalStatus2.) In this case, the
originating application may wish to stop the
transaction’s workflow.

• ame_util.forwardStatus means the approver forwarded


the notification requesting approval, without approving
the items identified in the notification. You can pass this
status to ame_api2.updateApprovalStatus and
ame_api2.updateApprovalStatus2.

• ame_util.noResponseStatus means the originating


application sent the approver a notification requesting
approval, but the approver did not respond to the
notification in a timely fashion. (The originating
application decides what "timely" means.) You can pass
this status to ame_api2.updateApprovalStatus and
ame_api2.updateApprovalStatus2. AME responds to it
by inserting the approver’s surrogate into the approver
list, immediately after the approver.

• ame_util.notifiedStatus means the originating


application has told AME that it has sent the approver a
notification, and—if the notification requested
approval—the approver has not yet responded to it.

• ame_util.nullStatus (or better yet, a null approval_status

Appendix B ame_util Package 89


value) means the approver has not yet been notified, or
that their previous approval_status value was cleared.

• ame_util.rejectStatus means the approver rejected one


or more of the items in the approver list of the relevant
transaction. You can pass this status to
ame_api2.updateApprovalStatus and
ame_api2.updateApprovalStatus2.

• ame_util.repeatedStatus means this occurrence of the


approver has been aggregated with one or more other
occurrences of the same approver, in the relevant
transaction's approver list. (See the documentation of
the repeatedApprovers configuration variable in Chapter
11 of the Oracle Approvals Management Implementation
Guide for details.) The ame_api2.getNextApprovers[n]
routines treat this status as equivalent to
ame_util.approvedStatus, and so never output approvers
with this status.

• ame_util.suppressedStatus means this occurrence of the


approver has been suppressed, typically by a call to one
of the ame_api3.suppressApprover(s) routines. The
ame_api2.getNextApprovers[n] routines treat this status
as equivalent to ame_util.approvedStatus, and so never
output approvers with this status.

action_type_id

For AME-generated approvers, this field contains the ID that


AME assigns to the action type that generated the approver. For
example, if a rule using the absolute-job-level action type
requires an approver, and that action type has the action-type ID
456, the approver's action_type_id value would be 456. For
inserted chain-of-authority approvers, this field contains the
same value that AME assigns to the AME-generated approvers
in the same chain. For inserted ad-hoc approvers, this field
contains the constant ame_util.nullInsertionActionTypeId.

group_or_chain_id

This field's semantics depend on whether the approver belongs


to an approval group or a chain of authority. In the former case,
the field contains the ID that AME assigns to the approval group.
In the latter case, the action type generating the chain of
authority assigns its chains ascending positive integer
group_or_chain_id values, starting at one. For example, the dual-
chains-of-authority approval type generates two chains of
authority. Approvers in the first chain have a group_or_chain_id
value of one, and approvers in the second chain have a
group_or_chain_id value of two. For inserted chain-of-authority
approvers, this field contains the same value that AME assigns to
rule-generated approvers in the same chain. For ad hoc inserted
approvers, this field contains the constant
ame_util.nullInsertionGroupOrChainId.

Appendix B ame_util Package 90


occurrence

The occurrence field indicates how many times the approver's


wf_roles.name value has occurred in the approver's approval
group or chain of authority, including the approver proper. For
example, if an approver occurs twice in a given chain of
authority, the first occurrence has the occurrence value one, and
the second the value two.

source

This field's semantics may vary over time. You should never
parse or interpret this field yourself. Instead, use
ame_api3.parseApproverSource to do so. AME development
will not support any code you write to parse the source field.

item_class

This field contains the name of the item class of the item ID
identified by the approver's item_id field.

item_id

When an approver must approve or be notified about a single


item, this field contains the ID of the item. When the approver
must approver or be notified about several items, this field is
null, and the list of items appears in certain API routines’ output
arguments instead. See the ame_api2.getNextApprovers1
documentation in Appendix A for details.

item_class_order_number

AME uses this field internally to calculate the approver's


approver_order_number value.

item_order_number

AME uses this field internally to calculate the approver's


approver_order_number value.

sub_list_order_number

AME uses this field internally to calculate the approver's


approver_order_number value.

action_type_order_number

AME uses this field internally to calculate the approver's


approver_order_number value.

group_or_chain_order_number

AME uses this field internally to calculate the approver's

Appendix B ame_util Package 91


approver_order_number value.

member_order_number

AME uses this field internally to calculate the approver's


approver_order_number value.

approver_order_number

AME uses the six other order-number fields to calculate the


approver_order_number value by treating them as a six-tuple
and sorting them in lexicographic order. AME uses the
approver_order_number to determine which approvers to return
in successive calls to the ame_api2.getNextApprovers[n]
routines. See Chapter 11 of the implementation guide for details.

approversTable2

AME’s API represents approver lists as arguments of type


approversTable2, which is a PL/SQL table of approverRecord2
records. Objects of this type should always be indexed by
consecutive ascending integers starting at one.

insertionRecord2

The ame_api3.getAvailableInsertions procedure uses the


insertionRecord2 record to represent a possible approver
insertion. This type has the declaration,

type insertionRecord2 is record(

item_class ame_item_classes.name%type,

item_id ame_temp_old_approver_lists.item_id%type,

action_type_id integer,

group_or_chain_id integer,

order_type varchar2(50),

parameter ame_temp_insertions.parameter%type,

api_insertion varchar2(1),

authority varchar2(1),

description varchar2(200));

Fields that also Occur in approverRecord2

The item_class, item_id, action_type_id, group_or_chain_id,


api_insertion, and authority fields have the same semantics here
as they do for the approverRecord2 type. Here are explanations

Appendix B ame_util Package 92


of the other fields.

The order_type, parameter, and description Fields

The order_type field indicates the order relation that AME uses
to determine the insertion’s index in an approver list. AME
recalculates the location each time it generates the approver list.
Here are brief explanations of each possible value for the
order_type field, with accompanying syntax and semantics rules
for the parameter and description fields.

Absolute Order

The value ame_util.absoluteOrder means the insertionRecord’s


parameter field should be interpreted as an absolute order
number. In this case the parameter should be the string
representation of a positive integer between one and one more
than the number of approvers already in the approver list. The
description should have the syntax

ame_util.absoluteOrderDescription || n || '. '

where n is the index at which the insertion should take place.


For example, if the insertee should always be third in the
transaction's approver list, the parameter should be ’3’.

After an Approver

The value ame_util.afterApprover means the insertee should


immediately follow the approver that the insertion parameter
identifies. In this case the parameter should have the syntax
approver.name ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id ||
ame_util.fieldDelimiter ||
approver.action_type_id ||
ame_util.fieldDelimiter ||
approver.group_or_chain_id ||
ame_util.fieldDelimiter ||
approver.occurrence

and the description should have the form

ame_util.afterApproverDescription || approver.display_name

Before an Approver

The value ame_util.beforeApprover means the insertee should


immediately precede the approver that the insertion parameter
identifies. In this case the parameter should have the syntax
approver.name ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||

Appendix B ame_util Package 93


approver.item_id ||
ame_util.fieldDelimiter ||
approver.action_type_id ||
ame_util.fieldDelimiter ||
approver.group_or_chain_id ||
ame_util.fieldDelimiter ||
approver.occurrence
and the description should have the form
ame_util.afterApproverDescription ||
approver.display_name

First Authority

The value ame_util.firstAuthority means the insertee should be


the first chain–of–authority approver in the chain of authority
identified by the parameter. In this case the parameter should
have the syntax
ame_util.firstAuthorityParameter ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id ||
ame_util.fieldDelimiter ||
approver.action_type_id ||
ame_util.fieldDelimiter ||
approver.group_or_chain_id
and the description should have the form
ame_util.firstAuthorityDescription

First Post-Approver

The value ame_util.firstPostApprover means the insertee should


be the first post–approver in the approver list for the item
identified by the parameter. In this case the parameter should
have the syntax
ame_util.firstPostParameter ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id
and the description should have the form
ame_util.firstPostApproverDescription

First Pre-Approver

The value ame_util.firstPreApprover means the insertee should


be the first pre–approver in the approver list for the item
identified by the parameter. In this case the parameter should
have the syntax
ame_util.firstPreParameter ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id
and the description should have the form
ame_util.firstPreApproverDescription

Appendix B ame_util Package 94


Last Post-Approver

The value ame_util.lastPostApprover means the insertee should


be the last post–approver in the approver list for the item
identified by the parameter. In this case the parameter should
have the syntax
ame_util.lastPostParameter ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id
and the description should the form
ame_util.lastPostApproverDescription

Last Pre-Approver

The value ame_util.lastPreApprover means the insertee should


be the last pre–approver in the approver list for the item
identified by the parameter. In this case the parameter should
have the syntax
ame_util.lastPreParameter ||
ame_util.fieldDelimiter ||
approver.item_class ||
ame_util.fieldDelimiter ||
approver.item_id
and the description should have the form

ame_util.lastPreApproverDescription

insertionsTable2

The insertionsTable2 type is a PL/SQL table of


ame_util.insertionRecord2 records. The getAvailableInsertions
procedure uses an argument of this type to represent the set of
possible approver insertions at a given index in an approver list.
Objects of this type should always be indexed by consecutive
ascending integers starting at one.

approverRecord

In AME versions prior to 11.5.10 the approverRecord type


represented an approver in an approver list. This data type is
available for backward compatibility. It has the declaration

type approverRecord is record(

user_id fnd_user.user_id%type,

person_id per_all_people_f.person_id%type,

first_name per_all_people_f.first_name%type,

last_name per_all_people_f.last_name%type,

api_insertion varchar2(1),

Appendix B ame_util Package 95


authority varchar2(1),

approval_status varchar2(50),

approval_type_id integer,

group_or_chain_id integer,

occurrence integer,

source varchar2(500));

Below are explanations of the allowed values and semantics for


each field that does not occur in the ame_util.approverRecord2
type. (The rules for the other fields are the same here as there.)

user_id

The user_id field is null if and only if the person_id field is not
null. If the user_id field is not null, it must contain a valid
fnd_user.user_id value.

person_id

The person_id field is null if and only if the user_id field is not
null. If the person_id field is not null, it must contain a valid
per_all_people_f.person_id value.

first_name

If the person_id field is null, the first_name field contains the


approver's fnd_user.user_name value. Otherwise the first_name
field contains the approver's per_all_people_f.first_name value.

last_name

If the person_id field is null, the last_name field is also null.


Otherwise the last_name field contains the approver's
per_all_people_f.last_name value.

approval_type_id

The approval_type_id field has the same semantics as the


action_type_id field in an approverRecord2. See
“approverRecord2” above.

approversTable

This data type is a PL/SQL table of approverRecord records.


The ame_api package represents approver lists as
approversTable objects. Objects of this type should always be
indexed by consecutive ascending integers starting at one. (This
type is available for backward compatibility.)

Appendix B ame_util Package 96


insertionRecord

In AME versions prior to 11.5.10 the ame_util.insertionRecord


record represented a possible approver insertion. This type is
available for backward compatibility. It has the declaration,

type insertionRecord is record(

order_type varchar2(50),

parameter ame_temp_insertions.parameter%type,

api_insertion varchar2(1),

authority varchar2(1),

description ame_temp_insertions.description%type);

The api_insertion and authority fields have the same


interpretation here as for the approverRecord type. See the
description above of the insertionOrder2 type for explanations of
the available order types. Below are explanations of the syntax
and semantics rules for each order type’s parameter and
description values.

Absolute Order

The absolute-order order relation has the same order_type,


parameter, and description values here as for the
insertionRecord2 type.

After an Approver

The after-approver order type requires parameters with the


syntax
{person_id,user_id}:n

The string preceding the colon indicates the semantics of n,


where n is the person or user ID of the approver that the insertee
should follow. For example, ’person_id:123’ indicates that the
insertee should follow the approver with the person ID 123. The
description should have the form

ame_util.afterApproverDescription || first_name || ‘ ‘ ||
last_name

where first_name and last_name are the values that you would
assign to the first_name and last_name fields of an
approverRecord representing the inserted approver.

Before an Approver

The before-approver order type requires parameters of the same


form as those for the after-approver order type. The description

Appendix B ame_util Package 97


should have the form

ame_util.beforeApproverDescription || first_name || ‘ ‘ ||
last_name

where first_name and last_name are the values that you would
assign to the first_name and last_name fields of an
approverRecord representing the inserted approver. See “After
an Approver” above.

First Authority

The first-authority order type does not use the parameter field.
The description should be

ame_util.firstAuthorityDescription

First Post-Approver

The first post-approver order relation does not use the parameter
field. The description should be

ame_util.firstPostApproverDescription

First Pre-Approver

The first pre-approver order relation does not use the parameter
field. The description should be

ame_util.firstPreApproverDescription

Last Post-Approver

The last post-approver order relation does not use the parameter
field. The description should be

ame_util.lastPostApproverDescription

Last Pre-Approver

The last pre-approver order relation does not use the parameter
field. The description should be

ame_util.lastPreApproverDescription

insertionTable

The insertionsTable type is a PL/SQL table of insertionRecord


records. The ame_api.getAvailableInsertions procedure uses an
argument of this type to represent the set of possible approver
insertions at a given index in an approver list. Objects of this
type should always be indexed by consecutive ascending
integers starting at one. (This type is available for backward
compatibility.)

Appendix B ame_util Package 98


Constants

The following table lists and describes frequently used ame_util


constants, sorted first by purpose and then by alphabetical order.

Purpose Name Description

approval status approveAndForwardStatus The approver approved and


forwarded.

approvedStatus The approver approved without


forwarding.

beatByFirstResponderStatus The approver’s approval group or


chain of authority had the first-
responder-wins voting regime, and
the approver was not the first
responder.

clearExceptionsStatus When passed to


ame_api[n].updateApprovalStatus[
n], tells AME to clear an exception
raised by the transaction’s approval
process.

exceptionStatus The transaction’s approval process


raised an exception.

forwardStatus The approver forwarded.

noResponseStatus The approver did not respond in


the time allowed by the originating
application.

notifiedStatus The approver has been notified,


and—if the approver must
approve—has not yet responded.

nullStatus The approver has not yet been


notified.

rejectStatus The approver rejected.

repeatedStatus AME aggregated the approver with


another occurrence of the same
approver in the transaction's
approver list.

Appendix B ame_util Package 99


Purpose Name Description

suppressedStatus The originating application


suppressed the approver from the
transaction’s approver list.

approver approvalApproverCategory The approver’s response is


category required.

fyiApproverCategory The approver’s response is not


required.

API insertion apiAuthorityInsertion The approver is an inserted chain-


of-authority approver.

apiInsertion The approver is an ad hoc


approver.

oamGenerated The approver is generated by


approval rules.

attribute names allowAutoApprovalAttribute ALLOW_REQUESTOR_APPROVA


L.

allowEmptyGroupAttribute ALLOW_EMPTY_APPROVAL_GR
OUPS

effectiveRuleDateAttribute EFFECTIVE_RULE_DATE

firstStartingPointAttribute FIRST_STARTING_POINT_PERSO
N_ID

jobLevelStartingPointAttribute JOB_LEVEL_NON_DEFAULT_STA
RTING_POINT_PERSON_ID

includeAllApproversAttribute INCLUDE_ALL_JOB_LEVEL_APP
ROVERS

lineItemStartingPointAttribute LINE_ITEM_STARTING_POINT_P
ERSON_ID

nonDefStartingPointPosAttr NON_DEFAULT_STARTING_POI
NT_POSITION_ID

nonDefPosStructureAttr NON_DEFAULT_POSITION_STR
UCTURE_ID

Appendix B ame_util Package 100


Purpose Name Description

secondStartingPointAttribute SECOND_STARTING_POINT_PER
SON_ID

simplePosStartPointAttribute SIMPLE_POS_NON_DEFAULT_ST
ARTING_POINT_PERSON_ID

supStartingPointAttribute SUPERVISORY_NON_DEFAULT_
STARTING_POINT_PERSON_ID

topPositionIdAttribute TOP_POSITION_ID

topSupPersonIdAttribute TOP_SUPERVISOR_PERSON_ID

transactionDateAttribute TRANSACTION_DATE

transactionRequestorAttribute TRANSACTION_REQUESTOR_PE
RSON_ID

transactionReqUserAttribute TRANSACTION_REQUESTOR_US
ER_ID

transactionOrgAttribute TRANSACTION_ORG_ID

transactionGroupAttribute TRANSACTION_GROUP_ID

transactionReqPositionAttr TRANSACTION_REQUESTOR_PO
SITION_ID

transactionSetOfBooksAttribute TRANSACTION_SET_OF_BOOKS_
ID

authority authorityApprover The approver is a member of a


chain of authority.

postApprover The approver is a member of a post-


approval approval group.

preApprover The approver is a member of a pre-


approval approval group.

insertion order absoluteOrder The approver should be inserted at


the approver-list index identified by
the insertion parameter.

Appendix B ame_util Package 101


Purpose Name Description

afterApprover The approver should be inserted


right after the approver specified by
the insertion parameter.

beforeApprover The approver should be inserted


right before the approver specified
by the insertion parameter.

firstAuthority The approver should be the first


approver in the target chain of
authority.

firstPreApprover The approver should be the first


pre-approver for the item_class and
item_id specified by insertion
parameter.

firstPostApprover The approver should be the first


post-approver for the item_class
and item_id specified by insertion
parameter.

lastPreApprover The approver should be the last


pre-approver for the item_class and
item_id specified by insertion
parameter.

lastPostApprover The approver should be the last


post-approver for the item_class
and item_id specified by insertion
parameter.

item-class names costCenterItemClassName the cost-center item class

headerItemClassName the header item class

lineItemItemClassName the line-item item class

originating fndRespOrigSystem the FND_RESP originating system


system names

fndUserOrigSystem the FND_USR originating system

perOrigSystem the PER originating system

Appendix B ame_util Package 102


Purpose Name Description

posOrigSystem the POS originating system

pseudo-boolean booleanAttributeFalse the false value for boolean


constants attributes

booleanAttributeTrue the true value for boolean attributes

booleanFalse a varchar2(1) pseudo-boolean


constant for false

booleanTrue a varchar2(1) pseudo-boolean


constant for true

no the false value for boolean


configuration variables

yes the true value for boolean


configuration variables

REJECTION_RES continueAllOtherItems Only the rejected item’s approval


PONSE possible process stops.
values

continueOtherSubItems The header and rejected


subordinate items’ approval
processes stop. Other items’
approval processes continue.

StopAllItems All items’ approval processes stop.

Routines

Here are some frequently used ame_util routines.

getAdminName

Syntax
function getAdminName(
applicationIdIn in integer default null)
return varchar2;

Description

This function returns the default value of the the adminApprover

Appendix B ame_util Package 103


configuration variable. You should only call this function in
action-type handlers.

fieldDelimiter

Syntax
function fieldDelimiter
return varchar2;

Description

This function returns the field delimiter used by AME. You


should only call this function in action-type handlers.

recordDelimiter

Syntax
function recordDelimiter
return varchar2;

Description

This function returns the record delimiter used by AME. You


should only call this function in action-type handlers.

appendRuleIdToSource

Syntax
procedure appendRuleIdToSource(
ruleIdIn in integer,
sourceInOut in out nocopy varchar2);

Description

This procedure appends the input rule ID to the input source


value, and outputs the source value in place. Use this function in
an action-type handler to build an approverRecord2’s source
value.

copyApproverRecord2

Syntax
procedure copyApproverRecord2(
approverRecord2In in approverRecord2,
approverRecord2Out out nocopy approverRecord2);

Description

This procedure copies the input approverRecord2 to the output


approverRecord2.

Appendix B ame_util Package 104


copyApproversTable2

Syntax
procedure copyApproversTable2(
approversTable2In in approversTable2,
approversTable2Out out nocopy approversTable2);

Description

This procedure copies the input approversTable2 to the output


approversTable2.

runtimeException

Syntax
procedure runtimeException(
packageNameIn in varchar2,
routineNameIn in varchar2,
exceptionNumberIn in integer,
exceptionStringIn in varchar2);

Description

All code that extends AME functionality should call


runtimeException. This routine logs runtime exceptions in the
AME exception log, and in the Workflow exception stack as
appropriate.

Appendix B ame_util Package 105


Appendix C
The Action-Type-
Handler
Programming
Interface

Appendix C The Action-Type-Handler Programming Interface 107


Overview
The ame_util and ame_engine PL/SQL packages define a
programming interface for action-type handlers. The ame_util
package defines a set of datatypes and utility routines. The
ame_engine package provides a collection of routines that it uses
to exchange data with action-type handlers. See Appendix B of
this guide for details about ame_util. This appendix documents
the relevant ame_engine routines.

The ame_engine.engStApprovers Data Structure

The engine stores and manipulates a transaction’s approver list


in a private data structure, ame_engine.engStApprovers, which
is of type ame_util.approversTable2. This section refers to the
data structure for convenience only. You should not modify the
engine to access this data structure directly. (For one thing, the
engine’s internal implementation may change, breaking your
code’s references to ame_engine.engStApprovers.)

Engine Functions

getActionTypeChainOrderMode

Syntax
function getActionTypeChainOrderMode(
actionTypeIdIn in integer)
return varchar2;

Description

Returns the chain-ordering mode of the action type with ID


actionTypeIdIn. The possible values are
ame_util.parallelChainsMode and ame_util.serialChainsMode.
An authority handler typically uses this function to calculate the
group_or_chain_order_number values of the approvers it
generates.

getActionTypeVotingRegime

Syntax
function getActionTypeVotingRegime(
actionTypeIdIn in integer)
return varchar2;

Description

Returns the voting regime of the action type with ID


actionTypeIdIn. The possible values are

Appendix C The Action-Type-Handler Programming Interface 108


ame_util.consensusVoting, ame_util.firstApproverVoting, and
ame_util.serializedVoting. An authority handler typically uses
this function to calculate the member_order_number values of
the approvers it generates.

getAttributeName

Syntax
function getAttributeName(
attributeIdIn in integer)
return varchar2;

Description

Returns the name of the attribute with the ID attributeIdIn.

getAttributeIdByName

Syntax
function getAttributeIdByName(
attributeNameIn in varchar2)
return integer;

Description

Returns the ID of the attribute with the name attributeNameIn.

getEffectiveRuleDate

Syntax
function getEffectiveRuleDate
return date;

Description

Returns the value of the RULE_EFFECTIVE_DATE attribute for


the transaction that the engine is currently processing.

getHandlerActionTypeId

Syntax
function getHandlerActionTypeId
return integer;

Description

Only an action-type handler may call this function. It returns the


ID of the action type that uses the handler. Typically a handler
calls this function to populate an ame_util.approverRecord2
record’s action_type_id field.

Appendix C The Action-Type-Handler Programming Interface 109


getHandlerActionTypeOrderNum

Syntax
function getHandlerActionTypeOrderNum
return integer;

Description

Only an action-type handler may call this function. It returns the


order number of the action type that uses the handler. Typically
a handler calls this function to populate an
ame_util.approverRecord2 record’s action_type_order_number
field.

getHandlerApprovalStatus

Syntax
function getHandlerApprovalStatus(
approverIn in ame_util.approverRecord2)
return varchar2;

Description

Only an action-type handler may call this function. It returns the


current approval status of the approver identified by approverIn.
Typically a handler calls this function to populate an
ame_util.approverRecord2 record’s approval_status field.

getHandlerAuthority

Syntax
function getHandlerAuthority
return varchar2;

Description

Only an action-type handler may call this function. It returns the


ame_util sub-list (authority) constant of the approvers that the
handler generates. A handler should only call this function if it
always generates approvers in a fixed sub-list. Typically a
handler calls this function to populate an
ame_util.approverRecord2 record’s authority field.

getHandlerItemClassId

Syntax
function getHandlerItemClassId
return integer;

Description

Only an action-type handler may call this function. It returns the

Appendix C The Action-Type-Handler Programming Interface 110


ID of the item class of the item whose approver list the engine is
currently constructing. (This is not necessarily the ID of the item
class of the item that satisfies the rule that uses the handler’s
action type. These items, and their item classes, differ for
header-level rules with conditions on subordinate-item-class
attributes, when per-item evaluation is enabled.) A handler
might call this function when preparing to populate an
am_util.approverRecord2 record’s item_class field (using
ame_engine.getItemClassName) or item_class_order_number
field (using ame_engine.getItemClassOrderNumber). It is
usually more efficient simply to call
ame_engine.getHandlerItemClassName or
ame_engine.getHandlerItemClassOrderNumber directly.

getHandlerItemClassName

Syntax
function getHandlerItemClassName
return varchar2;

Description

Only an action-type handler may call this function. It returns the


name of the item class of the item whose approver list the engine
is currently constructing. Typically a handler calls this function
to populate an ame_util.approverRecord2 record’s item_class
field. See also getHandlerItemClassId above.

getHandlerItemClassOrderNumber

Syntax
function getHandlerItemClassOrderNumber
return integer;

Description

Only an action-type handler may call this function. It returns the


order number of the item class of the item whose approver list
the engine is currently constructing. Typically a handler calls
this function to populate an ame_util.approverRecord2 record’s
item_class_order_number field. See also getHandlerItemClassId
above.

getHandlerItemId

Syntax
function getHandlerItemId
return integer;

Description

Only an action-type handler may call this function. It returns the


ID of the item whose approver list the engine is currently

Appendix C The Action-Type-Handler Programming Interface 111


constructing. Typically a handler calls this function to populate
an ame_util.approverRecord2 record’s item_id field. See also
getHandlerItemClassId above.

getHandlerItemOrderNumber

Syntax
function getHandlerItemOrderNumber
return integer;

Description

Only an action-type handler may call this function. It returns the


order number of the item whose approver list the engine is
currently constructing. Typically a handler calls this function to
populate an ame_util.approverRecord2 record’s
item_order_number field. See also getHandlerItemClassId
above.

getHandlerOccurrence

Syntax
function getHandlerOccurrence(
nameIn in varchar2,
itemClassIn in varchar2 default null,
itemIdIn in varchar2 default null,
actionTypeIdIn in integer default null,
groupOrChainIdIn in integer default null)
return integer;

Description

Only an action-type handler may call this function. It returns the


occurrence value of the approver identified by the input
arguments (which should have the values of the corresponding
fields in the approver’s ame_util.approverRecord2 record). If
any of the default-null input arguments is null, the function
returns the occurrence value appropriate for adding the
approver to the end of the approver list in
ame_engine.engStApprovers. Typically a handler calls this
function to populate an ame_util.approverRecord2 record’s
occurrence field.

getHandlerSublistOrderNum

Syntax
function getHandlerSublistOrderNum
return integer;

Description

Only an action-type handler may call this function. It returns the


order number of the sub-list that the engine is currently

Appendix C The Action-Type-Handler Programming Interface 112


populating. Typically a handler calls this function to populate an
ame_util.approverRecord2 record’s sub_list_order_number field.

getHeaderAttValue1

Syntax
function getHeaderAttValue1(
attributeIdIn in integer)
return varchar2;

Description

This function returns the value of the header-level attribute with


the ID attributeIdIn, for the transaction that the engine is
currently processing. The function only works for attributes that
are not of the currency attribute type. For header-level currency
attributes, use one of the getHeaderAttValues[n] procedures (see
below). A handler could call this function to fetch the value of
one of its required attributes, but it would have to fetch the
attribute’s ID (using ame_engine.getAttributeIdByName) first.
Typically a handler would take the direct route by calling
ame_engine.getHeaderAttValue2 (see below) instead. Note that
any attribute referenced by your handler must be listed among
the corresponding action type’s required attributes. (See
“Creating an Action Type” below for details.)

getHeaderAttValue2

Syntax
function getHeaderAttValue2(
attributeNameIn in varchar2)
return varchar2

Description

This function returns the value of the header-level attribute with


the name attributeNameIn, for the transaction that the engine is
currently processing. The function only works for attributes that
are not of the currency attribute type. For header-level currency
attributes, use one of the getHeaderAttValues[n] procedures (see
below). Typically a handler calls this function to fetch the value
of one of its required attributes. Note that any attribute
referenced by your handler must be listed among the
corresponding action type’s required attributes. (See “Creating
an Action Type” below for details.)

getItemClassId

Syntax
function getItemClassId(
itemClassNameIn in varchar2)
return integer;

Appendix C The Action-Type-Handler Programming Interface 113


Description

This function returns the ID of the item class with the name
itemClassNameIn.

getItemClassName

Syntax
function getItemClassName(
itemClassIdIn in integer)
return varchar2;

Description

This function returns the name of the item class with ID


itemClassIdIn.

getItemClassOrderNumber

Syntax
function getItemClassOrderNumber(
itemClassIdIn in integer)
return integer;

Description

This function returns the order number of the item class with ID
itemClassIdIn, for the transaction type of the transaction that the
engine is currently processing. Typically a handler calls this
function to populate an ame_util.approverRecord2 record’s
item_class_order_number field.

getItemOrderNumber

Syntax
function getItemOrderNumber(
itemClassNameIn in varchar2,
itemIdIn in varchar2)
return integer;

Description

This function returns the order number for the item with the ID
itemIdIn in the item class with the name itemClassNameIn.
Typically a handler calls this function to populate populate an
ame_util.approverRecord2 record’s item_order_number field.

getRuntimeGroupCount

Syntax
function getRuntimeGroupCount(
groupIdIn in integer)

Appendix C The Action-Type-Handler Programming Interface 114


return integer;

Description

This function returns the number of static members of the


approval group with ID groupIdIn.

getSublistOrderNum

Syntax
function getSublistOrderNum(
itemClassNameIn in varchar2,
authorityIn in varchar2)
return integer;

Description

This function returns the sub-list order number for the sub-list
identified by the ame_util sub-list (authority) constant
authorityIn, for the item class with the name itemClassNameIn.
Typically a handler calls this function to populate an
ame_util.approverRecord2 record’s sub_list_order_number field.

Engine Procedures

addApprover

Syntax
procedure addApprover(
approverIn in ame_util.approverRecord2);

Description

This procedure appends the record approverIn to the end of the


approver list in ame_engine.engStApprovers. Typically a
handler calls this procedure to add an approver to the end of the
approver list.

getApprovalGroupConfigs

Syntax
procedure getApprovalGroupConfigs(
groupIdsInOut in out nocopy ame_util.idList,
orderNumbersOut out nocopy ame_util.idList,
votingRegimesOut out nocopy ame_util.charList);

Description

This procedure sorts the approver-group IDs groupIdsInOut in


place by group order number first and then by group ID. It then
returns the groups’ order numbers and voting regimes in a

Appendix C The Action-Type-Handler Programming Interface 115


consistent order. Typically an approver-group handler uses this
procedure to populate the group_or_chain_order_number and
member_order_number fields of the ame_util.approverRecord2
records representing the approvers in the input approval groups.
(For details about approver-group voting regimes, see Appendix
C of the implementation guide.)

getHandlerCOAFirstApprover

Syntax
procedure getHandlerCOAFirstApprover(
itemClassIn in varchar2,
itemIdIn in varchar2,
actionTypeIdIn in integer,
groupOrChainIdIn in integer,
nameOut out nocopy varchar2,
origSystemOut out nocopy varchar2,
origSystemIdOut out nocopy integer,
displayNameOut out nocopy varchar2,
sourceOut out nocopy varchar2);

Description

Only an action-type handler may call this procedure. If the


originating application has inserted a starting point (first
approver) for the chain of authority that the engine is currently
constructing, this procedure returns the inserted approver in
nameOut, origSystemOut, origSystemIdOut, and
displayNameOut; and it returns the appropriate source-field
value for the returned approver’s ame_util.approverRecord2
record. If no starting point has been inserted, the output
arguments’ values are null.

getHandlerCOAInsertion

Syntax
procedure getHandlerCOAInsertion(
nameIn in varchar2,
itemClassIn in varchar2,
itemIdIn in varchar2,
actionTypeIdIn in integer,
groupOrChainIdIn in integer,
occurrenceIn in integer,
approvalStatusIn in varchar2,
nameOut out nocopy varchar2,
origSystemOut out nocopy varchar2,
origSystemIdOut out nocopy integer,
displayNameOut out nocopy varchar2,
sourceOut out nocopy varchar2);

Description

Only an action-type handler may call this procedure. If the


originating application has inserted a chain-of-authority
approver into the chain of authority immediately after the input

Appendix C The Action-Type-Handler Programming Interface 116


approver (identified by all of the input arguments), this
procedure returns the inserted approver in nameOut,
origSystemOut, origSystemIdOut, and displayNameOut; and it
returns the appropriate source-field value for the returned
approver’s ame_util.approverRecord2 record. If no such
insertion has occurred, the output arguments’ values are null.

getHandlerRules

Syntax
procedure getHandlerRules(
ruleIdsOut out nocopy ame_util.idList,
approverCategoriesOut out nocopy
ame_util.charList,
parametersOut out nocopy ame_util.stringList,
parameterTwosOut out nocopy ame_util.stringList);

Description

Only an action-type handler may call this procedure. It returns


in ruleIdsOut the IDs of the rules that apply to the transaction
the engine is currently processing, which use the action type. For
each rule ID, the procedure also returns in
approverCategoriesOut the approver category of the transaction
type’s rule usage for the rule, and the action parameters of the
rule’s action in parametersOut and parameterTwosOut. (If an
applicable rule has several actions of the same action type, they
appear in separate rows in the output arguments.)

Typically a handler uses getHandlerRules for several purposes.


First, it uses the action parameters to compute the set of
approvers the rules require. Second, it uses the rule usages’
approver categories to determine each required approver’s
approver category (that is, the approver_category field of the
approver’s ame_util.approverRecord2). Third, it uses the rule
IDs to populate the source field of each approver’s
ame_util.approverRecord2.

Use getHandlerRules2 if the actions processed by the handler


only have one parameter each.

getHandlerRules2

Syntax
procedure getHandlerRules2(
ruleIdsOut out nocopy ame_util.idList,
approverCategoriesOut out nocopy
ame_util.charList,
parametersOut out nocopy ame_util.stringList);

Description

The handlers of action types whose actions only have one


parameter should use getHandlerRules2 instead of

Appendix C The Action-Type-Handler Programming Interface 117


getHandlerRules (which a handler expecting two parameters per
action should use). Otherwise, this procedure functions just like
getHandlerRules. See “getHandlerRules” above for details.

getHandlerRules3

Syntax
procedure getHandlerRules3(
ruleIdsOut out nocopy ame_util.idList,
parametersOut out nocopy ame_util.stringList,
listModParameterOnesOut out nocopy
ame_util.stringList,
listModParameterTwosOut out nocopy
ame_util.longStringList);

Description

Only a handler for an action type used by list-modification rules


may call this procedure. It functions in much the same way as
getHandlerRules1, but for list-modification action types. Each
row in the two listModParameter[n]Out arguments represents a
list-modification condition. Each row in
listModParameterOnesOut contains one of the constants
ame_util.anyApprover and ame_util.finalApprover. Each row in
listModParameterTwosOut contains the wf_roles.name of a
target approver. the See “getHandlerRules1” above for further
details.

getHandlerLMApprovers

Syntax
procedure getHandlerLMApprovers(
listModParameterOneIn in varchar2,
listModParameterTwoIn in varchar2,
includeFyiApproversIn in boolean,
includeApprovalGroupsIn in boolean,
returnForwardeesIn in boolean,
approverIndexesOut out nocopy ame_util.idList,
lastForwardeeIndexesOut out nocopy
ame_util.idList);

Description

Only a list-modification action-type handler may call this


procedure. It returns the indexes of the approvers in
ame_engine.engStApprovers that satisfy the following
requirements:

1. The approver has the wf_roles.name value


listModParameterTwoIn.

2. The approver is in a position consistent with


listModParameterOneIn (which can be
ame_util.anyApprover or ame_util.finalApprover).

Appendix C The Action-Type-Handler Programming Interface 118


3. If includeFyiApproversIn is false, the approver’s
approver category is
ame_util.approvalApproverCategory.

4. If includeApprovalGroupsIn is false, the approver is in a


chain of authority.

The procedure returns matching approver occurrences’ indexes


(in ame_engine.engStApprovers) in approverIndexesOut. If
returnForwardeesIn is true, lastForwardeeIndexesOut(i) contains
the index of the approver at the end of a succession of
forwardings, starting with a forwarding from the approver at the
index approverIndexesOut(i). (If there are no forwardings, the
two values are the same.)

Use getHandlerLMApprovers in conjunction with


getHandlerRules3 (see “getHandlerRules3” above).

getHeaderAttValues1

Syntax
procedure getHeaderAttValues1(
attributeIdIn in integer,
attributeValue1Out out nocopy varchar2,
attributeValue2Out out nocopy varchar2,
attributeValue3Out out nocopy varchar2);

Description

This procedure returns the values of the header-level attribute


with the ID attributeIdIn. The procedure returns null in
attributeValue2Out and attributeValue3Out unless attributeIdIn
identifies a currency attribute. Typically a handler uses this
procedure to fetch a currency attribute’s values. However, the
handler would typically first have to fetch the attribute’s ID,
starting with its name, using
ame_engine.getAttributeIdByName. The direct route is typically
to use getHeaderAttValues2 (see “getHeaderAttValues2” below).

getHeaderAttValues2

Syntax
procedure getHeaderAttValues2(
attributeNameIn in varchar2,
attributeValue1Out out nocopy varchar2,
attributeValue2Out out nocopy varchar2,
attributeValue3Out out nocopy varchar2);

Description

This procedure returns the values of the header-level attribute


with the name attributeNameIn. The procedure returns null in
attributeValue2Out and attributeValue3Out unless
attributeNameIn identifies a currency attribute. Typically a

Appendix C The Action-Type-Handler Programming Interface 119


handler uses this procedure to fetch a currency attribute’s values.

getRuntimeGroupMembers

Syntax
procedure getRuntimeGroupMembers(
groupIdIn in integer,
approverNamesOut out nocopy
ame_util.longStringList,
approverOrderNumbersOut out nocopy
ame_util.idList,
approverDisplayNamesOut out nocopy
ame_util.longStringList,
origSystemIdsOut out nocopy ame_util.idList,
origSystemsOut out nocopy ame_util.stringList);

Description

This procedure returns the members of the approval group with


ID groupIdIn. The members’ order numbers within the group
(corresponding to the member_order_number field of an
ame_util.approverRecord2) are in approverOrderNumbersOut.
Typically a pre-approval, post-approval, or approver-group
chain-of-authority action type uses this procedure to fetch an
approval group’s membership, so the handler can add the group
to the approver list.

insertApprover

Syntax
procedure insertApprover(
indexIn in integer,
approverIn in ame_util.approverRecord2,
adjustMemberOrderNumbersIn in boolean default
false);

Description

This procedure inserts the approver represented by approverIn


at index indexIn of the current approver list (in
ame_engine.engStApprovers). indexIn must be between one and
one more than the number of approvers already in the list
(inclusive). If adjustMemberOrderNumbersIn is true,
insertApprover performs the insertion and then adjusts the
member_order_number values of the approvers at and above
indexIn, in the same group or chain as approverIn.

insertApprovers

Syntax
procedure insertApprovers(
firstIndexIn in integer,
approversIn in ame_util.approversTable2);

Appendix C The Action-Type-Handler Programming Interface 120


Description

This procedure inserts the list of approvers in approversIn into


consecutive positions in the current approver list, starting at the
index firstIndexIn, which must be between one and one more
than the number of approvers already in the list. Unlike
insertApprover, insertApprovers does not adjust the member
order numbers of any approvers following the inserted
approvers. For this reason you should only use insertApprovers
in cases where you’re confident no such adjustment could be
appropriate.

substituteApprover

Syntax
procedure substituteApprover(
approverIndexIn in integer,
nameIn in varchar2,
actionTypeIdIn in varchar2,
ruleIdIn in integer);

Description

This procedure replaces the wf_roles.name of the approver in


ame_engine.engStApprovers at index approverIndexIn with the
nameIn. It also appends ruleIdIn to the rule-ID list in the target
approver’s source field.

truncateChain

Syntax
procedure truncateChain(
approverIndexIn in integer,
ruleIdIn in integer);

Description

Only a list-modification action type’s handler may call this


procedure. The procedure truncates the chain of authority
containing the approver at index approverIndexIn of
ame_engine.engStApprovers, so that this approver becomes the
final approver in the chain. If the allowFyiNotifications
configuration variable is set to yes, the approvers that would
otherwise be truncated remain in the approver list, but their
approver category becomes ame_util.fyiApproverCategory. The
procedure also appends ruleIdIn to the truncated approvers’
source value.

Appendix C The Action-Type-Handler Programming Interface 121


Appendix D
Sample AME Objects

Index 122
Overview
This chapter illustrates how to create a variety of AME objects that a
development team would typically create, in the process of seeding a
transaction type:

• a transaction type proper

• mandatory-attribute usages

• an item-class usage

• a header-level attribute and a usage for it

• a line-item-level attribute and a usage for it.

The chapter includes sample code for each object, where


appropriate. It generally assumes that it describes the activities
of the development team for a fictitious Oracle Applications
product Some Application.

Transaction Type

Before actually creating a transaction type, the team reviews and


documents the following decisions:

1. How many transaction types to create

2. What usages to give the mandatory attributes

3. What item-class usages to create

4. How to configure the item-class usages.

The following subsections describe these decisions.

Number of Transaction Types

Suppose an originating application wants to integrate AME. The


application has historically included its own approvals
functionality. The approvals functionality applies the same
approvals logic to all transactions generated by the application.
The logic interprets its decision variables the same way for all
transactions. In the development team’s experience, their
customers generally implement a modest number of rules in the
old approvals functionality. For all these reasons the
development team concludes that it only needs to seed one
transaction type.

Mandatory-Attribute Usages

Next, the development team reviews the mandatory attributes to

Index 123
decide what values or usages to seed for each. Their guiding
principle is to preserve or improve upon their old approvals
logic in their AME seed data. Here are their decisions:

• The old approvals logic never allowed an end user to


suppress approvers required by the application’s approvals
logic, so the development team gives
ALLOW_DELETING_RULE_GENERATED_APPROVERS a
static false usage.

• Likewise, the old approvals logic never allowed an end user


to approve the transactions they submit, so the development
team gives ALLOW_REQUESTOR_APPROVAL a static false
usage.

• In the old logic, all transactions having a total value over a


user-configuration threshold must have someone’s approval.
The application owns a PL/SQL package named
some_app_package that contains a public function
getApprovalThreshold; this function returns the threshold.
Therefore the development team gives
AT_LEAST_ONE_RULE_MUST_APPLY the dynamic usage

select decode(sign(sum(line_item_amount) –

some_app_package.getApprovalThreshold),

1, ‘true’, ‘false’)

from some_app_line_items

where transaction_id = :transactionId;

Note that this usage assumes that the line-item amounts are in
the same currency as the threshold.

• The old logic always evaluates its rules as of sysdate; so the


development team gives EFFECTIVE_RULE_DATE a static
null usage.

• The old logic does not have a rule-priority construct, so the


team gives EVALUATE_PRIORITIES_PER_ITEM a static
false usage.

• The old logic is able to request approval per line item, and it
stops a transaction’s approval process when any line item is
rejected. So the team gives REJECTION_RESPONSE a static
usage having the value ame_util.stopAllItems.The old logic
never does per-line-item rule evaluation, so the team gives
USE_RESTRICTIVE_ITEM_EVALUATION a static false
usage.

• The team will integrate AME API calls into its application’s
Workflow process, so it gives USE_WORKFLOW a static true
usage.

Index 124
• The team uses its transactions’ Workflow item keys as
transaction IDs, so it gives WORKFLOW_ITEM_KEY the
dynamic usage

select :transactionId from dual

• The team will give its master Workflow approvals process


the item type the named ‘OSA’, so it gives
WORKFLOW_ITEM_TYPE the static usage ‘OSA’.

Configuration-Variable Values

The development team chooses its seeded configuration-variable


values according to the same principle by which it chose its
mandatory-attribute usages: preserving or improving upon their
application’s pre-AME functionality. Here are their decisions:

• Each customer organization will have its own administrative


approver, so the team does not seed a value for
adminApprover.

• The team plans to seed a new approver type based on the


(imaginary) ‘ORG’ originating system in Workflow Directory
Services. So the team seeds the value ‘yes’ for
allowAllApproverTypes.

• The old functionality uses line items, so the team seeds the
value ‘true’ for allowAllItemClassRules.

• The team plans to enable FYI notifications in their approvals


Workflow process, so the team sets allowFyiNotifications to
‘yes’.

• The old functionality limits currency conversions to a two-


month period, so the team sets currencyConversionWindow
to 60 (days).

• The team decides not to seed values for


forwardingBehaviors, assuming that their customers will
generally already have created appropriate default values for
this variable.

• The team will not use AME’s production functionality, so it


sets productionFunctionality to ‘no’.

• The old approvals functionality clears and restarts a


transaction’s approval process if it does not finish within two
weeks, so the team sets purgeFrequency to 14 (days).

• The old functionality does not suppress repeated approvers,


so the team sets repeatedApprovers to ‘each occurrence’.

Index 125
• The old functionality does not have a rule-priority construct,
so the team disables rule priorities for all rule types in
rulePriorityModes.

Item-Class Usage

Next the team prepares to create an item-class usage for the line-
item item class.

Item-Class Order Number

The old approvals functionality created an approver list for each


line item. It ordered all approvers serially, with line items’
approver lists following the header’s approver list.
Consequently the team assigns the line-item item class the item-
class order number two.

Parallelization Mode

Per the above, the team assigns the line-item item class the serial
parallelization mode.

Sublist Mode

Per the above, the team assigns the line-item item class the serial
sublist mode.

Line-Item-ID Query

The application’s line items apear in the table


some_app_line_items; their IDs are in the line_item_id column of
that table. That table joins the application’s some_app_headers
table via the transaction_id column. So the item-class usage
must have the line-item-ID query

select to_char(line_item_id)

from some_app_line_items

where transaction_id = :transactionId

order by line_item_id asc;

Note that the order-by clause orders the item IDs in ascending
numerical order, rather than in ascending character-set order.
Character-set ordering would force the transaction type’s line-
item-level attributes’ usages to order by to_char(line_item_id),
which would be inefficient and easy to forget.
Action Parameters, 14 approval_status, 88
Action Type, 12 chain of authority, 12, 14, 17, 20, 24,
action_type_id, 90 43, 66, 82, 88, 89, 90, 91, 94, 99,
AME Security, 8, 9 101, 102, 116, 119, 121
appendRuleIdToSource, 104 clearAllApprovals, 55, 78

Index 126
clearInsertion, 69 getItemClassName, 74
clearInsertions, 69 getItemStatus1, 61
clearSuppression, 68 getItemStatus2, 61
Configuration-Variable Values, 125 getItemStatuses, 62
Creating a Transaction Type, 9 getNextApprover, 80
Define an Item Class, 38 getNextApprovers1, 62
deleteApprover, 78 getNextApprovers2, 63
deleteApprovers, 78 getNextApprovers3, 63
Exception Handling, 41 getNextApprovers4, 64
fieldDelimiter, 104 getOldApprovers, 74, 81
final (signing) authority, 43 getPendingApprovers, 64
getActionTypeChainOrderMode, 108 getRuleDescription, 68
getActionTypeVotingRegime, 108 getRuleDetails1, 75
getAdminApprover, 56 getRuleDetails2, 75
getAdminName, 103 getRuleDetails3, 76
getAllApprovalGroups, 70 getTransactionProductions, 65
getAllApprovers, 57, 79 group_or_chain_id, 90
getAllApprovers1, 56 initializeApprovalProcess, 65
getAllApprovers3, 57 insertApprover, 76, 81
getAllApprovers4, 58 List-Editing-Handler, 23
getAllApprovers5, 59 list–modification, 12
getAllApprovers6, 59 parseApproverSource, 76
getAllApprovers7, 60 PL/SQL Exceptions, 24
getAllItemApprovers, 60 post-approval, 12, 16, 20, 101, 120
getAllItemApprovers2, 60 pre-approval, 12, 20, 101, 120
getAndRecordAllApprovers, 61 production, 12, 14, 57, 65, 125
getApplicableRules1, 70 recordDelimiter, 104
getApplicableRules2, 70 setFirstAuthorityApprover, 66, 82
getApplicableRules3, 71 suppressApprover, 77
getApprovalGroupId, 71 suppressApprovers, 77
getAttributeValue, 71 Suppressing Approvers, 42
getAvailableInsertions, 80 the Default Approver List, 41
getAvailableOrders, 80 Unresponsive Approvers, 42
getConditionDetails, 72 updateApprovalStatus, 66, 82
getGroupMembers1, 72 updateApprovalStatus2, 67, 82
getGroupMembers2, 73 updateApprovalStatuses, 67
getGroupMembers3, 73 updateApprovalStatuses2, 68
getGroupMembers4, 73 validateApprover, 55, 78
getItemClasses, 74 Workflow Directory Services, 30
getItemClassId, 74

Index 127

You might also like