Standard functionality in Oracle Web Applications Desktop Integrator does not allow uploading columns marked as read-only; this is highlighted in Bug 6607618.
The following customisation can be used as a workaround, however as it requires direct modification of underlying tables it is not supported nor recommended by Oracle (and don't blame me if it goes wrong!).
In the application do NOT set the columns as read-only, instead, after defining the Integrator and Content identify the CONTENT_CODE using the following:
SELECT bint.user_name
, bint.integrator_code
, bcon.content_code
FROM bne_integrators_tl bint
, bne_contents_b bcon
WHERE bint.integrator_code = bcon.integrator_code
AND bint.user_name = &IntegratorName;
Then, update the READ_ONLY_FLAG to ‘Y’ on the table BNE_CONTENT_COLS_B for the columns you want to be read-only (based on the CONTENT_CODE identified in the above script).
Finally, clear the BNE cache (refer to Metalink Note 1075840.1).
Translate
Wednesday, 3 April 2013
Friday, 13 January 2012
Oracle: Submitting BI Publisher Reports using PL/SQL
This simple example shows how to submit concurrent programs that use BI Publisher to render the output.Before calling the fnd_request.submit_request procedure to create the concurrent request the BI Publisher template must be assigned, to do this use the seeded fnd_request.add_layout procedure:
**XXAPPS : Application Short Code
**XXAPPS_TEMPLATE_CODE : Template Code (as defined in XML Publisher Administrator)
**en : Template Language
**00 : Template Territory
**PDF : Output Format
**XXAPPS_PROGRAM_CODE : Concurrent Program Short Code
**PARAM1/2 : Concurrent Program Parameters
declare
xml_layout BOOLEAN;
jreq_id NUMBER;
begin
xml_layout := fnd_request.add_layout ('XXAPPS'
, 'XXAPPS_TEMPLATE_CODE'
, 'en'
, '00'
, 'PDF');
jreq_id := fnd_request.submit_request ('XXAPPS'
, 'XXAPPS_PROGRAM_CODE'
, ''
, ''
, FALSE
, 'PARAM1'
, 'PARAM2');
end;
**XXAPPS : Application Short Code
**XXAPPS_TEMPLATE_CODE : Template Code (as defined in XML Publisher Administrator)
**en : Template Language
**00 : Template Territory
**PDF : Output Format
**XXAPPS_PROGRAM_CODE : Concurrent Program Short Code
**PARAM1/2 : Concurrent Program Parameters
Monday, 5 September 2011
Oracle: Adding a message box with Form Personalisations
The seeded Payment Overview form (APXPWALL) in Oracle Payables shows limited details relating to the payee, in this example we will make the payee bank details visible on this form.
We could use Custom PLL to add additional fields to the form, however the simpler approach is to use Form Personalisations to display the details in a Pop-up message box.
From the Payment Overview form select Form Personalisations and create an action that will enable a new Menu option:
Trigger Event: WHEN-NEW-FORM-INSTANCE
Action Type: Menu
Menu Entry: SPECIAL3
Menu Label: Payment Details
Then create an action that will display the message box:
Trigger Event: SPECIAL3
Action Type: Message
Message Type: Show
Message Text: =SELECT xxapps_forms_util_pkg.inv_payee_bank_details(:PAYMENT.CHECK_ID,:PAYMENT.PAYMENT_METHOD) FROM dual
The above action calls a function in a custom package to return the formatted details, the function is defined as:
Now, from within the Payment Overview form select Tools > Payment Details to view the message
We could use Custom PLL to add additional fields to the form, however the simpler approach is to use Form Personalisations to display the details in a Pop-up message box.
From the Payment Overview form select Form Personalisations and create an action that will enable a new Menu option:
Trigger Event: WHEN-NEW-FORM-INSTANCE
Action Type: Menu
Menu Entry: SPECIAL3
Menu Label: Payment Details
Then create an action that will display the message box:
Trigger Event: SPECIAL3
Action Type: Message
Message Type: Show
Message Text: =SELECT xxapps_forms_util_pkg.inv_payee_bank_details(:PAYMENT.CHECK_ID,:PAYMENT.PAYMENT_METHOD) FROM dual
The above action calls a function in a custom package to return the formatted details, the function is defined as:
FUNCTION inv_payee_bank_details (p_check_id IN NUMBER
, p_pay_method IN VARCHAR2)
RETURN VARCHAR2
IS
v_payee_details VARCHAR2 (250);
BEGIN
IF p_pay_method = 'Electronic'
THEN
SELECT 'Bank Name: '
|| xba.bank_name
|| CHR (10)
|| 'Sort Code: '
|| xba.branch_number_fmt
|| CHR (10)
|| 'Account Num: '
|| xba.bank_account_num
|| CHR (10)
|| 'Account Name: '
|| xba.bank_account_name
INTO v_payee_details
FROM xxapps_iby_bank_accounts_v xba
, ap_checks_all aca
WHERE aca.external_bank_account_id = xba.ext_bank_account_id
AND aca.check_id = p_check_id;
ELSE
v_payee_details := 'Paid by Cheque';
END IF;
RETURN v_payee_details;
EXCEPTION
WHEN OTHERS
THEN
RETURN 'No Data Found!';
END inv_payee_bank_details;
Now, from within the Payment Overview form select Tools > Payment Details to view the message
Thursday, 4 August 2011
Oracle: Concurrent Request Security
In previous releases of Oracle concurrent request access was controlled by the use of profile values, however in Release 12 access is controlled by the use of Roles. In these examples we will create two Roles; one which grants access to the output of concurrent programs based on Responsibility, and one which grants access to all outputs (for use by System Administrators).
First up we will create the Role for Responsibility based security.
Within the Functional Developer responsibility search for the Object named "Concurrent Requests", then select the 'Object Instance Sets' tab and create a new Instance Set:
Name: XXAPPS Responsibility Concurrent Access
Code: XXAPPS_RESP_CR_ACCESS
Description: Responsibility Concurrent Access
Predicate:
To assign this to all users create a new Grant:
Name: XXAPPS Responsibility Concurrent Access
Description: Access to view all concurrent requests in current responsibility
Grantee Type: All Users
Data Security > Object: Concurrent Requests
Data Context Type: Instance Set (select the Instance Set XXAPPS Responsibility Concurrent Access)
Permission Set: Request Operations
Now, create a new Instance Set for the System Administrator access:
Name: XXAPPS System Administrator Concurrent Access
Code: XXAPPS_SYS_ADMIN_CR_ACCESS
Description: System Administrator Concurrent Access
Predicate:
This Instance Set will be assigned to named users, so we need to create a Role (within the User Management responsibility):
Role:-
Category: Miscellaneous
Role Code: XXAPPS_SYS_ADMIN_CR_ACCESS
Display Name: XXAPPS System Administrator Concurrent Access
Description: Access to view all concurrent requests
Application: XXAPPS Application
Grant:-
Name: XXAPPS System Administrator Concurrent Access
Description: Access to view all concurrent requests
Data Security > Object: Concurrent Requests
Data Context Type: Instance Set (select the Instance Set XXAPPS System Administrator Concurrent Access)
Permission Set: Request Operations
First up we will create the Role for Responsibility based security.
Within the Functional Developer responsibility search for the Object named "Concurrent Requests", then select the 'Object Instance Sets' tab and create a new Instance Set:
Name: XXAPPS Responsibility Concurrent Access
Code: XXAPPS_RESP_CR_ACCESS
Description: Responsibility Concurrent Access
Predicate:
&TABLE_ALIAS.request_id IN ( SELECT request_id FROM fnd_concurrent_requests WHERE concurrent_program_id IN (SELECT fru.request_unit_id FROM fnd_responsibility_vl frv , fnd_request_groups frg , fnd_request_group_units fru WHERE frv.request_group_id = frg.request_group_id AND frg.request_group_id = fru.request_group_id AND fru.request_unit_type IN ('P', 'S') AND frv.responsibility_id = fnd_global.resp_id))To assign this to all users create a new Grant:
Name: XXAPPS Responsibility Concurrent Access
Description: Access to view all concurrent requests in current responsibility
Grantee Type: All Users
Data Security > Object: Concurrent Requests
Data Context Type: Instance Set (select the Instance Set XXAPPS Responsibility Concurrent Access)
Permission Set: Request Operations
Now, create a new Instance Set for the System Administrator access:
Name: XXAPPS System Administrator Concurrent Access
Code: XXAPPS_SYS_ADMIN_CR_ACCESS
Description: System Administrator Concurrent Access
Predicate:
&TABLE_ALIAS.request_id IN (SELECT request_id FROM fnd_concurrent_requests)This Instance Set will be assigned to named users, so we need to create a Role (within the User Management responsibility):
Role:-
Category: Miscellaneous
Role Code: XXAPPS_SYS_ADMIN_CR_ACCESS
Display Name: XXAPPS System Administrator Concurrent Access
Description: Access to view all concurrent requests
Application: XXAPPS Application
Grant:-
Name: XXAPPS System Administrator Concurrent Access
Description: Access to view all concurrent requests
Data Security > Object: Concurrent Requests
Data Context Type: Instance Set (select the Instance Set XXAPPS System Administrator Concurrent Access)
Permission Set: Request Operations
Tuesday, 21 June 2011
Oracle: Universal Work Queue – Advanced Collections
The Universal Work Queue can be integrated with many other Oracle applications, in this example we will be using it to display Task information generated from Oracle Advanced Collections.
Out of the box the Universal Work Queue has a number of nodes that display data relating to Advanced Collections and Delinquencies, however we have a requirement to categorise the Tasks based on Customer Attributes and Collector information.
The first step is to create the Lookup Types that will be used, for this example the custom Lookup Type name that has been created is "XXAPPS IEU Node Labels" (XXAPPS_IEU_NODE_LABELS”). The Lookup Code "Tasks : Customer Category" (XXAPPS_IEU_NEW_TAKS) has been created within this Lookup Type.
Lookup Type:
Name XXAPPS IEU Node Labels
Code XXAPPS_IEU_NODE_LABELS
Description Node Labels for Custom UWQ Nodes
Application XXAPPS Application
Access Extensible
Lookup Codes:
Code XXAPPS_IEU_NEW_TASKS
Description Tasks : Customer Category
The next step is to create the database views that will be used by the custom node, in this example the view is based on the seeded IEU_UWQ_TASKS_V view with additional fields added to return the Customer Attribute information. Next, create the Spreadtable Metadata Definition (within the CRM Administration responsibility), for this example the Datasource Name is XXAPPS_IEU_UWQ_TASKS and the referenced Relational View is XXAPPS_IEU_UWQ_TASKS_V.
Within the CRM Administrator the Work Provider can be created based on the configuration completed so far:
Application Name XXAPPS Application
Node Name Lookup Type XXAPPS_IEU_NODE_LABELS
Node Name Lookup Code XXAPPS_IEU_NEW_TASKS
Node Name Lookup Meaning Tasks
Enumerator UUID XXAPPS_TASK_NODE
Registration Type Non Media
Enumerator Procedure XXAPPS_iex_util_pkg.enumerate_group_uwq_nodes
Refresh Procedure XXAPPS_iex_util_pkg.refresh_group_uwq_nodes
View Name XXAPPS_IEU_UWQ_TASKS_V
The Enumerator and Refresh Procedures defined above reference PL/SQL packages that build the Nodes and populate the UWQ with the relevant data.
The XXAPPS_IEX_UTIL_PKG is defined as:
Now, within System Administrator enable the Profile Option “IEU: Queue: Tasks : Customer Category” (linked to the UWQ Work Provider) and the nodes will be visible within the Universal Work Queue.
Out of the box the Universal Work Queue has a number of nodes that display data relating to Advanced Collections and Delinquencies, however we have a requirement to categorise the Tasks based on Customer Attributes and Collector information.
The first step is to create the Lookup Types that will be used, for this example the custom Lookup Type name that has been created is "XXAPPS IEU Node Labels" (XXAPPS_IEU_NODE_LABELS”). The Lookup Code "Tasks : Customer Category" (XXAPPS_IEU_NEW_TAKS) has been created within this Lookup Type.
Lookup Type:
Name XXAPPS IEU Node Labels
Code XXAPPS_IEU_NODE_LABELS
Description Node Labels for Custom UWQ Nodes
Application XXAPPS Application
Access Extensible
Lookup Codes:
Code XXAPPS_IEU_NEW_TASKS
Description Tasks : Customer Category
The next step is to create the database views that will be used by the custom node, in this example the view is based on the seeded IEU_UWQ_TASKS_V view with additional fields added to return the Customer Attribute information. Next, create the Spreadtable Metadata Definition (within the CRM Administration responsibility), for this example the Datasource Name is XXAPPS_IEU_UWQ_TASKS and the referenced Relational View is XXAPPS_IEU_UWQ_TASKS_V.
Within the CRM Administrator the Work Provider can be created based on the configuration completed so far:
Application Name XXAPPS Application
Node Name Lookup Type XXAPPS_IEU_NODE_LABELS
Node Name Lookup Code XXAPPS_IEU_NEW_TASKS
Node Name Lookup Meaning Tasks
Enumerator UUID XXAPPS_TASK_NODE
Registration Type Non Media
Enumerator Procedure XXAPPS_iex_util_pkg.enumerate_group_uwq_nodes
Refresh Procedure XXAPPS_iex_util_pkg.refresh_group_uwq_nodes
View Name XXAPPS_IEU_UWQ_TASKS_V
The Enumerator and Refresh Procedures defined above reference PL/SQL packages that build the Nodes and populate the UWQ with the relevant data.
The XXAPPS_IEX_UTIL_PKG is defined as:
CREATE OR REPLACE PACKAGE XXAPPS_iex_util_pkg
AS
PROCEDURE enumerate_group_uwq_nodes (P_RESOURCE_ID IN NUMBER
, P_LANGUAGE IN VARCHAR2
, P_SOURCE_LANG IN VARCHAR2
, P_SEL_ENUM_ID IN NUMBER);
PROCEDURE refresh_group_uwq_nodes (P_RESOURCE_ID IN NUMBER
, p_node_id IN NUMBER
, P_COUNT OUT NOCOPY NUMBER);
END XXAPPS_iex_util_pkg;
/
CREATE OR REPLACE PACKAGE BODY XXAPPS_iex_util_pkg
AS
PROCEDURE enumerate_group_uwq_nodes (P_RESOURCE_ID IN NUMBER
, P_LANGUAGE IN VARCHAR2
, P_SOURCE_LANG IN VARCHAR2
, P_SEL_ENUM_ID IN NUMBER)
AS
l_node_label VARCHAR2 (200);
uwq_ld_list IEU_PUB.EnumeratorDataRecordList;
l_bind_list IEU_PUB.BindVariableRecordList;
l_node_counter NUMBER;
v_org_id NUMBER := iex_org_override;
BEGIN
SAVEPOINT start_node_enumeration;
l_node_counter := 0;
uwq_ld_list (l_node_counter).NODE_LABEL := 'Tasks : Customer Category';
uwq_ld_list (l_node_counter).VIEW_NAME := 'XXAPPS_IEU_UWQ_TASKS_V';
uwq_ld_list (l_node_counter).DATA_SOURCE := 'XXAPPS_IEU_UWQ_TASKS';
uwq_ld_list (l_node_counter).MEDIA_TYPE_ID := '';
uwq_ld_list (l_node_counter).WHERE_CLAUSE :=
'CUSTOMER_ORG_ID = ' || v_org_id;
uwq_ld_list (l_node_counter).NODE_TYPE := 0;
uwq_ld_list (l_node_counter).HIDE_IF_EMPTY := '';
uwq_ld_list (l_node_counter).NODE_DEPTH := 1;
DECLARE
CURSOR c1
IS
SELECT customer_type
FROM (SELECT lookup_code customer_type
FROM ar_lookups
WHERE lookup_type = 'ADDRESS_CATEGORY'
UNION
SELECT 'GENERAL' FROM DUAL)
WHERE EXISTS
(SELECT 'x'
FROM jtf_tasks_b tasks_b
, hz_cust_site_uses_all casu
, hz_cust_acct_sites_all cas
WHERE casu.cust_acct_site_id = cas.cust_acct_site_id
AND casu.site_use_id = tasks_b.source_object_id
AND TRUNC (
NVL (tasks_b.planned_start_date, SYSDATE)) <=
SYSDATE
AND NVL (tasks_b.deleted_flag, 'N') = 'N'
AND tasks_b.open_flag = 'Y'
AND tasks_b.entity = 'TASK'
AND cas.org_id = v_org_id
AND NVL (
NVL (cas.customer_category_code
, UPPER (cas.attribute_category))
, 'GENERAL') = customer_type
AND tasks_b.owner_type_code = 'RS_GROUP')
ORDER BY 1;
BEGIN
FOR x IN c1
LOOP
l_node_counter := l_node_counter + 1;
uwq_ld_list (l_node_counter).NODE_LABEL := x.customer_type;
uwq_ld_list (l_node_counter).VIEW_NAME := 'XXAPPS_IEU_UWQ_TASKS_V';
uwq_ld_list (l_node_counter).DATA_SOURCE := 'XXAPPS_IEU_UWQ_TASKS';
uwq_ld_list (l_node_counter).MEDIA_TYPE_ID := '';
uwq_ld_list (l_node_counter).WHERE_CLAUSE :=
'CUSTOMER_TYPE = '
|| ''''
|| x.customer_type
|| ''''
|| ' and CUSTOMER_ORG_ID = '
|| v_org_id;
uwq_ld_list (l_node_counter).NODE_TYPE := 0;
uwq_ld_list (l_node_counter).HIDE_IF_EMPTY := 'Y';
uwq_ld_list (l_node_counter).NODE_DEPTH := 2;
END LOOP;
END;
IEU_PUB.ADD_UWQ_NODE_DATA (P_RESOURCE_ID, P_SEL_ENUM_ID, uwq_ld_list);
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK TO start_node_enumeration;
RAISE;
END enumerate_group_uwq_nodes;
PROCEDURE refresh_group_uwq_nodes (p_resource_id IN NUMBER
, p_node_id IN NUMBER
, p_count OUT NOCOPY NUMBER)
IS
sql_stmt VARCHAR2 (500);
l_view_name VARCHAR2 (500);
l_label VARCHAR2 (500);
l_where VARCHAR2 (500);
l_depth NUMBER;
v_count NUMBER;
v_org_id NUMBER := iex_org_override;
BEGIN
BEGIN
SELECT where_clause
, node_label
, node_depth
INTO l_where
, l_label
, l_depth
FROM IEU_UWQ_SEL_RT_NODES
WHERE node_id = p_node_id
AND resource_id = p_resource_id
AND data_source = 'XXAPPS_IEU_UWQ_TASKS';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
l_where := NULL;
l_label := NULL;
END;
IF l_depth = 1
THEN
SELECT COUNT ( * )
INTO p_count
FROM jtf_tasks_b tasks_b
, hz_cust_site_uses_all casu
, hz_cust_acct_sites_all cas
WHERE casu.cust_acct_site_id = cas.cust_acct_site_id
AND casu.site_use_id = tasks_b.source_object_id
AND NVL (tasks_b.deleted_flag, 'N') = 'N'
AND tasks_b.open_flag = 'Y'
AND tasks_b.entity = 'TASK'
AND cas.org_id = v_org_id
AND tasks_b.owner_type_code = 'RS_GROUP'
AND TRUNC (NVL (tasks_b.planned_start_date, SYSDATE)) <= SYSDATE;
ELSE
SELECT COUNT ( * )
INTO p_count
FROM jtf_tasks_b tasks_b
, hz_cust_site_uses_all casu
, hz_cust_acct_sites_all cas
WHERE casu.cust_acct_site_id = cas.cust_acct_site_id
AND casu.site_use_id = tasks_b.source_object_id
AND NVL (tasks_b.deleted_flag, 'N') = 'N'
AND tasks_b.open_flag = 'Y'
AND tasks_b.entity = 'TASK'
AND cas.org_id = v_org_id
AND NVL (
NVL (cas.customer_category_code
, UPPER (cas.attribute_category))
, 'GENERAL') = l_label
AND tasks_b.owner_type_code = 'RS_GROUP'
AND TRUNC (NVL (tasks_b.planned_start_date, SYSDATE)) <= SYSDATE;
END IF;
END refresh_group_uwq_nodes;
END XXAPPS_iex_util_pkg;
Now, within System Administrator enable the Profile Option “IEU: Queue: Tasks : Customer Category” (linked to the UWQ Work Provider) and the nodes will be visible within the Universal Work Queue.
Friday, 27 May 2011
Documentum: Automating Subscriptions
Subscriptions within Documentum are an effective way of quickly getting to the Cabinets, Folders and documents that you require, they do however require visibility of the target in the first instance in order to create the subscription.
In this scenario a Preset has been created within WebTop that has removed the Cabinet node in the navigation panel, therefore visibility of the available Cabinets and Folders will controlled via Subscriptions.
The 'Subscription Targets' will be assigned based on the groups that the user is in, a custom Java Method identifies the users and 'Targets' and creates a
The first step is to create a custom Type that will hold the Group and 'Target' values, the Type is called
In this example we want to automatically subscribe users of the doc_authors group to the Cabinet named 'Instructions'; so, we create a new object of the Type
The following DQL statement returns users of the group (along with their ID) and the object ID of the Cabinet, excluding any users that already have a subscription to the 'Target' (as we don't waste processing time creating subscriptions that already exist):
The script can be used as the bases of a record group in a Java Method that is subsequently used in an API call to create a
Attach the Java Method to a Job in DA and it can then be scheduled to run at regular intervals to create subscriptions without the need of manual intervention.
In this scenario a Preset has been created within WebTop that has removed the Cabinet node in the navigation panel, therefore visibility of the available Cabinets and Folders will controlled via Subscriptions.
The 'Subscription Targets' will be assigned based on the groups that the user is in, a custom Java Method identifies the users and 'Targets' and creates a
dm_relation record.The first step is to create a custom Type that will hold the Group and 'Target' values, the Type is called
xapps_subscription_config and has the following two custom repeating attributes c_group and c_subscribe_target.In this example we want to automatically subscribe users of the doc_authors group to the Cabinet named 'Instructions'; so, we create a new object of the Type
xapps_subscription_config and populate c_group with the value 'doc_authors' and c_subscribe_target with the object_id of the 'Instructions' Cabinet (as the names of Cabinets, Folders and Documents can change we are using object ID's instead of object names). The following DQL statement returns users of the group (along with their ID) and the object ID of the Cabinet, excluding any users that already have a subscription to the 'Target' (as we don't waste processing time creating subscriptions that already exist):
select distinct us.user_name
, us.r_object_id as user_id
, csc1.c_subscribe_target
from dm_group_r gr
, dm_group_s gs
, dm_user_s us
, xapps_subscription_config csc
, xapps_subscription_config csc1
, dm_sysobject ds
where gs.r_object_id = gr.r_object_id
and csc.r_object_id = csc1.r_object_id
and gr.users_names = us.user_name
and gs.group_name = csc.c_group
and ds.r_object_id = csc1.c_subscribe_target
and us.user_state = 0
and csc.c_enabled = true
and not exists
(select 'x'
from dm_relation dr
where dr.relation_name = 'dm_subscription'
and dr.child_id = us.r_object_id
and dr.parent_id = csc1.c_subscribe_target)
enable(row_based)The script can be used as the bases of a record group in a Java Method that is subsequently used in an API call to create a
dm_relation record:public void execute(Map parameters, OutputStream ostream)
throws Exception {
try {
String strQuery = "select distinct us.user_name,"
+ " us.r_object_id as user_id,"
+ " csc1.c_subscribe_target" + " from dm_group_r gr,"
+ " dm_group_s gs," + " dm_user_s us,"
+ " xapps_subscription_config csc,"
+ " xapps_subscription_config csc1," + " dm_sysobject ds"
+ " where gs.r_object_id = gr.r_object_id"
+ " and csc.r_object_id = csc1.r_object_id"
+ " and gr.users_names = us.user_name"
+ " and us.user_state = 0"
+ " and gs.group_name = csc.c_group"
+ " and csc1.c_subscribe_target = ds.r_object_id"
+ " and csc.c_enabled = true" + " and not exists"
+ " (select 'x'" + " from dm_relation dr"
+ " where dr.relation_name = 'dm_subscription'"
+ " and dr.child_id = us.r_object_id"
+ " and dr.parent_id = csc1.c_subscribe_target)"
+ " enable(row_based)";
IDfQuery idfQuery = new DfQuery();
idfQuery.setDQL(strQuery);
IDfCollection idfCQuery = idfQuery.execute(idfSession,
IDfQuery.DF_READ_QUERY);
while (idfCQuery.next()) {
String strUserName = idfCQuery.getString("user_name");
String strUserId = idfCQuery.getString("user_id");
String strSubscribeTo = idfCQuery
.getString("c_subscribe_target");
String strApi = "create dm_relation object set relation_name = 'dm_subscription', set parent_id = '"
+ strSubscribeTo
+ "', set child_id = '"
+ strUserId
+ "'";
IDfQuery idfApi = new DfQuery();
idfApi.setDQL(strApi);
IDfCollection idfCApi = idfApi.execute(idfSession,
IDfQuery.DF_EXEC_QUERY);
idfCApi.close();
}
idfCQuery.close();
} catch (Exception e) {
DfLogger.error(null, “Exception …", null, e);
} finally {
}
}Attach the Java Method to a Job in DA and it can then be scheduled to run at regular intervals to create subscriptions without the need of manual intervention.
Tuesday, 10 May 2011
Oracle: Subqueries in Discoverer
With no out-of-the box method of using dynamic parameters in SQL queries within Discoverer, reports can become very cumbersome and costly to run. However, there is a work around for this with the use of database context values.
In this example we will create a package to set a context value that can then be referenced within a custom Discoverer workbook.
The first step is to create the custom context and a package that will set and return the context value (in this example xxapps_eul_us is the database user owning the Discoverer EUL):
Within Discoverer Administrator select Tools > Register PL/SQL Functions and create a new function:
Function Name: SET_CONTEXT
Display Name: XXAPPS Set Context
Owner: APPS
Package: XXAPPS_EUL_DISCO
Database Link:
Return Type: Varchar
Description: Set Context
Identifier: SET_CONTEXT
Available in Desktop/Plus: True
In this example the context is set based on the value entered as a parameter in the workbook (the parameter is named ‘As of date’). To set the context; create a workbook Condition referencing the XXAPPS Set Context function:
Item: ‘DUMMY’
Condition: <>
Values: =XXAPPS Set Context(‘EFFECTIVE DATE’,:“As of date”)
Now, within the SQL of the workbook the context value can be referenced as a subquery, EG:
In this example we will create a package to set a context value that can then be referenced within a custom Discoverer workbook.
The first step is to create the custom context and a package that will set and return the context value (in this example xxapps_eul_us is the database user owning the Discoverer EUL):
CREATE OR REPLACE CONTEXT EUL_DISCO USING xxapps_eul_disco
/
CREATE OR REPLACE PACKAGE xxapps_eul_disco AUTHID DEFINER AS
FUNCTION set_context(p_name VARCHAR2
,p_value VARCHAR2)
RETURN VARCHAR2;
FUNCTION show_context(p_name VARCHAR2)
RETURN VARCHAR2;
END xxapps_eul_disco;
/
CREATE OR REPLACE PACKAGE BODY xxapps_eul_disco AS
FUNCTION set_context(p_name VARCHAR2
,p_value VARCHAR2) RETURN VARCHAR2 AS
BEGIN
dbms_session.set_context('EUL_DISCO', p_name, p_value);
RETURN p_value;
END set_context;
FUNCTION show_context(p_name VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN SYS_CONTEXT('EUL_DISCO', p_name);
END show_context;
END xxapps_eul_disco;
/
GRANT ALL ON xxapps_eul_disco TO xxapps_eul_us;
Within Discoverer Administrator select Tools > Register PL/SQL Functions and create a new function:
Function Name: SET_CONTEXT
Display Name: XXAPPS Set Context
Owner: APPS
Package: XXAPPS_EUL_DISCO
Database Link:
Return Type: Varchar
Description: Set Context
Identifier: SET_CONTEXT
Available in Desktop/Plus: True
In this example the context is set based on the value entered as a parameter in the workbook (the parameter is named ‘As of date’). To set the context; create a workbook Condition referencing the XXAPPS Set Context function:
Item: ‘DUMMY’
Condition: <>
Values: =XXAPPS Set Context(‘EFFECTIVE DATE’,:“As of date”)
Now, within the SQL of the workbook the context value can be referenced as a subquery, EG:
SELECT ...
FROM ...
WHERE date <= TO_DATE(xxapps_eul_disco.show_context('EFFECTIVE DATE'),'DD-MON-RRRR')
Tuesday, 3 May 2011
Oracle: Using Forms Personalisations to restrict a List of Values
In this scenario there is a requirement for end users in the Payables Department to be able to amend and create Flex Values (using the seeded Segment Values form). As there are many Flex Values that these users should not be given access to, Forms Personalisations is used to restrict the form (this personalisation can be adapted to any LOV in any form).
The value set is called XXAPPS_CUST_ID, and the form to be personalised is Segment Values (FNDFFMSV).
As we will be modifying the seeded Record Group attached to the LOV the first step is to download the FMB file from the application server and open it in Forms Developer to identify the query used in the record group. The record group attached to the LOV is FLEX_VALUE_SET_NAME_QF and the query is:
Within Forms Personalisations create a new personalisation with a Trigger Event of WHEN-NEW-FORM-INSTANCE and the following Actions;
Action Type: Builtin
Builtin Type: Create Record Group from Query
Argument:
Group Name: XXAPPS_LOV
This creates a new Record Group (based on the seeded query but restricted to only the XXAPPS_CUST_ID value set).
Action Type: Property
Object Type: LOV
Target Object: FLEX_VALUE_SET_NAME_QF
Property Name: GROUP_NAME
Value: XXAPPS_LOV
This assigns the Records Group to the List Of Values.
These steps are all that is required to restrict the LOV, however to fully restrict the form we also need to amend the DEFAULT_WHERE (to stop users running ‘non-restricted’ queries IE: CTRL+F11) and also disable the other Radio Buttons in the Form.
To amend the DEFAULT_WHERE create the following action:
Action Type: Property
Object Type: Block
Target Object: VSET
Property Name: DEFAULT_WHERE
Click in the Value field and select 'Get Value' – this will return the seeded value, this can then be modified to restrict the results:
To disable the other Radio Buttons create actions to set the Property ENABLED to False for the following items:
QUERY_FIND.REGION_POPUP.KEY
QUERY_FIND.REGION_POPUP.DESCR
QUERY_FIND.REGION_POPUP.CONC
CONTROL.REGION_POPUP.KEY
CONTROL.REGION_POPUP.DESCR
CONTROL.REGION_POPUP.CONC
Now when the form is opened the only available option is Values Sets and the LOV and Default Where is restricted to the XXAPPS_CUST_ID value.
The value set is called XXAPPS_CUST_ID, and the form to be personalised is Segment Values (FNDFFMSV).
As we will be modifying the seeded Record Group attached to the LOV the first step is to download the FMB file from the application server and open it in Forms Developer to identify the query used in the record group. The record group attached to the LOV is FLEX_VALUE_SET_NAME_QF and the query is:
select v.validation_type, v.flex_value_set_name,
l.meaning, v.parent_flex_value_set_id, v.flex_value_set_id
from fnd_flex_value_sets v,
fnd_lookups l,
fnd_flex_validation_tables t
where v.flex_value_set_id = t.flex_value_set_id (+)
and ((v.validation_type in ('D','I','X','Y')) or
(v.validation_type = 'F' and t.summary_allowed_flag = 'Y'))
and l.lookup_code = v.validation_type
and l.lookup_type = 'SEG_VAL_TYPES'
order by v.flex_value_set_nameWithin Forms Personalisations create a new personalisation with a Trigger Event of WHEN-NEW-FORM-INSTANCE and the following Actions;
Action Type: Builtin
Builtin Type: Create Record Group from Query
Argument:
select v.validation_type, v.flex_value_set_name,
l.meaning, v.parent_flex_value_set_id, v.flex_value_set_id
from fnd_flex_value_sets v,
fnd_lookups l,
fnd_flex_validation_tables t
where v.flex_value_set_id = t.flex_value_set_id (+)
and ((v.validation_type in ('D','I','X','Y')) or
(v.validation_type = 'F' and t.summary_allowed_flag = 'Y'))
and l.lookup_code = v.validation_type
and l.lookup_type = 'SEG_VAL_TYPES'
and v.flex_value_set_name in ('XXAPPS_CUST_ID')
order by v.flex_value_set_nameGroup Name: XXAPPS_LOV
This creates a new Record Group (based on the seeded query but restricted to only the XXAPPS_CUST_ID value set).
Action Type: Property
Object Type: LOV
Target Object: FLEX_VALUE_SET_NAME_QF
Property Name: GROUP_NAME
Value: XXAPPS_LOV
This assigns the Records Group to the List Of Values.
These steps are all that is required to restrict the LOV, however to fully restrict the form we also need to amend the DEFAULT_WHERE (to stop users running ‘non-restricted’ queries IE: CTRL+F11) and also disable the other Radio Buttons in the Form.
To amend the DEFAULT_WHERE create the following action:
Action Type: Property
Object Type: Block
Target Object: VSET
Property Name: DEFAULT_WHERE
Click in the Value field and select 'Get Value' – this will return the seeded value, this can then be modified to restrict the results:
((validation_type IN ('I', 'D', 'X', 'Y') OR (validation_type = 'F' AND summary_allowed_flag = 'Y')) and parent_value_set_name in ('XXAPPS_CUST_ID'))To disable the other Radio Buttons create actions to set the Property ENABLED to False for the following items:
QUERY_FIND.REGION_POPUP.KEY
QUERY_FIND.REGION_POPUP.DESCR
QUERY_FIND.REGION_POPUP.CONC
CONTROL.REGION_POPUP.KEY
CONTROL.REGION_POPUP.DESCR
CONTROL.REGION_POPUP.CONC
Now when the form is opened the only available option is Values Sets and the LOV and Default Where is restricted to the XXAPPS_CUST_ID value.
Friday, 15 April 2011
Documentum: Site Caching Services with multiple targets
Documentum Site Caching Services is limited by its inability to build functionality based on object attributes (the only attribute that it references is Version Label), so in this example a TBO is used to add custom labels.
The scenario is a document can be published to either the Internet or Intranet or both, this is identified by a custom repeating attribute on the document called c_web_target (possible values are ‘Intranet’ & ‘Internet’).
A simple lifecycle has been created for this document type with the stages ‘Draft’, ‘Active’ and ‘Expired’; only active documents are to be published to the web sites.
When the documents are promoted to Active the custom labels should be applied, these are dynamic based on the values in the c_web_target so are not applied within the lifecycle, instead either the doSave or doPromote actions can be extended to call the following procedure:
protected void applyVersionLabel() throws DfException {
String DELIM = ":";
String strTarget = this.getAllRepeatingStrings("c_web_target",DELIM);
StringTokenizer token = new StringTokenizer(strTarget, DELIM);
while (token.hasMoreTokens()) {
String strCurrTarget = token.nextToken();
this.appendString("r_version_label", strCurrTarget);
}
}Site Caching can then be configured using the versions labels ‘Internet’ and ‘Intranet’.
Monday, 11 April 2011
Documentum: Security on Lifecycles
Something that caught me out today (mainly due to not reading the manual!); as well as requiring the appropriate permissions on the document/object that you are applying the lifecycle to, you also requires at least RELATE permissions on the lifecycle. Installing a lifecycle without setting an ACL may result in the error DM_SYSOBJECT_E_NO_RELATE_ACCESS when trying to assign it to a document (or the lifecycle not being available to select).
To correct the ACL on a lifecycle that has been installed use DQL to find the ACL that has been applied ...
select acl_name from dm_policy where object_name = 'your lifecycle name'.. then, in DA update the ACL to allow the required users/groups RELATE permissions.
Monday, 4 April 2011
Oracle: HTML Personalisations (Raw Text and URL Include)
These first simple extensions shows how to add a bespoke 'Message Of The Day' banner to the Oracle Application Home Page.
Create a new item within the table layout "Home Contenttable" region.
Example xx_motd.htm
Example 1 – Raw Text.
Enable the profile option Personalize Self-Service Defn at user level, this enables the personalisation links on HTML forms and pages (after logging out and back in).
On the Application Home page select the Personalize "Home Contenttable” link.
Create a new item within the table layout "Home Contenttable" region.
Select the Item Style Raw Text, enter an ID (e.g.: xx_motd) and enter the static text or HTML code in Text field.
Example 2 – URL Include.
Create an htm file within the $OA_HTML (e.g.: xx_motd.htm) directory on the application server (see below for sample code).
Enable personalisation links and select Personalize "Home Contenttable" then create an item with an Item Style of URL include, enter an ID (e.g.: xx_motd) and in the Source URI enter the path to your htm file (e.g.: /OA_HTML/xx_motd.htm).
Example xx_motd.htm
| <!-- ---------------------------------- --> <!-- dbdrv: none --> <!-- File : xx_motd.htm --> <!-- Author : C Hammond --> <!-- Creation Date : 10-AUG-2010 --> <!-- Message Of The Day HTML Plugin --> <!-- ---------------------------------- --> <td id="MessageOfTheDay" class="x9k" valign="top" width="34%"> <table id="MessageOfTheDay" class="xn" cellpadding="0" cellspacing="0" style="border:1px #87B4D9 solid;" width="100%"> <tr> <td class="xp" style="background-image:url (/OA_HTML/cabo/images/swan/headingBarBg.gif);"> <h2 class="x75"> <!-- Plugin Header: --> Message Of The Day <!-- --> </h2> </td> </tr> <tr> <td style="background-color:#D9E5EF"> <br> <font face="Tahoma" size="2px" color="#147590"> <div style="padding-left: 0.5em;"> <!-- Plugin Text: --> <STRONG>Latest News</STRONG> <br> Your message goes here ... <!-- --> </div> </font> <br> </td> </tr> </table> </td> |
Subscribe to:
Posts (Atom)


