You are on page 1of 21

Groovy Code Samples

Reusable sample code to help with common use-cases

Follow: @fadevrel

Read: blogs.oracle.com/fadevrel

Watch: youtube.com/FADeveloperRelations

Discuss: bit.ly/fadevrelforum
Contents
Introduction .............................................................................................................................................. 5

ADF: Dates................................................................................................................................................. 6

ADF: User Data .......................................................................................................................................... 6

ADF: Session Variables .............................................................................................................................. 6

ADF: The Current Script Name ................................................................................................................. 7

ADF: Seeded Global Functions .................................................................................................................. 7

ADF: Using Ternary Operators .................................................................................................................. 7

ADF: Data Type Conversions ..................................................................................................................... 7

API: Importing Java and Groovy Libraries ................................................................................................. 8

Pages & URLs: Generate a JWT token ....................................................................................................... 8

Pages & URLs: Call Topology Manager ..................................................................................................... 8

Pages & URLs: Using URLEncoding ........................................................................................................... 8

Profile Options: Return Current Value ...................................................................................................... 8

UI Handling Data: Change Case................................................................................................................ 9

UI Handling Data: Check the data type ..................................................................................................... 9

UI Handling Data: Checking Field Properties ............................................................................................ 9

UI Handling Data: Get LOV meaning values .............................................................................................. 9

Web Services: Calling an undefined service using a Client ....................................................................... 9

Web Services: Parsing REST/JSON .......................................................................................................... 10

Web Services: Using The Values Returned ............................................................................................. 10

Web Services: Using The Values Returned ............................................................................................. 10

2
Web Services: Creating a findCriteria payload ....................................................................................... 11

Web Services: Inserting a simple record................................................................................................. 11

Web Services: Creating a payload........................................................................................................... 12

Web Services: using the findAttribute element and processing the response ...................................... 12

Web Services: More on the findAttribute element and parsing responses ........................................... 13

Web Services: Parsing Responses Using An Iterator .............................................................................. 14

Web Services: Parsing Response Using a String...................................................................................... 14

Querying VO Rows: Using the findbyKey function.................................................................................. 15

Querying VO Rows: Using multiple where criteria’s ............................................................................... 15

Querying VO Rows: Referencing Child Objects ....................................................................................... 15

Querying VO Rows: Product Items from Opportunity Revenue ............................................................. 16

Querying VO Rows: Using a Global Function .......................................................................................... 16

Querying VO Rows: Accessing Parent Object Fields ............................................................................... 17

Querying VO Rows: Get Appointments Object ....................................................................................... 17

Inserting VO Rows: Interactions ............................................................................................................. 18

Inserting VO Rows: Creating an Activity ................................................................................................. 18

Inserting VO Rows: Custom Objects ....................................................................................................... 19

Error Handling: Exception Details ........................................................................................................... 19

Error Handling: JBOExceptions and JBOWarnings .................................................................................. 19

Error Handling: ValidationException....................................................................................................... 20

Error Handling: Assertion ........................................................................................................................ 20

Security: Accessing Context Data............................................................................................................ 20

Security: VO Query for Person Resources Roles ..................................................................................... 20

3
Security: More VO Query for Person Resources Roles ........................................................................... 21

4
Introduction

This document provides examples of using Groovy code to achieve a range of common goals during
developing customisations in Oracle Sales Cloud using Application Composer.

The sample code here is not certified or supported by Oracle; it is intended for educational or testing
purposes only.

For further assistance in using Groovy and Application Composer please consult the following
recommended resources:

 Our Getting Started With Groovy Whitepaper

 Our Application Composer Series of blog articles

 Groovy Scripting Reference Guide

 Customizing Sales Guide

5
ADF: Dates
In addition to the items on the Release 9 Supported Functions list (in the Groovy Scripting Reference
Guide):
def newDate = adf.currentDate or adf.currentDateTime

A more detailed example, checking a persons age:


