Hi guys,
As you all are already aware of that Purchase Requisition list page is a shared list page across all legal entities.
"PurchReqTable" and "PurchReqLine" are the two main shared tables containing most of the information related to the Purchase Requisitions.
I got a requirement related to Purchase Requisitions visibility where in Department heads or Senior Management Personnel wants to see Purchase Requisitions of specific Originators across different legal entities that system does not support. Therefore, I had to do some minor customization in order to fulfill this requirement.
Whenever, i do any customization, i always make sure to parameterize in such a way that customization should be controlled in a proper manner and without doing any hard coding in code logic. All my customization are parameterized without affecting standard processes of the system.
Custom Table:
I created a custom shared table named "PRViewAccess" containing two fields that are sufficient to manage the customization
1) UserId [Current user]
Datatype: String.
Set "UserId" as EDT in property
2) Worker [PR Originator]
Datatype: Int64
Set "HcmWorkerRecId" as EDT in property
Set Index property for not allowing duplicate values in the combination of "UserId" and "Worker" which means same "UserId" and "Worker" combination values can't be saved in the table and system should throw error message like "Record already exists"
Custom Form:
I created a custom form and attached "PRViewAccess" as a Datasource to the form
Created a worker lookup for selecting Past, Present or Future workers across different legal entities.
Used standard "HcmWorkerLookup" class for loading and displaying lookup in "PR Originator" field instead of customizing new lookup in the PR View Access form
Below is the code snipped of Worker lookup in the Form
[Form]
public class PRViewAccess extends FormRun
{
//HcmWorkerLookup class
HcmWorkerLookup hcmWorkerLookup;
public void init()
{
super();
hcmWorkerLookup = HcmWorkerLookup::newActiveWorkers();
}
[DataSource]
class PRViewAccess
{
[DataField]
class Worker
{
/// <param name = "_formReferenceControl"></param>
/// <returns></returns>
public Common resolveReference(FormReferenceControl _formReferenceControl)
{
HcmWorker ret;
ret = super(_formReferenceControl);
if (ret != null && !hcmWorkerLookup.validateWorker(ret.RecId))
{
ret = null;
}
return ret;
}
/// <param name = "_formReferenceControl"></param>
/// <returns></returns>
public Common lookupReference(FormReferenceControl _formReferenceControl)
{
Common ret;
ret = hcmWorkerLookup.lookupWorker(_formReferenceControl);
return ret;
}
}
}
}
Created an EventHandler class for handling Purchase Requisition records filtering for specific users based on the Originator in the "All Purchase Requisitions" List page
PR Originators or Preparers that are assigned to specific users in PRViewAccess form, those specific users will be only able to view PRs prepared by those Originators or Preparers
For example:
"PRViewAccess" table contains below records just of explanation
Field1 Field2
UserId Worker
Record1 User1 Preparer1
Record2 User1 Preparer2
Record3 User2 Preparer1
Record4 User3 Preparer3
When User1 will login system then this user will be able to view PRs of Preparer1 and Preparer2 only, User2 can view PRs of Preparer1 only and User3 can view PRs of Preparer3 only.
public class PRViewAccessRestrictedByPROriginators
{
/// <summary>
/// This class is used to restrict users by workers assigned to the users
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[FormDataSourceEventHandler(formDataSourceStr(PurchReqTableListPage, PurchReqTable), FormDataSourceEventType::QueryExecuting)]
public static void PurchReqTable_OnQueryExecuting(FormDataSource sender, FormDataSourceEventArgs e)
{
FormRun PurchReqTableListPage = sender.formRun();
PRViewAccess viewAccess;
container workers;
//curUserId method returns logged in user
while select viewAccess
where viewAccess.UserId == curUserId()
{
workers += queryValue(HcmWorker::find(viewAccess.Worker).RecId);
}
if(conLen(workers) != 0)
{
sender.query().dataSourceName(sender.name()).addRange(fieldnum(PurchReqTable, Originator)).value(con2Str(workers));
//Applied RangeStatus as Locked to lock the range that is applied on the Originators
sender.query().dataSourceName(sender.name()).addRange(fieldnum(PurchReqTable, Originator)).status(RangeStatus::Locked);
}
}
}
}