Skip to Content

ABAP CORONA VIRUS REPORT

I open this topic as a question because I do not have the right to write a blog.

I want to tell you a little bit of my story. I came to the city of Krakow on 11 March 2020. I had previously rented an apartment. My intention was to visit the Auschwitz concentration camp. But two days before I arrived, the Polish government decided to close all museums temporarily. Unfortunately, my host did not let me know. I continued to stay there, thinking that I could at least see the historical Krakow streets. After 2 days, I learned that the Polish government closed all borders and the flights were suspended. The host told me that I couldn't stay there any longer and asked me to evacuate the house. He said that this was the decision of the Polish government that I could not stay any longer. It is obvious that he tried to fool me. I came to Warsaw from Kraków, dealing with an uber driver. I started looking for a laptop in a city I never knew, all the shops were closed luckily, I found one. I'm staying in a hotel in Warsaw. The owner of the hotel, Richard, said that “we will keep you alive, don’t worry”. If we do not count the person trying to get me out of the apartment, the Polish people are friendly, warm and helpful. I was talking with Chief this morning, he told me that I was the only person staying at the hotel, there is no longer a guest at the hotel and lost his job.

I did some research because I go out to buy food from the market once a day and I didn't know anyone here, or even I didn't know the city. I reached the API of the worldometers site, where I follow the developments related to Corona virus, from GITHUB.

I am sharing the sample Abap code for you below. I guess the code is clear. Actually I can write it better but this was only time killing activity. Sorry for Hardcodes and repeated codes. I would like to draw your attention to only one subject, there are some special characters in the response of JSON, for example "Tot Deaths / 1M pop". Make sure you don't delete any special characters when you want to copy and test. Because these characters do not appear and be sure to install the STRUST certificate on the system you want to test.

*&---------------------------------------------------------------------*
*& Report YCORONA
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ycorona.

CLASS lcl_covid_19 DEFINITION.

  PUBLIC SECTION.
    TYPES: BEGIN OF mtt_corona,
             country          TYPE string,
             total_cases      TYPE string,
             new_cases        TYPE string,
             total_deaths     TYPE string,
             new_deaths       TYPE string,
             total_recovered  TYPE string,
             active_cases     TYPE string,
             serious_critical TYPE string,
             tot_cases_1m_pop TYPE string,
           END OF mtt_corona.
    TYPES: mty_corona TYPE TABLE OF mtt_corona.
    METHODS: call_corona_api.

  PROTECTED SECTION.

  PRIVATE SECTION.
    METHODS: process_data IMPORTING VALUE(iv_response) TYPE string
                          EXPORTING VALUE(rt_corona)   TYPE mty_corona.
    METHODS: dispay_report IMPORTING VALUE(it_corona)  TYPE mty_corona.

ENDCLASS.
CLASS lcl_covid_19 IMPLEMENTATION.
  METHOD call_corona_api.
    DATA: lo_http_client TYPE REF TO if_http_client,
          lo_response    TYPE REF TO if_rest_entity,
          lo_request     TYPE REF TO if_rest_entity,
          lr_data        TYPE REF TO data,
          lv_url         TYPE string VALUE 'https://covid19-server.chrismichael.now.sh/api/v1/AllReports',
          response       TYPE string,
          lt_corona      TYPE TABLE OF mtt_corona.

    cl_http_client=>create_by_url( EXPORTING url = lv_url
                                    IMPORTING client             = lo_http_client  ).
    DATA(lo_rest_client) = NEW cl_rest_http_client( io_http_client = lo_http_client ).
    lo_http_client->request->set_version( if_http_request=>co_protocol_version_1_0 ).
    IF lo_http_client IS BOUND AND lo_rest_client IS BOUND.
      cl_http_utility=>set_request_uri( EXPORTING request = lo_http_client->request  uri = lv_url  ).

* Set Payload or body ( JSON or XML)
      lo_request = lo_rest_client->if_rest_client~create_request_entity( ).
      lo_request->set_content_type( iv_media_type = if_rest_media_type=>gc_appl_json ).
      lo_rest_client->if_rest_client~set_request_header( EXPORTING iv_name  = 'Content-Type'
                                                                   iv_value = 'application/json' ).
* GET
      lo_rest_client->if_rest_resource~get(  ).