def dob = nvl(PersonPartyVO?.DateOfBirth,today())
def age = 0
if (today()[Calendar.MONTH] > dob[Calendar.MONTH]){
age = today()[Calendar.YEAR]-dob[Calendar.YEAR]
}
else if(today()[Calendar.MONTH] == dob[Calendar.MONTH] && today()[Calendar.DATE] >=
dob[Calendar.DATE]){
age = today()[Calendar.YEAR]-dob[Calendar.YEAR]
}
Else
{
age = today()[Calendar.YEAR]-dob[Calendar.YEAR]-1
}
if(age > 65)…

ADF: User Data


Use the following to get user-related data from the runtime session context. Note: whilst you may read
that extensive ADF session objects exist for use in JDeveloper customizations, access to them through
Application Composer Groovy is limited.
adf.context.getSecurityContext()?.getUserProfile()?.getUserID()
= richard.bingham@oracle.com (login username)
adf.context.getSecurityContext()?.getUserProfile()?.getFirstName()
= Richard
adf.context.getSecurityContext()?.getUserProfile()?.getGUID()
= DBE25B1925AA9356E0401790938C507A
adf.context.getSecurityContext()?.getUserProfile()?.getPrincipal()
= [LDUserPrincipal]: richard.bingham@oracle.com
adf.context.getLocale() or adf.context.locale.getLanguage()
= en

ADF: Session Variables


Put a name-value pair in the user data map and then get it by the same key:
adf.userSession.userData.put('SomeKey', someValue)

6
def val = adf.userSession.userData.SomeKey

The internal ADF session object and its variables can be accessed, although details on intended use and
a list of attributes is not available at this time. Here is a usage example:
String var = session.getVariable("EmailSent");
if(var != 'Y') //Nothing is set on the session
{
someAPIToSendEmail();
session.putVariable("EmailSent","Y");
}
else if(var == "Y")
{
//Do nothing but reset the session variable value
session.putVariable("EmailSent",null); }
}

ADF: The Current Script Name


Useful in debugging through writing log lines.
println("[In: ${scriptName}]")

ADF: Seeded Global Functions


In Release 9 there are three global functions available for use but that are not listed in the Expression
Builder.
adf.util.getUserPartyId()
= Returns the logged-in user's Party_ID.
adf.util.getUserPartnerCompanyId()
= Returns the partner company's party_ID for the logged-in user, if the user is a partner user.
adf.util.getUserRootResourceOrgId()
- Returns the organization_ID for the logged-in user's organization hierarchy root resource organization.

ADF: Using Ternary Operators


This is a Groovy shortcut for writing if-the-else logic. The example below can be read as “if job is not a
SALESMAN then the new value of the salary must be greater than 100 else, greater than 0”.
def salary =(Job != "SALESMAN" ? newValue > 100 : newValue > 0)

ADF: Data Type Conversions


Simple toString() example for converting VO query data:
def view = newView('TerritoryPVO')
view.executeQuery()
view.reset()
def sb = new StringBuilder();
while(view.hasNext()) {
def row = view.next()
sb.append(row.getAttribute('TerritoryId'));
7
sb.append(row.getAttribute('Owner').toString());
}
println(sb.toString())

API: Importing Java and Groovy Libraries


The implementation of the Groovy execution engine in Application Composer is fairly generic, and as such it
automatically imports many utility functions for use.

Release 9 introduces a whitelist of supported functions (here) to prevent destabilizing the environment. The range
of usable functions is reasonably broad, including standard API’s under java.lang, java.util and java.sql along with
many Groovy and Oracle packages such as many under oracle.jbo and oracle.adf.

If you have a requirement for using other common utility API’s under the java or groovy packages then please log
this with Oracle Support along with your use-case so we can consider potential additions.

Pages & URLs: Generate a JWT token


Use the token string as a URL parameter in your dynamic hyperlink to the remote system.
def theToken =(new oracle.apps.fnd.applcore.common.SecuredTokenBean().getTrustToken())

Pages & URLs: Call Topology Manager


