Sunday, January 28, 2018

Behavior of think-time Functions in PeopleSoft

Some issues are uncommon, weird and hard to understand what exactly went wrong. One such weird issue in peoplesoft is related to Think-time functions. I know many of my colleagues who were stressed to the core and said ‘Its time to leave this planet’ because of this peculiar issue in Peoplesoft. Come!! Let’s sort this one out.

Think-time PeopleCode event (<think-time event>), but a SQL update has occurred in the commit interval.

In this article, let’s see what think-time functions are, and some of the limitations that require our attention when dealing with such functions.


Basically, any function that waits for user input or external process to complete is a think time function. Messagebox, for instance, waits for user to click Ok or Cancel button… Exec() function running in synchronous mode which suspends processing until the triggered process is complete.

Listed below are the think-time function in PS

  • DoCancel
  • DoModal
  • DoModalComponent
  • Exec(Only when it runs in Synchronous Mode)
  • AddAttachment, MAddAttachment, ViewAttachment, DetachAttachment
  • InsertImage, CropImage
  • CreateObject, ObjectDoMethod, ObjectSetProperty, ObjectGetProperty(When object Required User- action)
  • Prompt
  • RemoteCall
  • RevalidatePassword
  • WinExec(Only in Synchronous mode)
  • Winmessage and Messagebox(Depending on Style Parameter)
  • Calls to an External DLL

Think-time functions in Application Engine

Are you using Exec() or RemoteCall() in AE to run a batch file or a remote process? You should consider the following then:

Exec(&unixCmd, %Exec_Asynchronous + %FilePath_Absolute); /*Running in Asynchronous mode*/
&ExitCode = Exec(&unixCmd, %Exec_Synchronous + %FilePath_Absolute); /*Running in Synchronous mode*/

Running Exec() in Asynchronous mode is not a think-time function, as the AE process does not wait for the invoked command to complete. With Synchronous mode it is different, because the AE process needs to wait for the invoked command to complete. OH!! That’s Pathetic.. Don’t expect it to wait for you if you haven’t committed pending transactions, you will end up in think-time event error. 

The simple solution here is to issue a Commit before Exec() is invoked. If AE was written to be Restartable, then make sure that the previous step is committed before the step executing Exec. For AE with ‘Disable Restart’ checked, a CommitWork() has to be issued before Exec(). Easy right?

Think-time functions in Component Interface

Think-time functions are usually suppressed and ignored in CI. So, in such cases better to write a separate logic for CI.

If %CompIntfc then
/*Logic for CI*/
Else
/*Get user Input*/
End-if;

Think-time Functions in Peoplecode

Winmessage() and MessageBox() behaves as a think-time function only when the style parameter specifies more than one button. When you make the style parameter to show only Ok Button(0), then it behaves like a normal function. If style is neglected, Winmessage() displays both Ok and Cancel Button which acts as a think-time function. Hence you must always specify with style parameter like Winmessage(“Test Message”, 0) to show only Ok button.

Sometimes you would have noticed that your MessageBox or Winmessage does not work before call to a Transfer or TransferExact function. If you want to display your message, then change the style to show OK and Cancel Button.

It’s not so hard to debug when you receive error in peoplecode related to think-time functions. PeopleBooks suggests us not to use think-time functions in SavePreChange, Workflow, RowSelect, SavePostChange, and any peoplecode event that executes as a result of ScrollSelect, ScrollSelectNew, RowScrollSelect, or RowScrollSelectNew function call, and any peoplecode event that executes as a result of Rowset class Select or SelectNew method. If you are using think-time functions in one of the above events, just get red of it.



Monday, January 22, 2018

PeopleSoft - Data Conflict Issues

“Come on!!! This is such a simple and straightforward component.. It’s not fair… Why am I running into this issue…”. Ever felt disheartened like this when you see these kind of error messages? 


