This is a test message to test the length of the message box.
Login
ABAP RAP validation
Created by Software-Heroes

RAP - Validation

2059

Let's take a look at the validations in the RAP Business Object and how they are implemented in the framework.

In the business object, validations ensure that the data is consistent at all times, centrally across all actions that are carried out on the object. In this article we look at how to create such validations and how they work exactly.

 

General

Validations belong to the behavioral definition of a business object and are defined at the corresponding entity, where they should also apply. They are triggered when the data is saved and can be registered for the individual events such as create, update and delete. Furthermore, there is also the possibility that a validation is only triggered when a single field is changed.

 

General validation

The general validation refers to validations that are always triggered when saving certain events (Create, Update, Delete), see the following example.

 

Create

Let's define the first validation in an example. To do this, we begin by expanding the behavior definition:

validation validateKeyIsFilled on save { create; }

 

A validation is created with the keyword "validation", followed by the name of the validation and the event at which it is triggered. In almost all cases this is "on save", i.e. when saving the data in the save sequence. In the curly brackets we now state that the event only occurs when a data record is created. After enabling the behavior definition, we get the following warning message in Eclipse:

 

The implementation of the method in the behavior implementation (class) is still missing. You can easily create this by placing the cursor on the name of the validation and creating the method with CTRL + 1 in the Quick Assist. At the end you automatically end up in the class and the created method.

CLASS lhc_Partner DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    METHODS validatekeyisfilled FOR VALIDATE ON SAVE
      IMPORTING keys FOR partner~validatekeyisfilled.
ENDCLASS.

CLASS lhc_Partner IMPLEMENTATION.
  METHOD validateKeyIsFilled.
  
  ENDMETHOD.
ENDCLASS.

 

Implement

Before we start implementing the method, let's take a closer look at the interface. As you can see in the definition above, a parameter has been defined in the method interface, let's now check this in the signature:

 

In addition to the keys, you also have "failed" and "reported" available, which indirectly belong to the method.

  • KEYS - Passing the keys to be checked to the method.
  • FAILED - return the keys that failed.
  • REPORTED - Return the erroneous keys and messages describing the error.

 

Now let's implement the check in the method. Since this is a simple mandatory field check, the logic is correspondingly simple and within the loop we generate the error message:

LOOP AT keys INTO DATA(ls_key) WHERE PartnerNumber IS INITIAL.
  INSERT VALUE #( PartnerNumber = ls_key-PartnerNumber ) INTO TABLE failed-partner.

  INSERT VALUE #(
    PartnerNumber = ls_key-PartnerNumber
     %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'PartnerNumber is mandatory' )
  ) INTO TABLE reported-partner.
ENDLOOP.

 

There are two helper methods for filling the message, which are available through inheritance. With "new_message" we can create a T100 message and with "new_message_with_text" a simple text is enough to output a message:

 

The message can then be output directly in the UI in the lower left corner. According to the classification via "severity", we can influence the color and the icon (as in the SAP GUI):

 

Field level validation

The next validation is only triggered when the corresponding field changes. This is particularly useful when we check against interfaces or tables whether this value exists in order to save performance.

 

Create

As in the first example of the article, the system is created via the behavior definition and the subsequent generation in the behavior implementation. This time we always check when the two master data fields change. From a performance point of view, we should then rather make two validations out of it:

validation validateCoreData on save { field Country, PaymentCurrency; }

 

Implement

We already looked at the method's interface in the first example, so you'll notice that only the keys are passed to the method. Now, to get the missing information, we need to read the data via EML. We can then loop over the data and compare it against the master data.

READ ENTITIES OF ZBS_I_RAPPartner IN LOCAL MODE
  ENTITY Partner
  FIELDS ( Country PaymentCurrency )
  WITH CORRESPONDING #( keys )
  RESULT DATA(lt_partner_data)
  FAILED DATA(ls_failed)
  REPORTED DATA(ls_reported).

LOOP AT lt_partner_data INTO DATA(ls_partner).
  SELECT SINGLE FROM I_Country
    FIELDS Country
    WHERE Country = @ls_partner-Country
    INTO @DATA(ld_found_country).
  IF sy-subrc <> 0.
    INSERT VALUE #( PartnerNumber = ls_partner-PartnerNumber ) INTO TABLE failed-partner.

    INSERT VALUE #(
      PartnerNumber = ls_partner-PartnerNumber
       %msg = new_message_with_text( text = 'Country not found in I_Country' )
       %element-country = if_abap_behv=>mk-on
    ) INTO TABLE reported-partner.
  ENDIF.

  SELECT SINGLE FROM I_Currency
    FIELDS Currency
    WHERE Currency = @ls_partner-PaymentCurrency
    INTO @DATA(ld_found_currency).
  IF sy-subrc <> 0.
    INSERT VALUE #( PartnerNumber = ls_partner-PartnerNumber ) INTO TABLE failed-partner.

    INSERT VALUE #(
      PartnerNumber = ls_partner-PartnerNumber
       %msg = new_message_with_text( text = 'Currency not found in I_Currency' )
       %element-paymentcurrency = if_abap_behv=>mk-on
    ) INTO TABLE reported-partner.
  ENDIF.
