I am trying to achieve flattening a table into an array (or structure). My implementation is in SAP ABAP; however, I believe the question is code agnostic. I am wondering if there is an algorithm I'm not aware of or simple solution for what I'm trying to achieve. I will accept any language or pseudocode as an acceptable answer.
I am selecting from a "User Restrictions" (i.e., lt_restrictions) table stored on a database, e.g.:
This is needed for an SAP BSP MVC web app. When the app loads, I am doing user authorization checks to populate a "User Roles" (i.e., mt_user_roles) local table/array (i.e., attribute on an MVC model class).
The authorization checks involve routine ABAP -- using IF statements to conditionally populate the "User Roles" table, e.g.:
AUTHORITY-CHECK OBJECT 'PROGRAM_MANAGER_AUTH' ID 'xxx' FIELD 'yyy'.
IF ( sy-subrc = 0 ).
APPEND VALUE #( low = 'program_manager' ) TO me->mt_user_roles.
ENDIF.
If the user has both e.g., program manager AND entry user authorizations, this "User Roles" table/array would look like this:
With the two tables above, if the user has program manager and entry user roles, the only restriction is convert; therefore, I need to populate a "Restriction List" (i.e., ms_restrictions) like the following:
Otherwise, if the user has e.g., only the entry user role:
...there are 2 restrictions (release AND convert), so I would need to populate a "Restriction List" (i.e., ms_restrictions) like this:
I feel like there is a standard algorithm I could use or perhaps this could be done with SQL in a SELECT statement with my database table WHERE restriction = NULL (e.g., WHERE save = ' ') or using a SELECT ... WHERE x IN clause, perhaps, if the "Restrictions List" was a RANGE table?
I should mention, I already have an undesirable, partial solution which involves looping through the database table and having several IF statements for each restriction condition. "Restriction List" is named ms_restrictions, it is a class attribute ABAP STRUCTURE type (for ABAP newbies, this is basically a 1-D sized array):
LOOP AT lt_restrictions INTO DATA(ls_restriction).
LOOP AT mt_user_roles INTO DATA(ls_user_role).
"Check save restriction
IF (
ls_restriction-role = ls_user_role-role AND
ls_user_role = 'save'
).
ms_restrictions-save = 'x'.
ENDIF.
"Check release restriction
IF (
ls_restriction-role = ls_user_role-role AND
ls_user_role = 'release'
).
ms_restrictions-release = 'x'.
ENDIF.
"Check other restrictions
"......
ENDLOOP.
ENDLOOP.
The problem with the solution above is I have to write an IF statement for each restriction. More so, it doesn't take into account whether there are conflicts between 2 or more role restrictions, e.g., program manager has only 1 restriction while entry user has 2. My logic above could be extended to take this into account with -- well -- even more IF statements :-( .. I'm wondering if there's a different approach I can take?
Also, I should mention. The resulting "Restrictions List", i.e., mt_restrictions, is needed in my view for disabling HTML buttons, e.g.:
<button value = 'Save' disabled = '//model/mt_restrictions-save' />
<button value = 'Release' disabled = '//model/mt_restrictions-release' />
<button value = 'Convert' disabled = '//model/mt_restrictions-convert' />
<button ... />