* Collect response
      lo_response = lo_rest_client->if_rest_client~get_response_entity( ).
      response = lo_response->get_string_data( ).
      me->process_data( EXPORTING iv_response = response
                        IMPORTING rt_corona   = lt_corona ).
      me->dispay_report( it_corona = lt_corona ).
    ENDIF.
  ENDMETHOD.
  METHOD process_data.

    DATA: ls_corona TYPE mtt_corona,
          lv_name   TYPE char70,
          off_set   TYPE i,
          lv_string TYPE string,
          lr_data   TYPE REF TO data.
* deserialize JSON string json into internal table lt_flight doing camelCase to ABAP like field name mapping
    FIND FIRST OCCURRENCE OF '"table"' IN iv_response MATCH OFFSET off_set.
    DATA(lv_len) =  strlen( iv_response ).
    lv_len = lv_len - off_set - 2.
    lv_string = iv_response+off_set(lv_len).

    CONCATENATE '{' lv_string  INTO lv_string.
    REPLACE ALL OCCURRENCES OF 'Country,Other'     IN lv_string WITH 'CountryOther'.
    REPLACE ALL OCCURRENCES OF 'Serious,Critical'  IN lv_string WITH 'SeriousCritical'.
    REPLACE ALL OCCURRENCES OF 'Tot Cases/1M pop'  IN lv_string WITH 'TotCasesMPop'.
    REPLACE ALL OCCURRENCES OF 'Tot Deaths/1M pop' IN lv_string WITH 'TotDeathsMPop'.
    /ui2/cl_json=>deserialize( EXPORTING json = lv_string pretty_name = /ui2/cl_json=>pretty_mode-camel_case CHANGING data = lr_data ).

    lv_name = 'LR_DATA->TABLE->*[1]->*'.
    ASSIGN lr_data->* TO FIELD-SYMBOL(<fs_data>).

    lv_name = '<FS_DATA>-TABLE->*'.
    FIELD-SYMBOLS: <fs_corona> TYPE ANY TABLE,
                   <fs_table>  TYPE ANY TABLE.

    ASSIGN (lv_name) TO <fs_table>.
    LOOP AT <fs_table> ASSIGNING FIELD-SYMBOL(<fs_line>).
      lv_name = '<FS_LINE>->*'.
      ASSIGN (lv_name) TO <fs_corona>.
      EXIT.
    ENDLOOP.
    LOOP AT <fs_corona> ASSIGNING FIELD-SYMBOL(<fs_reports>).
      lv_name = '<FS_REPORTS>->*'.
      ASSIGN (lv_name) TO FIELD-SYMBOL(<fs_str>).

      ASSIGN COMPONENT 'ACTIVE_CASES' OF STRUCTURE <fs_str> TO FIELD-SYMBOL(<fs_field>).
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO FIELD-SYMBOL(<fs_value>).
        IF <fs_value> IS ASSIGNED.
          ls_corona-active_cases = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'COUNTRY' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-country = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'NEW_CASES' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-new_cases = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'NEW_DEATHS' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-new_deaths = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'SERIOUS_CRITICAL' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-serious_critical = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'TOT_CASES_1M_POP' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-tot_cases_1m_pop = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'TOTAL_CASES' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-total_cases = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'TOTAL_DEATHS' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-total_deaths = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.

      ASSIGN COMPONENT 'TOTAL_RECOVERED' OF STRUCTURE <fs_str> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        lv_name = '<FS_FIELD>->*'.
        ASSIGN (lv_name) TO <fs_value>.
        IF <fs_value> IS ASSIGNED.
          ls_corona-total_recovered = <fs_value>.
          UNASSIGN <fs_value>.
        ENDIF.
        UNASSIGN: <fs_field>.
      ENDIF.
      APPEND ls_corona TO rt_corona.
      CLEAR: ls_corona.
    ENDLOOP.
  ENDMETHOD.
  METHOD dispay_report.
    DATA: lo_alv   TYPE REF TO cl_salv_table.
    TRY.
        cl_salv_table=>factory(
          IMPORTING
            r_salv_table = lo_alv
          CHANGING
            t_table      = it_corona ).
        DATA(display_settings) =  lo_alv->get_display_settings( ).
        display_settings->set_striped_pattern( if_salv_c_bool_sap=>true ).
        display_settings->set_list_header( 'Corona Live Report' ).
        DATA(lo_columns) = lo_alv->get_columns( ).
        lo_columns->set_optimize( abap_true ).
        TRY .
            DATA(lr_column) = lo_columns->get_column( 'COUNTRY' ).
            lr_column->set_short_text( 'Cntry' ).
            lr_column->set_medium_text( 'Country,Other' ).
            lr_column->set_long_text( 'Country,Other' ).
          CATCH cx_salv_not_found INTO DATA(not_found).
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'TOTAL_CASES' ).
            lr_column->set_short_text( 'TotCases' ).
            lr_column->set_medium_text( 'Total Cases' ).
            lr_column->set_long_text( 'Total Cases' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'NEW_CASES' ).
            lr_column->set_short_text( 'NewCases' ).
            lr_column->set_medium_text( 'New Cases' ).
            lr_column->set_long_text( 'New Cases' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'TOTAL_DEATHS' ).
            lr_column->set_short_text( 'TotDeaths' ).
            lr_column->set_medium_text( 'Total Deaths' ).
            lr_column->set_long_text( 'Total Deaths' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.


        TRY .
            lr_column = lo_columns->get_column( 'NEW_DEATHS' ).
            lr_column->set_short_text( 'NewDeaths' ).
            lr_column->set_medium_text( 'New Deaths' ).
            lr_column->set_long_text( 'New Deaths' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'TOTAL_RECOVERED' ).
            lr_column->set_short_text( 'TRecovered' ).
            lr_column->set_medium_text( 'Total Recovered' ).
            lr_column->set_long_text( 'Total Recovered' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'ACTIVE_CASES' ).
            lr_column->set_short_text( 'ActvCases' ).
            lr_column->set_medium_text( 'Active Cases' ).
            lr_column->set_long_text( 'Active Cases' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'SERIOUS_CRITICAL' ).
            lr_column->set_short_text( 'SerCritic' ).
            lr_column->set_medium_text( 'Serious Critical' ).
            lr_column->set_long_text( 'Serious Critical' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        TRY .
            lr_column = lo_columns->get_column( 'TOT_CASES_1M_POP' ).
            lr_column->set_short_text( 'Tot 1M Pop' ).
            lr_column->set_medium_text( 'Total Cases 1M Pop' ).
            lr_column->set_long_text( 'Total Cases 1M Pop' ).
          CATCH cx_salv_not_found INTO not_found.
        ENDTRY.

        lo_alv->display( ).
      CATCH cx_salv_msg INTO DATA(err).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  NEW lcl_covid_19( )->call_corona_api( ).
capture.png (49.9 kB)
Add comment
10|10000 characters needed characters exceeded

  • Please rewrite this as a blog! It needs a wider audience.

  • Hi Matthew,

    Unfortunately, I cannot write a blog. Although I follow all the steps and update my profile, I still get the following error.

    "You have not achieved the blogging permission level required to perform this action. To learn more about user levels."
  • Hasan Tugay Birihan, did you

    1. check the resource about blogging in the SAP community
    2. successfully finish the Tour the SAP Community tutorial
    3. achieved the Contributor Level

    Here is the most important info from the above mentioned resource:

    Blogger levels

    To become a blogger in the SAP Community, you must go through a two-step process that will help familiarize you with our community’s culture and rules. The purpose of this process is to ensure the SAP Community provides the best information possible.

    Subscriber: entry level

    When new members register on SAP.com, they start automatically at the Subscriber level. A Subscriber has authorization to comment on blog posts, but cannot create them. To move to Contributor level, a Subscriber must complete the Tour the SAP Community tutorial. (Note: If you experience any issues with blogging levels, please send an email to community@sap.com.)

    Contributor:  learner level

    A Contributor can write blog posts, but cannot publish them independently. A moderator will review the blog post draft once the Contributor has submitted it for review and determine whether the post complies with the Rules of Engagement. The moderator can decide whether the post needs more work before publishing, as well as provide feedback and tips to help the member improve the post. Once the Contributor has two or more published blog posts, he or she automatically becomes an Author.

3 Answers

  • Posted on Mar 26 at 09:38 AM

    Hasan Tugay Birihan, thanks for your contribution to the ABAP community! Stay strong and healthy.

    In case anyone wants to find out more about the origin of the called URL, the different available APIs and the collected data by Chris Michael:

    The developer also provides a website to show his APIs in action, however, it is also in development stage, so not all functions are working or not available as of right now:

    Add comment
    10|10000 characters needed characters exceeded

  • Posted on Mar 26 at 03:40 AM

    Where are you from,bro?

    Add comment
    10|10000 characters needed characters exceeded

  • Posted on Mar 26 at 08:12 AM

    Nice job. I wish you lot of courage and patience to you!

    Add comment
    10|10000 characters needed characters exceeded