Saturday, December 5, 2020

Purchase Requisition records filtering for specific users based on the Originator X++

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);

            }

        }

    }

}

No comments:

Post a Comment

Enable and Disable Vendor invoice button on PO list and details page X++

Hi folks, This blog will be useful where vendor invoice process is required to be controlled based on certain conditions. Requirements: Proc...