Getting the URLs that are registered in FSM using ‘Manage Third Party Applications’.
oracle.topologyManager.client.deployedInfo.DeployedInfoProvider.getEndPoint("PApp")

Pages & URLs: Using URLEncoding


How to URL encode a string for use:
def encodedURL
def idp_url = "https://isv4-crm-crm-ext.oracle.com/fed/idp/initiatesso?providerid="
def sp_url = "https://incentdemo.xactlycorp.com"
def name = adf.context.securityContext.userProfile.name
def exactly_url1 =
“https://incentdemo.xactlycorp.com/xlsweb/jsp/orafusion/incent_estimator.jsp?orUserEmail="
def exactly_url2 =
"&orSessionId=DAC67915271127E47232806F3C56CE59&orServerUrl=https://isv29-crm-crm-
ext.oracle.com/opptyMgmtOpportunities/OpportunityService&opId="+OptyId+"&orSharedToken=784f13be9a
c991068df6514a808625"
def exactly_url = exactly_url1 + name + exactly_url2
def encoded_exactly_URL= URLEncoder.encode(exactly_url, "UTF-8")
def encodedURL = idp_url+sp_url+'&returnurl='+encoded_exactly_URL
return(encodedURL)

Profile Options: Return Current Value


def lvtURL = oracle.apps.fnd.applcore.Profile.get("AIT_LEAD_LVT_URL")
if (!lvtURL) {
throw new oracle.jbo.ValidationException('Leads Vision Tool URL
AIT_LEAD_LVT_URL definition is wrong - please contact system administrator')
}
return lvtURL + LeadNumber;

8
UI Handling Data: Change Case
Converting strings to all uppercase. The lowercase() function also exists
def str1 = UniqueNameAlias
setAttribute("UniqueNameAlias",uppercase(str1))

UI Handling Data: Check the data type


Various methods exist, but here are two:

1) Use a standard java function to convert the string to number.


Integer.valueOf(String)

2) If the string is not a number, below will throw an exception you can catch.
def isItNumber = TextField_c.isNumber()

UI Handling Data: Checking Field Properties


Example of making address fields required when creating customers. This is added as an Object level
validation on Organization Object:
def addr = PartySite
while(addr.hasNext())
{
def addr1 = addr.next();
if(addr1.Address1 == null || addr1.Address1 == '')
{
throw new oracle.jbo.ValidationException("Address is a requried field. Please Enter the
details")
}
else
return true
}

UI Handling Data: Get LOV meaning values


For single select lists:
println(getSelectedListDisplayValue('ReasonWonLostCode'))

For multi-selected values:


println(getSelectedListDisplayValues(‘OptySelectedList’))

Web Services: Calling an undefined service using a Client


Not a supported/recommended way of using web services, however put here for reference. Also note
from Release 9 use of some of these API’s will be restricted.
def authString = "Username:Password".getBytes().encodeBase64().toString()

9
def url = new URL("http://www.dummy.com/myServ/api/v1/1234")
org.apache.http.impl.client.DefaultHttpClient httpClient = new
org.apache.http.impl.client.DefaultHttpClient()
org.apache.http.client.methods.HttpGet getRequest= new
org.apache.http.client.methods.HttpGet(url);
getRequest.addHeader("Accept", "application/xml");
getRequest.addHeader("Authorization", "Basic " + authString);
org.apache.http.HttpResponse response = httpClient.execute(getRequest);
def status = response.getStatusLine().getStatusCode();
def returnMessage = ""
def customerName = ""
if (status>= 300) {
throw new org.apache.http.client.ClientProtocolException("Unexpected response status: " +
status)}
org.apache.http.HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
returnMessage= org.apache.http.util.EntityUtils.toString(responseEntity);
}
def customers = new XmlParser().parseText(returnMessage)
customerName = "Customer Name: " + customers.details.name.text()
return customerName

Web Services: Parsing REST/JSON


Again for reference only, and not a supported API and from Release 9 use of some use may be
restricted.

