Upload
hoangngoc
View
243
Download
0
Embed Size (px)
Citation preview
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
2
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
3
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
4
Security: More VO Query for Person Resources Roles ........................................................................... 21
5
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
6
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()
= [email protected] (login username)
adf.context.getSecurityContext()?.getUserProfile()?.getFirstName()
= Richard
adf.context.getSecurityContext()?.getUserProfile()?.getGUID()
= DBE25B1925AA9356E0401790938C507A
adf.context.getSecurityContext()?.getUserProfile()?.getPrincipal()
= [LDUserPrincipal]: [email protected]
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)
7
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'));
8
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;
9
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()
10
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
11
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',
12
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:
13
[
[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,
]],
]],
]],
14
],
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)
15
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()
}
16
}
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()
}
17
}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 }
18
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');
19
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} 備考:" + 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()
20
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)
}
}
21
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
}