Groovy Code Samples. Reusable sample code to help with common use-cases. Read: blogs.oracle.com/fadevrel

Similar documents
Oracle ADF 11g: New Declarative Validation, List of Values, and Search Features. Steve Muench Consulting Product Manager Oracle ADF Development Team

it is

An Oracle White Paper March Introduction to Groovy Support in JDeveloper and Oracle ADF 11g

How To use REST API inside Sales Cloud

<Insert Picture Here> How to Debug Oracle ADF Framework Applications

Oracle Eloqua and Salesforce

Oracle Fusion Middleware 11g: Build Applications with ADF Accel

ADF Code Corner How-to restrict the list of values retrieved by a model driven LOV. Abstract: twitter.com/adfcodecorner

Oracle. Sales Cloud Using Customer Data Management. Release 12

ADF Code Corner How-to enforce LOV Query Filtering. Abstract: twitter.com/adfcodecorner

An Oracle White Paper September 2014 (updated) Use of Oracle Business Rules (OBR) to Tailor Order Fulfillment for DOO

Oracle. Sales Cloud Integrating with Oracle Marketing Cloud. Release 13 (update 18B)

Oracle 1Z Oracle Eloqua Marketing Cloud Service 2017 Implementation Essentials.

ADF Mobile Code Corner

11i Extend Oracle Applications: Building OA Framework Applications Student Guide

Product Release Notes

Quick Start Guide (CM)

Accessing the Progress OpenEdge AppServer. From Progress Rollbase. Using Object Script

Teamcenter 11.1 Systems Engineering and Requirements Management

Composer Help. Web Request Common Block

Product Release Notes

1z0-412.oracle. ORACLE 1z Oracle Eloqua and Oracle Content Marketing Cloud Service 2013 Implementation Essentials

IBM Kenexa BrassRing on Cloud. Rules Automation Manager Guide

ADF Code Corner How-to bind custom declarative components to ADF. Abstract: twitter.com/adfcodecorner

Oracle. Sales Cloud Getting Started with Extending Sales. Release 13 (update 17D)

ADF Mobile Code Corner

Kick Off Meeting. OMi Management Pack Development Workshop. 23rd May 2016

Oracle. Sales Cloud Using Customer Data Management. Release 13 (update 17D)

Real Application Security Administration

Zoho Integration. Installation Manual Release. 1 P a g e

Oracle Middleware 12c: Build Rich Client Applications with ADF Ed 1 LVC

Oracle Eloqua Campaigns

PowerLink CRM User Guide

ADF Code Corner How-to further filter detail queries based on a condition in the parent view using ADF BC. Abstract: twitter.

Documentation for the new Self Admin

The NoPlsql and Thick Database Paradigms

Aim behind client server architecture Characteristics of client and server Types of architectures

Application Express Dynamic Duo

Building Extendable Oracle ADF Applications with Embedded Mule ESB. Miroslav Samoilenko. January 2008

Oracle JDeveloper/Oracle ADF 11g Production Project Experience

<Insert Picture Here> The Latest E-Business Suite R12.x OA Framework Rich User Interface Enhancements

ADF Code Corner. Oracle JDeveloper OTN Harvest 02 / Abstract: twitter.com/adfcodecorner

Pricing Cloud: Upgrading to R13 - Manual Price Adjustments from the R11/R12 Price Override Solution O R A C L E W H I T E P A P E R A P R I L

1Z0-560 Oracle Unified Business Process Management Suite 11g Essentials

Go to /Jdevbin/jdev/bin Double click on Jdevw.exe

The Salesforce Migration Playbook

GIFT Department of Computing Science Data Selection and Filtering using the SELECT Statement

EnterSpace Data Sheet

Oracle Fusion Middleware 11g: Build Applications with ADF I

Different color bars chart with Popup Box in ADF

Getting Your Data out of Salesforce Leveraging Your Salesforce Data in ZoomInfo Shipping Data Back to Salesforce

Contents Getting Started... 3 About Scribe Online and Connectors... 3 Scribe Online Services... 3 CDK Components... 3 Audience... 4 Prerequisites...

