The authorization check in SAP TM is modeled by default to the document level. If a certain user is authorized to modify a certain document, all data can be modified.
Sometimes there are requirements for an even more granular approach. For instance, one set of users is allowed to see and change a certain document in its entirety, some other set of users can see all data from the document, but modify only a part of it, while other set of users is allowed to see only a part of document.
There are more possible alternatives to fulfil such requirements. I am concentrating today on the UI-based approaches. Even here, depending on the exact use-case, there are more possibilities.
I am presenting today on one specific use case: some users are allowed to see all data from the document (exactly as it’s displayed in UI), but is allowed to change only parts of it. By “part” I mean a complete UI assignment block, like “General Data”, “Business Partners”, or at least a complete UI Building Block (UIBB) – a certain form, a certain list etc. The criteria used to determine whether the users can change the document are static (do not depend on the document itself).
The requirement to disable or hide partial data from a UIBB is more complex and needs to be covered differently then presented here.
For such a simple use-case, there is also a simple solution. Actually, the hardest part is to identify the required repository objects (WD application, application configuration, UIBB configuration, feeder class) – I assume here that you’re familiarized with Floorplan Manager (FPM) concepts. If not, I recommend you to visit the FPM space on SCN; there is ample documentation, examples and how-to-s posted there.
Luckily, someone has already blogged about a simple way to determine the names of the involved repository objects in SAP TM screens (okay, I know that the illeism can sometimes hint to developmental disorder…).
Now let’s go back to the solution for our requirement. It’s really simple and involves three steps.
Step 1: Locate the method GET_DEFINITION of the affected feeder class (the complete method name includes also the interface name, different for various FPM components – we have one for form, one for list and one for tree). Create (or reuse) an enhancement in this class and add a POST implementation exit to this method. Then add coding like depicted below
Of course, ZCL_MYCLASS is the class a customer needs to create, and the actual coding of the method IS_UIBB_WRITEPROTECTED depends on the exact definition of “a subset of users”. For the purpose of this enhancement, it suffices to know that the method returns a boolean which indicates whether the given user is forbidden to modify data from the given UIBB from the given application configuration of the given WD application.
If the UIBB must be “write-protected”, we disable the reference field for “read-only” functionality, to simplify setting the property later in step 2.
Make sure to create the member attribute in the enhancement class as highlighted in the screenshot.
Note: As you can I am using some ABAP language constructs (like inline data declaration) which are available in NW 7.4 only )so TM 9.1 and later). In older releases you’ll need to use the compatible alternative, like in this case declaring the reference and field symbol separately.
Step 2: Locate the method GET_DATA of the affected feeder class (again, the complete method name includes the interface name). Reuse the enhancement from step 1 and add a PRE implementation exit to the method. In it, add the following coding:
Not much to explain here, we’re just “remembering” the field and action properties as they are before the standard GET_DATA of feeder class runs. We’ll need it later for performance reasons. Make sure to create the member attribute in the implementation class as highlighted in the screenshot.
Step 3: Add now a POST implementation exit to the method. In it, add the following coding:
I think the coding is pretty straightforward – we are setting all fields of this UIBB to “read only”, and all actions to “disabled”.
The indicator whether the UIBB should be write-protected can be reused from Step 1. Since GET_DEFINITION runs only once in the lifetime of a screen, the reuse helps avoiding potential expensive calls to the check method.
The cache created in Step 2 helps us to determine whether or not an actual change occurred compared to the values already known by FPM framework. It’s better to avoid setting the flags *USAGES_CHANGED unnecessarily, since this would lead to an rather expensive re-rendering of the UIBB.
That’s it. In my example, the coding of method IS_UIBB_WRITEPROTECTED is rather trivial. For my user name, I am write-protecting the list of business partners in the freight order screen.
As a result, you can see that even if the freight order screen is in “edit” mode, and I can modify data in the list of stages, the business partners are read-only.