def returnMessage = '[{"id":1234, "name":"John"}]'


groovy.json.JsonSlurper js = new groovy.json.JsonSlurper()
// Parse the response as Map
def map = js.parseText( returnMessage )
def customerName=map[0].name
return customerName

Web Services: Using The Values Returned


Simple example that prints all the elements of the response lead record to the log.
def LeadW
S = adf.webServices.Leads2.getSalesLead(300000019381458);
def nElements = 0;
def s = "";
for (element in LeadWS ){
nElements++;
s = s + "," + element.value;
}
println("number of elements:" + nElements);
println("values: " + s);

Web Services: Using The Values Returned

This prints out just the status code field


def opty = adf.webServices.CHA_OpptyService.getOpportunity(optyId);
println("Response received from CHA:"+opty,StatusCode);

This prints out whole return payload


10
def optyId = '300000010825972';
def opty = adf.webServices.CHA_OpptyService.getOpportunity(optyId);
println("Response received from CHA:"+opty);

Web Services: Creating a findCriteria payload


Note that the structure of the input list is very specific.

def findCriteria =
[
filter:
[
group:
[
[
item:
[
[
attribute :'Deptno',
operator :'=',
value :[[item:30]]
],
[
attribute :'Comm',
operator :'>',
value :[[item:300]]
],
[
upperCaseCompare :true,
attribute :'Job',
operator :'STARTSWITH',
value :[[item:'sales']]
]
]
]
]
]
]
def findControl = [ ]
def emps = adf.webServices.EmployeesService.findEmployees(findCriteria, findControl)
for (emp in emps) {
println(emp)
}

Web Services: Inserting a simple record


First define the interaction web service in the web services screen, then use this script. From Release 9
the interaction is created via the Activities service/object.
println("Sales Lead Service")
if (isAttributeChanged('LeadStatus_c'))
{
def newint = [
InteractionId:23456779,
// InteractionStartDate:today(),
InteractionEndDate:today(),
InteractionDescription:'LeadCreatedFromSoapUI',

11
InteractionTypeCode: 'PHONE CALL',
DirectionCode:'OUTBOUND',
MediaItemId:1,
// InteractionAssociation:[ InteractionAssociationId:23456779,
InteractionId:23456779,
AssociatedObjectUid:300000014128636,
AssociatedObjectCode:'LEAD',
ActionCode:'CREATED']]
newint = adf.webServices.Interaction.createInteraction(newint)
}

Web Services: Creating a payload


This very simple example was used for an Eloqua web service call.
def vStatCode = nvl(StatusCode, "blank")
if(vStatCode == "CONVERTED" || vStatCode == "RETIRED")
{
def payload =
[
rowId :nvl(ExternalTextAttribute2_c, "blank"),
leadId :LeadId,
status :vStatCode,
description :nvl(Description,"blank"),
]
adf.webServices.SOA_Lead_Update.update(payload);
}

Web Services: using the findAttribute element and processing the response

println('***** Find appointments (Opportunity - Object Functions) START ***** ' + now());
def today1 = today();
def targetDate1 = today1 + 3;
println('Today : ' + today1);
println('Target Date : ' + targetDate1);
def findCriteria =
[
fetchStart: 0,
fetchSize: -1,
excludeAttribute: false,
filter:
[
conjunction: 'And',
group:
[[
conjunction: 'And',
upperCaseCompare: false,
item:
[[
conjunction: 'And',
upperCaseCompare: false,
attribute: 'PlannedStartDt',
operator: 'AFTER',
value:
[[
item: targetDate1,
]],
]],
]],
],
findAttribute:
12
[
[item: 'ActivityId'],
[item: 'ActivityName'],
[item: 'ActivityDescription'],
[item: 'PlannedStartDt'],
[item: 'PlannedEndDt']
]
]

def findControl =
[
retrieveAllTranslations :false,
]

