Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
March 2012
1 Introduction
SAP Sourcing supports scripting as a key feature in extending its default functionality. Scripting is also used
to implement workflow approvals, which enable implementation of complex business rules.
1.3 Terminology
Class: The SAP Sourcing class that is being scripted.
Collaborator: A SAP Sourcing user who has rights to a document.
Collaborator role: A role that defines the rights a collaborator has to a given document.
Collection: A group of data of the same type, subordinate to a parent document. In the UI, this data is
rendered in a tabulated form.
Extension collection: A collection that is user defined. Scripting interacts with these collections via the
ExtensionCollectionIfc interface.
Document (syn. Business Document, Object): An instance of the class.
Extension member (syn. Member): An IBean that is part of a collection. Members of extension collections
implement the ExtensionCollectionMemberIfc. Members of system collections return either an anonymous
system type or a predefined member type. See the IAPI Documentation for detailed information.
IBean: Any class that implements IBeanIfc. Every scriptable object is of this type.
Import Record: A data structure containing the raw data from the inbound import file for one record.
Home: A class that manages Lifecycle tasks related to its associated IBean. Every IBean has the Home
interface.
Top level (syn. Container): A class of objects that are by design not subordinate to another object. Projects,
companies, master agreements, and agreements are all top-level objects.
Script manager: The part of the underlying application that manages the script from creation to finish.
Subordinate: A class or object that is part of a collection within a top-level class. Collaborators, extension
collections, and RFx line items are all subordinate classes.
System collection: A collection that is part of the SAP Sourcing class by design. Scripting accesses these
collections via the parent class’s accessors. Members of these collections may have IAPI-defined types.
Workflow definition: The object in SAP Sourcing that represents the XPDL-defined workflow process.
Workflow engine: The part of SAP Sourcing that manages a workflow process.
Workflow item: The specific activity in a workflow process.
Workflow process: The active instance of a workflow definition.
XPDL: A format designed for the interchange of Business Processes.
2 Scripting
2.1 Scripting Business Documents
Scripts are executed at key times in the lifecycle of an SAP Sourcing document. Although scripting is not
supported by every class in the SAP Sourcing application, the main classes are scripting enabled. During
script definition, classes available for scripting are provided in a drop-down list
Context Description
A script in which both the old and new values of a field are known.
This script executes during tab changes, auto-refreshing fields, and
when the document is fully validated, as with a field context.*
Note
During field data edit, the target field's old and new
values are accessible via scripted variables. However, if
the same script accesses other fields in the business
document (that is, not the target field) and those fields
have been modified, but not saved, the script only
shows those fields' old values. For example, if a user
changes the display name of a document from Project
Foo to Project Bar, during a field data edit for another
field, and the script invokes doc.getDisplayName(),
Field Data Edit it returns Project Foo.
Document Lifecycle
Event A document script executes as dictated by the target lifecycle.
Toolbar Script Visibility View Mode, Edit Mode, or View Toolbar All top-level
or Edit Mode. Controls what edit scripts only classes
state the document can be in
before the script is executable.
• Script C executes when the target attribute changes on the collection member.
It may seem intuitive that script B, with the validate DLC event, is preferred over script A, as it only executes
for any changed member, but the overhead associated with the Script Manager actually results in reduced
performance. Script A is the preferred way to validate collections.
Caution
It is important that validation scripts are only created on either the Member or the Document,
never both. Data corruption can occur if validation scripts exist at both levels due to
interference in the database transaction.
An additional way to script the collection is the Document Validation Context on the supplier. Execute the
following to start operating on the collection:
ExtensionCollectionIfc certsCollection =
doc.getExtensionCollection(“CERTS”);
Reference to the
current document
being scripted, also
All All doc called an IBean
Instance of
IapiSessionConte
xtIfc for the current
All All session user’s session
Reference to
document that is
Document Duplicated otherDoc being duplicated
String representing
internal ID of current
phase of document.
In the Pre-Phase
context, this is the
current phase. In the
Pre and Post Post-Phase context, it
Document Phase Changes current_phase is the new phase.
String representing
internal ID of target
phase of document in
Pre-Phase change
script or previous
Pre- and Post- phase in Post-Phase
Document Phase Changes other_phase change script
Reference to the
Field & Field Data IBeanFieldMdIfc
Edit field for field in question
Reference to value of
field in question. In
the case of Field Data
Field & Field Data Edit, this is the old
Edit fieldValue value of the field.
Reference to new
Field Data Edit newFieldValue value
Reference to
collection being
scripted
Collection collection
hasValue(Object object) Use this method to test for null, Only works for Java String type
or test that a SAP Sourcing and the following SAP Sourcing
object, though not null, has types:
some real value set. SimpeObjectRefenceIfc,
AmountIfc, PriceIfc,
AttachmentIfc,
EnumTypeIfc,
ResourceIfIfc,
SysDateIfc,
SysDatetimeIfc,
SysTimeIfc
getFieldValue() In Field and Field Data Edit Not normally used, as variable
scripts, returns the value of fieldValue accomplishes this
field
Example
The following code samples are provided to illustrate exception features.
throw doc.createApplicationException(“APPROVAL_SIG”,
“custom.exception.approval.required”);
ae = new ApplicationException(session);
ae.chainAtEnd(doc.createApplicationException(“APPROVAL_SIG”,
“custom.exception.approval.required”));
Note
If a field level exception is thrown from a document context script, SAP Sourcing displays the
error twice: once under the field and once at the top of the document. This apparent bug is
actually a feature, because it allows a user to navigate around the document reviewing
potential dependencies that may have caused the error, without losing the actual error text.
There is no recommended way to suppress this output.
BeanShell does not enforce Caught Exception Handling per Java standards. If an exception is not caught
and it is not a ChainedApplicationException or a subclass, it is in a raw format, as shown in the
following figure.
As this format is not helpful to the end user, SAP recommends starting every script with a comment to
provide assistance in the event of an unexpected failure.
Example
The following is an example of a preceding comment:
/** An error occurred when validating the Display Name. Please contact
a system administrator */
Example
Alternatively, if the script or a dependent component is likely to fail, it may be better to inform
the user generically, as shown in the following example, and log the full exception in the system
log.
try {
myFailableCode();
} catch(e) {
Logger.error(Logger.createLogMessage(session).setException(e).setLogMe
ssage(“My script failed”));
throw new ApplicationException(session, “custom.exception.error.id”);
}
Note
Comments related to authorship and script intentions should not be included in the script. They
should be added to the Description field in the script definition.
Example
In the following example, SAP Sourcing presents the error in the language of the current user’s
session if the ID custom.exception.doc_desc.required is part of the bundle
exception and of the type ERROR. The value of this resource ID must be translated to the
relevant languages, or it is only displayed in the default language.
doc.createApplicationException(“DOCUMENT_DESCRIPTION”,
“custom.exception.doc_desc.required”);
Example
If an object does not expose an attribute, the value can still be obtained by using the field name
of the property, as in the following example.
• If an instance of the IBean is available, for example, the variable doc, the home can be accessed as:
// Change phase,
//
doc.getIBeanHome().changePhase(doc, “bid_solicitation” );
Once the Home is obtained, it can be used to find an instance of the IBean. Note that the lookup methods
vary from IBean to IBean:
// Find by Account Object Reference
//
ownerEmail = userHome.find(doc.getDocumentOwnerUserReference());
The following example indicates one way to incorporate a logging model for a script that may log in greater
volume due to its complexity:
// Create a log message and set the method to be the script event
//
log = Logger.createLogMessage(session);
log.setMethod(“ProjectPrePhase”);
try {
...
} catch(IOException e) {
logError(“Could not write to the file, because of an IOError: ” +
e.getMessage() );
return;
}
You can also log the exception and raise a more understandable exception, as follows:
try {
<script>
} catch(e) {
Logger.error(Logger.createLogMessage(session).setException(e));
throw new ApplicationException (session, “helpful message ID”);
}
Occasionally, a lower-level SAP Sourcing function raises an exception without providing the underlying
cause in the exception message. This can happen when saving the IBean. In such a case, substitute the
following line:
Logger.error(Logger.createLogMessage(session).setException(e.getRootEx
ception() ));
See Handling Exceptions (page 12) for further details on exception handling.
FIELDA = doc.getExtensionField(“FIELDA”).get();
FIELDB = doc.getExtensionField(“FIELDB”).get();
colln = doc.getExtensionCollection("my_collection");
if(colln.size() == 0) {
return;
}
iter = colln.iterator();
for(member : iter) {
feildA = member.get("FIELDA");
if(!hasValue(feildA) ) {
exception.chainAtEnd(member.createApplicationException("FEILDA",
"exception.feild.is.required"));
}
}
From a scripting perspective, an absolute reference is needed when checking values, so value lists should
always be referenced by their internal identifier.
Note
In the UI for Value List Value Definition, this is labeled as Display Name, although this value is
not displayed to the user.
Value lists are often configured to give the display name the same value as the value list value’s default
resource ID. However, if the value list values are longer than 40 characters, the display name must be
abbreviated, so these values are not always identical.
// Is the Project Status completed?
// Field validation script on STATUS
STATUS_COMPLETED = "Completed";
// … DO SOMETHING …
}
if(hasValue(fieldValue) @and
fieldValue.getDisplayName().equals(STATUS_COMPLETED)) {
// … DO SOMETHING …
}
// Check to make sure the Commodity (Int Cat) is not at the top level
//
if(!hasValue(fieldValue)) {
return;
}
if(!hasValue(categoryIBean.getParentObjRef()) ) {
throw doc.createApplicationException(field.getAttributeId(),
"custom.top_level_commodity_not_allowed");
}
if (hasValue(currentGroup) @and
currentGroup.findGroupMembers().contains(
session.getAccount().getAccountObjectReference()) ) {
isReportingUser = true;
break;
}
}
Example
An example is a script that runs every night and checks if any master agreements are past
expiration. If they are past the expiration date, the script changes the status of the master
agreement to Expired.
To create a new Explicitly Called Script:
1. Choose Setup Æ System Setup tab Æ Integration area Æ Explicitly Called Script.
2. On the Explicitly Called Script screen, choose the New button.
3. Enter the required information and your script and save your work.
3 Workflow
Workflow functionality in SAP Sourcing allows a business document to be submitted for approval to one or
more approvers. In a typical scenario, once a phase is reached with an assigned workflow definition, the
document is locked by the system. It can be released from this lock in the following ways:
• The approvers approve or reject the document.
• The workflow is deleted by use of the Workflow Processes Report found on the Workflow Definition
page.
The approvers’ action causes the workflow’s status to be evaluated and this may release the document from
workflow, generating any necessary emails. An approval outcome allows the document to continue to
advance to later phases; rejection only permits the document to regress phases.
Workflow is enabled on a number of documents. The functionality provided in this area is fixed by the
application to a large degree. However, scripting is used to customize the workflow by deciding which
approvers are added to the document.
Workflow partly utilizes a standardized format of a process definition called XPDL 2.0 (see
http://en.wikipedia.org/wiki/XPDL). SAP Sourcing links to an open source utility called Together Workflow
Editor CE for purposes of creating and editing process definitions. The XPDL file defines the steps the
workflow must go through and the scripts for adding the required approvers at each step.
The process of creating and assigning workflow definitions is described in this guide. For more detailed
information, see the SAP Sourcing Online Help.
SAP recommends that you use the templates provided as the basis for workflows, as opposed to creating
new ones.
Extended
Attribute Description
In addition to these extended attributes, there are informational attributes that are optional, but are used in
the workflow history or general email notifications to approvers.
Variable Description
This expression must only be getApprovalStatus(), followed by a Java operator (== or != ) and one of
the statuses described in the following table.
Status Description
Pending
Activity is still pending user action.
Denied
Activity is rejected.
In a multi-activity workflow, there are two transitions from each activity except for the last activity (refer to the
figure above depicting a multi-activity workflow). Each activity transitions based upon being approved or
denied, except for the last activity which transitions to the end only when the activity is not pending (its
precise status is not required at this point as this is the only way out of the workflow).
For a single activity workflow, the TransitionCondition is defined as an extended attribute, but contains
the same transition condition code.
When a script executes, the variable doc is the contract document IBean. If access is needed to the
container, as is often the case, a reference to it can be obtained as follows:
if(hasValue(doc.getParentIBean()) {
parentContainer = doc.getParentIBean();
else {
// Handle parent-not-loaded condtn here
cancelProcess(“Parent Document not loaded. Contact a System
Administrator.”);
return;
}
There is a possibility that the contract document can be loaded without its container, so handling the null
cases is mandatory.
User Level Document Type Lower Limit Upper Limit Approval Group
The role of the script on the activity is to perform the four-way match by iterating over this collection and
adding the approval group. See Workflow Examples (page 32) for a similar scenario to this one.
import
com.sap.odp.api.doc.collaboration.CollaboratorApprovalRuleType;
for(member : iterator) {
if(requestType.equals(member.get("REQUEST_TYPE")) @and
(cpSubGroup.equals(member.get("CP_SUB_GRP"))) ) {
if(projectContractValue.compareTo(member.get("FROM_VALUE"))
@gteq 0 @and
projectContractValue.compareTo(member.get("TO_VALUE")) @lteq 0) {
addApprover(member.get("APPROVER_GROUP"), new
CollaboratorApprovalRuleType(ANY));
found = true;
}
}
}
if(!found) {
3.8.2 Postscript
3.8.2.1 Scenario - End of Workflow Processing
The following script is implemented as postscript on the final activity. Its purpose is to advance the document
under workflow to the next phase and also to lock an amount field that is considered pivotal to the approval.
// If not denied move forward to RFP status
//
if(getApprovalStatus() != DENIED)
{
home = IBeanHomeLocator.lookup(session,
ProjectIBeanHomeIfc.sHOME_NAME);
home.upgradeToEdit(doc);
home.changePhase(doc, "RFP");
IapiDocumentLockManager.lockField(session,doc,"FundingRequest");
3.8.3 PreCancelScript
3.8.3.1 Scenario - When the workflow is rejected, or is manually canceled
When a script is canceled, such as is shown in the prescript example, the following example code regresses
the document back to draft phase. This can also be an approach in the postscript if the request was denied,
based on the business requirements.
doc.getIBeanHomeIfc().upgradeToEdit(doc);
home.changePhase(doc,"Request in Draft");
submitter = getSubmitter();
A.3 Exceptions
• Comment the top of the script with a failure message that describes where the script is
executing from.
• Always use resource IDs for scripted exceptions.
• Always use the object’s method for creating exception on that object.
A.4 General
• Do not use Internal APIs.
• Do not access the database directly.
• Only access objects from the home interface and even then, with utmost consideration to
system resources especially on methods like findWhere().
• If indirectly accessing an object using getFieldMetadata( ), use the property field on the
IBean only.
• If an attribute has no property field and the object does not have an IAPI, contact support to
request that it be added.
Crossgate, m@gic EDDY, B2B 360°, and B2B 360° Services are registered trademarks of Crossgate AG in
Germany and other countries. Crossgate is an SAP company.
All other product and service names mentioned are the trademarks of their respective companies. Data
contained in this document serves informational purposes only. National product specifications may vary.
These materials are subject to change without notice. These materials are provided by SAP AG and its
affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any
kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only
warranties for SAP Group products and services are those that are set forth in the express warranty
statements accompanying such products and services, if any. Nothing herein should be construed as
constituting an additional warranty.