When creating/modifying a business object, we want to check whether any fields are missing/appear inconsistent or could block the rest of the process. But sometimes, we just want to notify the user and ask for confirmation without reporting an error. To do this, we use a confirmation pop-up, and we will see how to configure this easily in ABAP RAP and Fiori Elements.
Our objective here will therefore be as follows: We will add a validation within the previously created Business Object that will check that the Text or Text2 fields are not empty. If both are empty, the validation will send a confirmation request message to the user.
The code is available on our Gitlab.
I. The various documents
Looking at the documentation, we can already see that there are two types of messages for reporting information back to the user:
- Transition message:
Lifetime: only valid during the execution of the query.
Scope: related to the action in progress (the “transition” between states), not to the Business Object itself.
Example in the documentation: An UPDATE on an entity, but it is locked by another user. In this case, the message “Business Object is locked by user &1” is a transition message.
- State message
Lifetime: linked to the current state of a Business Object instance.
Scope: reflects an inconsistency (validation) in the values or a change in state (determination) of the Business Object.
Example in the documentation: The CustomerID entered is not maintained in the Customers table. In this case, a State message must be sent.
Characteristics:
– Persists as long as the condition is true (example: as long as the customer is not modified).
– Typically triggered in validations (checks) or determinations (adjustments).
Next, based on this second piece of documentation, it is possible to ensure that a confirmation pop-up is created if the HTTP call return code is as follows: 412 “Precondition Failed.” The documentation states: “For SAP Fiori elements, the 412 message indicates that there are warnings that block the processing of the action, but users can still trigger the action if they choose to ignore the warnings and continue.”
Based on this documentation, we must therefore create a state message (because the check is a validation on an instance of our entity). And this validation must return a warning message (not an error) that triggers an HTTP 412 return code that can be interpreted by the Fiori Elements framework.
Point of attention:
It is noted in the latest documentation that the message returned on the backend side must be a transition message and not a state message.

Indeed, we can read here that “Only transition messages are transported in the error response. The messages may be bound or unbound.”
However, in our case, the RAP framework ensures that a transition message is sent via the OData response, even though on the RAP side, the message is a State message. We will also see, when testing via a transition message in RAP, that the behavior is different and does not correspond to what is expected.
II. Development
We start by adding validation to the Behavior Definition:

Since we are in Draft mode, we also add validation to the Prepare action so that it is performed. As a reminder, the Prepare action ensures the consistency of the Draft instance by calling the validations and determinations during registration that are specified for the Prepare action in the Behavior Definition.
Next, we add the validation:
METHOD validation.
READ ENTITIES OF zr_crt_test IN LOCAL MODE
ENTITY zrcrttest
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT DATA(results_read).
LOOP AT results_read INTO DATA(read).
APPEND VALUE #( %tky = read-%tky
%state_area = if_abap_behv=>state_area_all ) TO reported-zrcrttest.
IF read-Text IS INITIAL AND read-Text2 IS INITIAL.
APPEND VALUE #( %tky = read-%tky
%msg = NEW zside_effect_message(
textid = zside_effect_message=>missing_value
severity = if_abap_behv_message=>severity-warning )
%state_area = 'WARNING'
%element-text = if_abap_behv=>mk-on
%element-text2 = if_abap_behv=>mk-on
) TO reported-zrcrttest.
ENDIF.
ENDLOOP.
ENDMETHOD.
- We obviously specify the %tky that corresponds to the instance being modified.
- We add a warning message if_abap_behv_message=>severity-warning.
- To make the message a state message, we specify the %state_are
- Here, we specify %element-text and %element-text2 so that the fields in question are highlighted (in orange) in the UI.
- Finally, and this is very important, we ONLY fill in the REPORTED parameter and not FAILED.
Note: Status messages must be invalidated so that they are not continuously added to a REPORTED structure if the same query is triggered several times on the same instance, or if the error message has been corrected.
To do this, we added this piece of code:
APPEND VALUE #( %tky = read-%tky
%state_area = if_abap_behv=>state_area_all ) TO reported-zrcrttest.
III. Tests and analyses
Following our development, here is the result on the UI:

A pop-up appears asking the user for confirmation.
Note that the return message from the Activate action is indeed a 412: Precondition Failed.

And we find the error message configured in the response body:

After the error message is displayed, the user has two options:
- Cancel the operation: In this case, it returns to the previous page with the fields highlighted:

Confirm the operation: In this case, the Activate action is restarted.

And the entity is successfully created:

III. Just to test
- Case of a transition message in ABAP RAP
Now let’s change the state message created by a transition message at the validation level:
As seen in the documentation, simply remove the field %state_area = ‘WARNING’.
METHOD validation.
READ ENTITIES OF zr_crt_test IN LOCAL MODE
ENTITY zrcrttest
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT DATA(results_read).
LOOP AT results_read INTO DATA(read).
APPEND VALUE #( %tky = read-%tky
%state_area = if_abap_behv=>state_area_all ) TO reported-zrcrttest.
IF read-Text IS INITIAL AND read-Text2 IS INITIAL.
APPEND VALUE #( %tky = read-%tky
%msg = NEW zside_effect_message(
textid = zside_effect_message=>missing_value
severity = if_abap_behv_message=>severity-warning )
%element-text = if_abap_behv=>mk-on
%element-text2 = if_abap_behv=>mk-on
) TO reported-zrcrttest.
ENDIF.
ENDLOOP.
ENDMETHOD.
With this case, we no longer have a validation popup appearing. Only an information popup, which does not make sense here because the instance is created without the user’s consent.

We also note that the Activate action returned an HTTP 201 code rather than 412.

- In the case where we add the FAILED parameter
METHOD validation.
READ ENTITIES OF zr_crt_test IN LOCAL MODE
ENTITY zrcrttest
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT DATA(results_read).
LOOP AT results_read INTO DATA(read).
APPEND VALUE #( %tky = read-%tky
%state_area = if_abap_behv=>state_area_all ) TO reported-zrcrttest.
IF read-Text IS INITIAL AND read-Text2 IS INITIAL.
APPEND VALUE #( %tky = read-%tky
%msg = NEW zside_effect_message(
textid = zside_effect_message=>missing_value
severity = if_abap_behv_message=>severity-warning )
%state_area = 'WARNING'
%element-text = if_abap_behv=>mk-on
%element-text2 = if_abap_behv=>mk-on
) TO reported-zrcrttest.
APPEND VALUE #( %tky = read-%tky ) TO FAILED-zrcrttest.
ENDIF.
ENDLOOP.
ENDMETHOD.
In this case, the pop-up does not appear and the user cannot save the instance.

The HTTP call return code for the Activate action is 400 Bad Request.
Conclusion
We have seen that it is possible to use RAP and Fiori Elements to request user approval to create/modify an entity if a validation returns a warning. To do this, simply create a State Message in the validation and the framework will take care of the rest!