try
{
def appointments = adf.webServices.ActivityAppointmentService.findAppointment(findCriteria,
findControl);
for (appointment in appointments)
{
println('ActivityId : ' + appointment.get('ActivityId'));
println('ActivityName : ' + appointment.get('ActivityName'));
println('ActivityDescription : ' + appointment.get('ActivityDescription'));
println('PlannedStartDt : ' + appointment.get('PlannedStartDt'));
println('PlannedEndDt : ' + appointment.get('PlannedEndDt'));
}
}
catch(ex)
{
//println('ERROR : ' + ex.getClass().getName() + ' Message:' + ex.getMessage());
println('ERROR : ' + ex.getMessage());
}

println('***** Find appointments (Opportunity - Object Functions) END ***** ' + now());

Web Services: More on the findAttribute element and parsing responses


Obj Function assigned to a button on the UI.
println('***** Find leads test: ' + now());
def findCriteria =
[
fetchStart: 0,
fetchSize: -1,
excludeAttribute: false,
filter:
[
conjunction: 'And',
group:
[[
conjunction: 'And',
upperCaseCompare: false,
item:
[[
conjunction: 'And',
upperCaseCompare: false,
attribute: 'OwnerId',
operator: '=',
value:
[[
item: OwnerResourcePartyId,
]],
]],
]],

13
],
findAttribute:
[
[item: 'LeadId'],
[item: 'Description'],
]
]

def findControl =
[
retrieveAllTranslations :false,
]

def leads = adf.webServices.SalesLeadService.findSalesLead(findCriteria, findControl)


def fin=''
def sz = leads.size()
for(lead in leads)
{
fin += lead.get('LeadId') + ' ';
}
def rst = 'Found '+sz+' Leads. They are: '+fin
setAttribute('LongGroovyOutput_c',rst)

Web Services: Parsing Responses Using An Iterator


This example creates a map using the current Opportunity OwnerResourceId matching the lead
OwnerId, and calls the web service. Then parses the response using an iterator to get each lead, then
inside that parse the lead for each value and output them as comma separated.
def findCriteria =
[filter:[group:[[item:[[attribute:'OwnerId',operator:'=',value:[[item:OwnerResourcePartyId]]]]]]]
]
def findControl = []
def custs = adf.webServices.SalesLeadService.findSalesLead(findCriteria, findControl)
Iterator<String> iterator = custs.iterator();
def leadCount = 0
while (iterator.hasNext()) {
leadCount++
println('Lead '+ leadCount + ' is ')
println(iterator.next())
def nElements = 0;
def s = '';
for (element in iterator.next() ){
nElements++;
s = s + ',' + element.value;
}
println('Lead ' + leadCount+' has ' + nElements +' total elements inside');
println('Lead ' + leadCount+' values are ' + 'values: ' + s);
}
def total = (custs.size())
//output value into field
setAttribute('GroovyOutput_c',total)

Web Services: Parsing Response Using a String


Not the recommended way, but can be useful method for testing.
def findCriteria =
[filter:[group:[[item:[[attribute:'SalesAccountId',operator:'=',value:[[item:SalesAccountId]]]]]]
]]
println(findCriteria)

14
def findControl = []
def custs = adf.webServices.CustomerDataService.findSalesAccount(findCriteria, findControl)
println(custs)
def output = custs.toString()
def trn = output.indexOf(", PostalCode=")
def finx = trn + 10
def repo = output.substring(finx)
println(repo)

Querying VO Rows: Using the findbyKey function


How to check a user’s date of birth by findbyKey on the PersonProfile view object
def partyVO = newView('PersonProfile')
def partyRow = partyVO.findByKey(key(CustomerPartyId),1)
def found = partyRow.size() == 1 ? partyRow[0] : null;
if (found != null) {
msg += "DoB: ${partyRow.DateOfBirth}\n"
}

Querying VO Rows: Using multiple where criteria’s