Data being added conflicts with existing data(18,2 

or 

Changes conflict with another data item. (18,5)


Chill out!! You are not alone.. Let’s set this right..
The prime cause of this issue is because of writing into a PS Record with duplicate key values. Basically, there exists a row with some key values and you are trying to add another row with same key combination, so look out for how did you end up with such duplicate rows. 
I have itemized a few steps which needs validation when you encounter this error

Get the Basics Right – Record Level Structure

Remember your first lesson in creating multiple levels in PS? Yes.. Level 1 record must contain key fields from Level 0 Record and an additional key. Check out if your key structure is right, otherwise fix it now.

Stop Clashing with Component Processor – No Auto Select & No Auto Update Property

Either you do the selection of rows from tables or allow the component processor to do it for you. When you populate a grid or scroll area through peoplecode, you must check the ‘No Auto Select’ property. Likewise, when you have decided to take care of updating the backend records, better select the ‘No Auto Update’ option. When you ignore this, you end up updating the same row twice leading to this issue. 
Thoroughly check all the grid and scroll area properties from your main and secondary pages and make sure you don’t clash with the component processor.


I would recommend allowing the component processor to do its job unless you have some business requirement that requires selection or updation through peoplecode. Atleast try avoiding SQLEXEC statements to insert or update records which are readily available in your component buffer. Why reinvent the wheel??

Weird Field Assignments

Let’s say you have a field named ‘COMPANY’ which is a key field in one of your records and a peoplecode in ‘PreBuild’ or ‘Rowinit’ event sets a default value to this field. If this field is editable and user enters some value and saves it, the next time when user opens the page again, the default value is displayed again and if you try to modify this key field and save again, you will encounter Data Inconsistency issue.
So always look for such weird field assignments/modifications, 
Check out for Saveprechange or Savepostchange events, if some code is modifying your key values.
Did you overlook your record peoplecode? There are chances that the same record is being used in multiple components and the code written for some other purpose gets triggered for our business transaction resulting in data conflict issues.

Out of sync Sequence Numbers

When you use sequence numbers in your page that needs to be incremented and updated every time, better not to go with SQLEXEC Update statements, Instead use the delivered getNextNumberwithGapsCommit() function. This can help avoid data inconsistency issues. 

Clear App Server Cache

For no reason, if most of the users receive data conflict issues, I would suggest to clear the app server cache. Believe me, it helps sometimes.

Tuesday, January 9, 2018

You are not authorized to access this component. (40,20)

I once had a very dreadful day at office breaking my head trying to solve what looked like a very simple security issue. ‘You are not authorized to access this Component (40,20)’. If you are having one such distressing day today, then don’t worry, you have landed at the right place and we are going to fix this right away.

This is one of the most prevalent security issue in Peoplesoft faced by every Peoplesoft developer atleast once in their lifetime. We have prepared a simple checklist indicating all the possible scenarios where this issue could happen with quick solutions for the same.

    Security Access:

   First and foremost, check whether you have access to the component/page you are trying to access. Use the following query to verify if you have access.

SELECT R.rolename ,

  RC.classid

FROM psroleuser R ,

  psroleclass RC

WHERE RC.Rolename = R.Rolename

AND R.roleuser    = '<OPRID>'

AND RC.classid   IN

  (SELECT CLASSID

  FROM psauthitem AUTH

  WHERE AUTH.baritemname='<COMPONENT_NAME>'

      AND AUTH.pnlitemname  ='<PAGE_NAME>'

  )

Non-existing permission list assigned to the role:

There will be instances where a permission list exists in a role but not in the database. This usually happens when project is migrated from one database to another but does not include the permission list. Use the below query to identify if you have any such permission list missing.

Select R.rolename

, RC.classid

From psroleuser R

, psroleclass RC

Where RC.Rolename = R.Rolename

And not exists

(Select 'X' from psclassdefn C

Where C.classid = RC.classid)

-- And R.roleuser = '<OPRID>'


Still not able to access? Why not try running the Portal Security Sync process from the following Navigation.

  PeopleTools - Portal - Portal Security Sync

Issue with Transfer function:

There are scenarios where the system should change the flow of transaction from one component to another using Transfer function. In such cases, verify if the below points are taken care.
   i) Have you specified the correct action mode while using Transfer function?
    Transfer( False, MenuName.DEFINE_PAYROLL_PROCESS, BarName.SETUP,             ItemName.ACCOUNT_CODE_TABLE, Page.ACCT_CD_TABLE, "L", &Parmrec); 


As you see in the above example, the component is registered in ‘Update/Display’ and ‘Correction mode’, whereas Transfer function is trying to access this component in ‘Update/Display All’ mode, which is not correct. Accessing this component in ‘Add’ or ‘Update/Display All’ mode using Transfer function will result in this Security issue.

ii) Have you specified the correct ItemName in Transfer Function? People often tend to misinterpret ItemName with Component name, which is incorrect.

Transfer( False, MenuName.DEFINE_PAYROLL_PROCESS, BarName.SETUP, ItemName.ACCT_CD_TABLE_NEW, Page.ACCT_CD_TABLE, "U", &Parmrec);



As you see in the above example, Item Name is ‘ACCOUNT_CODE_TABLE’ and component name is ‘ACCT_CD_TABLE_NEW’.
The correct way of writing this Transfer function function is:
Transfer( False, MenuName.DEFINE_PAYROLL_PROCESS, BarName.SETUP, ItemName.ACCOUNT_CODE_TABLE, Page.ACCT_CD_TABLE, "U", &Parmrec);

    Mostly by now, you should have been able to fix this issue. If you are still reading this point, then I would suggest you to clear the application server cache and reboot the server and try again.