Introduction:
Main aim of any application is to keep the transactional document error free. That says how important is error handling and validations in the application process.
In this blogpost, I will explain how we can implement real time validations on field input in a transactional fiori application with ABAP RAP framework. Instead of executing the validations at the save in the end.
Problem statement:
In the traditional approach ( link ), the validations can only be executed at SAVE in the end. The disadvantage in this approach is that inconsistent values have already been entered and the document becomes inconsistent. if it is a draft enabled application, then these inconsistent values have already been stored in draft tables and transactional buffers. This is additional work for the user to clear all those errors at the end. As a user, he/she always expects to display the error on field input.
define behavior for ZBP_xxxx alias PurCon
...
{ ...
validation ValidateHeaderFields on save { field Supplier , CompCode ; }
… }
If it is a simple dependency, then it might be useful to use parameterized CDS value help. So that dependent field ( field #2 – Ex. Supplier contact person ) value help can restrict the possible values based on parameter ( field #1 – Supplier).
Supplier;
@UI:{ lineItem: [{ position: 50 }] , identification: [{ position: 50 ,qualifier: 'General'}]}
@Consumption.valueHelpDefinition: [{ entity: {
name: 'ZRK_I_SUP_CON',
element: 'SupConId'
} ,
additionalBinding: [{
localElement: 'Supplier',
localConstant: '',
element: 'SupNo',
usage: #FILTER_AND_RESULT
}] ,
useForValidation: true
}]
SupConId;
But the challenge in this approach is that if multiple large tables need to join to give the value help result then it might slow down the application. In those cases, evaluating errors is quicker than restricting the values from huge joins.
However this approach does not help if the user changes values vice versa( Ex. value of the supplier to something else).
Even this approach does not work, if we use custom entities for value help.
In both cases, we must implement validation at the SAVE interaction phase to ensure the document is consistent . But it is already too late to inform the user.
Solution:
Answer is YES and let us look at probable solutions to this problem statement. The solution is to trigger real time validation on field input and that can be implemented using PRECHECK in the RAP framework.
With a precheck implementation you can deny incoming requests before data reaches the transactional buffer. You can prevent illegal changes from reaching the transactional buffer by prechecking modify operations.
During PRECHECK implementation, we can keep validation logic and generate FAILED and REPORTED parameters so that error messages can be displayed on FIORI screen. This error will be cleared only after the user gives correct input to the field.
Implementation and business example:
Let us take a business case in which we have a complex logic to validate the usage of supplier and company code for the logged in user’s department and some customizing. So the validation needs to be executed whenever there is input either on supplier or company code.
Steps:
1. Enable PRECHECK for standard operation UPDATE using below syntax in the Behavior Body
update ( precheck );
2. Implement the respective method in the behavior pool class using quick fix.
METHODS precheck_update FOR PRECHECK
IMPORTING entities FOR UPDATE PurCon.
3. Check if the required fields have been modified using control structure ( 01 -> modified , 00 -> untouched in this interaction ).
CHECK <fs_entity>-%control-Supplier EQ '01' OR <fs_entity>-%control-CompCode EQ '01' .
4. If yes, then proceed with validation using wrapper business logic.
zrk_cl_mng_pur_con=>validate_supp_le(
iv_supplier = <fs_db_con>-Supplier
iv_comp_code = <fs_db_con>-CompCode
) .
5. If the validation fails, then fill the return structures FAILED and REPORTED ( refer the example ) .
METHOD precheck_update.
LOOP AT entities ASSIGNING FIELD-SYMBOL(<fs_entity>).
CHECK <fs_entity>-%control-Supplier EQ '01' OR <fs_entity>-%control-CompCode EQ '01' .
READ ENTITIES OF zrk_i_pur_con_ud IN LOCAL MODE
ENTITY PurCon
FIELDS ( Supplier CompCode )
WITH VALUE #( ( %key = <fs_entity>-%key ) )
RESULT DATA(lt_con).
READ TABLE lt_con ASSIGNING FIELD-SYMBOL(<fs_db_con>) INDEX 1.
IF sy-subrc EQ 0.
<fs_db_con>-Supplier = COND #( WHEN <fs_entity>-%control-Supplier EQ '01' THEN <fs_entity>-Supplier ELSE <fs_db_con>-Supplier ) .
<fs_db_con>-CompCode = COND #( WHEN <fs_entity>-%control-CompCode EQ '01' THEN <fs_entity>-CompCode ELSE <fs_db_con>-compcode ) .
IF NOT zrk_cl_mng_pur_con=>validate_supp_le(
iv_supplier = <fs_db_con>-Supplier
iv_comp_code = <fs_db_con>-CompCode
) .
APPEND VALUE #( %tky = <fs_entity>-%tky ) TO failed-purcon.
APPEND VALUE #( %tky = <fs_entity>-%tky
%state_Area = 'VALIDATE_SUP_LE'
)
TO reported-purcon.
APPEND VALUE #( %tky = <fs_entity>-%tky
%state_Area = 'VALIDATE_SUP_LE'
%msg = NEW zrk_cx_msg(
severity = if_abap_behv_message=>severity-error
textid = zrk_cx_msg=>c_sup_le_match
supplier = <fs_db_con>-Supplier
comp_code = <fs_db_con>-CompCode )
%element-supplier = if_abap_behv=>mk-on
%element-compcode = if_abap_behv=>mk-on
) TO reported-purcon.
ELSE.
APPEND VALUE #( %tky = <fs_entity>-%tky
%state_Area = 'VALIDATE_SUP_LE'
)
TO reported-purcon.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.
6. Now you can see the error on FIORI UI without reaching the transaction buffer to the database.
No comments:
Post a Comment