You can apply two conditions in your query by defining two rows in the ViewCriteria, as below for
Opportunities for NAME starts with A and equals AMMM
def vo = newView('OpportunityVO');
def vc = vo.createViewCriteria();
def vcRow = vc.createViewCriteriaRow();
def vcRow1 = vc.createViewCriteriaRow();
def vc1 = vcRow.ensureCriteriaItem("Name");
vc1.setOperator("STARTSWITH");
vc1.setValue("A");
def vc2 = vcRow1.ensureCriteriaItem("Name");
vc2.setOperator("=");
vc2.setValue("AMMM");
vcRow.setConjunction(1);
vc.insertRow(vcRow);
vc.insertRow(vcRow1);
vo.applyViewCriteria(vc);
vo.executeQuery();
while(vo.hasNext()){
def row = vo.next()
println(row.getAttribute('Name'))
}

Querying VO Rows: Referencing Child Objects

Reference your child objects using a collection name, specified upon its creation. This example
uses is CollateralCollection collection name for the Collateral child custom object.
double result = 0;
def iterator = CollateralCollection__c
if (iterator != null) {
while (iterator.hasNext()) {
// define a variable to hold the child (Collateral) in the iterator
def child = rs.next();
result += ((Number)child.Amount__c).doubleValue()
}

15
}
return new BigDecimal(result);

Querying VO Rows: Product Items from Opportunity Revenue


