OAF - Oracle Application
OAF - Oracle Application
Personalizations ................................................................................... 44
Poziom administratora.......................................................................................................... 44
Poziom uytkownika ............................................................................................................ 45
Wybr kontekstu personalizacji ........................................................................................... 45
LOV ..................................................................................................... 45
Create LOV .......................................................................................................................... 45
Advanced: LOV with a custom query .............................................................................. 46
Assign LOV to field ............................................................................................................. 47
Assign LOV to field - personalization ............................................................................. 51
Assign search region do result table ................................................................................. 52
LOV hierarchical (dependent LOVs) ................................................................................ 53
LOV hierarchical hide dependent LOV ......................................................................... 54
2
Naming convensions
Jesli dodajemy cokolwiek, np. klasy java, kontrolery, modu aplikacyjny, widoki, na pocztku
dodajemy kod klienta np. pzu.
jdev
Programujemy w jdeveloper
Istotna jest wersja narzedzia
Do EBS 11 trzeba uywa jdevelopera 9.
Do EBS 12 trzeba uywa jdevelopera 10.
Do jdev trzeba pobra rozszerzenie: Oracle Application Extensions. How to do it:
1/ go to Oracle Metalink:
How to find the correct version of JDeveloper to use with eBusiness Suite 11i or Release 12.x
[ID 416708.1]
2/ unzip file and configure jdev ( go to jdev documentation in .zip, in short: set env variable
and .dbc file ).
Note: after downloading .dbc file erase from it "/" chars if any in connection string
Oaf forms consists of two elements:
- Layout (xml files)
- java code
Layout is kept in database- you can get it:
- using jdr_utils.printDocument ( parameter for this function is to be get from
personalization form)
- XMLExporter java utility
Java code is kept in $java_top on the app server.
To see changes you must compile java code and bouce apache.
Architektura MVC (DB-entity object-view object-application module-OA controller)
MVC to standard otwarty, nie Oraclowy
Model = baza danych
View = strona
Controller = przepyw informacji
Package jdr_utils
Strony s zapisane w bazie, mog by na serwerze ale tylko jako kopia, tworzone przez nas
dodawne s i do bazy i na serwer.
begin
dbms_output.put_line('*START');
Jdr_utils.listcustomizations('/oracle/apps/per/irc/vacancy/webui/VacSrchPG');
dbms_output.put_line('*STOP');
end;
Jdr_utils.PrintDocument
exec
jdr_utils.DeleteDocument('/oracle/apps/eam/workorder/webui/customizations/s
ite/0/EAM_EW_START_PAGE')
- kasuje personalizacj
Przenoszenie personalizacji
1. Za pomoc funkcji
XMLImporter - podajemy plik XML personalizacji. Ktrego formularza personalizacja
dotyczy jest zapisane w tym pliku XML
XMLExporter
2. albo za pomoc funkcji w aplikacji
2.
3.
4.
5.
6.
Deployment
There is no one-button-click procedure. Do this:
Copy XMLs (Pages, VOs, COs, AMs, ..) and .class files to the server
Copy exact catalog tree from myclasses to $JAVA_TOP on the server
(all files: XMLs and .class files)
Building forms
Sample form
10
General remarks
Top-level-region has to have reference to Application Module.
Top-level-region or any region on page can have controller code.
11
Database table has to have standard EBS who columns. There is nothing to do, framework
will populate it by default.
Inse
rt
Before
(code in controller.processRequest)
In controller:
OAApplicationModule am =
pageContext.getApplicationModule(webBean);
am.invokeMethod("createMove", null);
???TransactionUnitHelper.endTransactionUnit(page
Context, "MoveCreateTxn");
??? TransactionUnitHelper.endTransactionUnit(pageContext,
"MoveCreateTxn");
Go to search page:
pageContext.forwardImmediately("OA.jsp?page=/pzu/oracle/ap
ps/eam/zn_008_move/webui/MoveSearchPG",
null,
in am:
public void createMove()
{
OAViewObject vo =
(OAViewObject)getXxex008HeadersFullVO1();
int maxFetch = vo.getMaxFetchSize();
vo.setMaxFetchSize(0);
vo.executeQuery();
vo.setMaxFetchSize( maxFetch );
Row row = vo.createRow();
vo.insertRow(row);
pageContext.forwardImmediately("OA.jsp?page=/p
zu/oracle/apps/eam/zn_008_move/webui/MovePG
&MoveId="+moveId,
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null, null, true,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null, null, true,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
OAWebBeanConstants.ADD_BREAD_CRUMB_N
O);
row.setAttribute("FileFormat", "IGNORE" );
row.setNewRowState(Row.STATUS_INITIALIZED
);
}
Up
date
In controller:
Same an insert
Same an insert
W controlerze:
else if (pageContext.getParameter("Delete") != null)
{
am.invokeMethod("deleteSelectedCemliLines");
No code
OAApplicationModule am =
pageContext.getApplicationModule(webBean);
TransactionUnitHelper.startTransactionUnit(pageCon
text, "moveCreateTxn");
Serializable[] parameters = { MoveId };
am.invokeMethod("initDetails", parameters);
in am:
public void initDetails(String MoveId)
{
Xxex008HeadersFullVOImpl vo =
getXxex008HeadersFullVO1();
if (vo == null)
{
MessageToken[] errTokens = { new
MessageToken("OBJECT_NAME",
"getXxex008HeadersFullVO1")};
throw new OAException("AK",
"FWK_TBX_OBJECT_NOT_FOUND", errTokens);
}
vo.initQuery( MoveId );
vo.first();
}
Del
ete
In vo:
public void initQuery(String MoveId)
{
setWhereClause("MOVE_ID = :1");
setWhereClauseParams(null); // Always reset
Number nMoveId = null;
try {
nMoveId = new Number(MoveId);
} catch (SQLException e) {
OAException.wrapperException(e);
}
setWhereClauseParam(0, nMoveId );
executeQuery();
} // end initQuery()
Co code
You need checkbox column and button
w am:
public void deleteSelectedCemliLines() {
OAViewObjectImpl linesVO =
12
getCemliLinesVO();
Row lines[] =
linesVO.getFilteredRows("Checked", "Y");
if (lines != null)
for (int i = 0; i < lines.length; i++)
lines[i].remove();
} // END deleteSelectedCemliLines()
Tips:
- Make the same screen to insert/update (you can set form in insert/update mode based
on whether id is null or not)
- You need no code to refresh detail block on master-detalil form. It will happen
automatically. All you need is to build associations and VO-links
Dont be afraid of experimetantion- framework returns clear to understand run-time error
messages.
Framework forces appropriate XML structure.
But be aware it some traps
VO and page item Data types must always fit, or else you will obtain null value ( not cast
error )
VO attriute is Number =>
formValue has to be number
13
Adv query
Idea:
Application module -< VO -< item
Destination URI property on search item table:
OA.jsp?page=/pzu/oracle/apps/eam/zn_008_move/webui/MoveDetailsPG&MoveId={@MoveId}&retainAM=Y&addBreadCrumb=Y
Controller code
----------------import java.io.Serializable;
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
// Always call this first.
super.processRequest(pageContext, webBean);
// Get the employeeNumber parameter from the URL
String MoveId;
MoveId = pageContext.getParameter("MoveId");
// Now we want to initialize the query for our single employee
// with all of its details.
OAApplicationModule am = pageContext.getApplicationModule(webBean);
Serializable[] parameters = { MoveId };
am.invokeMethod("initDetails", parameters);
}
AM code (*Impl)
----------------public void initDetails(String MoveId)
{
Xxex008HeadersFullVOImpl vo = getXxex008HeadersFullVO1();
if (vo == null)
{
MessageToken[] errTokens = { new MessageToken("OBJECT_NAME", "getXxex008HeadersFullVO1")};
throw new OAException("AK", "FWK_TBX_OBJECT_NOT_FOUND", errTokens);
}
vo.initQuery( MoveId );
} // end initDetails()
VO Code (*Impl)
----------------public void initQuery(String MoveId)
{
setWhereClause("MOVE_ID = :1");
setWhereClauseParams(null); // Always reset
setWhereClauseParam(0, MoveId);
executeQuery();
14
} // end initQuery()
Attachments
Way 1:
It is trongly recommended to use standard attachemnts functionality.
This is very easy to use read standard documentation.
15
Way 2:
Create EO, create VO on EO.
You can modify SQL of VO, creation will still work !
package pzu.oracle.apps.eam.zn_008_move.webui;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.io.Serializable;
oracle.apps.fnd.common.VersionInfo;
oracle.apps.fnd.framework.OAApplicationModule;
oracle.apps.fnd.framework.OAException;
oracle.apps.fnd.framework.OAViewObject;
oracle.apps.fnd.framework.webui.OAControllerImpl;
oracle.apps.fnd.framework.webui.OADataBoundValueViewObject;
oracle.apps.fnd.framework.webui.OAPageContext;
oracle.apps.fnd.framework.webui.OAWebBeanConstants;
oracle.apps.fnd.framework.webui.beans.OAWebBean;
oracle.apps.fnd.framework.webui.beans.message.OAMessageFileUploadBean;
oracle.jbo.Row;
java.sql.Connection;
java.sql.PreparedStatement;
oracle.apps.fnd.common.MessageToken;
oracle.apps.fnd.framework.OAFwkConstants;
/**
* Controller for ...
*/
public class MoveUploadRegionCO extends OAControllerImpl
{
public static final String RCS_ID="$Header$";
public static final boolean RCS_ID_RECORDED =
VersionInfo.recordClassVersion(RCS_ID, "%packagename%");
private boolean isEmpty(String str) {
return str == null || str.length()==0;
}
/**
* Layout and page setup logic for a region.
* @param pageContext the current OA page context
16
/**
* Procedure to handle form submissions for form elements in
* a region.
* @param pageContext the current OA page context
* @param webBean the web bean corresponding to the region
*/
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
if (pageContext.getParameter("Cancel") != null) {
// Perform a rollback on the database
OAApplicationModule am = pageContext.getApplicationModule(webBean);
am.getTransaction().rollback();
}
else if (pageContext.getParameter("Apply") != null) {
// Set column FILE_FORMAT to IGNORE, this column is used for the online help index
String MoveId = pageContext.getParameter("MoveId");
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("FndLobsVO");
Row row = vo.getCurrentRow();
row.setAttribute("FileFormat", "X:" + MoveId );
//if ( isEmpty( (String)row.getAttribute("FileContentType") ) ) {
// row.setAttribute("FileContentType", "application/vnd.ms-excel");
//}
am.getTransaction().commit();
// Display upload confirmation message
oracle.jbo.domain.Number fileId = (oracle.jbo.domain.Number)vo.getCurrentRow().getAttribute("FileId");
//String fileName = (String)vo.getCurrentRow().getAttribute("FileName");
//OAException confirmMessage = new OAException( MoveId + "File "+fileName+ "uploaded succesfully with ID
"+fileId+".",OAException.CONFIRMATION);
//pageContext.putDialogMessage(confirmMessage);
try {
Connection conn =
pageContext.getApplicationModule(webBean).getOADBTransaction().getJdbcConnection();
String sql =
"UPDATE XXEX_008_HEADERS SET fnd_lobs_file_id = " + fileId.toString() +
" WHERE MOVE_ID = " + MoveId;
//(webBean.findChildRecursive("FndLobsFileId")).setValue(pageContext, fileId);
17
Source: http://robertjungerius.wordpress.com/2011/04/08/building-a-genericupload-page-in-oa-framework/
EmployeeEOImpl, add:
public void remove()
{ super.remove(); }
Implement deleteColumn
1/ Add to VO column DELETE_SWITCHER
2/ Add to region Switch with fireAction delete
3/ format deleteColumn in controller (center allign)
Implement deleteAction:
On AM (procedure delete)
On CO (show confirmation and onOK pressed)
18
You can also create non-database VO. How to create non-database VO ? Create VO without
SQL statement and without EO reference. Add attributes manually.
Master-detail
Simplest demo
1/ Create MasterEO and DetailEO.
2/ Create MasterVO and DetailVO
3/ Create association MasterEO DetailEO. Indicate master and data columns. Select
cardinality. Accept all default settings.
4/ Create view link MasterVO DetailVO. Select master and data columns too.
19
Incorrect !
20
That is all, no code to refresh details is required. You will see the result.
21
Preparing layout
Fundamentals
Most used form items:
messageStyledText
formValue
messageLOVText
Field text
Hidden field
Field text + LOV
.rendered = .visible
Menu
Each page is a SEPARATED page. In order to organize pages into tabs you have to build a
menu in apriopriate way. It is not difficult to do, glance on existing menu to find out more.
Tabs are not active ? Read this:
Po zdefinowaniu autoryzacji naley doda jej dostp do organizacji magazynowych (?!?)
(Tabela: org_access - (inaczej nie bd wywietlay si opcje - ze stronami OAF i by moe
Forms)
Naley to zrobi z aplikacji:
(A) Autoryzacja: Magazyn
(N) Opcja: Konfiguracja -> Organizacje -> Dostp do organizacji
Wycig dla przykadowej autoryzacji:
select o.name
, a.organization_code
, a.application_name
, a.responsibility_name
--, a.*
from org_access_v
a
22
, hr_all_organization_Units o
where responsibility_id IN (51222) --, 51059)
and a.organization_id = o.organization_id
Grid layout
Tab layout
Hide/show region
Header
Region style: header
Dialogbox
MessageBox (message box)
With fnd_new_messages
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.common.MessageToken;
String MoveNumber = (String)vo.getCurrentRow().getAttribute("MoveNumber");
23
QuestionBox
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
if (pageContext.getParameter("Create") != null)
{
pageContext.setForwardURL("OA.jsp?page=/pzu/oracle/apps/eam/zn_008_move/webui/MovePG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
true, // Retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_YES,
OAWebBeanConstants.IGNORE_MESSAGES);
}
else if ("delete".equals(pageContext.getParameter(EVENT_PARAM)))
{
String MoveNumber = pageContext.getParameter("MoveNumber");
String MoveId = pageContext.getParameter("MoveId");
// String MoveNumber = (String)vo.getCurrentRow().getAttribute("MoveNumber");
MessageToken[] tokens = { new MessageToken("NUMBER", MoveNumber) };
OAException mainMessage = new OAException("XXEX", "XXEX_008_MOVE_DEL_CONFIRM", tokens);
OADialogPage dialogPage = new OADialogPage(OAException.WARNING,
mainMessage, null, "", "");
String yes = pageContext.getMessage("AK", "FWK_TBX_T_YES", null);
String no = pageContext.getMessage("AK", "FWK_TBX_T_NO", null);
dialogPage.setOkButtonItemName("DeleteYesButton");
dialogPage.setOkButtonToPost(true);
dialogPage.setNoButtonToPost(true);
dialogPage.setPostToCallingPage(true);
dialogPage.setOkButtonLabel(yes);
dialogPage.setNoButtonLabel(no);
java.util.Hashtable formParams = new java.util.Hashtable(1);
formParams.put("MoveNumber", MoveNumber);
formParams.put("MoveId", MoveId);
24
dialogPage.setFormParameters(formParams);
pageContext.redirectToDialogPage(dialogPage);
}
else if (pageContext.getParameter("DeleteYesButton") != null)
{
String MoveNumber = pageContext.getParameter("MoveNumber");
String MoveId = pageContext.getParameter("MoveId");
Serializable[] parameters = { MoveId };
OAApplicationModule am = pageContext.getApplicationModule(webBean);
am.invokeMethod("deleteMove", parameters);
MessageToken[] tokens = { new MessageToken("NUMBER", MoveNumber) };
OAException message = new OAException("XXEX",
"XXEX_008_MOVE_DELETED", tokens, OAException.CONFIRMATION, null);
pageContext.putDialogMessage(message);
}
}
Approach 2 javascript:
javascript:if (confirm('Are you sure you want to?')) {
this.disabled=true; this.value='Submitted...';
doSubmit('OA.jsp?page=/XXX/oracle/apps/xxx/......&retainAM=Y');
}
Actions
When-button-pressed
Code on controller.
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
if (pageContext.getParameter("Go") != null)
{
String userContent = pageContext.getParameter("HelloName");
String message = "Hello, " + userContent + "!";
throw new OAException(message, OAException.INFORMATION);
}
}
Links
Way 1 image & action type
25
onFormRequest:
if ("delete".equals(pageContext.getParameter(EVENT_PARAM)))
OA.jsp?page=/pzu/oracle/apps/eam/zn_008_move/webui/MovePG&MoveId={@MoveId}&r
etainAM=Y&addBreadCrumb=Y
26
mainAMImpl am = (mainAMImpl)pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("Xxex008HeadersFullVO1");
String MoveId = vo.getCurrentRow().getAttribute("MoveId")+"";
"OA.jsp?page=/pzu/oracle/apps/eam/zn_008_move/webui/MoveSearchPG&MoveId="+MoveId
Or
pageContext.setForwardURL("OA.jsp?page=/pzu/oracle/apps/eam/zn_008_move/web
ui/MovePG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
true, // Retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_YES,
27
OAWebBeanConstants.IGNORE_MESSAGES);
setForwardURL does not break controller code immediately.
Code snippets
FND_NEW_MESSAGES
String sReturnMsg = oapagecontext.getMessage("XXSCM",
"XXSCM_MANDATORY_FIELD ", new MessageToken[] {new MessageToken("FIELD_NAME
", "PO Number") });
More:
http://imdjkoch.wordpress.com/tag/fnd_new_messages/
Serializable
See below
Set_where_clause
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject( "assetsVO" );
String lineSourceFloorId = "dummy1";
String lineSourceOfficeId = "dummy2" ;
Serializable params[] = { lineSourceFloorId, lineSourceOfficeId
Class paramTypes[] = { String.class, String.class };
vo.invokeMethod( "modifyWhereClause", params, paramTypes );
};
}
public class assetsVOImpl extends OAViewObjectImpl {
/**This is the default constructor (do not remove)
*/
public assetsVOImpl() {
}
public void modifyWhereClause( String lineSourceFloorId, String lineSourceOfficeId )
{
setWhereClauseParams(null); // Always reset
setWhereClause(
"instance_id in\n"+
"(\n"+
"select child_instance_id\n"+
" from xxex_008_hierarchy_v\n"+
" connect by prior child_instance_id = parent_instance_id\n"+
" start with parent_instance_id = nvl(:1, :2)\n"+
")"
);
setWhereClauseParam( 0, lineSourceFloorId );
setWhereClauseParam( 1, lineSourceOfficeId );
}
}
28
((OAViewObject)localObject1).setWhereClauseParams(localObject2);
((OAViewObject)localObject1).executeQuery();
((OAViewObject)localObject1).first();
if (((OAViewObject)localObject1).getCurrentRow().getAttribute("CurrencyCode") != null)
{
str5 = ((OAViewObject)localObject1).getCurrentRow().getAttribute("CurrencyCode").toString();
}
}
Set_item_value, get_item_value
page context:
String s12 = pageContext.getParameter("MoveNumber");
You can referer to form parameters only. You cannot referer to page elements this way !
Page elements:
((OAMessageDateFieldBean)paramOAWebBean.findChildRecursive("DateFromSS")).setValue(paramOAPage
Context, (String)null);
moveNumber = ((OAMessageTextInputBean)webBean.findChildRecursive("MoveNumber")).getValue(pageContext);
fileNumber = (String)((OAFormValueBean)webBean.findChildRecursive("FndLobsFileId")).getValue(pageContext);
in general:
(OAMessageDateFieldBean):
OA<item style here>Bean, for example
OAMessageTextInputBean
OAFormValueBean
OAMessageDateFieldBean
From VO:
import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.OAViewObject;
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("DebugLabEmpFullVO1");
String MoveNumber = (String)vo.getCurrentRow().getAttribute("MoveNumber");
java.sql.Date MoveDate = (oracle.jbo.domain.Date)vo.getCurrentRow().getAttribute("MoveDate")
.dateValue();
Set_item_property, get_item_property
Way 1 CO code
Read-only field:
webBean.findIndexedChildRecursive("MoveNumber").setAttributeValue(READ_ONLY_ATTR, new
Boolean(true));
disabled button:
webBean.findChildRecursive("Create").setAttributeValue(DISABLED_ATTR, new Boolean(true));
NULLPointerException ?
findIndexedChildRecursive returns NULL => use
findChildRecursive instead of findIndexedChildRecursive
Example:
29
30
IsNotActive is database column. We cannot use it directly since SPEL requires Boolean
string, bo String value. So we created Boolean attribute called BIsNotActive.
31
More:
http://oracle.anilpassi.com/spel-in-oa-framework-with-audio-visual-demo.html
OAMessageLovInputBean taskDsp =
(OAMessageLovInputBean)webBean.findChildRecursive("TaskDsp");
taskDsp.setAttributeValue( READ_ONLY_ATTR,
new NotBoundValue( new StringExistsBoundValue( new OADataBoundValueViewObject(
taskDsp, "ProjectDsp" ) ) ) );
32
Set focus
http://robertjungerius.blogspot.com
In OAF it is easy to set the focus to the first input field so the user can start typing and does
not need the mouse.
Add the following to processRequest:
import oracle.apps.fnd.framework.webui.beans.OABodyBean;
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
// Set focus on the first search item segment1
OABodyBean oabean = (OABodyBean)pageContext.getRootWebBean();
oabean.setInitialFocusId("Segment1");
}
from:
http://mukx.blogspot.com/2007/07/javascript-in-oa-framework.html
33
from:
http://mukx.blogspot.com/2007/07/javascript-in-oa-framework.html
Validations
Simple example dependences inside record
Desired effect:
Code:
34
Code:
Solution:
35
Most tables in EBS have a unique identifier which can be generated using a database sequence.
For custom tables i also use the same approach.
In Oracle Forms this is relatively easy to achieve, how about OA Framework ?
If you use an EO (Entity Object) then it is also very easy to achieve, just put the code in the setter
method of the required column:
public void setFileId(Number value) {
if (value == null) {
OADBTransaction t = getOADBTransaction();
value = t.getSequenceValue("<sequence_name>");
}
setAttributeInternal(FILEID, value);
}
If you need to do it in the PR of PFR then use:
OAApplicationModule ap = pageContext.getApplicationModule(webBean);
// Assign a new sequence value to a row attribute for example
row.setAttribute("FileId",ap.getSequenceValue("<sequence_name>"));
36
if (rgnBean != null)
setRegionKidsReadOnly(rgnBean);
rgnBean = webBean.findIndexedChildRecursive("WntLayout");
if (rgnBean != null)
setRegionKidsReadOnly(rgnBean);
}
protected void setRegionKidsReadOnly(OAWebBean rgnBean)
{
int i = rgnBean.getIndexedChildCount();
for(int j = 0; j <= i - 1; j++)
{
OAWebBean itemBean = (OAWebBean)rgnBean.getIndexedChild(j);
itemBean.setAttributeValue(READ_ONLY_ATTR, new Boolean(true));
setRegionKidsReadOnly( itemBean );
}
}
Hide a Button
OASubmitButtonBean saveT = (OASubmitButtonBean)webBean.findChildRecursive("Save1");
saveT.setRendered(true);
Disable a Button
OASubmitButtonBean saveT = (OASubmitButtonBean)webBean.findChildRecursive("Save1");
saveT.setDisabled(true);
37
In controller:
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
// mainAMImpl your AM class name here
mainAMImpl tmp = (mainAMImpl)pageContext.getApplicationModule(webBean);
if ( tmp.getReadOnlyFormFlag().equals("Y") ) {
webBean.findChildRecursive("Create").setAttributeValue(DISABLED_ATTR, new Boolean(true));
};
}
Breadcrums
OABreadCrumbsBean oabreadcrumbsbean =
(OABreadCrumbsBean)oapagecontext.getPageLayoutBean().getBreadCrumbsLocator(
);
if(oabreadcrumbsbean != null)
{
oabreadcrumbsbean.removeAllLinks(oapagecontext);
int j = oabreadcrumbsbean.getLinkCount();
38
if(j > 1)
oabreadcrumbsbean.removeLink(oapagecontext, 1);
}
Menu in OAF
=>
It is achieved by menu i special spell in function definition:
Special spell
39
40
OA.jsp?page=/oracle/apps/eam/workorder/webui/EAM_EW_START_PAGE&akRegionAppl
icationId=426&OAPB=EAM_BRAND_NAME&OAHP=EAM_MAIN_SS&eAMReleaseSea
rch=Y&eAMRequestsSearch=Y
try {
Connection conn =
pageContext.getApplicationModule(webBean).getOADBTransaction().getJdbcConnection();
// Update FND_LOBS ProgramName column
String sql =
"UPDATE fnd_lobs SET Program_Name = 'XXXXXX_" + appListSelectedValue +
"' WHERE FILE_ID = " + fileId.toString();
PreparedStatement updateFndLobs = conn.prepareStatement(sql);
int rs = updateFndLobs.executeUpdate();
} catch (java.sql.SQLException e) {
OAException sqlErrorMessage =
new OAException("SQL Error: " + e.getMessage(),
OAException.ERROR);
pageContext.putDialogMessage(sqlErrorMessage);
}
OASubmitButtonBean oasb =
(OASubmitButtonBean)pageContext.getWebBeanFactory().createWebBean(pageContext,
"BUTTON_SUBMIT");
oasb.setID("xxCustomButton");
oasb.setUINodeName("xxCustomButton");
oasb.setEvent("xxCustomButton");
41
Sysdate
row.setAttribute("UploadDate", am.getOADBTransaction().getCurrentDBDate());
Integration
Run Oracle Forms from OAF
42
ProgramApplication -Application Short name of application under which the program is registered.
ProgramName - Concurrent Program Name for which the request has to be submitted
ProgramDescription - Concurrent Program Description
StartTime - Time at which the request has to start running.
SubRequest - Set to TRUE if the request is submitted from another running request and has to be treated as a sub request.
Parameters - Parameters of the concurrent Request
Here is the example for calling a concurrent program from a OA framework page.
import oracle.apps.fnd.cp.request.ConcurrentRequest;
import oracle.apps.fnd.framework.server.OADBTransaction;
public int submitCPRequest(Number headerId) {
try {
OADBTransaction tx = (OADBTransaction)getDBTransaction();
java.sql.Connection pConncection = tx.getJdbcConnection();
ConcurrentRequest cr = new ConcurrentRequest(pConncection);
String applnName = "PO"; //Application that contains the concurrent program
String cpName = "POXXXX"; //Concurrent program name
String cpDesc = "Concurrent Program Description"; // concurrent Program description
// Pass the Arguments using vector
// Here i have added my parameter headerId to the vector and passed the vector to the concurrent program
Vector cpArgs = new Vector();
cpArgs.addElement(headerId.stringValue());
43
tx.commit();
return requestId;
} catch (RequestSubmissionException e) {
OAException oe = new OAException(e.getMessage());
oe.setApplicationModule(this);
throw oe;
}
}
You can call the Request Monitoring page by calling following URL
OA.jsp?akRegionCode=FNDCPREQUESTVIEWREGION&akRegionApplicationId=0
Personalizations
S dwa tryby wprowadzania personalizacji:
Administratora
Uytkownika
Poziom administratora
Link Informacje na temat strony na dole strony: tutaj mona odczyta z drzewa nazw
widoku VO
Link Strona personalizacji tutaj mona dodawa wasne elementy, personalizowa
istniejce.
eby ww linki byy dostpne trzeba ustawi profil (patrz prezentacja)
Personalizacje s trzymane w bazie danych.
Wasne kryteria wyszukiwania to waciwoci elementu:
Initial value
Rendered = visible
Promet
Mona np. zmienia kryteria filtrowania dla lov, dodawa pola.
Tworzenie pozycji (Np. Dodawanie nowego przycisku do eksportu)
styl pozycji export button => wypenij rwnie View instancje
message test input pole do wpisania => wypenij view attribute i view instancje
tip balloon hint
44
Poziom uytkownika
Moe mniej ni admin.
Moe utworzy perspektyw z okreleniem kolumn, order.
Moe zmienia tylko atrybuty oznaczone jako user personalization
LOV
Challenge:
Create LOV
Create VO
Select no java files
Postfix name by VO
Set VO in folder lov/server
45
Create Region
+
Scope=public
Advanced Search Allowed=true
+searchAllowed = true
46
Source: https://forums.oracle.com/forums/thread.jspa?threadID=840715
1.
2.
3.
4.
Example
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject( "BoardMembersVO" );
Dictionary passiveCriteriaItems = pageContext.getLovCriteriaItems();
String strInvoiceAmt = (String)passiveCriteriaItems.get( "SigningLimit" );
OADBTransactionImpl trx = (OADBTransactionImpl)am.getOADBTransaction();
String currCode = (String)trx.getValue( "invoiceCurrency" );
Number invoiceAmt = (new XXUtil()).getCurrencyNumericValue( trx, strInvoiceAmt, currCode );
Serializable params[] = { invoiceAmt };
Class paramTypes[] = { Number.class };
vo.invokeMethod( "modifyWhereClause", params, paramTypes );
}
47
48
49
50
51
52
+required=true
Tip: you can customize this error message here:
53
AM:
public void resetLinePOAttributes( String rowRef, Number level )
{
int lvl = 999;
NoteLinesVORowImpl row = (NoteLinesVORowImpl)findRowByRef( rowRef );
if (row != null)
{
if (level != null)
lvl = level.intValue();
if (lvl <= 1)
row.setPoLineId( null );
if (lvl <= 2)
row.setLineLocationId( null );
if (lvl <= 3)
row.setPoDistributionId( null );
}
}
Picklist (LOV)
1/ Prepare VO, per OAF standards put this VO in location *.poplist.server
2/ insert an item with properties
54
Typical Personalizations/Customizations
What
VO
xml - $JAVA_TOP
RN
Substytucj podmieniamy VO
(busines components > substitutions, zapisywane s w
pliku .jpx, wanego dla caego projektu)
Xml database
CO
AM, AS, EO
55
Substytucj podmieniamy AM
UWAGA: po zmianach klas java trzeba zrestartowa serwer http i serwer aplikacyjny
56
57
Extra info:
Reviewing and deleting substitutions
-----------------------------------------exec jdr_utils.listDocuments('/oracle/apps/eam/asset/server', true)
/oracle/apps/eam/asset/server/customizations/site/0/AssetSearchVO
exec jdr_utils.DeleteDocument('/oracle/apps/eam/asset/server/customizations/site/0/AssetSearchVO')
commit
xxea_008_move.jpx is an ordinary xml file so you can check whether substitution is added:
b) copy VO changes
1/ Compile java classes ( if any )
58
- apache
- OC4J
$ADMIN_SCRIPTS_HOME/adapcctl.sh stop
$ADMIN_SCRIPTS_HOME/adoacorectl.sh stop
$ADMIN_SCRIPTS_HOME/adoacorectl.sh start
$ADMIN_SCRIPTS_HOME/adapcctl.sh start
6. Review changes
Note that VO name will not be changed, but SQL statement will be changed.
Old name:
59
60
begin
dbms_output.put_line('*START');
Jdr_utils.listcustomizations('/oracle/apps/eam/asset/webui/EAM_AD_ADVSEARCH
_PAGE');
dbms_output.put_line('*STOP');
end;
*START
/oracle/apps/eam/asset/webui/customizations/site/0/EAM_AD_ADVSEARCH_PAGE
*STOP
java oracle.jrad.tools.xml.exporter.XMLExporter
/oracle/apps/eam/asset/webui/customizations/site/0/EAM_AD_ADVSEARCH_PAGE \
-rootdir $XXEX_TOP/xxeraseme \
-username apps \
-password n8thobn1 \
-dbconnection
"(description=(address_list=(address=(community=tcp.world)(protocol=tcp)(ho
st=ERPTSTAP.PZU.PL)(port=1528)))(connect_data=(sid=OSEAD2)))"
--------------------------------------------------------------------------cd $XXEX_TOP/xxeraseme/oracle/apps/eam/asset/webui/customizations/site/0
java oracle.jrad.tools.xml.importer.XMLImporter
$XXEX_TOP/xxeraseme/oracle/apps/eam/asset/webui/customizations/site/0/EAM_A
D_ADVSEARCH_PAGE.xml \
-username apps \
-password n8thobn1 \
-rootdir $XXEX_TOP/xxeraseme/ \
-rootPackage / \
-dbconnection
"(description=(address_list=(address=(community=tcp.world)(protocol=tcp)(ho
st=ERPTSTAP.PZU.PL)(port=1528)))(connect_data=(sid=OSEAD2)))"
CO replacement
Challenge: we need to replace CO. How to do this:
1/ Extend CO in JDeveloper
a) Copy file JAVA_TOP$/oracle/apps/eam/workorder/webui/WOQuerySimpleSearchCO.class
b) Decompile it using jad.exe or other decompiler.
c) Copy decompiled file into your jdeveloper:
$JDEV_HOME/oracle/apps/eam/workorder/webui/WOQuerySimpleSearchCO.java
d) Make a copy of file (using windows explorer) and make a new one
$JDEV_HOME/pzu/oracle/apps/eam/workorder/webui/PzuWOQuerySimpleSearchCO.java
e) Modify file header and make changes:
Replace from
package oracle.apps.eam.workorder.webui;
public class WOQuerySimpleSearchCO
Replace to
package
pzu.oracle.apps.eam.workorder.webui;
public class PzuWOQuerySimpleSearchCO
extends WOQuerySimpleSearchCO
61
f) Deploy your java file as described before. Bounce server ( for the first time you do not
need this. You can replace your class file name each time to prevent from bouncing )
2/ Tell application to use your new CO. Do it by personalization (poprzez menu: Strona
personalizacji, jeli klikamy na personalizacje na linkach regionw moemy nie znale
wszystkiego i nie wida nazw kontrolerw, ktre chcemy podmieni)
pzu.oracle.apps.eam.workorder.webui.PzuWOQuerySimpleSearchCO
We can see now, that CO is changed
62
Code:
package pzu.oracle.apps.pa.project.webui;
import
import
import
import
import
import
import
oracle.apps.fnd.common.VersionInfo;
oracle.apps.fnd.framework.webui.OAPageContext;
oracle.apps.fnd.framework.webui.OAWebBeanConstants;
oracle.apps.fnd.framework.webui.beans.OAWebBean;
oracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean;
oracle.apps.fnd.framework.webui.beans.nav.OALinkBean;
oracle.apps.pa.project.webui.ProjectHomePageLayoutCO;
63
public static final String RCS_ID = "$Header: ProjectHomePageLayoutCO.java 120.1 2005/07/12 11:29:26 appldev ship $";
public static final boolean RCS_IDRECORDED = VersionInfo.recordClassVersion("$Header: ProjectHomePageLayoutCO.java 120.1
2005/07/12 11:29:26 appldev ship $", "oracle.apps.pa.project.webui");
}
Note: You can also add link manually, by personalization page. Use described here method
only for creating links with dynamic content.
64
65
super.processRequest(pageContext, webBean);
OAApplicationModule amroot = pageContext.getRootApplicationModule();
OAViewObjectImpl TaskDetailsVO = (OAViewObjectImpl)amroot.findViewObject("TaskDetailsVO");
Row r = TaskDetailsVO.getCurrentRow();
oracle.jbo.domain.Number peId = (oracle.jbo.domain.Number )r.getAttribute("ProjElementId");
if (pageContext.isLoggingEnabled(OAFwkConstants.STATEMENT)) pageContext.writeDiagnostics(this,"XXXX Inside
WorkRequestsCO.processRequest peId=" + peId,OAFwkConstants.STATEMENT);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
66
OAViewObjectImpl v = (OAViewObjectImpl)am.findViewObject("WorkOrdersVO");
v.setWhereClause("task_id <> :1");
v.setWhereClauseParams(null);
v.setWhereClauseParam(0, peId );
v.executeQuery();
v.first();
67
Receipe:
1/ Add table or advanced table as usual
2/ Add combobox (=messagechoice) with the following properties:
<oa:messageChoice
id="woStatusFilter"
defaultValue="OPENED"
pickListDispAttr="Meaning"
pickListValAttr="LookupCode"
pickListViewDef="pzu.oracle.apps.pa.xxzn_wiele_020.poplist.server.WrStatusesVO"
prompt="Filtr"
required="yes">
<ui:primaryClientAction>
<ui:firePartialAction event="StatusFilterChange"/>
68
</ui:primaryClientAction>
</oa:messageChoice>
oracle.apps.fnd.common.VersionInfo;
oracle.apps.fnd.framework.OAApplicationModule;
oracle.apps.fnd.framework.OAFwkConstants;
oracle.apps.fnd.framework.server.OAViewObjectImpl;
oracle.apps.fnd.framework.webui.OAControllerImpl;
oracle.apps.fnd.framework.webui.OAPageContext;
oracle.apps.fnd.framework.webui.OAWebBeanConstants;
oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.apps.fnd.framework.webui.beans.message.OAMessageChoiceBean;
import oracle.jbo.Row;
/**
* Controller for ...
*/
public class WorkOrdersCO extends OAControllerImpl
{
public static final String RCS_ID="$Header$";
public static final boolean RCS_ID_RECORDED =
VersionInfo.recordClassVersion(RCS_ID, "%packagename%");
OAMessageChoiceBean StatusFilter =
(OAMessageChoiceBean)webBean.findChildRecursive("woStatusFilter");
Object StatusFilterObj = StatusFilter.getValue(pageContext);
String StatusFilterValue = StatusFilterObj.toString();
if (pageContext.isLoggingEnabled(OAFwkConstants.STATEMENT))
pageContext.writeDiagnostics(this,"XXXX Inside WorkRequestsCO.processRequest
StatusFilterValue=" + StatusFilterValue,OAFwkConstants.STATEMENT);
/*
select status_id, work_order_status --, system_status, system_status_desc
from eam_wo_statuses_v order by 1
1
Niewydane
3
Wydane
4
Zakoczone
5
Wykonane - bez obciania
6
Wstrzymane
7
Anulowane
12
Zamknite
14
Oczekujce na zamknicie
15
Zamykanie nie powiodo si
17
Kopia robocza
98
Anulowane przez obsug zapobiegawcz
99
Anulowane przez osob zatwierdzajc
1000
Cykliczny - z harmonogramu
*/
String filterClause = "0=0";
if ( StatusFilterValue.equalsIgnoreCase("OPENED") ) {
69
}
/**
* Layout and page setup logic for a region.
* @param pageContext the current OA page context
* @param webBean the web bean corresponding to the region
*/
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
setFilter(pageContext, webBean);
}
/**
* Procedure to handle form submissions for form elements in
* a region.
* @param pageContext the current OA page context
* @param webBean the web bean corresponding to the region
*/
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
if
("StatusFilterChange".equals(pageContext.getParameter(OAWebBeanConstants.EVENT_PARAM)))
{
setFilter(pageContext, webBean);
}
Launch SetFilter on
onComboboxChange event
}
}
70
In a Controller
Step 1
import oracle.apps.fnd.framework.OAFwkConstants;
if (pageContext.isLoggingEnabled(OAFwkConstants.STATEMENT))
pageContext.writeDiagnostics(this,"building :"+s_building,OAFwkConstants.STATEMENT);
Tip: you can use web browser back button to go to your page back.
Set 3- see result:
72
Now you will be able to see the application log appened to the bottom of the page.
Then set profile option AFLOG_LEVEL
"FND: Debug Log Level/BOA: Poziom dziennika usuwania bdw (at user-level).
Finally query FND_LOG_MESSAGES in the database for all the debugging messages:
SELECT module, message_text
FROM fnd_log_messages
WHERE user_id = AND timestamp > SYSDATE - (1/24/60) -- in the past minute;
this cuts down the number of records
ORDER BY timestamp;
page.
3. Select `Set Trace Level? and click Go
4. Select the desired trace level and click Save
5. Write down the trace id number(s).
6. Perform the activity that you want to trace
7. Return to the 'Diagnostics' page.
8. Select `Set Trace Level' and click Go
9. Select 'Disable Trace' and click Go.
10. Write down the trace id number(s) if different.
11. Go to user_dump_dest for your database and collect the raw trace file(s)
suffixes by the trace id number(s) you have recorded.
12. Exit Applications.
Note: you can identify the user_dump_dest directory in your environment by running the
following SQL:
SQL> select name, value from v$parameter where name like 'user%';
More:
http://apps2fusion.com/apps/oa-framework/187-debugging-oa-framework-7-different-techniques
debugging am.invokeMethod
Be aware of that issue:
74
inne informacje
Apps2fusion.com - great video presentations by anil passi
http://imdjkoch.wordpress.com/category/oracle/oracle-technologies/oa-framework/ - brilliant
articles R12compatible
Fine help
75
76