ENDLOOP.

 

In the example we used a few things that we want to explain again here:

  • READ - When reading, we didn't specify the key in the field selector, but it's automatically read as it's used to identify the entity.
  • LOCAL MODE - The verification of the user and the status is omitted, the system assumes that this was done before. Possible blocks by the user will be avoided.
  • %ELEMENT - When generating the error messages, we also specified and activated the element, which ensures that the field is also marked and the error message appears.

 

Complete

If you try the validation, you will find that it does not work when creating the entry. The set validation only reacts to changes in the field, which is not the case with the system since the data record does not yet exist. To do this, we also have to include the create, so that at least the validation is also carried out during the creation.

validation validateCoreData on save { create; field Country, PaymentCurrency; }

 

Complete example

The full example behavior definition and implementation can be found here.

 

Behavior definition
managed implementation in class zbp_bs_demo_rappartner unique;
strict;

define behavior for ZBS_I_RAPPartner alias Partner
persistent table zbs_dmo_partner
lock master
authorization master ( instance )
{
  create;
  update;
  delete;

  validation validateKeyIsFilled on save { create; }
  validation validateCoreData on save { create; field Country, PaymentCurrency; }

  mapping for zbs_dmo_partner
  {
    PartnerNumber = partner;
    PartnerName = name;
    Street = street;
    City = city;
    Country = country;
    PaymentCurrency = payment_currency;
  }
}

 

Behavior implementation
CLASS lhc_Partner DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
      IMPORTING keys REQUEST requested_authorizations FOR Partner RESULT result.

    METHODS validatekeyisfilled FOR VALIDATE ON SAVE
      IMPORTING keys FOR partner~validatekeyisfilled.

    METHODS validatecoredata FOR VALIDATE ON SAVE
      IMPORTING keys FOR partner~validatecoredata.
ENDCLASS.

CLASS lhc_Partner IMPLEMENTATION.
  METHOD get_instance_authorizations.
  ENDMETHOD.


  METHOD validateKeyIsFilled.
    LOOP AT keys INTO DATA(ls_key) WHERE PartnerNumber IS INITIAL.
      INSERT VALUE #( PartnerNumber = ls_key-PartnerNumber ) INTO TABLE failed-partner.

      INSERT VALUE #(
        PartnerNumber = ls_key-PartnerNumber
         %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'PartnerNumber is mandatory' )
      ) INTO TABLE reported-partner.
    ENDLOOP.
  ENDMETHOD.


  METHOD validateCoreData.
    READ ENTITIES OF ZBS_I_RAPPartner IN LOCAL MODE
      ENTITY Partner
      FIELDS ( Country PaymentCurrency )
      WITH CORRESPONDING #( keys )
      RESULT DATA(lt_partner_data)
      FAILED DATA(ls_failed)
      REPORTED DATA(ls_reported).

    LOOP AT lt_partner_data INTO DATA(ls_partner).
      SELECT SINGLE FROM I_Country
        FIELDS Country
        WHERE Country = @ls_partner-Country
        INTO @DATA(ld_found_country).
      IF sy-subrc <> 0.
        INSERT VALUE #( PartnerNumber = ls_partner-PartnerNumber ) INTO TABLE failed-partner.

        INSERT VALUE #(
          PartnerNumber = ls_partner-PartnerNumber
           %msg = new_message_with_text( text = 'Country not found in I_Country' )
           %element-country = if_abap_behv=>mk-on
        ) INTO TABLE reported-partner.
      ENDIF.

      SELECT SINGLE FROM I_Currency
        FIELDS Currency
        WHERE Currency = @ls_partner-PaymentCurrency
        INTO @DATA(ld_found_currency).
      IF sy-subrc <> 0.
        INSERT VALUE #( PartnerNumber = ls_partner-PartnerNumber ) INTO TABLE failed-partner.

        INSERT VALUE #(
          PartnerNumber = ls_partner-PartnerNumber
           %msg = new_message_with_text( text = 'Currency not found in I_Currency' )
           %element-paymentcurrency = if_abap_behv=>mk-on
        ) INTO TABLE reported-partner.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Conclusion

The validations are a powerful tool to keep your data clean within the business object and to ensure that only valid information is stored. Accordingly, when creating your RAP BO, you should consider which information should be validated and when.


Included topics:
RAPBTPValidation
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


RAP - Deep Action in OData v4

Category - ABAP

In this article we will look at actions with deep structures, how we can create them and pass data to an API endpoint.

05/24/2024

BTP - Connect On-Premise (Consumption Model v2)

Category - ABAP

In this article we want to provide another update on the connection of on-premise systems and how this is done with a communication arrangement.

12/15/2023

RAP - Show app count (Tile)

Category - ABAP

This example is about displaying a counter on the tile of a Fiori Elements application and how such a thing can be implemented.

10/06/2023

RAP - Generator (Fiori)

Category - ABAP

In this article we will look at the more complex RAP generator as a Fiori Elements application and what advantages you have with it.

09/15/2023

RAP - Generator (ADT)

Category - ABAP

Today, let's take a look at the RAP Generator, which is already integrated into ABAP Development Tools, and how you can use it to easily build new RAP apps.

09/08/2023