This was an interesting requirement. Customer wanted the Search record of a Component to be changed dynamically- When different set of users accesses the same Component.( Assume, Different Search record for Different Permission List/Role).
One quick solution for similar problem is: Registering the component with another Menu and over-ridding the search record of component at Menu item level. PeopleSoft has used this approach at few places (e.g For Job Component), but this approach will invariably need another Portal Content Reference ( a different navigation) which customer might not agree for.
Analysis of this requirement:
a) Can't we change the search record of component the way we change the prompt table associated with a record-field (Remember %Edittable1,%Edittable2...) ? No, If we enter these values, error message pops up saying Invalid search record.
b) Can't we leave the search record field empty and fill it at run time ? No, this is a mandatory data while creating a component ( It has to be, and you know why)
c) Is there a way to change search record of a component at run time ? Yes, we can, but that will be 'changing Metadata' which is shared by all the users. So, if change search record 'REC1' for the component then this search record will be shared among all the users accessing that component (unless we keep on changing it for all different users). Please understand that PeopleTools table PSPNLGRPDEFN is not user (oprid or role or permission list) dependent and we should not alter it. (PS: We take this approach when we need to maintain User's role dynamically in PSROLEUSER table).
d) We are not quite sure which PeopleCode event should be used to achieve above mentioned three points.
e) We need to understand the purpose of Search record in a component and how PeopleSoft makes use of it.
(1) The search/alt srch fields in the search record are the fields that brings the Search Dialog Box to the User as a search criteria.
(2) The search record field populates the high-level, or level 0, key fields on a page.
(3) The search record for a component might differ from the primary record definition for a page and might contain any number of search keys, but it must contain all of the keys for each main level 0 record for a page.
(4) Out of the Box 'Row level Security' is implemented by PeopleSoft using Search Record only. We can add our own logic to filter out the data based on business rules.
(4) There is no Events outside the Component Processor flow which can manipulate the values returned by the search record. When component starts building up from reset state, the first two PeopleCode event which triggers are SearchInit and SearchSave written over Search Record of the Component.These PCode events have specific purposes and can't control the data fetched from the search record.
Proposed Solution:
Lets say, for Permission list 'HCCPHR3310' Search Record should be 'SEARCH_VW1', for 'HCCPHR3320'--> 'SEARCH_VW2' and for 'HCCPHR3330'--> 'SEARCH_VW3'.
( I assume these search records are custom sql views covering all the business rules and no more validation is required on top of this)
Step 1: By now we understand that changing search record of component dynamically is not advisable/feasible. However, we can control the data returned by the search record. For this, we'll create a Dynamic View (RKA_DYN_VW) which will serve our purpose. The Dynamic View will have all the search and alt search record required - level 0 key fields of a page. ( Assume EMPLID and EMPL_RCD are two search key fields in our Dynamic View)
Step 2: Create a Sql something like this (Sql Name: RKA_DYN_SQL):
SELECT EMPLID
,EMPL_RCD
FROM %Table(%P(1))-----> will Pass the Record Name
WHERE EXISTS (
SELECT 'X'
FROM PSROLECLASS A
, PSROLEUSER B
, PSOPRDEFN C
WHERE A.ROLENAME = B.ROLENAME
AND C.OPRID = B.ROLEUSER
AND C.OPRID = %OperatorId----> Will take Current user's Operator Id
AND A.CLASSID=%P(2))----> Will pass the Permission List
Step 3:
Create a new SQL RKA_UDYN_SQL, as below:
%Sql(RKA_DYN_SQL,SEARCH_VW1,'HCCPHR3310')
UNION %Sql(RKA_DYN_SQL,SEARCH_VW2,'HCCPHR3320')
UNION %Sql(RKA_DYN_SQL,SEARCH_VW3,'HCCPHR3330')
step 4:
View Defn of RKA_DYN_VW
SELECT DISTINCT ABC.EMPLID
, ABC.EMPL_RCD
FROM (%Sql(RKA_UDYN_SQL)) ABC
So, at run time this dynamic view will expand to:
SELECT DISTINCT A.EMPLID
, A.EMPL_RCD
FROM (
SELECT EMPLID
,EMPL_RCD
FROM PS_SEARCH_VW1
WHERE EXISTS (
SELECT 'X'
FROM PSROLECLASS A
, PSROLEUSER B
, PSOPRDEFN C
WHERE A.ROLENAME = B.ROLENAME
AND C.OPRID = B.ROLEUSER
AND C.OPRID = 'PSHC'
AND A.CLASSID='HCCPHR3310')
UNION
SELECT EMPLID
,EMPL_RCD
FROM PS_SEARCH_VW2
WHERE EXISTS (
SELECT 'X'
FROM PSROLECLASS A
, PSROLEUSER B
, PSOPRDEFN C
WHERE A.ROLENAME = B.ROLENAME
AND C.OPRID = B.ROLEUSER
AND C.OPRID = 'PSHC'
AND A.CLASSID='HCCPHR3320')
UNION
SELECT EMPLID
,EMPL_RCD
FROM PS_SEARCH_VW3
WHERE EXISTS (
SELECT 'X'
FROM PSROLECLASS A
, PSROLEUSER B
, PSOPRDEFN C
WHERE A.ROLENAME = B.ROLENAME
AND C.OPRID = B.ROLEUSER
AND C.OPRID = 'PSHC'
AND A.CLASSID='HCCPHR3330')) ABC
PS:*** We can write SearchInit PeopleCode to handle Search record prompt record change (Using Edittable or by any other approach over %PermissionLists).
*** Validation can be taken care by SearchSave PeopleCode
*** There could to a simple approach to achieve the same result (the way Row Level Sec is implemented using SJT). But in this present solution there is a high degree of flexibility because of the sql object RKA_UDYN_SQL.