An example of getting regularly requested data from opportunities.
println("[Before Insert Trigger - CheckProductItem] Start")
def oProductItem = nvl(Item, "NO_OBJ")
println("[Before Insert Trigger - CheckProductItem] The Item object is
${oProductItem}")
if ( oProductItem != "NO_OBJ"){
while( oProductItem.hasNext()){
def oItemRec = oProductItem.next()
println("[Before Insert Trigger - CheckProductItem] The Item Record is ${oItemRec}")
def sItmDesc = nvl(oItemRec.getAttribute('Description'),"N")
println("[Before Insert Trigger - CheckProductItem] The Item Description is ${sItmDesc}")
}
}
println("[Before Insert Trigger - CheckProductItem] End")

Querying VO Rows: Using a Global Function


This is taken from a global function that defines a new view criteria with one view criteria row having a
view criteria item for each map entry in the 'fieldsToFilter' input parameter. The function has
parameters = vo (Type=Object) and fieldsToFilter (Type=Map)
def criteria = vo.createViewCriteria()
def criteriaRow = criteria.createRow()
criteria.insertRow(criteriaRow)
for (curField in fieldsToFilter?.keySet()) {
def filterValue = fieldsToFilter[curField]
// if the value to filter on is a List then
if (filterValue instanceof List) {
adf.util.addMultiValueCriteriaItem(criteriaRow,curField,filterValue,true)
} else {
def criteriaItem = criteriaRow.ensureCriteriaItem(curField)
if (filterValue != null){
criteriaItem.setValue(filterValue)
}else {
criteriaItem.setOperator('ISBLANK')
}
}
}
vo.appendViewCriteria(criteria)

Here is a usage example of the same, calling O_INT_ApplyFilter as the global function name.
try{
def searchParams = [:]
searchParams.put('PartyId', OrganizationProfile_c.PartyId)
def salesAccountVO = newView('SalesAccountVO')
adf.util.O_INT_ApplyFilter(salesAccountVO, searchParams)
salesAccountVO.executeQuery()
if (salesAccountVO.hasNext()) {
return salesAccountVO.next()
}
16
}catch (e){
def message = adf.util.O_INT_GetLogMsg('0086', 'Cannot find the Sales Account by searching
Account PartyId')
throw new oracle.jbo.ValidationException(message)
}

Querying VO Rows: Accessing Parent Object Fields


References the parent using the dot notation (i.e. accRecords1?.ParentParty?.PartyUniqueName).
if(PrimaryCustomerId!=null){
def account = newView('SalesAccountVO')
def vc = account.createViewCriteria()
def vcr = vc.createRow()
def vci1 = vcr.ensureCriteriaItem('PartyId')
vci1.setOperator('=')
vci1.setValue(PrimaryCustomerId)
vc.insertRow(vcr)
account.appendViewCriteria(vc)
account.executeQuery()
while(account.hasNext()){
def accRecords1 = account?.next()
def pname1=accRecords1?.ParentParty?.PartyUniqueName
setAttribute('PrimaryAddressLine1',accRecords1?.Address1)
setAttribute('PrimaryAddressLine2',accRecords1?.Address2)
setAttribute('PrimaryAddressCity',accRecords1?.City)
setAttribute('PrimaryAddressState',accRecords1?.State)
setAttribute('PrimaryAddressPostalCode',accRecords1?.PostalCode)
}

Querying VO Rows: Get Appointments Object


Note: From Release 9 the Activities Object/Service should be used.
def i=1;
def vo = newView('AppointmentVO')
def vc = vo.createViewCriteria()
def vcr = vc.createRow()
def vci = vcr.ensureCriteriaItem('SourceObjectId')
vci.setOperator('=')
vci.setValue(OptyId)
vc.insertRow(vcr)
vo.appendViewCriteria(vc)
vo.executeQuery()
while(vo.hasNext())
{
def CO = vo.next()
def AN = CO.getAttribute('ActivityName')
println("Appointment${i}:${AN}")
i=i+1
}

17
Inserting VO Rows: Interactions
Following is an example of Groovy Script that you can write on “Before Update in Database” trigger, to
create an Interaction when the Opportunity status is set to Won. From Release 9 the API changed to the
Activities service.
if(isAttributeChanged('StatusCode') && nvl(StatusCode,'') == 'WON') {
def interVO = newView('InteractionVO')
def newinter = interVO.createRow()
newinter.setAttribute('InteractionDescription', 'Interaction description goes here..')
newinter.setAttribute('InteractionStartDate', today())
interVO.insertRow(newinter)
def interassocVO = newinter.InteractionAssociation
def newinterassoc = interassocVO.createRow()
newinterassoc.setAttribute("AssociatedObjectCode", "OPPORTUNITY")
newinterassoc.setAttribute("AssociatedObjectUid", OptyId)
interassocVO.insertRow(newinterassoc)
}
Another example using an interaction.
def opptyUpdatedName = Name
def opptyOwnerId = OwnerResourcePartyId
def voInteraction = newView('InteractionVO')
def voIntAssociation = newView('InteractionAssociationVO')

def createInt = voInteraction.createRow()


def createIntAssc = voIntAssociation.createRow()

//Corrected voInteraction to vorAppointment


def currentDateTime = now()
def interactionName = 'OptyNameModifed' + currentDateTime

//createInt.setAttribute('Subject_c', interactionName)
createInt.setAttribute('InteractionStartDate', currentDateTime)
createInt.setAttribute('InteractionEndDate', currentDateTime)
createInt.setAttribute('OwnerId',opptyOwnerId)
createInt.setAttribute('CustomerId',TargetPartyId)

createIntAssc.setAttribute('AssociatedObjectUid',OptyId )
createIntAssc.setAttribute('AssociatedObjectCode','OPPORTUNITY')

voInteraction.setAttribute('voInteraction.voIntAssociation',createIntAssc)
voInteraction.insertRow(createInt)

Inserting VO Rows: Creating an Activity


The following is the release 9 equivalent for creating a task associated with an Object in Sales (an
appointment on a Lead).
def voActivity = newView("ActivityVO");
def rowActivity = voActivity.createRow();
def startTime = dateTime(year(now()),month(now()),day(now()),10,0);
def endTime = dateTime(year(now()),month(now()),day(now()),11,0);
rowActivity.setAttribute("Subject", "Appointment for " + Name + " ");
rowActivity.setAttribute('SourceObjectId',LeadId);
rowActivity.setAttribute('SourceObjectCd','LEAD');
18
rowActivity.setAttribute("ActivityFunctionCode", "APPOINTMENT");
rowActivity.setAttribute("ActivityTypeCode", "CALL");
rowActivity.setAttribute("ActivityStartDate", startTime);
rowActivity.setAttribute("ActivityEndDate", endTime);
voActivity.insertRow(rowActivity);

Inserting VO Rows: Custom Objects


Custom object is Book_c and this is an Opportunity object function put on a button.
def oName = Name
def voBook = newView('Book_c')
def createBook = voBook.createRow()
def currentDateTime = now()
def bookname = 'The Story of '+ oName
createBook.setAttribute('RecordName', bookname)
voBook.insertRow(createBook)

Error Handling: Exception Details


Simple example of a VO query on a revenue custom field, printing any resulting error stack to the log
messages screen.
try{
if(nvl(ITC_Trigger_c, 'N') == 'Y'){
setAttribute('ITC_Trigger_c', 'N')
def revenueItemVO = nvl(ChildRevenue, 0)
def revenueItem = null
def i = 0
while(revenueItemVO?.hasNext()){
revenueItem = revenueItemVO?.next()
println("${i} &#20633;&#32771;:" + revenueItem?.getAttribute('ITC_Description_c'))
i++
revenueItem?.setAttribute('ITC_Description_c', "Updated from ITC_UpdateDesc")
}
}
} catch(e) {
println("Exception = " + e.getMessage())
if(e instanceof oracle.jbo.JboException){
if(e.getDetails() != null){
for(Object detailEx: e.getDetails()){
println("Detail exception:")
println(detailEx.getMessage())
}
}
}
}

Error Handling: JBOExceptions and JBOWarnings


You can use the following methods when details with Oracle.jbo.jboexception or oracle.jbo.jbowarning
objects, using similar example given above:

 getDetails()
 getErrorCode()
 getErrorParameters()
 getLocalizedMessage()
 getMessage()

19
Error Handling: ValidationException
Example of using the ValidationException manually.
if (ApprovalStatus__c != 'DRAFT')
{
setAttribute("ApprovalStatus__c","DRAFT")
}
else
{
throw new
oracle.jbo.ValidationException(adf.object.hints.ApprovalStatus__c.label +
"Approval cannot be submitted as this record already in an approval pending
status")
}

Error Handling: Assertion


Rather than causing a fatal NPE or similar error you can use assertion to check your variables.
assert i < 9999999999

Security: Accessing Context Data


Capturing the security context object data and getting the username from it.
def secCtx = adf.context.getSecurityContext()
def userNameStr = secCtx.userName

Security: VO Query for Person Resources Roles


Code to check roles assigned to a person (resource)
def resourceView = newView('Resource')
def vc = resourceView.createViewCriteria()
def vcr = vc.createRow()
def vci1 = vcr.ensureCriteriaItem('Username')
vci1.setOperator('=')
//userNameStr from above
vci1.setValue(nvl(userNameStr,''))
vc.insertRow(vcr)
resourceView.appendViewCriteria(vc)
resourceView.executeQuery()
def userRoles
if(resourceView.hasNext())
{
userRoles = resourceView.next().getAttribute('Roles')
println('userRoles ' + userRoles)
if (userRoles == 'Fastaff Administrator' && INTST == 'I')
{
def msg='You don\'t have enough privileges to delete Sales Account. Please contact the
Administrator.'
throw new oracle.jbo.ValidationException(msg)
}
}

20
Security: More VO Query for Person Resources Roles
Another example of looking up roles.
def vo = newView('Resource');
def vc = vo.createViewCriteria()
def vcr = vc.createRow()
def vci1 = vcr.ensureCriteriaItem('PartyId')
vci1.setOperator('=')
vci1.setValue(adf.util.getUserPartyId())
vc.insertRow(vcr)
vo.appendViewCriteria(vc)
vo.executeQuery()
if(vo.hasNext()) {
def r = vo.next()
def x = r?.Roles.toString()
if (x == 'Operation Executive' || x == 'Operation Supervisor' || x == 'Country Operation
Manager' || x == 'Operation Supervisor' || x == 'Sales Administrator') {
return true
}
else {
return false
}
}
else {
return false
}

21

You might also like