Oracle. SCM Cloud Configurator Modeling Guide. Release 13 (update 17D)

Learning Objectives. Description. Your AU Expert(s) Trent Earley Behlen Mfg. Co. Shane Wemhoff Behlen Mfg. Co.

CLASS DESIGN. Objectives MODULE 4

Administrator Preview Guide. Release 34 February 2017 VERSION

TABLE OF CONTENTS DOCUMENT HISTORY

MyClinic. Password Reset Guide

Fast Track Model Based Design and Development with Oracle9i Designer. An Oracle White Paper August 2002

5/31/18 AGENDA AIS OVERVIEW APPLICATION INTERFACE SERVICES. REST and JSON Example AIS EXPLAINED. Using AIS you can perform actions such as:

ADF Mobile Code Corner

Oracle Database. Installation and Configuration of Real Application Security Administration (RASADM) Prerequisites

Using Page Composer with Fusion Cloud Applications

J2EE Development Best Practices: Improving Code Quality

Certification Exam Guide SALESFORCE CERTIFIED A DVANCED ADMINISTRATOR. Winter Salesforce.com, inc. All rights reserved.

Programming Assignment Comma Separated Values Reader Page 1

How-to Build Card Layout Responses from Custom Components

Oracle BI 11g R1: Build Repositories Course OR102; 5 Days, Instructor-led

Actual4Test. Actual4test - actual test exam dumps-pass for IT exams

Oracle Big Data Cloud Service, Oracle Storage Cloud Service, Oracle Database Cloud Service

Oracle. Sales Cloud Understanding Import and Export Management. Release 13 (update 18B)

Unit 2 - Data Modeling. Pratian Technologies (India) Pvt. Ltd.

Oracle Policy Automation The modern enterprise advice platform

IBM WebSphere Adapter for Oracle E-Business Suite Quick Start Tutorials

HP Service Manager. Software Version: 9.40 For the supported Windows and Unix operating systems. Knowledge Management help topics for printing

Different color bar chart with popup box in ADF

Java SE 8 Programmer I and II Syballus( Paper codes : 1z0-808 & 1z0-809)

Integration Guide. LoginTC

Oracle. Loyalty Cloud Extending Loyalty. Release 13 (update 18B)

Early Learning SF User Guide for Programs

Oracle Interaction Center Intelligence

Oracle Revenue Management and Billing. File Upload Interface (FUI) - User Guide. Version Revision 1.1

Oracle EBS Adapter Sample Outbound processing

Anaplan Connector Guide Document Version 2.1 (updated 14-MAR-2017) Document Version 2.1

Enterprise Java Unit 1- Chapter 6 Prof. Sujata Rizal

BMC Remedy Action Request System Using a BIRT Editor to Create or Modify Web Reports

Oracle Fusion Middleware 11g: Build Applications with ADF I

Oracle BI 12c: Build Repositories

34: Customer Relationship Management (CRM)

GEL Scripts Advanced. Your Guides: Ben Rimmasch, Yogesh Renapure

Build Mobile Cloud Apps Effectively Using Oracle Mobile Cloud Services (MCS)

Technosoft HR Recruitment Workflow Developers Manual

Opaali Portal Quick guide

ADF Code Corner. 65. Active Data Service Sample Twitter Client. Abstract: twitter.com/adfcodecorner

Procedures Oracle FLEXCUBE Universal Banking Release 12.0 [May] [2012] Oracle Part Number E

Oracle Enterprise Data Quality New Features Overview

Modules and Features

11G ORACLE DEVELOPERS Training Program

API Documentation for PHP Clients

Enhanced Class Design -- Introduction

Transcription:

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 > dobcalendar.month) age = today()calendar.year-dobcalendar.year else if(today()calendar.month == dobcalendar.month && today()calendar.date >= dobcalendar.date) age = today()calendar.year-dobcalendar.year Else age = today()calendar.year-dobcalendar.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-crmext.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=map0.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? partyrow0 : 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 = fieldstofiltercurfield // 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 備考:" + 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